NewProvince is only required for addresses in Spain
BeeL
Get startedMulti-NIFVeriFactuRulesStripeAPI referenceChangelog

AI agents

How to build a BeeL. integration with an AI agent — the official SDK, the MCP server, the Claude Code plugin, the Markdown docs and llms.txt, the fiscal rules as data, and an AGENTS.md block to paste into your repository.


An agent that writes invoicing code needs two things: the API, and the fiscal rules that depend on the data it sends and on the business that issues. BeeL. publishes both in forms an agent reads directly, so it does not have to scrape HTML or guess.

Pick a way in

You want the agent toUse
Act on your BeeL. account: issue, void, look up invoicesThe MCP server, https://mcp.beel.es/mcp
Write the integration codeThe Node.js / TypeScript SDK (@beel_es/sdk 2.2.0+, for projects with package.json), with the code in From order to invoice, Idempotency
Review integration code in your repository, or have it scaffoldedThe Claude Code plugin, with its implement and audit skills
Read the docs/llms.txt, the index, and any page as Markdown: add .md to its URL
Know what it must never doThe fiscal rules: every way to use them from your tools
Search the docs from a terminalbeel docs search in the CLI

Give your agent the rules

Paste this into the AGENTS.md or CLAUDE.md of the repository where the integration lives. It tells the agent which SDK to install for the stack, with the REST basics as the fallback, and lists the rules marked critical. It is built from the SDK catalogue and the rules, so it changes when they do; copy it again after a release.

## BeeL. invoicing API- Docs index for agents: https://docs.beel.es/llms.txt — every page has a Markdown twin at `<url>.md`.- Fiscal rules: https://docs.beel.es/rules (JSON: https://docs.beel.es/api/rules.json). Cite rule ids (e.g. LIF-001) when a rule decides a change.- Test keys (`beel_sk_test_…`) hit the sandbox; live keys (`beel_sk_live_…`) issue real invoices. Develop and run tests with a test key only. Never commit or log a key; read it from the environment (`BEEL_API_KEY`).### SDKUse the official BeeL. SDK for your stack. If it is not installed in the project, installing it is step one: do not hand-write HTTP calls for the flows it covers, the SDK carries the typed request bodies and the safe retries.If your project configures the API URL, pass it as `baseUrl` instead of calling the API by hand; without it the client uses production. Read the key and the URL from your project's own environment variables, whatever their names.- TypeScript / JavaScript (`package.json`): `npm install @beel_es/sdk` (2.2.0 or later). Code for each case: https://docs.beel.es/guides/order-to-invoice.md, https://docs.beel.es/guides/idempotency.md- Python (`pyproject.toml`, `requirements.txt`, `setup.py`, `Pipfile`): beel-sdk is legacy. Version 1.0.0 calls the routes without the company in the path, which retire on the date in the deprecation policy. Until a new release, call the REST API.- Java (`pom.xml`, `build.gradle`, `build.gradle.kts`): es.beel:beel-sdk is legacy. Version 1.0.2 calls the routes without the company in the path, which retire on the date in the deprecation policy. Until a new release, call the REST API.- No recommended SDK for your stack: call the REST API as the API reference describes, or generate a typed client from the OpenAPI specification. Catalogue: https://docs.beel.es/api/sdks.json### REST, for a stack without a recommended SDK- API base: `https://app.beel.es/api`; every path starts with `/v1`. Auth: `Authorization: Bearer $BEEL_API_KEY`.- Company-scoped routes are `/v1/companies/{company_id}/…`.- Send an `Idempotency-Key` on every create, issue, void or corrective, and reuse it only to retry that same request.### Critical rules- Once an invoice is issued, neither the invoice nor its billing record is changed or removed. Any correction goes through a later document: a corrective invoice or a void. ([LIF-001](https://docs.beel.es/rules/LIF-001.md))- Do not issue test invoices with a production key. An invoice issued in production is a real invoice, sent to AEAT and numbered in your series, even if it was meant as a test; one issued by mistake has to be voided. ([LIF-003](https://docs.beel.es/rules/LIF-003.md))- Send an Idempotency-Key header on every call that creates, issues, corrects or voids an invoice, and repeat the same key when you retry. A retried request returns the stored response of the first one, a 5xx included, for 24 hours; a 4xx answer frees the key, so the corrected request can reuse it. ([LIF-004](https://docs.beel.es/rules/LIF-004.md))- Void an invoice only when it was issued by mistake: the sale or service it describes never took place, it was a test, or it is an accidental duplicate. An invoice for an operation that did happen is not voided to fix its amounts, VAT or details; it is corrected with a corrective invoice. The one exception is a withholding that should not have been applied: the withholding is not a cause for a corrective (COR-024), so that invoice is voided and issued again without it. The API asks for the confirmation once the invoice was sent or paid (VOI-004) and refuses to void a corrected invoice (VOI-005). ([VOI-001](https://docs.beel.es/rules/VOI-001.md))- Send the rectification_code that matches the cause: R1 for an error founded in law or art. 80 Uno, Dos and Seis LIVA, R2 for insolvency, R3 for bad debt, R4 for the rest. A simplified invoice is always corrected with R5, and R5 corrects nothing else. ([COR-002](https://docs.beel.es/rules/COR-002.md))- Do not expect or send an invoice number: a draft has none, and BeeL. assigns the next number of the chosen series when the invoice is issued. Read invoice_number from the response of the issue call. ([NUM-001](https://docs.beel.es/rules/NUM-001.md))- Treat every issued number as consumed for good. A voided invoice, or a test issued in production, keeps its number in the series; the invoice that replaces it gets a new one. BeeL. never gives two invoices of a company the same number: a series whose format could print the numbers of another series of the company is rejected with SERIES_FORMAT_OVERLAPS. If AEAT already holds a record with the same number and issue date that is not this invoice, for example one issued with the software you used before, the invoice is not registered: its verifactu.submission_status is REJECTED, and it has to be issued again with a different series or number. ([NUM-002](https://docs.beel.es/rules/NUM-002.md))- Do not use a standard or simplified invoice with a negative total as a credit note. A refund or a reduction is a corrective invoice against the original. An invoice that totals zero is valid. ([CNT-019](https://docs.beel.es/rules/CNT-019.md))- Do not issue a simplified invoice whose total, VAT included, is above 3,000 €. Above it, issue a standard invoice (F1) with the customer identified. ([SIM-001](https://docs.beel.es/rules/SIM-001.md))- The API has no currency field: every amount you send is read as euros. Convert foreign-currency prices to euros before sending them; you may mention the original currency in the notes. ([TAX-013](https://docs.beel.es/rules/TAX-013.md))- The API has no writable issue date: an invoice is dated the day it is issued, and a scheduled one the day it is scheduled for. To record when the sale happened, send operation_date. ([DAT-001](https://docs.beel.es/rules/DAT-001.md))- Do not render or send a document of an invoice under VeriFactu before its QR data exists. Wait for the invoice.pdf.generated webhook, or read the invoice until verifactu.qr_url is present. The API applies the same rule to its own PDF: it is painted once, with the QR, and never modified afterwards — voiding or correcting the invoice does not change it. Asking for the PDF of an invoice whose record ended without QR data answers INVOICE_NOT_REGISTERED_NO_PDF; an email requested before the PDF exists is accepted with 202 and sent when the PDF is stored, or recorded as failed if the record ends without QR data. ([QRC-002](https://docs.beel.es/rules/QRC-002.md))- Track each issued invoice's verifactu.submission_status (NOT_SUBMITTED, PENDING, ACCEPTED, REJECTED, VOIDED) through the verifactu.status.updated webhook and a periodic reconciliation. A transient AEAT error keeps the invoice PENDING while BeeL. retries it. A REJECTED invoice is not registered: read its error_message, and its error_code when AEAT gave one, and fix it. GET /v1/companies/{company_id}/invoices/{invoice_id}/verifactu-records lists each record of the invoice, its cancellation included, with its own status. ([REC-008](https://docs.beel.es/rules/REC-008.md))

Each rule it names has a page with its legal basis, who checks it, the error the API answers and a right and a wrong example. To give an agent the rest of the catalogue — as JSON, one rule at a time, through the MCP tools or the Claude Code skill — see Use the rules in your tools.

What the docs serve to agents

  • /llms.txt — the index: instructions for agents, one line per page and per rule, and child indexes for the error codes, the API reference and the changelog.
  • /<area>/llms-full.txt — every page of one area in full, for example /verifactu/llms-full.txt; /llms-full.txt has them all.
  • <page>.md — any page as Markdown. HTML pages announce it with a Link: <…md>; rel="alternate"; type="text/markdown" header, and the Markdown response carries x-markdown-tokens with its approximate size.
  • /api/sdks.json — which official SDK to use for each stack: how to detect the stack, the package and its install command, the minimum version, and the guides with code for it. Its shape is on SDKs.
  • /rules/<ID>.md, /api/rules.json and /rules/llms-full.txt — the fiscal rules; what each one holds is in Use the rules in your tools.
  • /.well-known/skills/index.json — where to find the agent skill that teaches the rules.
  • /api/openapi — the contract.

Every one of them is generated from the same sources as the pages, on each build.

Gotchas

Give an agent a test key (beel_sk_test_…). With a live key, an invoice it issues is real: it is numbered in your series, registered with AEAT, and can only be voided or corrected — see LIF-003 Test in the sandbox, never with real invoices.

  • Agents retry. Every write must carry an Idempotency-Key, the same one on each retry of that request — see LIF-004 Retry writes with the same Idempotency-Key. The SDK does both for you, and for invoices tied to an order the recipe makes a second run safe; code that calls the API directly has to do it itself.
  • An agent cannot tell a test invoice from a real one, or a void from a correction, without the rules. Point it at Void or correct before it touches an issued invoice.