Changelog
Track all updates to the BeeL. API.
Read your API request logs
A new Request Logs endpoint family lets you inspect the requests your own API keys have made (live + test) — method, path, status, timing, and the full request/response detail — so you can correlate and debug integrations without leaving your stack.
GET /v1/developers/request-logs— list your past API requests, cursor-paginated. Filter byenvironment(live/test),only_errors,method,http_status,path_contains,api_key_id, and afrom/totime range. By default the last 30 days are returned.GET /v1/developers/request-logs/{request_id}— full detail of a single request, including request/response bodies and headers. Pass the optionaltimestamphint (the value from the list) to look up logs older than the default window.- Cursor pagination — navigate with the opaque
next_cursor/prev_cursorreturned in each response;has_next/has_previoustell you when you've reached the edges. - Correlate with
X-Request-Id— each log'srequest_idmatches theX-Request-Idresponse header (andmeta.request_id), so you can jump straight from a live response to its full log. - Works with your existing API key (
Authorization: Bearer) — no extra scope required.
- GET/v1/developers/request-logsList your API request logs (cursor-paginated, filterable by environment, status, method, path, key and time range)
- GET/v1/developers/request-logs/{request_id}Get the full detail (bodies + headers) of a single request log
BeeL CLI — run the API from your terminal
The official BeeL CLI is now published on npm as @beel_es/cli. Run any API endpoint straight from the terminal — sandbox by default — with nothing to install thanks to npx. Commands are derived at runtime from the OpenAPI spec bundled with the installed version, so the CLI always matches the API surface of that release.
- Zero-install with
npx @beel_es/cli— ornpm install -g @beel_es/clifor a globalbeelcommand. Runs against sandbox by default. - Every endpoint is a command —
beel commandslists them and--helpat any level shows flags, enums, defaults and body fields, all derived from the spec, so there's no hand-maintained list to drift. - Agent-first — authenticate with an env var (ideal for agents/CI) or a
~/.config/beel/config.json(chmod 600), with a structured output contract that's easy to parse. - Generic escape hatch — call any endpoint the installed version doesn't know yet; update the CLI to pick up newly added endpoints as new commands.
- Search the docs from the terminal without leaving your shell.
Node.js / TypeScript SDK now available
The official BeeL SDK for Node.js and TypeScript is now published on npm as @beel_es/sdk. It is fully typed from the OpenAPI spec, with automatic retries, idempotency keys, typed errors, and webhook signature verification built in.
- Install with
npm install @beel_es/sdk— Node.js 18+, ships both ESM and CommonJS with a single runtime dependency. - Fully-typed client auto-generated from the OpenAPI spec — invoices, customers, products, configuration, series, and NIF validation.
- Automatic retries with exponential backoff on 429 and 5xx, plus auto idempotency keys on every POST so retries never create duplicates.
- Typed errors — catch
BeeLNotFoundError,BeeLValidationError, and friends instead of checking status codes. - Webhook signature verification with HMAC-SHA256 and PDF download as a Buffer.
API v1.3.0 — contract fixes: flexible idempotency keys, optional country, HTTPS-only webhooks
Contract-correctness wave from an API test pass. Idempotency keys no longer have to be UUIDs, address country becomes optional, webhook endpoints must be HTTPS, and several error responses are now more accurate (correct codes, correct status, and a previously-opaque 500 turned into an actionable 422).
Idempotency-Keyaccepts any unique string — not just a UUID. Any client-generated key matching^[a-zA-Z0-9_-]{1,255}$works (e.g.invoice-order-12345). UUIDs still work but are no longer required. Previously a non-UUID key was rejected with 422.address.countryis now optional —country_code(ISO 3166-1 alpha-2) is the canonical field. If you omitcountryit defaults to the country name; you only need to sendcountry_code.X-Request-Idresponse header — every response now carriesX-Request-Id, matchingmeta.request_idin the body, so you can correlate logs without parsing the payload.POST /v1/companiesreturns a clear 403 — when multi-NIF isn't available on your plan it now responds 403MULTI_NIF_NOT_ENABLEDinstead of a misleading 404COMPANY_NOT_FOUNDon a creation endpoint.- Series with an unknown format variable now fails cleanly —
POST /v1/configuration/serieswith an unrecognized{VARIABLE}returns 422SERIES_FORMAT_UNRECOGNIZED_VARSwith the standard error envelope, instead of an opaque empty 500. - Consistent error code for alternative IDs — the wire error code is now
ALTERNATIVE_ID_INVALID(matching the published catalog), not an internal Spanish variant.
- Webhook endpoints must be HTTPS —
POST /v1/webhooks(and updates) now rejecthttp://URLs with 422WEBHOOK_URL_MUST_BE_HTTPS. Signed fiscal payloads are never delivered in cleartext. Re-register any non-HTTPS endpoint over HTTPS. - Customers can't carry both
nifandalternative_id— sending both onPOST /v1/customersnow returns 422ALTERNATIVE_ID_AND_NIF_EXCLUSIVE. Previously the alternative_id was silently dropped and only the NIF kept. Send exactly one identifier. POST /v1/companiesstatus changed 404 → 403 — clients branching on 404COMPANY_NOT_FOUNDfor the multi-NIF-unavailable case must switch to 403MULTI_NIF_NOT_ENABLED.
- POST/v1/companiesReturns 403 MULTI_NIF_NOT_ENABLED (was 404) when multi-NIF is not available on the plan
Renamed the active-company header
The request header that selects which company a request operates on has been renamed from X-Active-Profile to Beel-Active-Company.
- Send
Beel-Active-Company: <company_id>to scope a request to a specific company. - The previous
X-Active-Profileheader keeps working during a deprecation grace period, so you can migrate at your own pace. - While you still send the old header, responses include a
Deprecation: trueheader and aLink: …; rel="deprecation"pointing to this entry. Switch toBeel-Active-Companyto clear it.
API v1.2.0 — VeriFactu validation pack, public error catalog, metadata filters, RD-ley rates, BIZUM
Third wave of VeriFactu compliance hardening: invalid fiscal combinations are now rejected at request time with specific 422s, a public error-code catalog is available at docs.beel.es with stable per-code pages, Stripe-style metadata filtering on the invoices list, RD-ley 11/2022 temporary rates (5% IVA + 0.625% recargo de equivalencia), BIZUM as a new payment method, and several Stripe Connect refinements.
- VeriFactu validation pack — incompatible fiscal combinations now fail with a specific 422 before the registro de facturación is built: SIMPLIFICADA combined with cross-border / IRPF / ISP, ISP carrying recargo de equivalencia, OSS regime + ISP exemption, 0% IVA lines without an explicit reason, regimes / exemption articles that are currently unsupported. Each case returns its own error code so you can branch on it.
- Public error-code catalog at
docs.beel.es/errors/{code}— every code that an API-key integrator can receive now has a stable, deep-linkable page. ThetypeURI in error responses resolves there directly. The catalog covers 199 codes across 8 domains; codes that only surface from the web app are deliberately kept out. metadata[key]=valuefilter onGET /v1/invoices— Stripe-style deepObject filtering. Multiple pairs are AND'd together. Up to 50 pairs per request; keys must match^[A-Za-z0-9_\-.]{1,64}$. Example:?metadata[external_order_id]=ORD-42&metadata[tenant]=acme.- New 5% VAT rate (RD-ley 11/2022) —
VatPercentagenow accepts5as a valid temporary reduced rate alongside 0, 4, 10 and 21. - New 0.625% recargo de equivalencia —
EquivalenceSurchargePercentageadds0.625, the surcharge that pairs with 5% VAT under RD-ley 11/2022. Documented allowed pairings: 4 ↔ 0.5, 5 ↔ 0.625, 10 ↔ 1.4, 21 ↔ 5.2. - BIZUM as a payment method —
payment_info.methodnow acceptsBIZUM. Returned in responses and accepted onPOST/PUT /v1/invoices. - Clearer error when scheduling an ORDINARIA invoice without a recipient identifier — now returns 422 with a specific, actionable message instead of the previous generic validation error.
- PDF includes the VeriFactu QR consistently — the downloaded PDF now always carries the VeriFactu QR when the invoice has one (previously a race could ship a PDF without it).
- Stripe Connect refinements — forward and corrective invoices generated from Stripe now mirror the exact Stripe charge total (no recalculation). SIMPLIFICADA invoices preserve the Stripe customer's name/email instead of falling back to
Consumidor final. The cross-border alternative-ID gap is closed.
- Stricter VeriFactu validation rejects previously-accepted invoices — invoices that combined incompatible options (ISP + recargo de equivalencia, OSS + ISP exemption, SIMPLIFICADA + IRPF, 0% IVA without reason, etc.) used to pass the request and fail later. They now fail with 422 and a specific code at request time. Re-test integrations that exercise edge-case fiscal combinations.
VatPercentageschema type widened fromintegertonumber— all currently allowed values are still whole numbers (0, 4, 5, 10, 21), so wire-level responses do not change. Strongly-typed SDK clients generated from the OpenAPI spec (Java, C#, Go) should regenerate to pick up the new schema type; loose clients (JavaScript, Python without strict typing) need no changes.payment_info.method = BIZUMmay be returned where it previously wasn't — clients that exhaustively switch onmethodshould add aBIZUMbranch (or a default arm).lines[].iva_rate = 5.00may now be returned — same as above for clients enumerating known rates.
- GET/v1/invoicesAdded `metadata[key]=value` query parameter (deepObject) for filtering by metadata pairs
API v1.2.0 — Metadata filter on invoices, RD-ley 11/2022 reduced rates (5% IVA / 0.625% RE)
GET /v1/invoices now accepts Stripe-style metadata filtering, and tax schemas add the RD-ley 11/2022 temporary rates (5% IVA paired with 0.625% recargo de equivalencia). The VatPercentage schema type widens from integer to number.
- Metadata filter on
GET /v1/invoices— Filter by any metadata key/value pair using?metadata[key]=value(deepObject style). Multiple keys are AND'd together. Up to 50 pairs per request; keys must match^[A-Za-z0-9_\-.]{1,64}$. Example:?metadata[external_order_id]=ORD-42&metadata[tenant]=acme. - New 5% VAT rate (RD-ley 11/2022) — The
VatPercentageenum accepts5as a valid temporary reduced rate alongside 0, 4, 10 and 21. - New 0.625% recargo de equivalencia —
EquivalenceSurchargePercentageadds0.625, the surcharge that pairs with 5% VAT under RD-ley 11/2022. The schema description now documents every allowed pairing explicitly: 4↔0.5, 5↔0.625, 10↔1.4, 21↔5.2.
VatPercentageschema type widened fromintegertonumber— All currently allowed values are still whole numbers (0, 4, 5, 10, 21), so wire-level responses do not change. Strongly-typed SDK clients generated from the OpenAPI spec (Java, C#, Go) should regenerate to pick up the new schema type; loose clients (JavaScript, Python without strict typing) need no changes.
- GET/v1/invoicesAdded `metadata[key]=value` query parameter (deepObject) for filtering by metadata pairs
API v1.1.0 — Refactored invoice recipient & payment_info, new series defaults
Invoice recipient and payment_info schemas have been refactored to use structured objects with allOf composition. This change normalizes the API and enables future extensibility. Also adds new series defaults endpoints.
- Structured
recipientandpayment_info— PUT /v1/invoices/{invoice_id} now usesallOfcomposition withPaymentInfoandRecipientschemas. Fields likenif,legal_name,iban,methodare still available via the referenced schemas, but the structure changed from inline to composed. Regenerate your SDK if you use one. - New series defaults endpoints — POST /v1/configuration/series/defaults and GET /v1/configuration/series/defaults-status allow setting and checking per-document-type default series.
- Idempotency-Key header — Now formally documented on POST /v1/customers.
- Invoice email options — All invoice endpoints now return
email_configandsend_automaticallyfields in responses.
- PUT /v1/invoices/{invoice_id} schema change —
recipientandpayment_infonow useallOfcomposition referencingRecipientandPaymentInfoschemas. The fields (nif,legal_name,iban,method, etc.) remain available but the schema path changed from inline properties to a $ref. Clients using generated SDKs may need to regenerate. - SDK regeneration recommended — If you use generated clients from the OpenAPI spec, regenerate them to pick up the new schema references. The underlying fields are the same; only the structure (and how the SDK types represent them) has changed.
- PUT/v1/invoices/{invoice_id}recipient and payment_info now use allOf composition — update your request payload structure
- POST/v1/configuration/series/defaultsSet default series per document type
- GET/v1/configuration/series/defaults-statusCheck which series have defaults configured
API v1.1.0 — Refactored invoice recipient & payment_info, new series defaults
Invoice recipient and payment_info schemas have been refactored to use structured objects with allOf composition. This change normalizes the API and enables future extensibility. Also adds new series defaults endpoints.
- Structured
recipientandpayment_info— PUT /v1/invoices/{invoice_id} now usesallOfcomposition withPaymentInfoandRecipientschemas. Fields likenif,legal_name,iban,methodare still available via the referenced schemas, but the structure changed from inline to composed. Regenerate your SDK if you use one. - New series defaults endpoints — POST /v1/configuration/series/defaults and GET /v1/configuration/series/defaults-status allow setting and checking per-document-type default series.
- Idempotency-Key header — Now formally documented on POST /v1/customers.
- Invoice email options — All invoice endpoints now return
email_configandsend_automaticallyfields in responses.
- PUT /v1/invoices/{invoice_id} schema change —
recipientandpayment_infonow useallOfcomposition referencingRecipientandPaymentInfoschemas. The fields (nif,legal_name,iban,method, etc.) remain available but the schema path changed from inline properties to a $ref. Clients using generated SDKs may need to regenerate. - SDK regeneration recommended — If you use generated clients from the OpenAPI spec, regenerate them to pick up the new schema references. The underlying fields are the same; only the structure (and how the SDK types represent them) has changed.
- PUT/v1/invoices/{invoice_id}recipient and payment_info now use allOf composition — update your request payload structure
- POST/v1/configuration/series/defaultsSet default series per document type
- GET/v1/configuration/series/defaults-statusCheck which series have defaults configured
API v1.0.3 — VeriFactu exemptions, document types, stricter validations
Second round of VeriFactu compliance improvements: invoice lines can now carry an explicit exemption reason, the tax-types endpoint exposes the full LIVA exemption catalog, invoice series can be typed, and the id_otro VeriFactu rules are now enforced with specific error messages.
- Invoice line exemption reasons —
exemption_reason(enum coveringEXENTA_ART_*,NO_SUJETA_*,ISP_ART_84_2_*,REGIMEN_ART_*andOTRO) and the free-textexemption_reason_textare now accepted and returned on invoice lines. Required by VeriFactu whenever a line is exempt or not-subject. - Exemption reasons catalog —
GET /v1/configuration/tax-typesreturns the full LIVA exemption catalog so integrators can build UIs without hardcoding the list. - Typed invoice series — new
document_typeon/v1/configuration/series(request, response and list query filter), so you can segregate series for invoices, corrective invoices, etc. - Descriptive alternative ID types —
id_otro.typenow acceptsPASSPORT,COUNTRY_ID,NIF_IVA,RESIDENCE_CERTIFICATE,OTHER_DOCUMENT,NOT_REGISTEREDalongside the legacy numeric codes02–07(still valid, now deprecated). - VeriFactu
id_otrorules enforced at the boundary — ifcountry_code = ESthetypemust bePASSPORT(03) orNOT_REGISTERED(07); iftype = NOT_REGISTEREDthecountry_codemust beES. Violations return 422 with a specific message per rule (previously a generic "identificador alternativo no es válido").
irpf_rateenum —21.00is removed and1.00is added onlines[].irpf_rate(POST/PUT /v1/invoices,POST /v1/invoices/{invoice_id}/corrective) and ondefault_irpf_rate(PUT /v1/configuration/taxes). 21% IRPF is not a valid withholding rate for the flows Beel supports.template_htmlremoved — thetemplate_types[].template_htmlproperty no longer ships inGET /v1/configuration/invoice-customization-options. PDF templates are owned and rendered by the backend; clients should not inspect the raw HTML.- Stricter NIF pattern —
POST/PUT /v1/customersandPOST /v1/customers/bulknow validatenifagainst the full DNI/NIE/CIF regex^(\d{8}[A-Z]|[ABCDEFGHJKLMNPQRSUVW]\d{7}[A-Z0-9]|[XYZ]\d{7}[A-Z])$instead of the permissive^[A-Z0-9]{9}$. Previously-accepted but invalid strings (e.g.ABCDEFGHI) will now be rejected.
API v1.0.1 — VeriFactu operation_date & spec improvements
This release aligns the API with Spanish anti-fraud law (Ley Antifraude / VeriFactu) requirements for invoice dates. The issue_date is now always set to today and a new operation_date field lets you record when the operation actually took place.
- New
operation_datefield on invoices — use when invoicing for a past operation (e.g., services delivered last month but invoiced this month) issue_dateis now read-only and always set to today per VeriFactu regulationsissue_dateremoved from required fields in CreateInvoiceRequest- Duplicate invoice no longer accepts a custom
issue_date— duplicates are always dated today - Idempotency header renamed from
X-Idempotency-KeytoIdempotency-Key(standard naming) - Improved
due_datedocumentation — must be same as or after today's date - New
start_datefield on recurring invoice creation
- POST/v1/invoicesoperation_date replaces issue_date in request body
- PUT/v1/invoices/{invoice_id}operation_date (nullable) replaces issue_date
- POST/v1/invoices/{invoice_id}/duplicateissue_date param removed from request
BeeL API v1.0 — Public Launch
The BeeL API is now publicly available. Full REST API for invoicing, customer management, products, tax configuration, and VeriFactu compliance — all with a 7-day free trial.
- Complete invoice lifecycle: create, issue, send, pay, void, and correct
- Customer and product catalog management with bulk operations
- VeriFactu compliance with automatic AEAT submission
- Webhook notifications for invoice and VeriFactu events
- Idempotency support for safe retries on all creation endpoints
- Sandbox environment with unlimited invoices for testing
- OpenAPI 3.0 specification for client generation in any language