Convert a proforma into an invoice (deprecated)
Scopeinvoices:writeConverts an accepted proforma into a real invoice.
- Deprecated: use
POST /v1/companies/{company_id}/invoices/{invoice_id}/convert-to-invoice, which behaves identically. - Result: the proforma moves to the terminal status
CONVERTEDand a newSTANDARDinvoice is created inDRAFT. - Issuing:
issue: truenumbers and issues that new invoice in the same call.
Retires on 9 December 2026. See the migration guide for what moved where and what changes when you switch.
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
Proforma ID to convert
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 <= 255If true, emit the resulting invoice atomically in the same act
(assigns a fiscal number and runs the quota/ledger/VeriFactu→PDF flow).
If false or omitted, the invoice is left in DRAFT.
falseResponse Body
application/json
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/invoices/550e8400-e29b-41d4-a716-446655440000/convert-to-invoice" \ -H "Content-Type: application/json" \ -d '{}'{
"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": "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": "UNAUTHORIZED",
"message": "Authentication is required to access this resource"
},
"meta": {
"timestamp": "2025-01-15T10:30:00Z",
"request_id": "4bf92f3577b34da6a3ce929d0e0e4736"
}
}{
"success": false,
"error": {
"code": "FORBIDDEN",
"message": "You do not have permission to access this resource"
},
"meta": {
"timestamp": "2025-01-15T10:30:00Z",
"request_id": "4bf92f3577b34da6a3ce929d0e0e4736"
}
}{
"success": false,
"error": {
"code": "INVOICE_NOT_FOUND",
"message": "Invoice not found"
},
"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": "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"
}
}Convert a proforma into an invoice POST
Converts an accepted proforma of this company into a real invoice. The new invoice is created as a `STANDARD` draft linked back through `source_proforma_id`. - **What converts:** only proformas in status `ACTIVE`. One shown as `EXPIRED` is still `ACTIVE` underneath and converts too. - **The proforma:** preserved as the record of what the customer accepted — it keeps its `PRO-...` number and PDF and moves to the terminal status `CONVERTED`. - **`issue`:** with `true` the new invoice is numbered and issued in the same atomic call. If issuing fails nothing is created and the proforma stays `ACTIVE`. That includes `400 SERIES_NUMBER_COLLISION`: the number the series would assign is already used by another invoice of the same company, and the series needs review, so contact support. - **Errors:** `422 CONVERSION_REQUIRES_PROFORMA` when the document is not a proforma, `422 PROFORMA_NOT_CONVERTIBLE` when it is not `ACTIVE`, and `409 PROFORMA_ALREADY_CONVERTED` when it has already been converted — a second call never creates a second invoice.
Create a customer for a company POST
Creates a new customer under this company. - **`Idempotency-Key`:** it identifies the same operation on the deprecated flat route, so a retry that switches route replays instead of creating twice.