Skip to main content
Glama
beel-es

BeeL MCP server

Official
by beel-es

beel_list_invoices

Read-onlyIdempotent

Retrieve a paginated list of a company's invoices, filtered by status, type, series, customer, date range, or search text.

Instructions

Returns a paginated list of the invoices of this company, filterable by status, type, series, customer, date range and free text. Only the documents of the company in the path are returned.

Endpoint: GET /v1/companies/{company_id}/invoices

⚠️ Read before calling:

  • Fiscal rules, domains lifecycle: beel_rules_list with domain, or resource beel://guardrails/.

  • The status names, the proforma lifecycle, and which tool performs each operation. (resource: beel://guardrails/invoice-state-machine)

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
pageNoPage number, starting at 1. The response echoes it back as `pagination.current_page`.
typeNoFilter by invoice type
limitNoHow many items to return per page. The response echoes it back as `pagination.items_per_page`.
searchNoGlobal search across invoice number, recipient name, recipient NIF, and series code (partial, case-insensitive)
statusNoFilter 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.
date_toNoIssue date to (YYYY-MM-DD)
sort_byNoField 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.
metadataNoFilter 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`
date_fromNoIssue date from (YYYY-MM-DD)
total_maxNoMaximum invoice total
total_minNoMinimum invoice total
company_idYesUnique 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.
sort_orderNoSort directiondesc
customer_idNoFilter by customer UUID
fiscal_onlyNoWhen `true`, returns only fiscal documents (STANDARD, CORRECTIVE, SIMPLIFIED), excluding proformas and any other non-fiscal document. Defaults to `false` (the list returns every document type). Ignored when an explicit `type` is given.
series_codeNoFilter by series code (exact match, case-insensitive). Use `search` for partial matching across the invoice number, recipient and series code.
external_refNoFilter by exact external reference (client-supplied order/cart/contract id).
recipient_nifNoFilter by recipient's NIF (partial search)
invoice_numberNoSearch by invoice number (e.g., 2025/0001)
payment_methodNoFilter 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.
recipient_nameNoFilter by recipient's fiscal name (partial, case-insensitive search)
taxable_base_maxNoMaximum taxable base
taxable_base_minNoMinimum taxable base
verifactu_statusNoFilter 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).
verifactu_enabledNoFilter by whether VeriFactu is enabled for the invoice — the same flag published as `verifactu.enabled`. `false` returns the invoices that never reach AEAT.
rectified_invoice_idNoReturn the corrective invoices that correct this invoice. Accepts the id of an issued invoice; a single invoice can have several partial correctives.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed8 schema fields changedv0.9.0
    • changedInput schema / $defs / InvoiceStatus / description
      Previous value: -"- SCHEDULED: Scheduled invoice to be issued automatically on a future date\n- DRAFT: Draft invoice not sent yet (modifiable)\n- ISSUED: Finalized invoice with definitive number but not sent\n- SENT: Invoice sent to customer\n- PAID: Invoice paid\n- OVERDUE: Overdue invoice (not paid after due date)\n- RECTIFIED: Partially corrected invoice (one or more PARTIAL corrective invoices)\n- VOIDED: Cancelled invoice. Reached either through a direct void request or\n  through a TOTAL corrective invoice; `void_cause` tells the two apart.\n- CONVERTED: Proforma converted into an invoice (terminal; the proforma survives\n  as the record of the accepted quote, linked to the created invoice)\n- ACTIVE: Active proforma. The single working state of a proforma (non-fiscal\n  document): born numbered (PRO-...) and editable, never reaching the fiscal\n  statuses. It transitions to CONVERTED when turned into an invoice, or to VOIDED\n  when the offer is rejected/withdrawn (POST /v1/invoices/{invoice_id}/void).\n- EXPIRED: Proforma whose offer validity (`valid_until`) has passed. Derived on read\n  and never stored; the proforma stays convertible and editable.\n"New value: +"- SCHEDULED: Scheduled invoice to be issued automatically on a future date\n- DRAFT: Draft invoice not sent yet (modifiable)\n- ISSUED: Finalized invoice with definitive number but not sent\n- SENT: Invoice sent to customer\n- PAID: Invoice paid\n- OVERDUE: Reserved. No operation sets this status and it is not computed from `due_date`;\n  an unpaid invoice past its due date keeps its status (`ISSUED` or `SENT`). Compare\n  `due_date` with today to find overdue invoices.\n- RECTIFIED: Partially corrected invoice (one or more PARTIAL corrective invoices)\n- VOIDED: Cancelled invoice. Reached either through a direct void request or\n  through a TOTAL corrective invoice; `void_cause` tells the two apart.\n- CONVERTED: Proforma converted into an invoice (terminal; the proforma survives\n  as the record of the accepted quote, linked to the created invoice)\n- ACTIVE: Active proforma. The single working state of a proforma (non-fiscal\n  document): born numbered (PRO-...) and editable, never reaching the fiscal\n  statuses. It transitions to CONVERTED when turned into an invoice, or to VOIDED\n  when the offer is rejected/withdrawn (POST /v1/invoices/{invoice_id}/void).\n- EXPIRED: Proforma whose offer validity (`valid_until`) has passed. Derived on read\n  and never stored; the proforma stays convertible and editable.\n"
    • changedInput schema / $defs / InvoiceType / description
      Previous value: -"- STANDARD: Standard invoice\n- CORRECTIVE: Corrects or cancels a previous invoice\n- SIMPLIFIED: Simplified invoice without all recipient requirements (up to 3,000€ VAT included)\n- PROFORMA: Commercial document (formal quote) with no fiscal validity.\n  Never enters VeriFactu (no QR, no AEAT submission) and `verifactu_enabled`\n  is always forced to `false`. Requires full recipient data, like STANDARD.\n  Cannot be corrective nor reference a rectified invoice.\n"New value: +"- STANDARD: Standard invoice\n- CORRECTIVE: Corrects or cancels a previous invoice\n- SIMPLIFIED: Simplified invoice (ticket), for a recipient that is not identified. BeeL.\n  requires a STANDARD invoice when the recipient is identified, at any amount: a\n  SIMPLIFIED invoice whose recipient carries an `nif` or `alternative_id` is rejected\n  with `SIMPLIFIED_INVOICE_FORBIDS_IDENTIFIED_RECIPIENT`. The only amount BeeL\n  enforces is a cap of 3,000€ VAT included (`SIMPLIFIED_INVOICE_EXCEEDS_LEGAL_LIMIT`). The\n  general limit of RD 1619/2012 is 400€ (art. 4.1.a); up to 3,000€ applies only to the\n  activities listed in art. 4.2. BeeL does not check which activity the issuer carries\n  out.\n- PROFORMA: Commercial document (formal quote) with no fiscal validity.\n  Never enters VeriFactu (no QR, no AEAT submission): `verifactu.enabled` is\n  always `false`, whatever the company's regime. Requires full recipient data,\n  like STANDARD.\n  Cannot be corrective nor reference a rectified invoice.\n"
    • addedInput schema / $defs / PaymentMethod
      Added value: +{
      +  "description": "Payment method shown on invoices and recurring invoices.\n\n- `NONE`: no payment information is shown.\n- `BANK_TRANSFER`: bank transfer to the IBAN of the payment details; the only method\n  that requires an IBAN.\n- `CARD`: card payment.\n- `CASH`: cash payment.\n- `CHECK`: payment by cheque.\n- `DIRECT_DEBIT`: direct debit from the customer's bank account.\n- `BIZUM`: payment through Bizum.\n- `OTHER`: any other method.\n",
      +  "enum": [
      +    "NONE",
      +    "BANK_TRANSFER",
      +    "CARD",
      +    "CASH",
      +    "CHECK",
      +    "DIRECT_DEBIT",
      +    "BIZUM",
      +    "OTHER"
      +  ],
      +  "type": "string"
      +}
    • changedInput schema / $defs / VeriFactuSubmissionStatus / description
      Previous value: -"Submission status of an invoice's VeriFactu record to AEAT.\n\nSingle vocabulary for the whole axis: the same values are published in\n`verifactu.submission_status` of an invoice and accepted by the `verifactu_status`\nfilter of `GET /v1/invoices`, so a value read from an invoice can be fed straight\nback into the filter.\n\n* `PENDING` — queued, AEAT has not answered yet.\n* `ACCEPTED` — accepted by AEAT (with or without non-blocking warnings).\n* `VOIDED` — a cancellation record was accepted by AEAT.\n* `REJECTED` — rejected by AEAT, or the submission was rejected by the provider\n  before reaching AEAT (see `error_code` / `error_message`).\n* `NOT_SUBMITTED` — the invoice is issued with VeriFactu enabled but has no live\n  record: the submission fell through (lost event, exhausted retries) and AEAT\n  does not know the invoice exists. Transient right after issuing (the async\n  submission may still be in flight); if it persists, the registration needs to\n  be re-driven.\n\nDrafts and scheduled invoices have no submission to describe yet and omit the\nfield. Invoices with `verifactu.enabled = false` are outside this axis and are\nselected with the `verifactu_enabled` filter.\n"New value: +"Submission status of an invoice's VeriFactu record to AEAT.\n\nSingle vocabulary for the whole axis: the same values are published in\n`verifactu.submission_status` of an invoice and accepted by the `verifactu_status`\nfilter of `GET /v1/invoices`, so a value read from an invoice can be fed straight\nback into the filter.\n\n* `PENDING` — queued, AEAT has not answered yet. A temporary AEAT server error also\n  stays `PENDING`: BeeL. retries it automatically, and it only becomes `REJECTED` if the\n  retries run out.\n* `ACCEPTED` — accepted by AEAT (with or without non-blocking warnings).\n* `VOIDED` — a cancellation record was accepted by AEAT.\n* `REJECTED` — rejected by AEAT, or the submission was rejected by the provider\n  before reaching AEAT (see `error_code` / `error_message`).\n* `NOT_SUBMITTED` — the invoice is issued with VeriFactu enabled but has no live\n  record: the submission fell through (lost event, exhausted retries) and AEAT\n  does not know the invoice exists. Transient right after issuing (the async\n  submission may still be in flight); if it persists, the registration needs to\n  be re-driven.\n\nDrafts and scheduled invoices have no submission to describe yet and omit the\nfield. Invoices with `verifactu.enabled = false` are outside this axis and are\nselected with the `verifactu_enabled` filter.\n"
    • addedInput schema / properties / payment_method
      Added value: +{
      +  "description": "Filter by payment method. Accepts a comma-separated list to match any of several\nmethods, for example `payment_method=DIRECT_DEBIT,CARD`. A single value is also valid.\n`NONE` also matches invoices that have no payment method stored. Combine it with\n`date_from`/`date_to` to list, for example, the direct debits of a month. An empty\nvalue (`payment_method=`) is the same as omitting the parameter.\n",
      +  "items": {
      +    "$ref": "#/$defs/PaymentMethod"
      +  },
      +  "type": "array"
      +}
    • changedInput schema / properties / sort_by / description
      Previous value: -"Field to sort by (e.g., issue_date, invoice_number, invoice_total)"New value: +"Field to sort by: `issue_date` (default), `operation_date`, `due_date`,\n`invoice_number`, `series_code`, `status`, `invoice_total`, `taxable_base`,\n`total_vat`, `total_equivalence_surcharge`, `total_discounts`, `recipient_name`,\n`recipient_nif`, `created_at` or `updated_at`. Any other value is rejected with `400`\n`VALIDATION_ERROR`, whose `details` name `sort_by` and the accepted values.\n"
    • changedInput schema / properties / status / description
      Previous value: -"Filter by invoice status. Accepts a comma-separated list to match any of several\nstatuses, for example `status=DRAFT,ISSUED`. A single value is also valid.\n"New value: +"Filter by invoice status. Accepts a comma-separated list to match any of several\nstatuses, for example `status=DRAFT,ISSUED`. A single value is also valid. An empty\nvalue (`status=`) is the same as omitting the parameter.\n"
    • removedInput schema / properties / status / minItems
      Removed value: -1
  2. Changed5 schema fields changedv0.5.0
    • removedInput schema / $defs / SortOrder / example
      Removed value: -"desc"
    • removedInput schema / $defs / UUID / example
      Removed value: -"550e8400-e29b-41d4-a716-446655440000"
    • removedInput schema / $defs / VeriFactuSubmissionStatus / example
      Removed value: -"ACCEPTED"
    • addedInput schema / additionalProperties
      Added value: +false
    • changedInput schema / properties / company_id / description
      Previous value: -"NIF (company) the operation acts on. 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 NIF you do not reach answers `403`, and so does a NIF that does not exist, so the existence of a NIF in another account is never disclosed."New value: +"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."
  3. First observedv0.3.1

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, idempotent, non-destructive and openWorld, so the safety profile is covered. The description adds real context beyond that: the company-in-path scoping rule, pagination behavior, and the guardrail resources an agent must consult before relying on status values. It does not mention auth requirements or rate limits.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose is front-loaded in the first sentence, followed by a short scope note and the endpoint, then a clearly delimited warning block. The endpoint line is mildly redundant, but nothing else is padding.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 26-parameter, nested-object list tool with no output schema, the description covers purpose, scope, pagination and the guardrail resources needed to interpret the fiscal filters. Return-value details are not spelled out, but the schema fully documents the inputs and the description need not restate them.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the 26 parameters carry detailed per-field docs (enum lifecycles, sort_by whitelist, metadata key rules), so the schema does the heavy lifting. The description only restates the filter categories at a high level, adding no syntax or format detail beyond the schema, which is the baseline-3 case.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Returns a paginated list of the invoices of this company') and enumerates the filter axes (status, type, series, customer, date range, free text), which lets an agent separate it from single-document tools like beel_get_invoice and from beel_list_recurring_invoices. The scope clause 'Only the documents of the company in the path are returned' pins down what the list contains.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The 'Read before calling' block gives concrete prerequisites: consult beel_rules_list with the relevant domain, or the beel://guardrails/<domain> and beel://guardrails/invoice-state-machine resources, before using the status and proforma filters. It does not name alternative list tools or state when not to use this one, so it stops short of full routing guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Deploy Server

Other Tools