List invoices
Returns a paginated list of invoices, with filters, sorting and pagination.
- Deprecated: use GET /v1/companies/{company_id}/invoices, which returns the same list with the same filters.
- Difference: the legacy alias external_reference is not carried over there. Use external_ref, which this route also accepts.
Retires on 9 December 2026. See the migration guide for what moved where and what changes when you switch.
Request
- Base URL: https://app.beel.es/api
- URL: https://app.beel.es/api/v1/invoices
- Auth: HTTP bearer
Query parameters
Page number, starting at 1. The response echoes it back as pagination.current_page.
How many items to return per page. The response echoes it back as pagination.items_per_page.
Global search across invoice number, recipient name, recipient NIF, and series code (partial, case-insensitive)
Filter by invoice status. Accepts a comma-separated list to match any of several statuses, for example status=DRAFT,ISSUED. A single value is also valid. An empty value (status=) is the same as omitting the parameter.
Filter by payment method. Accepts a comma-separated list to match any of several methods, for example payment_method=DIRECT_DEBIT,CARD. A single value is also valid. NONE also matches invoices that have no payment method stored. Combine it with date_from/date_to to list, for example, the direct debits of a month. An empty value (payment_method=) is the same as omitting the parameter.
[ "BANK_TRANSFER" ]
- STANDARD: Standard invoice
- CORRECTIVE: Corrects or cancels a previous invoice
- SIMPLIFIED: Simplified invoice (ticket), for a recipient that is not identified. BeeL. requires a STANDARD invoice when the recipient is identified, at any amount: a SIMPLIFIED invoice whose recipient carries an nif or alternative_id is rejected with SIMPLIFIED_INVOICE_FORBIDS_IDENTIFIED_RECIPIENT. The only amount BeeL enforces is a cap of 3,000€ VAT included (SIMPLIFIED_INVOICE_EXCEEDS_LEGAL_LIMIT). The general limit of RD 1619/2012 is 400€ (art. 4.1.a); up to 3,000€ applies only to the activities listed in art. 4.2. BeeL does not check which activity the issuer carries out.
- PROFORMA: Commercial document (formal quote) with no fiscal validity. Never enters VeriFactu (no QR, no AEAT submission): verifactu.enabled is always false, whatever the company's regime. Requires full recipient data, like STANDARD. Cannot be corrective nor reference a rectified invoice.
Filter by invoice type
When true (the default), returns only fiscal documents (STANDARD, CORRECTIVE, SIMPLIFIED), excluding proformas and any other non-fiscal document. Set it to false to list every document type. Ignored when an explicit type is given: use type=PROFORMA to list proformas.
Universally Unique Identifier (UUID v4)
Filter by customer UUID
Date from, inclusive (YYYY-MM-DD). It applies to the operation date when set, and to the issue date otherwise.
Date to, inclusive (YYYY-MM-DD). Applies to the same date as date_from.
Search by invoice number (e.g., 2025/0001)
Filter by recipient's fiscal name (partial, case-insensitive search)
Filter by recipient's NIF (partial search)
Filter by series code (exact match, case-insensitive). Use search for partial matching across the invoice number, recipient and series code.
Filter by exact external reference (client-supplied order/cart/contract id).
This parameter was previously named external_reference. The old name is still accepted for backwards compatibility (see external_reference below) and will be withdrawn in a future major version — send external_ref.
Deprecated — former name of external_ref, still honoured so existing integrations keep working. Ignored when external_ref is also present. Use external_ref.
Minimum taxable base
Maximum taxable base
Minimum invoice total
Maximum invoice total
Submission status of an invoice's VeriFactu record to AEAT.
Single vocabulary for the whole axis: the same values are published in verifactu.submission_status of an invoice and accepted by the verifactu_status filter of GET /v1/invoices, so a value read from an invoice can be fed straight back into the filter. ACCEPTED does not include the records accepted with errors, which have their own value. New values may be added over time: treat any value you do not recognise as an unknown status.
- PENDING — queued, AEAT has not answered yet. A temporary AEAT server error also stays PENDING: BeeL. retries it automatically, and it only becomes REJECTED if the retries run out. So does a submission that failed because of a technical problem on BeeL.'s side: BeeL. submits it again once the problem is fixed. Do not void it or issue another invoice for it.
- ACCEPTED — accepted by AEAT without remarks.
- ACCEPTED_WITH_ERRORS — accepted by AEAT, which also reported errors in the record (see error_code / error_message). The record stands, but the data AEAT flagged must be reviewed. Do not treat it as a clean ACCEPTED.
- VOIDED — a cancellation record was accepted by AEAT.
- REJECTED — rejected by AEAT, or the submission was rejected by the provider before reaching AEAT (see error_code / error_message).
- NOT_SUBMITTED — the invoice is issued with VeriFactu enabled but has no live record: the submission fell through (lost event, exhausted retries) and AEAT does not know the invoice exists. Transient right after issuing (the async submission may still be in flight); if it persists, the registration needs to be re-driven.
Drafts and scheduled invoices have no submission to describe yet and omit the field. Invoices with verifactu.enabled = false are outside this axis and are selected with the verifactu_enabled filter.
Filter by the VeriFactu submission status of the invoice, using the very same vocabulary that verifactu.submission_status publishes on each invoice. NOT_SUBMITTED selects issued invoices with VeriFactu enabled whose registration never happened (no live record).
Only invoices with VeriFactu enabled can match. To select the ones outside the axis (VeriFactu disabled), use verifactu_enabled=false instead.
Filter by whether VeriFactu is enabled for the invoice — the same flag published as verifactu.enabled. false returns the invoices that never reach AEAT.
Filter by metadata key/value pairs (exact match, AND between keys). Repeat the bracket-style param to filter on multiple keys. Max 50 pairs per request. Keys must match ^[A-Za-z0-9_\-.]{1,64}$. Example: ?metadata[external_order_id]=ORD-42&metadata[tenant]=acme
Field to sort by: issue_date (default), operation_date, due_date, invoice_number, series_code, status, invoice_total, taxable_base, total_vat, total_equivalence_surcharge, total_discounts, recipient_name, recipient_nif, created_at or updated_at. Any other value is rejected with 400 VALIDATION_ERROR, whose details name sort_by and the accepted values. invoice_number sorts by series code and then by the number within the series, compared numerically (F-9 before F-10). Ties on any field are broken by series code, then by the number within the series and then by id, in the requested direction.
Sort direction. Shared vocabulary for every sort_order query param: declared once so the generator emits a real enum and an unknown direction is rejected with 400 instead of being silently ignored.
Sort direction
Headers
Which company (tax ID) the request operates on.
An API key belongs to an account, and an account may hold several companies. Endpoints that read or write company-owned data — invoices, customers, products, series, tax and VeriFactu settings — resolve their target company from this header when the path does not already name one.
On a path that names the company, such as /v1/companies/{company_id}/invoices, the path is the target and this header is not read at all: it neither switches the target nor makes the request fail, so sending one that disagrees with the path is silently ignored rather than rejected. Prefer those paths whenever you need to be explicit about which tax ID you are operating on.
On an account holding a single company the header may be omitted — that company is used. On an account holding several it is required: the request fails with 403 ACTIVE_COMPANY_REQUIRED otherwise. A company-owned record always belongs to one tax ID, so operating on it without saying which one has no meaning.
The company does not have to belong to the API key's own account: one you manage works too, which is what makes the company_id returned by POST /v1/accounts usable here to invoice on a provisioned account's behalf. What you may do with it is then decided by your access level over that account, and issuing also requires a signed fiscal representation.
This header is how you operate on a company, never how you find one: a value you do not reach answers 403, the same as one that does not exist, so guessing reveals nothing. Get the company_id from the response that created the company.
Requires the companies:read scope. Returns 403 if the company is neither yours nor one you manage.
Response
Invoice list retrieved successfully
Example response
{
"success": true,
"data": {
"invoices": [
{
"invoice_number": "2025/0001",
"series": {
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"code": "FAC"
},
"number": 1,
"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",
"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",
"additional_info": "Nº Colegiado: 12345"
},
"recipient": {
"legal_name": "Empresa SL",
"trade_name": "Empresa",
"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"
},
"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",
"taxable_base": 1800,
"line_total": 2178,
"total_excluding_tax": 1,
"total_including_tax": 100,
"line_type": "NORMAL"
}
],
"totals": {
"taxable_base": 2000,
"vat_breakdown": [
{
"type": 21,
"base": 2000,
"amount": 420,
"regime_key": "18"
}
],
"total_vat": 420,
"total_irpf": 300,
"invoice_total": 2120,
"total_to_pay": 2120
},
"payment_info": {
"method": "BANK_TRANSFER",
"iban": "ES1234567890123456789012",
"swift": "ABCDESMMXXX",
"payment_term_days": 30
},
"voided_at": "2025-01-20T09:12:44Z",
"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"
},
"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": {
"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...",
"submission_status": "ACCEPTED",
"skip_reason": "CONFIG_DISABLED",
"error_code": "3000",
"error_message": "Factura ya existe en el sistema"
},
"sending_history": [
{
"sent_at": "2025-01-29T18:45:00Z"
}
],
"email_delivery": {
"status": "REJECTED",
"reason": "error.email.envio_no_permitido"
},
"id": "550e8400-e29b-41d4-a716-446655440000",
"custom_fields": [
{
"key": "store",
"label": "Store",
"value": "Gran Vía 12"
}
]
}
],
"pagination": {
"current_page": 1,
"total_pages": 5,
"total_items": 87,
"items_per_page": 20
}
},
"meta": {
"timestamp": "2025-01-15T10:30:00Z",
"request_id": "4bf92f3577b34da6a3ce929d0e0e4736"
}
}Changes
No recorded changes to this operation across all 1 revision of this API.