# pop-mcp [Health: Active]

**Category:** 💻 Developer Tools  
**Repository:** https://github.com/getpopapi/pop-mcp  
**GitHub Stars:** 0  
**Views:** 0  
**Installs:** 0  
**Upvotes:** 0  
**Directory Page:** https://allmcps.com/mcp/pop-mcp

## Description
Italian e-invoicing (FatturaPA/SdI), Peppol, and PDF invoice generation via POP

## Claude Desktop Quick Installation
Install path detected from listing signals. Uses `npx` (confidence: high):

```json
"mcpServers": {
  "pop-mcp": {
    "command": "npx",
    "args": ["-y","@modelcontextprotocol/inspector"]
  }
}
```

## Documentation & README

<!-- mcp-name: io.github.popapidev/pop-mcp -->

# pop-mcp

MCP (Model Context Protocol) server for **POP** — enabling LLMs to generate, submit, and manage Italian e-invoices (FatturaPA/SdI), Peppol, KSeF, ZUGFeRD/Factur-X, and PDF invoices directly from AI assistants.

> **npm:** `@getpopapi/pop-mcp` · **Remote:** `https://mcp.popapi.io/mcp`

[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Node.js](https://img.shields.io/badge/Node.js-%3E%3D20-green)](https://nodejs.org/)

---

## Remote MCP (HTTP) — fastest way to get started

Don't want to install anything? `pop-mcp` runs as a hosted, multi-tenant MCP server at:

```
https://mcp.popapi.io/mcp
```

Head to [popapi.io](https://popapi.io) to grab a license key, then point any MCP-speaking client at
that URL with your key as a Bearer token. No local install, no `POP_API_KEY` env var, no build step
— this is the recommended way to try `pop-mcp` for most people. Use the local stdio setup below only
if you specifically need a Claude Desktop config running a process on your own machine.

### How it works

This endpoint speaks MCP **2026-07-28**, which is fully stateless: there is no `initialize`
handshake and no session to open or track. Every request is self-contained — it names its own
protocol version and capabilities — and the server answers it independently. Because of that,
this is a **multi-tenant** endpoint: it never reads a fixed `POP_API_KEY` from its own environment.
Every request must carry your own POP license key as a Bearer token:

```
Authorization: Bearer <your_license_key>
```

A missing or malformed `Authorization` header returns a `401` with `error_code: "unauthorized_user"`
before any POP API call is made. An invalid-but-well-formed key is passed straight through to POP's
API and surfaces whatever error POP returns (`unauthorized_user`, `insufficient_level`, etc.) — the
server does not re-validate keys itself.

Any modern MCP HTTP client can connect: Claude (remote connector), the OpenAI Responses API, n8n,
[MCP Inspector](https://github.com/modelcontextprotocol/inspector), or a custom integration — not
just Claude Desktop. All invoice, status, advanced, and onboarding tools are available; onboarding
tools use their own `onboarding_token` per call and don't require the Bearer key.

### Example with curl

Discover the server's supported protocol versions and capabilities (optional — clients can also
just call `tools/list` or `tools/call` directly and handle a version-negotiation error inline):

```bash
curl -X POST https://mcp.popapi.io/mcp \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer your_license_key_here" \
  -H "MCP-Protocol-Version: 2026-07-28" \
  -H "Mcp-Method: server/discover" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "server/discover",
    "params": { "_meta": { "io.modelcontextprotocol/protocolVersion": "2026-07-28", "io.modelcontextprotocol/clientCapabilities": {} } }
  }'
```

List the available tools — every request is self-contained, so `_meta` (protocol version + client
capabilities) travels on every call, not just the first one:

```bash
curl -X POST https://mcp.popapi.io/mcp \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer your_license_key_here" \
  -H "MCP-Protocol-Version: 2026-07-28" \
  -H "Mcp-Method: tools/list" \
  -d '{
    "jsonrpc": "2.0",
    "id": 2,
    "method": "tools/list",
    "params": { "_meta": { "io.modelcontextprotocol/protocolVersion": "2026-07-28", "io.modelcontextprotocol/clientCapabilities": {} } }
  }'
```

The tool catalog is identical for every license key, so `tools/list` and `server/discover`
responses carry a one-hour public cache hint (`ttlMs: 3600000, cacheScope: "public"`) — clients and
gateways may cache them across tenants.

> **`MCP-Protocol-Version` and `Mcp-Method` are required on every request** (per SEP-2243), and must
> match the body's `_meta.protocolVersion` and `method` exactly, or the server rejects the request
> with a `400` and JSON-RPC error `-32020` (`HeaderMismatch`). `tools/call` requests additionally
> require an `Mcp-Name` header matching `params.name`.

### Example with MCP Inspector

```bash
npx @modelcontextprotocol/inspector
```

Configure it to connect to `https://mcp.popapi.io/mcp` with header
`Authorization: Bearer <your_license_key>`.

This endpoint runs as a Vercel serverless function (`api/mcp.ts` → `src/mcpHandler.ts`). To run it
locally: `npx vercel dev` (requires `vercel link` to the project first).

---

## What is POP?

[POP](https://popapi.io) is a cloud service for electronic invoice generation and delivery, supporting:

- 🇮🇹 **Italian e-invoicing (FatturaPA/SdI)** — compliant with D.Lgs. 127/2015
- 🇪🇺 **Peppol** — pan-European cross-border B2B invoicing (UBL 2.1)
- 📄 **PDF invoices** — branded, with email delivery
- ✅ **Validation** — fiscal codes, VAT numbers, document pre-submission checks
- 🗄️ **Preservation** — Italian legal archival (conservazione sostitutiva)

---

## Tools Available (11 total)

### Invoice Creation
| Tool | Endpoint | Plan |
|------|----------|------|
| `pop_create_sdi_invoice` | POST `/create-xml` | Any |
| `pop_create_peppol_invoice` | POST `/create-ubl` | Any (Basic+ to submit) |
| `pop_create_pdf_invoice` | POST `/create-pdf` | Any (Basic+ for email) |
| `pop_create_ksef_invoice` | POST `/create-ksef-xml` | Any (KSeF setup for provider submission) |
| `pop_create_zugferd_invoice` | POST `/create-zugferd` | Any |
| `pop_sync_zoho_document` | POST `/integration/zoho/sync` | Zoho connector required |

### Status & Retrieval
| Tool | Endpoint | Plan |
|------|----------|------|
| `pop_get_invoice_status` | POST `/sdi/document-notifications` | Any |
| `pop_get_peppol_document` | POST `/peppol/document-get` | Basic+ |
| `pop_get_sdi_document` | POST `/sdi/document-get` | Basic+ |

### Validation & Advanced SdI
| Tool | Endpoint | Plan |
|------|----------|------|
| `pop_verify_sdi_document` | POST `/sdi/document-verify` | Basic+ |
| `pop_preserve_document` | POST `/sdi/document-preserve` | Basic+ |

---

## Prerequisites

- Node.js >= 20
- A [POP](https://popapi.io) license key
- For SdI/Peppol submission: active integration on your POP account (Basic/Growth plan)

---

## Authentication

### Get Your License Key

> **New to POP?** Visit [popapi.io](https://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:

1. Open [https://popapi.io/otp-login/](https://popapi.io/otp-login/)
2. Enter your email address
3. Receive a one-time password (OTP) by email and enter it
4. Complete the configuration wizard
5. Open [https://popapi.io/](https://popapi.io/) → **Account > API**
6. Copy the default generated `license_key`

### Key Management

- Your account includes one default `license_key`, visible under **Account > API**
- You can generate additional keys linked to the same account from that same page
- Every `license_key` must be treated as a secret credential — do not commit it to source control

### Recommended First Steps

1. Get your `license_key`
2. Test it with `GET /account-profile`
3. Send one document-generation request with a real payload
4. Add optional delivery integrations only after local generation works

---

## Installation

### From npm (recommended)

```bash
npm install -g @getpopapi/pop-mcp
```

### From Source

```bash
git clone https://github.com/getpopapi/pop-mcp
cd pop-mcp
npm install
npm run build
```

---

## Configuration

Set your POP license key as an environment variable:

```bash
export POP_API_KEY=your_license_key_here
```

Optional — use the staging environment:

```bash
export POP_ENVIRONMENT=staging
```

---

## Claude Desktop Setup

Add to your `claude_desktop_config.json`:

**If installed from npm:**

```json
{
  "mcpServers": {
    "pop": {
      "command": "pop-mcp",
      "env": {
        "POP_API_KEY": "your_license_key_here"
      }
    }
  }
}
```

**If running from source:**

```json
{
  "mcpServers": {
    "pop": {
      "command": "node",
      "args": ["/path/to/pop-mcp/dist/cli.js"],
      "env": {
        "POP_API_KEY": "your_license_key_here"
      }
    }
  }
}
```

**Config file locations:**
- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
- Windows: `%APPDATA%\Claude\claude_desktop_config.json`
- Linux: `~/.config/Claude/claude_desktop_config.json`

---

## Tool Reference

The `license_key` is always injected automatically from `POP_API_KEY` — never pass it manually.

### `pop_create_sdi_invoice`

Generate an Italian FatturaPA XML document. Optionally submit it to the SdI (Sistema di Interscambio).

**MCP inputs:**

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `data` | object | ✅ | Full invoice data (see Invoice Data Structure) |
| `submit_to_sdi` | boolean | — | Set `true` to submit to SdI. Requires Basic+ plan with active SdI integration. Default: `false` |
| `integration` | object | — | Override integration config. Overrides `submit_to_sdi` if set. |
| `environment` | string | — | Target environment (e.g. `"sandbox"`) |

**Integration options for `integration.use`:**
- `"sdi-via-pop"` or `"sdi"` — Submit via POP SdI
- `"pop-to-webhook"` — Deliver to a webhook (requires `id`)
- `"fatture-in-cloud"` — Deliver to Fatture in Cloud

**API payload sent:**

```json
{
  "license_key": "YOUR_LICENSE_KEY",
  "user_agent": "pop-mcp",
  "user_agent_version": "1.0.0",
  "data": { "...invoice fields..." },
  "integration": { "use": "sdi-via-pop", "action": "create" }
}
```

> `integration` is omitted when `submit_to_sdi` is `false` and no override is provided (XML-only generation).

---

### `pop_create_peppol_invoice`

Generate a Peppol UBL 2.1 document. Optionally submit it to the Peppol network.

**MCP inputs:**

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `data` | object | ✅ | Full invoice data. `customer_type` must be `"company"` or `"freelance"` |
| `submit_to_peppol` | boolean | — | Set `true` to submit to the Peppol network. Requires Basic+ plan. Default: `false` |
| `integration` | object | — | Override integration config |
| `environment` | string | — | Target environment |

**Integration options for `integration.use`:**
- `"peppol-via-pop"` or `"peppol"` — Submit via POP Peppol
- `"pop-to-webhook"` — Deliver to a webhook (requires `id`)

**API payload sent:**

```json
{
  "license_key": "YOUR_LICENSE_KEY",
  "user_agent": "pop-mcp",
  "user_agent_version": "1.0.0",
  "data": { "...invoice fields..." },
  "integration": { "use": "peppol-via-pop", "action": "create" }
}
```

---

### `pop_create_pdf_invoice`

Generate a branded PDF invoice. Optionally email it to up to 3 recipients.

**MCP inputs:**

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `data` | object | ✅ | Invoice data. Must include `data.pdf` for PDF-specific settings |
| `send_email` | boolean | — | Set `true` to email the PDF (requires `data.pdf.email_invoice`, Basic+ plan). Default: `false` |
| `environment` | string | — | Target environment |

**`data.pdf` fields:**

| Field | Description |
|-------|-------------|
| `doc_type_title` | Title shown on document (e.g. `"Invoice"`, `"Receipt"`) |
| `logo_url` | Company logo URL (HTTPS) |
| `head.store_info_address` | Supplier address string in header |
| `head.billing[]` | Customer billing address array |
| `head.shipping[]` | Shipping address array (optional) |
| `email_invoice.to` | Up to 3 recipient email addresses |
| `email_invoice.from` | Reply-to address |
| `footer_text` | Custom footer message |
| `total_tax` | Total tax amount as string |

**API payload sent:**

```json
{
  "license_key": "YOUR_LICENSE_KEY",
  "user_agent": "pop-mcp",
  "user_agent_version": "1.0.0",
  "data": {
    "...invoice fields...",
    "pdf": {
      "doc_type_title": "Invoice",
      "logo_url": "https://example.com/logo.png",
      "head": { "store_info_address": "Via Roma 1, 00100 Roma IT", "billing": [] },
      "total_tax": "22.00",
      "email_invoice": { "to": ["customer@example.com"] }
    }
  }
}
```

---

### `pop_create_ksef_invoice`

Generate a Polish KSeF FA(3) XML invoice or credit note. Optionally submit it through a configured KSeF provider integration.

**MCP inputs:**

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `data` | object | ✅ | Full invoice data for KSeF FA(3) generation |
| `integration` | object | — | Optional KSeF provider submission config: `{ use: "ksef" \| "ksef-via-pop", action }` |
| `environment` | string | — | Target environment (e.g. `"sandbox"`) |

**Domain rules specific to KSeF:**
- Poland only — `transfer_lender.personal_data.tax_id_vat.country_id` must be `"PL"` with a 10-digit NIP as `id_code`
- `customer_type` must be `"company"` or `"freelance"` (no private individuals)
- `nature` is **always required** at the top level for KSeF (unlike SdI/Peppol, where it's only required at 0% VAT) — reuses the same SdI nature codes (`N1`, `N2.1`, `N2.2`, `N3.1`, `N3.2`, `N4`, ...) to derive KSeF's internal fiscal variant
- `transmitter_data` is not used (SdI-only concept)
- `payment_data.payment_details` only accepts `MP01`, `MP02`/`MP03`, `MP05`, `MP08` — other payment method codes are rejected at generation time
- Base XML generation is available on any plan; provider submission via `integration.use: "ksef"` requires a Basic+ plan and the supplier already enrolled as a KSeF legal entity in the POP dashboard

**API payload sent:**

```json
{
  "license_key": "YOUR_LICENSE_KEY",
  "user_agent": "pop-mcp",
  "user_agent_version": "1.0.0",
  "data": { "...invoice fields...", "nature": "N1" },
  "integration": { "use": "ksef", "action": "create" }
}
```

> `integration` is omitted entirely for local XML-only generation (no provider submission).

**Returns:** raw FA(3) XML (`application/xml`) for local generation, or JSON (with a UUID) when submitted through a provider integration.

---

### `pop_create_zugferd_invoice`

Generate a ZUGFeRD/Factur-X document package: a visual PDF, an EN16931 CII XML, and a hybrid PDF/A-3 with the XML embedded.

**MCP inputs:**

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `data` | object | ✅ | Full invoice data for ZUGFeRD/Factur-X generation |
| `environment` | string | — | Target environment (e.g. `"sandbox"`) |

This tool has no `integration` parameter — ZUGFeRD generation is local only, with no submit/delivery step.

**API payload sent:**

```json
{
  "license_key": "YOUR_LICENSE_KEY",
  "user_agent": "pop-mcp",
  "user_agent_version": "1.0.0",
  "data": { "...invoice fields..." }
}
```

**Returns:** JSON with generation metadata and three Base64-encoded attachments:

```json
{
  "success": true,
  "data": {
    "valid": true,
    "profile": "EN16931",
    "attachments": {
      "pdf": { "filename": "...", "mime": "application/pdf", "content_base64": "..." },
      "xml": { "filename": "...", "mime": "application/xml", "content_base64": "..." },
      "hybrid_pdf": { "filename": "...", "mime": "application/pdf", "content_base64": "..." }
    },
    "validation": { "...": "..." },
    "errors": [],
    "warnings": []
  }
}
```

---

### `pop_get_invoice_status`

Retrieve the SdI processing status and notifications for a submitted invoice.

**MCP inputs:**

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `uuid` | string (UUID) | ✅ | Invoice UUID returned by `pop_create_sdi_invoice` when `submit_to_sdi=true` |
| `response_format` | `"markdown"` \| `"json"` | — | Output format. Default: `"markdown"` |
| `environment` | string | — | Target environment |

**API payload sent:**

```json
{
  "license_key": "YOUR_LICENSE_KEY",
  "integration": { "uuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" }
}
```

**SdI notification statuses:** `pending` · `accepted` · `rejected` · `delivery`

> SdI processing is asynchronous and can take minutes to hours. Retry if no notifications are returned yet.

---

### `pop_get_peppol_document`

Retrieve a Peppol document from the network by UUID.

**MCP inputs:**

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `uuid` | string (UUID) | ✅ | Peppol document UUID from `pop_create_peppol_invoice` |
| `zone` | string (2 chars) | — | Country code of the Peppol access point (e.g. `"BE"` for Belgium). Required for some regions. |
| `response_format` | `"markdown"` \| `"json"` | — | Output format. Default: `"markdown"` |
| `environment` | string | — | Target environment |

**API payload sent:**

```json
{
  "license_key": "YOUR_LICENSE_KEY",
  "integration": { "uuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "zone": "IT" }
}
```

> `zone` is omitted from the payload if not provided.

---

### `pop_get_sdi_document`

Retrieve an archived SdI (FatturaPA) document from POP storage by UUID.

**MCP inputs:**

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `uuid` | string (UUID) | ✅ | SdI document UUID |
| `response_format` | `"markdown"` \| `"json"` | — | Output format. Default: `"markdown"` |
| `environment` | string | — | Target environment |

**API payload sent:**

```json
{
  "license_key": "YOUR_LICENSE_KEY",
  "integration": { "uuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" }
}
```

Requires: Basic+ plan with active SdI integration.

---

### `pop_verify_sdi_document`

Validate an SdI XML document for compliance before submission. Does not submit the document.

**MCP inputs:**

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `xml_base64` | string | ✅ | The SdI XML document encoded as a Base64 string |
| `environment` | string | — | Target environment |

**API payload sent:**

```json
{
  "license_key": "YOUR_LICENSE_KEY",
  "skip_business_check": true,
  "integration": { "xml": "<base64-encoded-xml-string>" }
}
```

**Validation checks performed:** XML schema conformance · fiscal code format · VAT number validity · required field presence · amount consistency

Requires: Basic+ plan with active SdI integration and registered business.

---

### `pop_preserve_document`

Archive an SdI document in certified long-term digital storage (conservazione sostitutiva). Italian law requires invoices to be preserved for 10 years.

**MCP inputs:**

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `uuid` | string (UUID) | ✅ | UUID of the SdI document to archive |
| `environment` | string | — | Target environment |

**API payload sent:**

```json
{
  "license_key": "YOUR_LICENSE_KEY",
  "integration": { "uuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" }
}
```

> **Important:** Only call this tool when `pop_get_invoice_status` returns status `RC` (Ricevuta di Consegna) or `MC` (Mancata Consegna). Do not call for statuses `NS`, `EC`, `SE`, or `DT`.

Requires: Basic+ plan with active SdI integration.

---

## Usage Examples

### Generate a Simple Italian Invoice (XML Only)

Ask your AI assistant:

> "Create a FatturaPA invoice for 1000€ + 22% VAT to Rossi SRL (VAT IT12345678901, Milan). My company is Bianchi SRL (VAT IT98765432109, Rome), using payment method bank transfer to IBAN IT60X0542811101000000123456."

### Submit Invoice to SdI

> "Create and submit to SdI an invoice #45 for consulting services, 500€ + 22% VAT to customer Mario Rossi (fiscal code RSSMRA80A01H501U) in Rome."

### Check Invoice Status After Submission

> "What's the status of SdI invoice with UUID abc123-def456-...?"

### Generate PDF with Email Delivery

> "Create a PDF invoice for order #123 and email it to customer@example.com."

### Verify SdI Document Before Sending

> "Verify SdI document with UUID abc123-... for compliance before submission."

---

## Plan Requirements

| Feature | Free | Basic/Growth | Pro |
|---------|------|-------------|-----|
| XML generation (local) | ✅ | ✅ | ✅ |
| PDF generation | ✅ | ✅ | ✅ |
| SdI submission | ❌ | ✅ | ✅ |
| Peppol submission | ❌ | ✅ | ✅ |
| PDF email delivery | ❌ | ✅ | ✅ |
| SdI document verification | ❌ | ✅ | ✅ |
| Document preservation | ❌ | ✅ | ✅ |

---

## Testing

### MCP Inspector (Interactive)

```bash
npm run inspector
# or
npx @modelcontextprotocol/inspector dist/cli.js
```

### Quick Smoke Test

```bash
POP_API_KEY=your_key node -e "
import('./dist/cli.js').catch(e => {
  if (e.message.includes('stdin')) process.exit(0);
  console.error(e); process.exit(1);
});
"
```

### Test Tool Schema Listing

```bash
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' | POP_API_KEY=test node dist/cli.js
```

---

## Development

```bash
# Run with auto-reload
npm run dev

# Build
npm run build

# Clean build artifacts
npm run clean
```

---

## Invoice Data Structure

The `data` parameter for invoice creation follows the FatturaPA structure:

```
data
├── id                    Invoice/order ID (numeric)
├── filename              Output filename without extension (e.g. 'IT99900088876_00009')
├── type                  "invoice" | "credit_note"
├── version               "FPR12" | "FPA12"
├── sdi_type              7-char SDI code ('0000000' for private individuals)
├── customer_type         "private" | "company" | "freelance" | "pa"
├── nature                VAT exemption code (required when rate is 0%, e.g. 'N2.1', 'N6.1')
├── transmitter_data
│   ├── transmitter_id    { country_id, id_code }
│   ├── progressive       Transmission progressive ID (e.g. '00001')
│   ├── transmitter_format  "FPR12" | "FPA12"
│   ├── sdi_code          7-char code
│   ├── transmitter_contact { phone, email }
│   └── recipient_pec     PEC email (alternative to sdi_code)
├── transfer_lender       Supplier/seller
│   ├── personal_data     { tax_id_vat: { country_id, id_code, tax_regime }, company_name }
│   ├── place             { address, zip_code, city, province_id, country_id }
│   └── contact           { phone, email }
├── transferee_client     Customer/buyer
│   ├── personal_data     { tax_id_vat, tax_id_code (fiscal code for IT private), company_name }
│   └── place             { address, zip_code, city, province_id, country_id }
├── invoice_body
│   ├── general_data      { doc_type (TD01|TD04), date (YYYY-MM-DD), invoice_number, currency }
│   └── total_document_amount
├── order_items[]
│   ├── description, quantity, unit
│   ├── unit_price, total_price
│   ├── rate              VAT rate as string (e.g. '22.00')
│   ├── total_tax         VAT amount (number)
│   └── item_type         "product" | "shipping" | "fee"
├── payment_data
│   ├── terms_payment     TP01 (instalment) | TP02 (full) | TP03 (advance)
│   ├── payment_details   MP01 (Cash) | MP02 (Check) | MP05 (Bank Transfer) | MP08 (Credit Card) | ...
│   ├── payment_amount
│   ├── beneficiary       Required for MP05 (bank transfer)
│   ├── financial_institution  Required for MP05
│   └── iban              Required for MP05
├── purchase_order_data   (optional) { id, date }
├── connected_invoice_data[]  (required for credit notes) { id, date }
├── overrides             (optional) { language, bollo_force_apply }
└── pdf                   (only for pop_create_pdf_invoice)
    ├── doc_type_title
    ├── logo_url
    ├── head              { store_info_address, billing[], shipping[] }
    ├── total_tax
    ├── email_invoice     { to[] (max 3), from }
    └── footer_text
```

---

## Error Reference

| Error Code | Meaning | Solution |
|-----------|---------|---------|
| `unauthorized_user` | Invalid license key | Check `POP_API_KEY` |
| `insufficient_level` | Plan too low | Upgrade POP plan |
| `business_not_registered` | No business profile | Register on popapi.io |
| `integration_inactive` | SdI/Peppol not enabled | Activate on popapi.io |
| `pop_api_email_limit` | >3 email recipients | Reduce to max 3 |
| `pop_api_email_not_allowed` | Plan doesn't allow email | Upgrade to Basic+ |

---

## Related Projects

- [n8n-nodes-pop](https://github.com/getpopapi/n8n-nodes-pop) — n8n community nodes for POP
- [POP](https://popapi.io) — Official website
- [API Documentation](https://documenter.getpostman.com/view/41622997/2sAYkLmGT8) — Postman docs

---

## License

MIT © [getpopapi](https://github.com/getpopapi)

