NewStripe: a buyer with a NIF always gets a standard invoice, and the simplified threshold is deprecated
BeeL
Get startedMulti-NIFVeriFactuRulesStripeAPI referenceChangelog
Invoice Series

Create invoice series (deprecated)

Scopeseries:write

Deprecated. Use POST /v1/companies/{company_id}/series, which behaves identically.

Creates a new invoice series for the company in focus.

  • Code: must be unique within the company; a code already taken answers 409.
  • Numbering: format must contain {NUM} or {NUM:X} and only accepts uppercase tokens. counter_reset defaults to ANNUAL, so a format with no year token has to be sent with counter_reset: NEVER.
  • Default series: the first series created for a document type is marked as default even if you send default_series: false.

Retires on 9 December 2026. See the migration guide for what moved where and what changes when you switch.


POST
/v1/configuration/series
AuthorizationBearer <token>

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

Header Parameters

Idempotency-Key?string

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.

StatusCodeWhen
400INVALID_IDEMPOTENCY_KEYThe key breaks the format rules above.
409IDEMPOTENCY_KEY_PROCESSINGThe first request is still in flight. Wait for the Retry-After seconds (2) and retry with the same key.
409IDEMPOTENCY_KEY_MISMATCHThe key was already used with a different body. Use a new key.
Match^[a-zA-Z0-9_-]+$
Lengthlength <= 255
document_typestring

Document type associated with a series. Values mirror InvoiceType, so the series a document needs is named exactly like the document:

  • UNASSIGNED: Legacy value of series created before types existed. A series numbers only documents of its own type, so an UNASSIGNED series numbers none (422 SERIES_INCOMPATIBLE_DOC_TYPE); give it a type to keep using it. No series can be created with it or moved to it (422 SERIES_UNASSIGNED_TYPE_NOT_ALLOWED). The live ones were given the type they numbered most.
  • STANDARD: Standard invoice
  • SIMPLIFIED: Simplified invoice
  • CORRECTIVE: Corrects or cancels a previous standard invoice (R1–R4)
  • SIMPLIFIED_CORRECTIVE: Corrects a simplified invoice (R5). Spanish law requires R5 to be numbered apart from R1–R4, so they have a series type of their own
  • PROFORMA: Proforma (commercial document, non-fiscal numbering)
Value in"UNASSIGNED" | "STANDARD" | "SIMPLIFIED" | "CORRECTIVE" | "SIMPLIFIED_CORRECTIVE" | "PROFORMA"
namestring

Descriptive name of the series

Length1 <= length <= 100
codestring

Alphanumeric series code (used in {CODIGO} variable). Allows uppercase letters, numbers, hyphens and underscores.

Match^[A-Z0-9\-_]{1,50}$
Length1 <= length <= 50
description?string|null

Optional series description

Lengthlength <= 1000
formatstring

Format template with available variables (UPPERCASE ONLY):

  • {CODIGO}: Series code (e.g., "FAC")
  • {YYYY}: Year with 4 digits (e.g., "2025")
  • {YY}: Year with 2 digits (e.g., "25")
  • {MM}: Month with 2 digits (e.g., "01")
  • {NUM}: Sequential number without padding (e.g., "1")
  • {NUM:X}: Sequential number with padding (e.g., {NUM:4} → "0001")

REQUIRED: Must contain at least {NUM} or {NUM:X} IMPORTANT: Only uppercase (rejects {yy}, {mm}, {codigo}, etc.)

Valid examples:

  • "{CODIGO}-{YYYY}-{NUM:4}" → "FAC-2025-0001"
  • "{CODIGO}/{NUM:6}" → "FAC/000001"
  • "{YYYY}{MM}-{NUM:3}" → "202501-001"

The generated number is the invoice number sent to the AEAT, which accepts at most 60 printable ASCII characters and none of ", ', <, >, =. A format whose longest possible number breaks that rule is rejected with 422 SERIES_FORMAT_NUMBER_TOO_LONG or SERIES_FORMAT_INVALID_CHARACTERS. The counter counts as at least 9 digits, with or without padding: {NUM:X} is a minimum width, not a maximum.

Match^[A-Z0-9\-_/{}:]*$
Length1 <= length <= 255
counter_reset?string
Value in"NEVER" | "ANNUAL" | "MONTHLY"
initial_number?integer

Initial number for this series counter. Useful when migrating from another system and wanting to continue existing numbering. For example, if the last invoices were 2024-0150, you can set initial_number=151. Default value is 1. It applies only to the first period in which the series issues an invoice: with counter_reset: ANNUAL or MONTHLY, every later year or month starts at 1. With NEVER there is a single period, so numbering simply continues from it.

Default1
Formatint64
Range1 <= value <= 999999
active?boolean

Whether the series is active

Defaulttrue
default_series?boolean

Whether this is the default series for its document_type.

Auto-promotion: the domain guarantees that, while at least one series exists for a given (document_type, environment), exactly one of them is the default. So if you create the first series of a document_type (no default exists yet for that type and environment), it is marked as default even if you send false — the response will then return default_series: true. Send true to also unmark the current default of that type.

Defaultfalse

Response Body

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/configuration/series" \  -H "Content-Type: application/json" \  -d '{    "document_type": "UNASSIGNED",    "name": "Main Series",    "code": "FAC",    "format": "{CODIGO}-{YYYY}-{NUM:4}"  }'
{
  "success": true,
  "data": {
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "document_type": "UNASSIGNED",
    "name": "Main Series",
    "code": "FAC",
    "description": "Series for standard invoices",
    "format": "{CODIGO}-{YYYY}-{NUM:4}",
    "counter_reset": "NEVER",
    "initial_number": 1,
    "active": true,
    "default_series": false,
    "numbering_locked": true,
    "created_at": "2019-08-24T14:15:22Z",
    "next_number": 0,
    "updated_at": "2019-08-24T14:15:22Z"
  },
  "meta": {
    "timestamp": "2025-01-15T10:30:00Z",
    "request_id": "4bf92f3577b34da6a3ce929d0e0e4736"
  }
}
{
  "success": false,
  "error": {
    "code": "BAD_REQUEST",
    "message": "Invalid request"
  },
  "meta": {
    "timestamp": "2025-01-15T10:30:00Z",
    "request_id": "4bf92f3577b34da6a3ce929d0e0e4736"
  }
}
{
  "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": "FORBIDDEN",
    "message": "You do not have permission 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": "SERIES_FORMAT_NUMBER_TOO_LONG",
    "message": "The number this series generates can reach 64 characters and the AEAT accepts at most 60 (series and number together). Shorten the code or the fixed text of the format"
  },
  "meta": {
    "timestamp": "2026-09-24T10: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"
  }
}

Get default series status per document type (deprecated) GET

**Deprecated.** Use `GET /v1/companies/{company_id}/series/defaults`, which behaves identically. Reports, for each `DocumentType` used by automatic invoicing, whether there is a default invoice series and which one: `exists`, plus the `series_id` when there is one. - **Why check it:** a document type with no default series makes an incoming charge be skipped with `failure.payment.skip.missing_default_series` instead of invoiced. - **Environment:** test or production is resolved automatically from your request context; no input needed. **Retires on 9 December 2026.** See the [migration guide](https://docs.beel.es/changelog/resources-under-the-nif) for what moved where and what changes when you switch.

List invoice series (deprecated) GET

**Deprecated.** Use `GET /v1/companies/{company_id}/series`, which behaves identically. Retrieves the invoice series of the company in focus. The listing is always scoped to one company; it never spans several. - **Filters:** `active` restricts to active or inactive series — omit it and you get all of them. `document_type` returns the series of that type, the only ones that can number it. - **Pagination (opt-in):** send `page` and/or `limit` to receive a single page plus a `data.pagination` block with the totals. Omit both and the response carries the full list in `data.series` and no `pagination` block. **Retires on 9 December 2026.** See the [migration guide](https://docs.beel.es/changelog/resources-under-the-nif) for what moved where and what changes when you switch.