Send an invoice by email
Scopeinvoices:writeSends the invoice by email, attaching its PDF by default. When no recipient is given, the addresses configured on the customer are used.
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.
uuidInvoice ID
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 <= 255Recipients of the email. When omitted, the invoice's email_config recipients apply,
then the customer's billing_emails, then the customer's email.
CC recipients. Copied addresses count as recipients of the message: they are subject
to the same sending restrictions and to the same quota as the addresses in recipients.
When omitted, the CC addresses configured in the sender's email defaults apply; send an
empty array to deliver the message without any copy.
Email subject (optional, if not specified uses a default)
1 <= length <= 200Custom message (optional, added before standard message)
1 <= length <= 2000trueAttach a ZIP archive (suplidos_<invoice-number>.zip) containing the PDFs of the source invoices referenced by the invoice's SUPLIDO consolidation lines (source_invoice_ids). Each PDF inside the ZIP is named <invoice-number>_<issuer-tax-id>.pdf. Requires attach_pdf: true (the ZIP accompanies the invoice PDF). Access to sources owned by managed accounts is re-checked at send time with the same rules as issuing; the request fails with an actionable error — never a partial ZIP — if the invoice has no consolidation sources (ATTACH_SOURCE_INVOICES_NO_SOURCES), a source is not reachable (ATTACH_SOURCE_INVOICE_UNAVAILABLE), a source has no generated PDF (ATTACH_SOURCE_PDF_MISSING), or the ZIP exceeds the size limit (ATTACH_SOURCE_ZIP_TOO_LARGE).
false"es" | "en" | "ca"Response 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/companies/497f6eca-6276-4993-bfeb-53cbbbba6f08/invoices/550e8400-e29b-41d4-a716-446655440000/send" \ -H "Content-Type: application/json" \ -d '{ "subject": "Invoice A/2025/0042 from Tu Empresa SL", "message": "Dear customer,\n\nPlease find attached invoice A/2025/0042 for services rendered.\nPlease make payment before the due date.\n\nKind regards,\nTu Empresa SL\n" }'{
"success": true,
"data": {
"email_id": "550e8400-e29b-41d4-a716-446655440000",
"sent_to": [
"user@example.com"
],
"sent_at": "2019-08-24T14:15:22Z"
},
"meta": {
"timestamp": "2025-01-15T10:30:00Z",
"request_id": "4bf92f3577b34da6a3ce929d0e0e4736"
}
}{
"success": true,
"data": {
"email_id": "550e8400-e29b-41d4-a716-446655440000",
"sent_to": [
"user@example.com"
],
"sent_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": "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": "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": "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"
}
}Export invoices POST
Produces a spreadsheet with the invoices of this company and returns the file in the response. - **Selection:** the invoices named in `invoice_ids`, or, when that is absent, the ones matching `filters`. A request with neither is rejected with `400 EXPORT_SELECTION_REQUIRED`. - **Format:** `SUMMARY` writes one row per invoice with aggregated totals, `ITEMS` one row per invoice line. - **Values:** the status, payment method, tax type and line type columns carry the same values the API returns (`ISSUED`, `BANK_TRANSFER`, `IVA`, `SUPLIDO`…). A proforma past its validity is exported as `ACTIVE`, not `EXPIRED`. - **Limit:** up to 50000 invoices per export. Going over it is rejected with `422 EXPORT_LIMIT_EXCEEDED` — narrow the date range or split the selection. The export is never silently truncated.
Send several invoices in one email POST
Sends one email carrying the PDFs of several invoices of this company as attachments. - **`recipients`:** required, and must carry at least one address; no address is inferred from any profile. - **Limit:** up to 200 invoices per message (`invoice_ids`). - **Failures:** invoices whose PDF cannot be attached are reported in `failures`, and the message is still sent with the rest.