
Company News
Free Business Plan Upgrades for Open Source Maintainers
Open source maintainers are under more pressure than ever. We're raising our open source program from the Team plan to the Business plan, free.
@getpopapi/n8n-nodes-pop
Advanced tools
n8n community node for POP Cloud API (v2) — Italian SdI and Peppol e-invoicing
Community node for n8n that integrates with POP for automated electronic invoicing.
POP is an e-invoicing platform that automates the generation, delivery, and management of legally compliant electronic invoices. It supports both the Italian SdI (Sistema di Interscambio / FatturaPA) and the European Peppol network.
This node lets you create, send, and track electronic invoices directly from n8n workflows. Authenticate once with a POP credential (sent as the X-API-Key header) or supply the license key per operation — both are supported.
Follow the n8n community nodes installation guide.
@getpopapi/n8n-nodes-pop🔑 New to POP? Visit popapi.io to create your account and get your license key.
API-only users can activate their account and obtain a license_key with this flow:
license_keyKey management:
license_key, visible under Account > APIlicense_key must be treated as a secret credential — do not commit it to source controlRecommended first steps:
license_keyGET /account-profilePOP (v2) accepts the license key in two forms:
| Method | How | Status |
|---|---|---|
X-API-Key HTTP header | X-API-Key: <your_license_key> | Preferred |
license_key body param | { "license_key": "<your_license_key>", ... } | Legacy fallback |
When both are present, the header wins. The body fallback exists so older POP deployments continue to work without changes.
This node supports two ways of supplying the key, which can be combined:
X-API-Key: <your_license_key> on every request automatically.X-API-Key header and as license_key in the request body. Useful when one workflow needs to drive multiple licenses.For Use Incoming JSON, JSON, and Raw input modes the credential is the simplest option — the header is injected automatically. You can still embed license_key in the body if you prefer; the API accepts both.
| Mode | X-API-Key header | license_key in body |
|---|---|---|
| Form (key field set) | The form field value (overrides credential) | The form field value |
| Form (key field empty) | Credential value (if any) | Empty ("") — relies on header auth |
| Use Incoming JSON | Credential value (if any) | Whatever the upstream item provides |
| JSON | Credential value (if any) | Whatever you put in the JSON body |
| Raw | Credential value (if any) | n/a (raw payload) |
The Verify SdI Document (XML) operation auto-detects the license key from the upstream Create SdI Invoice node — that detected key is sent both as the header and in the body, taking precedence over the credential.
If you operate your own POP deployment, make sure it includes the auth-header support — see LicenseHelper::buildLicenseInfo and Utils::apiPermissionCallback in pop-cloud-api, which prefer X-API-Key and fall back to license_key. Older deployments without that change still work because this node also sends license_key in the body whenever it has a key to send.
Each invoice operation includes an Environment selector. The published node exposes only Production (https://popapi.io/wp-json/api/v2/).
Note for developers: The Staging option (
https://staging7.popapi.io/wp-json/api/v2/) is commented out in the source and can be re-enabled locally for testing against a staging deployment.
Generates an Italian e-invoice in FatturaPA format and optionally submits it to the Sistema di Interscambio.
POST /create-xmlYes to include the SdI integration object and trigger submission via POPGenerates a Peppol invoice in UBL format and optionally submits it to the Peppol network.
POST /create-ublYes to include the Peppol integration objectGenerates a Polish KSeF FA(3) invoice or credit note.
POST /create-ksef-xmlGenerates a ZUGFeRD/Factur-X package containing visual PDF, CII XML, and hybrid PDF output.
POST /create-zugferdRetrieves document notifications for a previously submitted SdI invoice.
POST /sdi/document-notifications{ license_key, integration: { uuid } }Retrieves a Peppol document by integration UUID.
POST /peppol/document-get{ license_key, integration: { uuid, zone? } }zone field (e.g. "BE") is required for Belgian VAT numbers; it is normalised to uppercase automaticallyValidates an SdI XML document via the POP document-verify endpoint. Designed to be used immediately after Create SdI Invoice (XML) in a workflow — it reads the XML from the incoming item, base64-encodes it, and auto-detects the license key from the upstream node.
POST /sdi/document-verify{ license_key, skip_business_check: true, integration: { xml: "<base64-encoded XML>" } }Syncs an invoice or credit note to Zoho Books/Invoice via POP's native Zoho connector. All Zoho-side mapping (tax, customer, payment terms, document status) happens server-side in the POP API — this node only gates the request and forwards the payload.
Yes (the default), the node first calls GET /integration/zoho/status and confirms data.active_connector === "zoho" and data.zoho_connected === true. If the connector isn't active, the operation fails immediately with a clear error instead of attempting the sync.POST /integration/zoho/syncTD01 (Invoice) or TD04 (Credit Note).id, e.g. [{"id": 123}]. The node validates this locally before sending the request and fails fast if it's missing.{
"connector_active": true,
"status_checked": true,
"sync_attempted": true,
"response": { "...": "raw POP API response" }
}
Before you can use Sync Document to Zoho, you need to connect your Zoho account to POP. This is a one-time setup done in the POP dashboard, not in n8n. Full documentation: docs.popapi.io/en/api/zoho.
Go to popapi.io/my-account/api-integrations/zoho-connector/connect and log in to your POP account.
Choose the Zoho product you actually use:
Once connected, POP will create invoices or credit notes directly in that Zoho account.
Create a Zoho OAuth app:
https://popapi.io/it/wp-json/api/v2/integration/oauth/callback?connector=zoho
?connector=zoho.Copy the credentials into POP:
Save and authorize the connection. Once active_connector is zoho and the connection shows as connected, the Sync Document to Zoho operation in this node will succeed (you can verify this with Check Connector Status First = Yes, the default).
Validates a VAT number against the official EU VIES (VAT Information Exchange System) SOAP service.
https://ec.europa.eu/taxation_customs/vies/services/checkVatServiceXI)valid (boolean), name, address, requestDate, attempts (number of retries), latencyMs| Field | Description |
|---|---|
| Country Code | EU country code from dropdown (e.g. IT, DE, EL, XI) |
| VAT Number | VAT number without the country prefix (e.g. 01234567890) |
Most invoice operations support the same four input modes:
| Mode | Description |
|---|---|
| Use Incoming JSON | Forwards the input item's JSON data directly to the API. Default mode, ideal for automated pipelines. |
| Form Fields | Structured form with all relevant fields. Best for manual entry or mapping from other nodes. |
| JSON | Paste or build the full request JSON payload manually. |
| Raw (XML/Other) | Send a raw string body (e.g. XML). Sets Content-Type: application/xml unless overridden via headers. |
Sync Document to Zoho only supports Use Incoming JSON, Form Fields, and JSON — the integration/zoho/sync endpoint accepts JSON only, so Raw is not offered for this operation.
The Form Fields input mode for Create SdI Invoice (XML) and Create Peppol Invoice (UBL) exposes the following sections. Fields marked with an asterisk (*) are required.
| Field | SDI | Peppol | Description |
|---|---|---|---|
| License Key | ✓ | ✓ | POP license key. Optional when a POP credential is configured. When set, sent both as X-API-Key header and license_key body param. |
Invoice / Order ID * | ✓ | ✓ | Numeric ID of the invoice or order |
Filename * | ✓ | ✓ | FatturaPA / Peppol filename (e.g. IT99900088876_00009) |
Customer Type * | ✓ | ✓ | Private / Company / Freelance (Peppol: no Private) |
SDI Type (Codice Destinatario) * | ✓ | — | SdI destination code (7 chars). Defaults to 0000000 for private customers without a code; forced to XXXXXXX for foreign clients |
Invoice Number * | ✓ | ✓ | Full invoice number (e.g. WEB9/2025) |
Invoice Date * | ✓ | ✓ | Invoice date in YYYY-MM-DD format |
Total Document Amount * | ✓ | ✓ | Total amount including taxes |
| Field | SDI | Peppol | Description |
|---|---|---|---|
| Country | ✓ | ✓ | ISO country code of the transmitter |
| ✓ | ✓ | Transmitter contact email | |
| ID Code | ✓ | ✓ | Transmitter identification code |
| Phone | ✓ | ✓ | Transmitter contact phone |
| Progressive | ✓ | — | Progressive identifier for the transmission |
| Recipient PEC | ✓ | — | PEC (certified email) of the recipient |
| SDI Code | ✓ | — | Codice destinatario SdI (7 chars) |
| Transmitter Format | ✓ | ✓ | FPR12 (Private) or FPA12 (Public Admin) |
| Field | SDI | Peppol | Description |
|---|---|---|---|
| Address | ✓ | ✓ | Street address |
| City | ✓ | ✓ | City name |
| Company Name | ✓ | ✓ | Company or business name |
| Country | ✓ | ✓ | ISO country code of the sender address |
| ✓ | ✓ | Contact email | |
| Phone | ✓ | ✓ | Contact phone |
| Province | ✓ | ✓ | Province abbreviation (e.g. CT, MI) |
| Tax Regime | ✓ | — | Italian tax regime code (e.g. RF01 — Ordinary) |
| VAT Country | ✓ | ✓ | ISO country code for VAT identification |
| VAT ID Code | ✓ | ✓ | Full VAT identification code |
| ZIP Code | ✓ | ✓ | Postal / ZIP code |
| Field | SDI | Peppol | Description |
|---|---|---|---|
| Address | ✓ | ✓ | Street address |
| City | ✓ | ✓ | City name |
| Company Name | ✓ | ✓ | Company name (leave empty for individuals) |
| Country | ✓ | ✓ | ISO country code of the recipient address |
| ✓ | ✓ | Email address | |
| First Name | ✓ | ✓ | First name (individuals) |
| Last Name | ✓ | ✓ | Last name (individuals) |
| Province | ✓ | ✓ | Province abbreviation |
| Tax ID Code (Codice Fiscale) | ✓ | — | Italian fiscal code of the recipient |
| VAT Country | ✓ | ✓ | ISO country code for VAT identification |
| VAT ID Code | ✓ | ✓ | VAT identification code |
| ZIP Code | ✓ | ✓ | Postal / ZIP code |
| Field | Description |
|---|---|
| Document Type | TD01 (Invoice) or TD04 (Credit Note) |
| Currency | ISO 4217 currency code (default: EUR) |
| Invoice Prefix | Prefix portion of the invoice number (e.g. WEB) |
| Invoice Suffix | Suffix portion of the invoice number (e.g. 2025) |
Each line item supports multiple values. Fields apply to both SDI and Peppol unless noted.
| Field | Description |
|---|---|
Description * | Item description text |
| Discount | No (default) or Yes. When Yes, sets discount_type = SC in the payload |
| Discount Percent | Required when Discount is Yes. Percentage to apply (e.g. 10.00) |
| Gift Product | No or Yes — whether the item is a gift / free product |
| Item Code Type | Type of item code (e.g. INTERNO, EAN) |
| Item Code Value | Value of the item code |
| Item Type | Product, Shipping, or Fee |
| Quantity | Quantity (e.g. 1.00) |
| Total Tax | Tax amount for this line item |
| Unit | Unit of measure (e.g. N., KG, LT) |
| Unit Price | Price per unit (e.g. 4.09) |
| VAT Rate | VAT rate percentage (e.g. 22.00, 10.00, 0.00) |
Discount behaviour: When Discount is set to
Yes, Discount Percent is required. Thediscount_amountandtotal_priceare automatically calculated by the node — they are not editable inputs:
total_price = unit_price × quantitydiscount_amount = total_price × discount_percent / 100total_price(sent to API)= total_price − discount_amount
Payment Method — select from the dropdown (code is sent in the payload):
| Label | Payload value |
|---|---|
| Bank Transfer | MP05 |
| Cash | MP01 |
| Check | MP02 |
| Credit Card | MP08 |
| Direct Debit | MP16 |
| PagoPA | MP23 |
| RIBA | MP12 |
| SEPA Core Direct Debit | MP21 |
| SEPA Direct Debit | MP19 |
| Special Account RIBA | MP15 |
| Withholding on Payments | MP22 |
Payment Data (fixedCollection):
| Field | Description |
|---|---|
| Payment Amount | Amount to be paid (typically equals the total document amount) |
| Payment Terms | TP01 (Instalment), TP02 (Full — default), TP03 (Advance) |
Bank Details — shown only when Payment Method is Bank Transfer:
| Field | Description |
|---|---|
Beneficiary * | Name of the payment beneficiary |
Financial Institution * | Name of the bank or institution |
IBAN * | IBAN for bank transfer payments |
Optional advanced fields available in both SDI and Peppol form modes:
| Field | Description |
|---|---|
| Connected Invoice Data (JSON) | Connected invoice references as a JSON array |
| Document Type (String) | Document type string (e.g. invoice, credit_note) |
| Purchase Order Date | Date of the related purchase order (YYYY-MM-DD) |
| Purchase Order ID | Reference to the related purchase order |
| Tax Exemption Reason | Normative reference text for VAT exempt operations |
| VAT Exemption Code | Nature code for VAT exempt operations (e.g. N1, N2, N3, N4) |
| VIES | Whether the transaction is intra-EU and VIES validated (true/false) |
[Webhook] → [POP: Create SdI Invoice] → [POP: Verify SdI Document] → [POP: Get Invoice Status] → [Slack]
[Manual Trigger] → [POP: Validate VAT] → [IF: valid?] → [Send Invoice / Flag for review]
valid field to decide whether to proceed with invoicingPOST /create-xml{
"license_key": "your_license_key",
"data": {
"id": 2575,
"filename": "IT99900088876_00009",
"type": "invoice",
"version": "FPR12",
"sdi_type": "",
"customer_type": "private",
"nature": "",
"ref_normative": null,
"vies": false,
"transmitter_data": {
"transmitter_id": { "country_id": "IT", "id_code": "IT99900088876" },
"progressive": "5b27a73cab",
"transmitter_format": "FPR12",
"sdi_code": "0000000",
"transmitter_contact": { "phone": "", "email": "" },
"recipient_pec": ""
},
"transfer_lender": {
"personal_data": {
"tax_id_vat": { "country_id": "IT", "id_code": "IT99900088876", "tax_regime": "RF01" },
"company_name": "TEST123"
},
"place": { "address": "Via Roma, 123", "zip_code": "95100", "city": "Catania", "province_id": "CT", "country_id": "IT" },
"contact": { "phone": "", "email": "" }
},
"transferee_client": {
"personal_data": {
"tax_id_vat": { "country_id": "IT", "id_code": "" },
"tax_id_code": "PCCLFA75L04A494S",
"company_name": "",
"first_name": "Alfio",
"last_name": "Piccione"
},
"place": { "address": "Via Roma 123", "zip_code": "95100", "city": "Catania", "province_id": "CT", "country_id": "IT" }
},
"invoice_body": {
"general_data": {
"doc_type": "TD01",
"currency": "EUR",
"date": "2025-01-31",
"invoice_number": "WEB9/2025",
"invoice_prefix": "WEB",
"invoice_suffix": "2025"
},
"total_document_amount": "16.38"
},
"purchase_order_data": { "id": "#2575", "date": "2025-01-31" },
"connected_invoice_data": [],
"order_items": [
{
"item_code": { "type": "INTERNO", "value": "2563" },
"item_type": "product",
"gift_product": "no",
"description": "Product A",
"quantity": "1.00",
"unit": "N.",
"discount_type": "",
"discount_percent": "",
"discount_amount": "",
"unit_price": "4.09",
"total_price": "4.09",
"rate": "0.00",
"total_tax": 0
}
],
"payment_data": {
"terms_payment": "TP02",
"payment_amount": "16.38",
"payment_details": "MP02",
"beneficiary": "",
"financial_institution": "",
"iban": ""
}
},
"integration": {
"use": "sdi-via-pop",
"action": "create"
}
}
POST /create-ubl{
"license_key": "your_license_key",
"data": {
"id": 2855,
"xml_style": "",
"view": false,
"save": false,
"save_bulk": false,
"filename": "BE0123456789_0000T",
"type": "invoice",
"version": "FPR12",
"sdi_type": "",
"customer_type": "company",
"nature": "",
"ref_normative": null,
"vies": false,
"transmitter_data": {
"transmitter_id": { "country_id": "BE", "id_code": "BE0123456789" },
"progressive": "cea0d365b4",
"transmitter_format": "FPR12",
"sdi_code": "0000000",
"transmitter_contact": { "phone": "", "email": "info@company.com" },
"recipient_pec": ""
},
"transfer_lender": {
"personal_data": {
"tax_id_vat": { "country_id": "BE", "id_code": "BE0123456789", "tax_regime": "" },
"company_name": "My Company SRL"
},
"place": { "address": "Via Roma, 123", "zip_code": "1000", "city": "Brussels", "province_id": "", "country_id": "BE" },
"contact": { "phone": "", "email": "info@company.com" }
},
"transferee_client": {
"personal_data": {
"tax_id_vat": { "country_id": "BE", "id_code": "BE0727506532" },
"tax_id_code": "",
"company_name": "Client Company NV",
"first_name": "",
"last_name": ""
},
"place": { "address": "Rue du Test 12", "zip_code": "4444", "city": "Liege", "province_id": "", "country_id": "BE" }
},
"invoice_body": {
"general_data": {
"doc_type": "TD01",
"currency": "EUR",
"date": "2025-10-03",
"invoice_number": "WEB097/2025",
"invoice_prefix": "WEB",
"invoice_suffix": "2025"
},
"total_document_amount": "4.80"
},
"purchase_order_data": { "id": "#2855", "date": "2025-10-03" },
"connected_invoice_data": [],
"order_items": [
{
"item_code": { "type": "INTERNO", "value": "2636" },
"item_type": "product",
"gift_product": null,
"description": "Product B",
"quantity": "1.00",
"unit": "N.",
"discount_type": "",
"discount_percent": "",
"discount_amount": "",
"unit_price": "4.80",
"total_price": "4.80",
"rate": "0.00",
"total_tax": 0
}
],
"payment_data": {
"terms_payment": "TP02",
"payment_amount": "4.80",
"payment_details": "MP01",
"beneficiary": "",
"financial_institution": "",
"iban": ""
}
},
"integration": {
"use": "peppol-via-pop",
"action": "create"
}
}
POST /sdi/document-notifications{
"license_key": "your_license_key",
"integration": {
"uuid": "your-integration-uuid"
}
}
POST /peppol/document-get{
"license_key": "your_license_key",
"integration": {
"uuid": "your-integration-uuid",
"zone": "BE"
}
}
POST /sdi/document-verifyThis operation has no manual payload — it is always passthrough. The node reads the XML from the incoming item (output of Create SdI Invoice (XML)), base64-encodes it, and auto-detects the license key from the upstream node.
The request sent to the API looks like:
{
"license_key": "<auto-detected from upstream node>",
"skip_business_check": true,
"integration": {
"xml": "<base64-encoded FatturaPA XML>"
}
}
POST /integration/zoho/syncInvoice (TD01):
{
"license_key": "your_license_key",
"data": {
"id": 0,
"filename": "",
"type": "invoice",
"customer_type": "private",
"transferee_client": {},
"invoice_body": {
"general_data": {
"doc_type": "TD01",
"date": "2025-01-31",
"currency": "EUR"
}
},
"order_items": [{}]
}
}
Credit note (TD04) — requires connected_invoice_data:
{
"license_key": "your_license_key",
"data": {
"id": 0,
"filename": "",
"type": "invoice",
"customer_type": "private",
"transferee_client": {},
"invoice_body": {
"general_data": {
"doc_type": "TD04",
"date": "2025-01-31",
"currency": "EUR"
}
},
"connected_invoice_data": [{ "id": 123 }],
"order_items": [{}]
}
}
The status check that runs first (unless disabled) calls GET /integration/zoho/status with no body.
This operation calls the EU VIES SOAP service, not the POP Cloud API.
Example response:
{
"valid": true,
"name": "GOOGLE ITALY S.R.L.",
"address": "VIA FEDERICO CONFALONIERI 4\n20124 MILANO MI",
"requestDate": "2026-04-02",
"attempts": 1,
"latencyMs": 412
}
n8n-nodes-pop/
├── nodes/Pop/
│ ├── Pop.node.ts # Node definition and metadata
│ ├── Pop.node.json # Codex metadata (categories, aliases, docs links)
│ ├── pop.svg # Node icon
│ ├── router.ts # Per-item operation dispatcher
│ ├── types/pop.ts # TypeScript resource/operation type map
│ ├── utils/request.ts # Shared HTTP helper (base URL + error wrapping)
│ ├── invoices/
│ │ ├── index.ts # Operation aggregator for the invoices resource
│ │ ├── invoiceFields.ts # Form field factory (shared by SdI, Peppol, and Zoho)
│ │ ├── invoicePayloadBuilder.ts # Assembles API payloads from form values
│ │ ├── createSdiInvoiceXml.ts # Operation: Create SdI Invoice
│ │ ├── createPeppolInvoiceUbl.ts# Operation: Create Peppol Invoice
│ │ ├── createKsefInvoiceXml.ts # Operation: Create KSeF FA(3) XML
│ │ ├── createZugferdInvoice.ts # Operation: Create ZUGFeRD package
│ │ ├── getInvoiceStatus.ts # Operation: Get Invoice Status
│ │ ├── getPeppolDocument.ts # Operation: Get Peppol Document
│ │ ├── verifySdiDocument.ts # Operation: Verify SdI Document (XML)
│ │ └── syncZohoDocument.ts # Operation: Sync Document to Zoho
│ └── vies/
│ ├── index.ts # Operation aggregator for the vies resource
│ └── validateVat.ts # Operation: Validate VAT (EU VIES SOAP)
├── package.json
├── tsconfig.json
└── eslint.config.mjs
.nvmrc: nvm use)npm install # Install dependencies
npm run build # Compile TypeScript → dist/
npm run lint # Check for linting issues
npm run lint:fix # Auto-fix linting issues where possible
npm run dev # Start watch mode + n8n
npm run dev (via @n8n/node-cli):
~/.n8n-node-cli/.n8n/custom/node_modules/tsc --watch, which recompiles on every file saven8n@latest via npx (first run may take a while)N8N_DEV_RELOAD=true so n8n picks up changes automaticallyOpen http://localhost:5678, search for POP in the node panel, and start testing. Code changes are picked up automatically — no restart needed.
npm login # Log in to your npm account
npm run release # Builds, versions, and publishes via @n8n/node-cli
From May 1st, 2026, all community nodes must be published via a GitHub Action that includes a provenance statement. See the n8n community node publishing guide for details.
MIT — Babini Mazzari S.r.l.
FAQs
n8n community node for POP Cloud API (v2) — Italian SdI and Peppol e-invoicing
The npm package @getpopapi/n8n-nodes-pop receives a total of 173 weekly downloads. As such, @getpopapi/n8n-nodes-pop popularity was classified as not popular.
We found that @getpopapi/n8n-nodes-pop demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Company News
Open source maintainers are under more pressure than ever. We're raising our open source program from the Team plan to the Business plan, free.

Security News
The supply chain control that delays freshly published gems now covers lockfile generation and gem vendoring in Ruby projects.

Security News
During a UK cyber test, a Mythos 5 agent used sockpuppets, social engineering, and prompt injection to try to get a maintainer to merge malware.