Exchange simplified invoices for a full invoice
Scopeinvoices:writeIssues a full invoice in exchange for one or more simplified invoices already issued, when the customer asks for an invoice with their details. It is not a corrective invoice: it documents the same operations again with the recipient identified (RD 1619/2012, art. 15.6).
- What it issues: a
STANDARDinvoice with the lines of the simplified invoices and therecipientsent, numbered inseries_idor in the company's default standard series. It lists the invoices it replaces inreplaced_invoice_ids. - The simplified invoices: each becomes
VOIDEDwithvoid_causeEXCHANGED, in the same act: their records are not cancelled, the exchange replaces them. They must be simplified invoices (422 EXCHANGE_REQUIRES_SIMPLIFIED), issued and not voided, exchanged or corrected before (422 SIMPLIFIED_NOT_EXCHANGEABLE), and each one listed once insimplified_invoice_ids(422 EXCHANGE_DUPLICATED_SIMPLIFIED, before anything is read or numbered). - The exchange invoice cannot be voided afterwards (
422 EXCHANGE_INVOICE_NOT_VOIDABLE), and when it is recorded asF3it cannot be corrected yet (see the corrective operation). - VeriFactu: the exchange invoice is recorded as
F3, identifying each simplified invoice it replaces by number and issue date. Each of them must already be accepted by the AEAT, or nothing is issued: one issued without VeriFactu fails with422 SIMPLIFIED_EXCHANGE_NOT_RECORDABLE; one whose record is still pending fails with422 EXCHANGE_SIMPLIFIED_NOT_YET_ACCEPTED(wait until the AEAT accepts it and retry); one whose record was rejected fails with422 EXCHANGE_SIMPLIFIED_RECORD_REJECTED(fix or resubmit it first).
Keys are prefixed beel_sk_, and each one carries the scopes it was created with: a key
short of the scope an operation needs is answered 403. The scope an operation requires
is shown next to its title, and the full catalogue lives in the Scopes reference.
Keys are created from the BeeL dashboard. They are secret credentials: do not share them or commit them to source control.
In: header
Path Parameters
Unique identifier (UUID) of the company the operation acts on — its identifier, not its NIF. It is the only source of context: the account that owns it is derived from it, and the BeeL-Active-Company header plays no part. A company you do not reach answers 403, and so does a company that does not exist, so the existence of a company in another account is never disclosed.
uuidHeader Parameters
Idempotency key to prevent duplicates in sensitive operations.
- Any unique client-generated string (e.g. an order id). A UUID also works but is not required
- Allowed characters: letters, digits,
_and-(max 255 chars) - Retrying with the same key replays the first response when it was a success (2xx) or a
server error (5xx): same status and body, plus the header
Idempotency-Replay: true. After a 5xx, check whether the operation took effect before retrying with a new key - A 4xx is not stored: the key is released, so the corrected request can reuse it
- Stored responses expire 24 hours after processing
The key is scoped per user and environment, and bound to the request body, so retrying after a network timeout replays the stored response instead of repeating the operation.
| Status | Code | When |
|---|---|---|
400 | INVALID_IDEMPOTENCY_KEY | The key breaks the format rules above. |
409 | IDEMPOTENCY_KEY_PROCESSING | The first request is still in flight. Wait for the Retry-After seconds (2) and retry with the same key. |
409 | IDEMPOTENCY_KEY_MISMATCH | The key was already used with a different body. Use a new key. |
^[a-zA-Z0-9_-]+$length <= 255The simplified invoices the full invoice replaces, issued and not voided, exchanged or
corrected. Their lines, in this order, become the lines of the full invoice. Each one
appears once: a repeated id fails with 422 EXCHANGE_DUPLICATED_SIMPLIFIED.
1 <= items <= 50Series of the full invoice. Optional: without it, the company's default series for standard invoices is used.
uuidObservations printed on the full invoice.
length <= 1000Controls how the invoice is processed after creation.
All fields default to false if not specified.
VeriFactu is not an option here: whether an invoice is registered with AEAT is a
fact of the tax identity (NIF x environment), resolved at issue time against the
company's regime. See verifactu.enabled in the invoice response for what was applied.
Common combinations:
- Draft (default): omit
optionsor set all tofalse - Issue immediately:
{ issue_directly: true } - Issue + wait for PDF:
{ issue_directly: true, wait_for_pdf: true } - Issue + send email:
{ issue_directly: true, send_automatically: true } - Full automation:
{ issue_directly: true, wait_for_pdf: true, send_automatically: true, email_config: { ... } }
Response Body
application/json
application/json
application/json
application/json
application/json
application/json
application/json
application/json
application/json
curl -X POST "https://app.beel.es/api/v1/companies/497f6eca-6276-4993-bfeb-53cbbbba6f08/invoices/simplified-exchanges" \ -H "Content-Type: application/json" \ -d '{ "simplified_invoice_ids": [ "550e8400-e29b-41d4-a716-446655440010" ], "recipient": { "customer_id": "8f1e2a3b-4c5d-6e7f-8091-a2b3c4d5e6f7" } }'{
"success": true,
"data": {
"invoice_number": "2025/0001",
"series": {
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"code": "FAC"
},
"number": 1,
"type": "STANDARD",
"status": "SCHEDULED",
"issue_date": "2025-01-15",
"operation_date": "2025-01-10",
"due_date": "2025-02-14",
"valid_until": "2025-02-28",
"payment_date": "2025-01-20",
"sent_at": "2025-01-29T18:45:00Z",
"paid_at": "2025-02-05T10:30:00Z",
"auto_emit_after": "2025-03-20",
"scheduled_for": "2025-02-15",
"scheduled_action": "DRAFT",
"issuer": {
"legal_name": "Juan Pérez García",
"trade_name": "JP Web Development",
"nif": "12345678A",
"address": {
"street": "Calle Mayor, 123",
"number": "123",
"floor": "2º A",
"door": "A",
"postal_code": "28001",
"city": "Madrid",
"province": "Madrid",
"country": "España",
"country_code": "ES"
},
"phone": "+34 612 345 678",
"email": "user@example.com",
"website": "https://beel.es",
"logo_url": "string",
"additional_info": "Nº Colegiado: 12345"
},
"recipient": {
"customer_id": "160c0c4b-9966-4dc1-a916-8407eb10d74e",
"legal_name": "Empresa SL",
"trade_name": "Empresa",
"nif": "12345678A",
"alternative_id": {
"type": "NIF_IVA",
"number": "string",
"country_code": "st"
},
"address": {
"street": "Calle Mayor, 123",
"number": "123",
"floor": "2º A",
"door": "A",
"postal_code": "28001",
"city": "Madrid",
"province": "Madrid",
"country": "España",
"country_code": "ES"
},
"phone": "+34 612 345 678",
"email": "user@example.com"
},
"lines": [
{
"description": "Web application development",
"quantity": 40,
"unit": "hours",
"unit_price": 50,
"discount_percentage": 10,
"main_tax": {
"type": "IVA",
"percentage": 21,
"regime_key": "01"
},
"equivalence_surcharge_rate": 5.2,
"irpf_rate": 15,
"exemption_reason": "EXENTA_ART_20",
"exemption_reason_text": "string",
"taxable_base": 1800,
"line_total": 2178,
"pricing_mode": "UNIT_PRICE",
"total_excluding_tax": 1,
"total_including_tax": 100,
"line_type": "NORMAL",
"source_invoice_reference": "string",
"source_invoice_ids": [
"497f6eca-6276-4993-bfeb-53cbbbba6f08"
]
}
],
"totals": {
"taxable_base": 2000,
"total_discounts": 0,
"vat_breakdown": [
{
"type": 21,
"base": 2000,
"amount": 420,
"regime_key": "18"
}
],
"total_vat": 420,
"surcharge_breakdown": [
{
"type": 0,
"base": 0,
"amount": 0
}
],
"total_equivalence_surcharge": 0,
"irpf_breakdown": [
{
"type": 0,
"base": 0,
"amount": 0
}
],
"total_irpf": 300,
"invoice_total": 2120,
"total_disbursements": 0,
"total_to_pay": 2120
},
"payment_info": {
"method": "BANK_TRANSFER",
"iban": "ES1234567890123456789012",
"swift": "ABCDESMMXXX",
"payment_term_days": 30
},
"notes": "string",
"replaced_invoice_ids": [
"497f6eca-6276-4993-bfeb-53cbbbba6f08"
],
"void_cause": "VOID_REQUEST",
"void_reason": "string",
"voided_at": "2025-01-20T09:12:44Z",
"rectified_invoice_id": "986b41f8-8e28-4058-9e03-5286d0c42999",
"source_proforma_id": "5f6c4143-c67e-4332-9fbc-f68d1420128f",
"converted_invoice_id": "c85716fe-5512-4945-9dc8-daa0106a270b",
"rectification_reason": "string",
"recurring_invoice_id": "e6018980-fb8b-475b-a83d-b7bb0aa7423a",
"recurring_invoice_name": "string",
"rectification_type": "TOTAL",
"rectification_code": "R1",
"external_ref": "ORD-2025-0042",
"metadata": {
"external_customer_id": "cus_ULGk8bzIr88aag",
"external_payment_id": "pi_3NqFGb2eZvKYlo2C0z1234AB",
"payment_intent_id": "pi_3NqFGb2eZvKYlo2C0z1234AB",
"charge_id": "ch_3NqFGb2eZvKYlo2C1234CDEF",
"payment_provider": "STRIPE_CONNECT",
"external_order_id": "ORD-2025-0042"
},
"send_automatically": true,
"email_config": {
"recipients": [
"client@example.com"
],
"cc": [
"accounting@example.com"
],
"subject": "Invoice 2025/0001 - Development services",
"message": "Please find attached the requested invoice. We remain at your disposal for any clarification."
},
"pdf_download_url": "/v1/companies/7c9e6679-7425-40de-944b-e07fc1f90ae7/invoices/550e8400-e29b-41d4-a716-446655440000/pdf",
"verifactu": {
"enabled": true,
"invoice_hash": "3A5B7C9D1E2F3A4B5C6D7E8F9A0B1C2D3E4F5A6B7C8D9E0F1A2B3C4D5E6F7A8B",
"registration_number": "4f8c2a1e-9b3d-4e7a-8c5f-1d2e3f4a5b6c",
"qr_url": "https://www2.agenciatributaria.gob.es/wlpl/TIKE-CONT/ValidarQR?nif=B12345674&numserie=A%2F2025%2F0042&fecha=20-01-2025&importe=1590.00",
"qr_base64": "iVBORw0KGgoAAAANSUhEUgAAAMgAAADI...",
"registered_at": "2019-08-24T14:15:22Z",
"submission_status": "ACCEPTED",
"skip_reason": "CONFIG_DISABLED",
"error_code": "3000",
"error_message": "Factura ya existe en el sistema"
},
"attachments": [
{
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"name": "string",
"url": "string",
"type": "string"
}
],
"sending_history": [
{
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"recipients": [
"string"
],
"cc": [
"string"
],
"subject": "string",
"status": "QUEUED",
"sent_at": "2025-01-29T18:45:00Z",
"external_message_id": "string",
"error": "string"
}
],
"email_delivery": {
"status": "REJECTED",
"reason": "error.email.envio_no_permitido"
},
"deleted_at": "2019-08-24T14:15:22Z",
"id": "550e8400-e29b-41d4-a716-446655440000",
"created_at": "2019-08-24T14:15:22Z",
"updated_at": "2019-08-24T14:15:22Z"
},
"meta": {
"timestamp": "2025-01-15T10:30:00Z",
"request_id": "4bf92f3577b34da6a3ce929d0e0e4736"
}
}{
"success": false,
"error": {
"code": "INVALID_JSON_FORMAT",
"message": "The field 'due_date' has an invalid date format: '2026-03-04fds'. Expected format: YYYY-MM-DD.",
"details": {
"field": "due_date",
"invalid_value": "2026-03-04fds",
"expected_format": "YYYY-MM-DD"
}
},
"meta": {
"timestamp": "2026-03-05T10:30:00Z",
"request_id": "4bf92f3577b34da6a3ce929d0e0e4736"
}
}{
"success": false,
"error": {
"code": "UNAUTHORIZED",
"message": "Authentication is required to access this resource"
},
"meta": {
"timestamp": "2025-01-15T10:30:00Z",
"request_id": "4bf92f3577b34da6a3ce929d0e0e4736"
}
}{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "The provided data is not valid",
"details": {
"field": "specific error message"
}
},
"meta": {
"timestamp": "2025-01-15T10:30:00Z",
"request_id": "4bf92f3577b34da6a3ce929d0e0e4736"
},
"type": "https://docs.beel.es/errors/INVOICE_NO_LINES",
"title": "INVOICE_NO_LINES",
"detail": "The invoice must have at least one line",
"instance": "/v1/invoices/abc-123"
}{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "The provided data is not valid",
"details": {
"field": "specific error message"
}
},
"meta": {
"timestamp": "2025-01-15T10:30:00Z",
"request_id": "4bf92f3577b34da6a3ce929d0e0e4736"
},
"type": "https://docs.beel.es/errors/INVOICE_NO_LINES",
"title": "INVOICE_NO_LINES",
"detail": "The invoice must have at least one line",
"instance": "/v1/invoices/abc-123"
}{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "The provided data is not valid.",
"details": {
"legal_name": "The field 'legal_name' cannot be empty",
"recipient.address.postal_code": "Contains invalid characters."
}
},
"meta": {
"timestamp": "2025-01-15T10:30:00Z",
"request_id": "4bf92f3577b34da6a3ce929d0e0e4736"
}
}{
"success": false,
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Too many requests. Please try again in 60 seconds."
},
"meta": {
"timestamp": "2025-01-15T10:30:00Z",
"request_id": "4bf92f3577b34da6a3ce929d0e0e4736"
}
}{
"success": false,
"error": {
"code": "INTERNAL_ERROR",
"message": "Internal server error"
},
"meta": {
"timestamp": "2025-01-15T10:30:00Z",
"request_id": "4bf92f3577b34da6a3ce929d0e0e4736"
}
}{
"success": false,
"error": {
"code": "UNSUPPORTED_MEDIA_TYPE",
"message": "Unsupported media type: text/plain. Supported: application/json"
},
"meta": {
"timestamp": "2025-01-15T10:30:00Z",
"request_id": "4bf92f3577b34da6a3ce929d0e0e4736"
}
}Create a corrective invoice POST
Issues a corrective invoice that amends the invoice in the path. It is a new fiscal document with its own number, not an edit of the original. - **`rectification_type`:** `TOTAL` leaves the original `VOIDED` and rectifies what is still invoiced on it: every line of the original and of its live correctives (voided ones do not count), negated. It takes no `lines` — sending them fails with `422 RECTIFICATIVA_TOTAL_CON_LINEAS`. `PARTIAL` leaves the original `RECTIFIED` and requires the adjustment `lines`. - **Never more than was invoiced:** a `PARTIAL` may raise any amount, but may not take the taxable base of any rate (tax, rate and equivalence surcharge; `SUPLIDO` lines by their amount) below zero once the previous correctives are counted. That fails with `422 CORRECTIVE_EXCEEDS_INVOICED_AMOUNT`, and `error.details` (`CorrectiveInvoiceErrorDetails`) carries `tax_group` (for example `IVA 21%`) and `max_reduction`, how much of that rate is left to rectify. A `TOTAL` on an invoice that previous correctives already brought to zero fails with `422 CORRECTIVE_NOTHING_LEFT_TO_RECTIFY`. - **Not for the withholding alone:** a `PARTIAL` whose lines leave the taxable base of every rate unchanged and only change the withholding fails with `422 CORRECTIVE_WITHHOLDING_ONLY`. A withholding is not a cause for a corrective: void the invoice and issue a new one without it. - **The original's PDF:** unchanged by either type. The corrective has its own PDF; the original keeps the one that was delivered, and its new status is in `status`. - **Total of 0:** a corrective whose `total_to_pay` is 0 has nothing to refund or collect, so it is issued as `PAID`, with `payment_date` equal to `issue_date`. - **What can be rectified:** an ordinary or simplified invoice in `ISSUED`, `SENT`, `PAID`, `OVERDUE` or `RECTIFIED`. Rectifying a corrective fails with `422 CORRECTIVE_NOT_RECTIFIABLE` — to fix an erroneous corrective, issue another one against the original invoice. - **Repeat rectifications:** several `PARTIAL` correctives are allowed, but a `VOIDED` invoice is no longer rectifiable, so a second `TOTAL` against the same invoice fails with `422 INVOICE_NOT_CORRECTIBLE_IN_CURRENT_STATUS`. - **Correcting the recipient's data:** when the invoice recorded its recipient with a wrong name, tax ID or address, send the corrected `recipient` with `rectification_type` `PARTIAL`, `rectification_code` `R4` and no `lines`. The corrective carries the corrected recipient and does not change the amounts: its lines negate what is still invoiced and repeat it, so every rate nets to zero. A different person is not a data correction (`422 CORRECTIVE_RECIPIENT_IS_ANOTHER_PERSON`): correct the invoice in full and issue a new one to the right customer. - **Original rejected by the AEAT:** when VeriFactu rejected the original's record and it has not been resubmitted, the original is not in the AEAT's books: fix and resubmit it first. Until then the request fails with `422 CORRECTIVE_ORIGINAL_RECORD_REJECTED`. - **Exchange invoice recorded as F3:** correcting a full invoice issued in exchange for simplified invoices is not available yet: `422 EXCHANGE_INVOICE_NOT_CORRECTABLE`. Contact support. - **Deadline:** four years from when the tax accrued (the original's operation date) or, for a cause of article 80 of the VAT Act, from the `circumstance_date` you declare. Past it the request fails with `422 CORRECTIVE_OUT_OF_TIME`, with `deadline` and `counted_from` in `error.details` (`CorrectiveInvoiceErrorDetails`). - **What the reason code requires** (Ley 37/1992, art. 80): `R2` (insolvency) and `R3` (bad debt) need a recipient established in Spain, the Canary Islands, Ceuta or Melilla —an `R2` also accepts a recipient in another EU member state, for insolvency proceedings there— and fail otherwise with `422 CORRECTIVE_RECIPIENT_NOT_ESTABLISHED`. An `R3` needs at least six months since the original's operation date (`422 CORRECTIVE_BAD_DEBT_TOO_EARLY`, with `earliest_date`; one year when the previous year's turnover exceeded 6,010,121.04 €, which is the issuer's to apply), and on an operation with a base of 50 € or less it needs `recipient_is_business` (`422 CORRECTIVE_BAD_DEBT_BASE_TOO_LOW`). The other conditions of each code (claims, guarantees, related parties, filing with the AEAT) are the issuer's to meet. - **Fiscal inheritance on a `PARTIAL`:** a line that omits `irpf_rate` or `equivalence_surcharge_rate` takes it from the **original invoice** — the document being amended — and never from the company's current tax profile, so a profile that changed after the original was issued does not leak into the credit note. An explicit value always wins, `0` included. The surcharge inherits the *regime* (on/off), not the rate: the rate is re-derived from each corrective line's own VAT (21→5.2, 10→1.4, 5→0.62, 4→0.5), and an original outside the regime pins the line to `0`. `SUPLIDO` lines are out of it on both sides. When the original is not unambiguous BeeL does not pick for you: different IRPF rates per line fail with `422 CORRECTIVE_ORIGINAL_MIXED_IRPF`, and a surcharge applied on some lines but not others fails with `422 CORRECTIVE_ORIGINAL_MIXED_SURCHARGE`. Declare the figure on every line to get past either — both only fire when some line actually needs to inherit. - **`series_id`:** when omitted, the document is numbered in the company's default corrective series, never in the series of the original: corrective invoices go in a series of their own (RD 1619/2012, art. 6.1.a). If the company has none, it is created on first use (code `R`, or the next free one that cannot repeat another series' numbers). An explicit `series_id` must be a corrective series. - **Numbering conflict:** if the number the series would assign is already used by another invoice of the same company, in this series or in another one, the request fails with `400 SERIES_NUMBER_COLLISION` without issuing anything or consuming a number. The series needs review, so contact support.
Void an issued invoice POST
Voids an issued invoice of this company. The document is kept and its number is never reused. - **When to use it:** the invoice was issued by mistake — the operation never took place, it was a test, or it is an accidental duplicate. If the operation did take place but the invoice is wrong, issue a corrective invoice instead (`POST …/{invoice_id}/corrective`). The exception is a withholding that should not have been applied: it is not a cause for a corrective, so void the invoice and issue a new one without it. - **Sent or paid:** voiding an invoice that was already sent or paid requires `issued_in_error: true`, confirming it was issued by mistake; without it the request fails with `422 VOID_REQUIRES_ISSUED_IN_ERROR`. - **Corrected invoices:** an invoice with live corrective invoices cannot be voided — it was corrected, so the operation took place; issue another corrective (`422 INVOICE_HAS_LIVE_CORRECTIVES`). A `TOTAL` corrective cannot be voided either: the invoice it rectifies would stay voided with nothing to offset it (`422 TOTAL_CORRECTIVE_NOT_VOIDABLE`). - **`reason`:** required, at least 10 characters — it is fiscal data. - **`void_date`:** deprecated. A date earlier than the invoice's issue date is rejected with `422 VOID_DATE_BEFORE_ISSUE_DATE`. - **VeriFactu:** when it is enabled for the invoice, a cancellation record is submitted to the AEAT. - **PDF:** unchanged. The PDF of the invoice stays the one that was delivered; the void is reported by the invoice's `status` and the `invoice.voided` webhook. - **Proformas:** voiding an `ACTIVE` proforma is a plain status change with no fiscal effect — no corrective invoice, nothing submitted to the AEAT. The voided proforma is kept as the record of a rejected or withdrawn offer and stays listed.