All error codes
Complete reference of every public API error code, grouped by bounded context, with its HTTP status and type.
This is the canonical reference of every error code the public API can return, grouped by the bounded context that emits it. Each code is stable across versions; the message is for display only. The total count and grouping are generated from the live catalog.
Account
| Code | Type | HTTP | Description |
|---|---|---|---|
account_not_found | not_found_error | 404 | The account behind the key could not be resolved, which usually means the key no longer points at a live company. |
api_key_already_revoked | invalid_request_error | 422 | The key was already revoked, and a revoked key admits no further operations: revocation is terminal. |
api_key_not_found | not_found_error | 404 | The identifier does not match any API key of the authenticated company. |
Authentication
| Code | Type | HTTP | Description |
|---|---|---|---|
api_key_expired | authentication_error | 401 | The key passed its expiry date. |
api_key_revoked | authentication_error | 401 | The key was revoked, and a revoked key never authenticates again — revocation is the way to cut off a leaked credential. |
invalid_api_key | authentication_error | 401 | The key does not match any active key. It may be mistyped, truncated, or belong to a different environment — test keys and live keys are not interchangeable. |
ip_not_allowed | authentication_error | 401 | The key restricts the addresses it accepts, and the request came from one outside that list. |
missing_api_key | authentication_error | 401 | The request carries no credentials: neither the Authorization header nor X-API-Key. |
origin_not_allowed | authentication_error | 401 | The request comes from a browser origin that the key does not accept. |
too_many_auth_failures | authentication_error | 429 | Too many failed authentication attempts arrived from the same address, so it is temporarily locked out to stop credential guessing. |
Authorization
| Code | Type | HTTP | Description |
|---|---|---|---|
addon_not_active | authorization_error | 403 | The functionality belongs to an add-on that is not active for the company right now. |
feature_not_available_in_plan | authorization_error | 403 | The feature is not included in the company plan. |
forbidden_action | authorization_error | 403 | The action is blocked for this resource even though the scope is right: the resource belongs to a shared catalogue, or the change travels through a different endpoint. |
insufficient_scope | authorization_error | 403 | The key authenticates correctly but does not carry the scope this operation requires. Scopes are granted when the key is issued and are not widened at call time. |
max_api_keys_exceeded | authorization_error | 422 | The company reached the number of API keys its plan allows. |
max_webhook_endpoints_exceeded | authorization_error | 422 | The company reached the number of webhook endpoints its add-on tier allows. |
module_not_available_in_sandbox | authorization_error | 403 | The resource belongs to a module vetoed in test mode. Sandbox never touches AEAT, banks or real billing, so those modules stay out on purpose. |
scope_not_allowed_by_plan | authorization_error | 422 | One of the requested scopes belongs to a module that the plan does not include, so the key would be born with a permission that could never be exercised. |
scope_not_allowed_in_sandbox | authorization_error | 422 | A test key cannot be born with scopes of modules vetoed in sandbox. |
Clients
| Code | Type | HTTP | Description |
|---|---|---|---|
alternative_id_type_invalid | invalid_request_error | 422 | The alternative identifier type is outside the catalogue nif_iva, passport, country_id, residence_certificate, other_document, not_registered. |
cannot_have_both_tax_id_and_alternative_id | invalid_request_error | 422 | The client sends tax_id and an alternative identifier at the same time. Fiscal identity is one: the alternative identifier exists precisely for parties without a Spanish tax id. |
census_requires_tax_id | invalid_request_error | 422 | Census verification checks the pair name plus tax id against AEAT, and one of the two is missing. |
client_has_documents | invalid_request_error | 422 | The client is referenced by issued documents. Deleting it would leave invoices, quotes or delivery notes without the party they were issued to, and fiscal records must remain traceable. |
client_import_too_large | invalid_request_error | 422 | The CSV exceeds the row limit the synchronous import accepts, since the whole file is processed within the request. |
client_not_found | not_found_error | 404 | The identifier does not resolve to any client of the authenticated company. |
client_requires_tax_identity | invalid_request_error | 422 | The client carries no fiscal identity: neither tax_id nor an alternative identifier, and an invoice cannot be issued to an unidentified party. |
direct_debit_requires_default_bank_account | invalid_request_error | 422 | Direct debit was selected as the payment method, but the client has no default bank account to charge. |
tax_id_already_exists | conflict_error | 409 | Another client of the company already holds that tax id, and the tax id identifies the party uniquely inside a company. |
Companies
| Code | Type | HTTP | Description |
|---|---|---|---|
company_inactive | authorization_error | 403 | The profile named in X-Active-Profile is one of your managed companies, but it is deactivated and cannot be operated until it comes back. |
gestoria_module_required | authorization_error | 403 | The master company holds a live plan, but one without the accounting-firm module, so it cannot create or operate managed companies. |
gestoria_plan_required | payment_required_error | 402 | The accounting firm has no active paid subscription, so there is no subscription on which to charge the seat. |
payment_method_required | payment_required_error | 402 | Adding a managed company charges a seat immediately, and the accounting firm operates in live mode with no payment method on file. |
seat_charge_failed | payment_required_error | 402 | The immediate pro-rated charge for the seat was declined: the card was refused, it needs authentication, or the payment provider was unreachable. The company is not created if the seat is not paid. |
Delivery Notes
| Code | Type | HTTP | Description |
|---|---|---|---|
delivery_note_not_found | not_found_error | 404 | The identifier does not resolve to any delivery note of the authenticated company. |
delivery_note_section_not_editable_in_status | invalid_request_error | 422 | The logistics section — carrier, vehicle, driver — is frozen because the delivery note is already delivered, invoiced or cancelled. |
driver_tax_id_requires_name | invalid_request_error | 422 | The driver tax id was sent without the driver name, and an identifier with no name identifies nobody on the delivery document. |
signature_payload_too_large | invalid_request_error | 422 | The signature image exceeds the accepted size for the field. |
Employees
| Code | Type | HTTP | Description |
|---|---|---|---|
employee_seat_charge_failed | payment_required_error | 402 | The immediate pro-rated charge for the employee seat was declined: the card was refused, it needs authentication, or the payment provider was unreachable. The employee is not activated if the seat is not paid. |
employee_seat_payment_method_required | payment_required_error | 402 | Adding or reactivating an employee charges a seat immediately, and the company operates in live mode with no payment method on file. |
Events
| Code | Type | HTTP | Description |
|---|---|---|---|
event_not_found | not_found_error | 404 | The identifier does not match any event of the authenticated company, or the event was purged by the 30-day retention policy. |
Idempotency
| Code | Type | HTTP | Description |
|---|---|---|---|
idempotency_key_in_use | idempotency_error | 409 | Another request with the same Idempotency-Key is still in flight, and the result is not known yet. |
idempotency_key_invalid | invalid_request_error | 400 | The Idempotency-Key does not fit the accepted format: it must be 1 to 255 printable ASCII characters. |
idempotency_key_reused | idempotency_error | 409 | That Idempotency-Key was already used with a different payload. The key identifies one specific operation, so reusing it for another would make replay meaningless. |
Invoices
| Code | Type | HTTP | Description |
|---|---|---|---|
corrective_invoice_inanulable | invalid_request_error | 422 | The invoice is itself a corrective, and correctives are never annulled: the correction chain has to stay auditable end to end. |
export_limit_exceeded | invalid_request_error | 422 | The filtered selection exceeds the 5,000-invoice cap of the export, so the file is refused up front instead of being silently truncated. |
invalid_correction_nature | invalid_request_error | 422 | correction_nature only accepts S (substitution: the corrective carries the full corrected amounts) or I (by difference: it carries only the delta). |
invalid_correction_reason | invalid_request_error | 422 | The correction reason is outside the closed fiscal list (error_fundado, concurso, incobrable, error_importe, error_cliente, devolucion, descuento, otras), which maps to the AEAT codes R1 to R4. |
invalid_invoice_id | invalid_request_error | 400 | The invoice reference received is not a valid identifier; it usually means an internal value slipped in where the API expects the public id. |
invalid_invoice_number | invalid_request_error | 422 | The invoice number does not follow the canonical format SERIES-YYYY-NNN, plus the -RECn suffix on correctives. |
invalid_invoice_status | invalid_request_error | 422 | The value sent as invoice status is outside the lifecycle catalogue (draft, scheduled, sent, paid, overdue, cancelled, annulled). |
invalid_invoice_uuid | invalid_request_error | 400 | The invoice identifier in the path or in the payload is not a valid UUID. |
invalid_payment_method | invalid_request_error | 422 | The payment method is outside the closed allowlist: bank_transfer, cash, credit_card, sepa_direct_debit, paypal, bizum, other. |
invoice_already_annulled | invalid_request_error | 422 | The invoice was already annulled. Annulment is terminal and, with VeriFactu active, its annulment record has already reached AEAT. |
invoice_already_paid | invalid_request_error | 422 | The invoice is already settled. paid is a terminal, accounting-closed state: the output VAT has been declared, or will be declared for the period. |
invoice_already_sent | invalid_request_error | 422 | The invoice was already issued: it holds a definitive series number and, with VeriFactu active, its registration with AEAT. Issuing does not happen twice. |
invoice_cannot_assign_number | invalid_request_error | 422 | A definitive number was requested for an invoice that is not a draft, or that already carries one. Series numbering is monotonic and numbers are never reassigned. |
invoice_invalid_status_transition | invalid_request_error | 422 | The target status is unreachable from the current one. The lifecycle is directed: draft moves to scheduled or sent, sent to paid, overdue or annulled, and paid, cancelled and annulled are terminal. |
invoice_not_cancellable_in_current_state | invalid_request_error | 422 | Cancelling withdraws a draft that is not yet fiscally binding, so it only applies while the invoice is draft. |
invoice_not_correctable_in_current_state | invalid_request_error | 422 | A corrective invoice can only be issued against an invoice that is already issued (sent or paid). A draft, a cancelled or an annulled invoice has nothing to correct. |
invoice_not_deletable_in_current_state | invalid_request_error | 422 | Only draft and cancelled invoices can be deleted. A numbered invoice never disappears: the correlative sequence must stay auditable. |
invoice_not_editable_in_current_state | invalid_request_error | 422 | Only a draft admits editing. Once issued, the invoice is immutable and its content is frozen along with its fiscal record. |
invoice_not_eligible_for_action | invalid_request_error | 422 | The requested action does not apply to this invoice: its type or its current state leaves it outside the scope of the operation. |
invoice_not_found | not_found_error | 404 | The identifier does not resolve to any invoice of the authenticated company. Invoices belonging to another company answer exactly the same way. |
invoice_not_modifiable_in_current_state | invalid_request_error | 422 | The field you are changing is frozen for the current state — for instance the tax regime of an annulled invoice. |
invoice_not_paid | invalid_request_error | 422 | A payment receipt was requested for an invoice with no settled payment, so there is nothing to certify. |
invoice_not_reschedulable_in_current_state | invalid_request_error | 422 | Rescheduling moves the issuing date of an invoice that is waiting in scheduled, and this invoice is not waiting. |
invoice_not_schedulable_in_current_state | invalid_request_error | 422 | Only a draft can be scheduled: scheduling reserves a future issuing moment without consuming a series number yet. |
invoice_not_unschedulable_in_current_state | invalid_request_error | 422 | Unscheduling returns an invoice from scheduled to draft, so it only applies while it is still waiting to be issued. |
invoice_not_unsendable_in_current_state | invalid_request_error | 422 | Undoing the delivery mark only applies to a sent invoice: it clears sent_at and keeps the invoice issued. |
invoice_requires_at_least_one_line | invalid_request_error | 422 | The invoice carries no operation line, so it has no taxable base and cannot be issued. This happens both when you send no lines at all and when every line you send is a disbursement: a disbursement is an amount paid on the customer's behalf (art. 78.Tres.3 LIVA), not an operation of your own. |
invoice_year_required_for_ambiguous_number | invalid_request_error | 422 | That invoice number exists in more than one fiscal year, so on its own it does not identify a single invoice. |
line_total_checksum_mismatch | invalid_request_error | 422 | The line_total you declared does not match the one Factuarea computes for that line (quantity × price − discount + VAT − withholding + surcharge) and the deviation is above the one-cent tolerance. The amount that gets invoiced and reported to the tax authority is always the one computed here, so the discrepancy means your system and the issued invoice would not reconcile. |
line_type_invalid | invalid_request_error | 422 | The line type falls outside the closed NORMAL / SUPLIDO catalogue. An issued invoice only tells two natures apart: what you sell, which forms the taxable base and carries VAT, and a disbursement (suplido), money advanced in the name and on behalf of the customer, which is therefore left out of the base (art. 78.Tres.3 of the Spanish VAT Act). |
no_invoices_in_period | invalid_request_error | 422 | The quarterly operation found no invoices in the requested period, so there is nothing to package or send. |
payment_method_invalid | invalid_request_error | 422 | Same closed allowlist as invalid_payment_method, reported when the value is rejected while reading the payment method field of the payload. |
reminder_not_applicable | invalid_request_error | 422 | The payment reminder does not apply: the invoice is not sent or overdue, there is no recipient email, the public link is missing or disabled, or another reminder went out in the last 24 hours. |
scheduled_for_in_past | invalid_request_error | 422 | scheduled_for is not strictly in the future, so there is no waiting period to reserve. |
simplified_invoice_cannot_be_substituted | invalid_request_error | 422 | One invoice of the substitution list cannot be replaced: it is not simplified, it is cancelled or annulled, it belongs to another company, or it already has a substitute. |
simplified_invoice_not_allowed | invalid_request_error | 422 | The operation is not eligible for a simplified invoice: it exceeds EUR 3,000, or it is an intra-EU supply, an export, a reverse-charge operation, or the customer needs a full invoice to deduct VAT. |
simplified_limit_exceeded | invalid_request_error | 422 | The lines would push the simplified invoice (F2) over the absolute legal cap of EUR 3,000 VAT included. |
suplido_line_cannot_carry_taxes | invalid_request_error | 422 | The disbursement line carries charges of its own: a VAT rate, withholding, equivalence surcharge, discount, regime key, exemption cause or product/pack. A disbursement is not an operation of the issuer, so charging tax on it would mean paying tax on a supply you never made, and tying it to a product would move stock you never sold. |
suplido_not_allowed_in_simplified_invoice | invalid_request_error | 422 | The invoice is simplified (F2) and a simplified invoice does not identify the recipient. With no identified recipient there is nobody to evidence the payment on behalf of, so the amount cannot take disbursement treatment on this invoice type. |
suplido_requires_source_invoice_reference | invalid_request_error | 422 | The disbursement line does not carry source_invoice_reference, the number of the supporting document the third party issued in the customer's name. Without that document the payment is not evidenced as made on someone else's behalf, and the tax authority would treat it as the issuer's own taxable base, with VAT charged on it. |
Notifications
| Code | Type | HTTP | Description |
|---|---|---|---|
notification_not_found | not_found_error | 404 | The identifier does not match any notification of the authenticated company, or the notification fell out of the retention window. |
Payments
| Code | Type | HTTP | Description |
|---|---|---|---|
invalid_payment_date | invalid_request_error | 422 | The payment date falls outside the accepted window: it cannot precede the invoice issue date, nor be in the future. |
payout_reconciliation_amount_mismatch | invalid_request_error | 422 | The confirmed amount does not match the net amount of the payout, so the reconciliation would close with a difference nobody accounts for. |
receipt_not_available | invalid_request_error | 422 | There is no receipt to issue because the document has no settled payment behind it. |
stripe_payout_already_reconciled | invalid_request_error | 422 | The payout was already reconciled, and reconciliation is terminal: repeating it would double-count the bank entry. |
stripe_payout_not_found | not_found_error | 404 | The identifier does not resolve to any payout of the authenticated company. |
Products
| Code | Type | HTTP | Description |
|---|---|---|---|
pack_in_use | invalid_request_error | 422 | The pack is referenced by issued documents, so deleting it would break their composition. |
pack_not_found | not_found_error | 404 | The identifier does not resolve to any pack of the authenticated company. |
pack_share_link_failed | api_error | 500 | The share link for the pack could not be produced. The pack itself is unaffected. |
product_in_use | invalid_request_error | 422 | The product is referenced by issued documents or by other catalogue entries, and removing it would leave those references dangling. |
product_not_found | not_found_error | 404 | The identifier does not resolve to any product of the authenticated company. |
sku_already_exists | conflict_error | 409 | Another product of the company already uses that SKU, and the SKU identifies the item uniquely in the catalogue. |
Proformas
| Code | Type | HTTP | Description |
|---|---|---|---|
invalid_expiry_date | invalid_request_error | 422 | The expiry date is earlier than the issue date, or more than 365 days after it. |
invalid_proforma_id | invalid_request_error | 400 | The pro forma reference received is not a valid identifier, usually because an internal value replaced the public id. |
invalid_proforma_number | invalid_request_error | 422 | The pro forma number does not follow the canonical numbering format of its series. |
invalid_proforma_status | invalid_request_error | 422 | The value sent as status is outside the catalogue draft, accepted, rejected, expired, invoiced, cancelled. |
invalid_proforma_uuid | invalid_request_error | 400 | The pro forma identifier in the path or in the payload is not a valid UUID. |
proforma_already_accepted | invalid_request_error | 422 | The customer already accepted the pro forma, and acceptance is registered once. |
proforma_already_rejected | invalid_request_error | 422 | The pro forma is already marked as rejected. |
proforma_cannot_be_accepted | invalid_request_error | 422 | Acceptance does not apply from the current state: an invoiced, cancelled or expired pro forma no longer admits it. |
proforma_cannot_be_rejected | invalid_request_error | 422 | Rejection does not apply from the current state: once invoiced, cancelled or expired, the pro forma is closed. |
proforma_cannot_be_sent | invalid_request_error | 422 | Sending by email does not apply to a pro forma in a terminal state: there is no live offer to deliver. |
proforma_invalid_status_transition | invalid_request_error | 422 | The target status is unreachable from the current one: a draft can be accepted, cancelled or expire; an accepted pro forma can be invoiced, rejected or expire; invoiced, cancelled and expired are terminal. |
proforma_not_convertible_in_current_state | invalid_request_error | 422 | Converting into an invoice requires the customer to have accepted the pro forma; from any other state there is no agreement to bill. |
proforma_not_deletable_in_current_state | invalid_request_error | 422 | Only a draft pro forma can be deleted. Once it has been accepted, rejected or invoiced, it is part of the commercial trail. |
proforma_not_draft | invalid_request_error | 422 | The operation only makes sense while the pro forma is a draft, and this one has already moved on. |
proforma_not_editable_in_current_state | invalid_request_error | 422 | Only a draft pro forma admits editing. Once it is accepted, rejected, expired, invoiced or cancelled, its content is settled. |
proforma_not_found | not_found_error | 404 | The identifier does not resolve to any pro forma of the authenticated company. |
proforma_requires_at_least_one_line | invalid_request_error | 422 | The pro forma has no lines, so there is no amount to put in front of the customer. |
public_link_expires_at_exceeds_max_days | invalid_request_error | 422 | The requested expiry for the public link goes beyond the maximum window your plan allows for shared documents. |
Purchase Invoices
| Code | Type | HTTP | Description |
|---|---|---|---|
attachment_invalid_filename | invalid_request_error | 422 | The file name is not usable: it is empty, it carries path components, or it exceeds 200 characters. |
attachment_mime_not_allowed | invalid_request_error | 422 | The file type is outside the accepted set: PDF, PNG, JPEG, XML and HTML. |
attachment_missing | not_found_error | 404 | The purchase invoice exists but carries no attached file, so there is nothing to download. |
attachment_too_large | invalid_request_error | 422 | The file exceeds the maximum size allowed for a document attachment. |
cannot_attach_to_cancelled_purchase_invoice | invalid_request_error | 422 | The invoice is cancelled, and attaching documents to a cancelled record would alter closed documentation. |
invalid_purchase_invoice_id | invalid_request_error | 400 | The purchase invoice reference received is not a valid identifier, usually because an internal value replaced the public id. |
invalid_purchase_invoice_number | invalid_request_error | 422 | The invoice number is empty or does not fit the accepted format. On a purchase invoice the number is the one the supplier printed, not one Factuarea generates. |
invalid_purchase_invoice_uuid | invalid_request_error | 400 | The purchase invoice identifier in the path or in the payload is not a valid UUID. |
operation_regime_invalid | invalid_request_error | 422 | The operation regime is outside the catalogue general, intracomunitaria, importacion_exportacion, isp. |
purchase_invoice_already_exists | conflict_error | 409 | That supplier already has a purchase invoice registered with the same number. The pair supplier plus number identifies the document uniquely and prevents recording an expense twice. |
purchase_invoice_not_deletable_in_current_state | invalid_request_error | 422 | Only draft and cancelled purchase invoices can be deleted. A pending or paid one is part of the expense ledger. |
purchase_invoice_not_draft | invalid_request_error | 422 | The operation only applies while the purchase invoice is a draft, and this one has already been registered. |
purchase_invoice_not_editable_in_current_state | invalid_request_error | 422 | Only a draft purchase invoice can be edited. Once registered as pending, paid or cancelled, its content backs an accounting entry. |
purchase_invoice_not_found | not_found_error | 404 | The identifier does not resolve to any purchase invoice of the authenticated company. |
purchase_invoice_requires_at_least_one_line | invalid_request_error | 422 | The purchase invoice has no lines, so there is no expense nor deductible VAT to record. |
Quotes
| Code | Type | HTTP | Description |
|---|---|---|---|
quote_already_accepted | invalid_request_error | 422 | The quote was already approved, and approval is registered once. |
quote_already_rejected | invalid_request_error | 422 | The quote is already marked as rejected. |
quote_expired | invalid_request_error | 422 | The quote passed its validity date, so the offered conditions are no longer binding and it cannot be approved or converted as is. |
quote_not_found | not_found_error | 404 | The identifier does not resolve to any quote of the authenticated company. |
Rate Limit
| Code | Type | HTTP | Description |
|---|---|---|---|
monthly_quota_exceeded | rate_limit_error | 429 | The company exhausted the monthly call quota its plan includes. |
rate_limit_exceeded | rate_limit_error | 429 | The key sent more requests than its rate allows in the current window. |
Recurring Invoices
| Code | Type | HTTP | Description |
|---|---|---|---|
invalid_frequency_interval | invalid_request_error | 422 | The interval is lower than 1, so the recurrence would never advance to a next run. |
invalid_frequency_type | invalid_request_error | 422 | The frequency is outside the catalogue daily, weekly, biweekly, monthly, bimonthly, quarterly, semiannual, annual, custom. |
invalid_holiday_handling | invalid_request_error | 422 | The holiday policy is outside the catalogue skip, before, after, same. |
invalid_recurring_invoice_id | invalid_request_error | 400 | The recurrence reference received is not a valid identifier, usually because an internal value replaced the public id. |
invalid_recurring_invoice_uuid | invalid_request_error | 400 | The recurrence identifier in the path or in the payload is not a valid UUID. |
recurring_already_active | invalid_request_error | 422 | The recurrence is already running, so there is nothing to activate. Legacy code kept for compatibility: current endpoints report this as recurring_invoice_already_active. |
recurring_invoice_already_active | invalid_request_error | 422 | The recurrence is already running. |
recurring_invoice_already_cancelled | invalid_request_error | 422 | The recurrence was already cancelled, and cancellation is terminal. |
recurring_invoice_already_paused | invalid_request_error | 422 | The recurrence is already paused, so pausing it again changes nothing. |
recurring_invoice_cancelled_cannot_resume | invalid_request_error | 422 | A cancelled recurrence cannot be resumed: cancellation closes it for good, unlike a pause. |
recurring_invoice_cannot_run | invalid_request_error | 422 | The recurrence cannot generate an invoice right now: it is not running, its cycle is over, or it lacks the data an invoice needs. error.message states the specific reason. |
recurring_invoice_has_generated_invoices | invalid_request_error | 422 | The recurrence already produced invoices, and those invoices depend on it for their traceability. |
recurring_invoice_not_found | not_found_error | 404 | The identifier does not resolve to any recurrence of the authenticated company. |
recurring_invoice_requires_at_least_one_line | invalid_request_error | 422 | The recurrence has no lines, so every generated invoice would come out empty. |
recurring_not_active | invalid_request_error | 422 | The operation needs a running recurrence and this one is paused, completed or cancelled. Legacy code kept for compatibility with older integrations. |
Request
| Code | Type | HTTP | Description |
|---|---|---|---|
business_rule_violation | invalid_request_error | 422 | A domain invariant rejected the operation. This code carries the family; error.subcode names the concrete rule and error.message explains it. |
conflicting_pagination_params | invalid_request_error | 422 | starting_after and ending_before travelled in the same request. They walk the collection in opposite directions, so only one of them can apply. |
external_id_already_exists | conflict_error | 409 | The external_id you use to reconcile with your own system is already assigned to another object of the same type in this company. |
invalid_param_format | invalid_request_error | 422 | A legacy form request rejected the shape of a value. Migrated endpoints report the same situation as parameter_invalid_format or parameter_invalid_integer. |
invalid_param_value | invalid_request_error | 422 | A legacy form request rejected the value of a field. Migrated endpoints report the same situation as parameter_invalid_enum or parameter_invalid_range. |
invalid_status_transition | invalid_request_error | 422 | The requested state is not reachable from the state the document is in right now. |
length_required | invalid_request_error | 411 | A request with a body arrived using chunked transfer encoding, without declaring its size. The API needs the length up front to reject oversized payloads before buffering them. |
metadata_too_many_keys | invalid_request_error | 422 | The metadata object exceeds the limit of 50 keys per resource. |
metadata_value_too_long | invalid_request_error | 422 | One value of metadata exceeds 500 characters once serialised to text. |
method_not_allowed | invalid_request_error | 405 | The path exists but does not accept the HTTP verb used. |
missing_required_param | invalid_request_error | 422 | A legacy form request found a required field missing. Endpoints already migrated to the canonical parsers report the same situation as parameter_missing. |
parameter_invalid | invalid_request_error | 422 | A value object built from the payload rejected the value it received. error.subcode names which one — tax code, country code, rate, and so on. |
parameter_invalid_boolean | invalid_request_error | 400 | A parameter that must be a boolean received a value outside the accepted representations (true/false, 1/0). |
parameter_invalid_cursor | invalid_request_error | 400 | The starting_after or ending_before cursor is not a valid UUID, so it cannot point at any row of the collection. |
parameter_invalid_empty | invalid_request_error | 400 | A parameter arrived with an empty value: an in filter with no items, a comparison with nothing after the operator, or an equality filter with an empty string. |
parameter_invalid_enum | invalid_request_error | 400 | The value falls outside the closed set the parameter accepts. On listings it also covers a filter operator other than eq, gte, lte, gt, lt, in or contains. |
parameter_invalid_format | invalid_request_error | 400 | The value has the right type but not the shape the parameter requires: a date, an identifier pattern or a header such as Factuarea-Version. |
parameter_invalid_integer | invalid_request_error | 400 | A parameter that must be a whole number received something that cannot be parsed as one, such as limit=abc. |
parameter_invalid_iso8601 | invalid_request_error | 400 | A range filter (gte, lte, gt, lt) received a value that is neither numeric nor an ISO 8601 date. |
parameter_invalid_range | invalid_request_error | 400 | A numeric parameter fell outside its accepted bounds. The usual case is limit, which must be between 1 and 100. |
parameter_invalid_string | invalid_request_error | 400 | A parameter that must be text received an array, an object or a value that cannot be read as a string. |
parameter_invalid_url | invalid_request_error | 400 | A field that must hold an absolute URL received a value that is not one, usually because the scheme or the host is missing. |
parameter_invalid_uuid | invalid_request_error | 400 | An identifier field received a value that is not a valid UUID. Every v1 resource id is a UUID. |
parameter_invalid_value | invalid_request_error | 422 | The value is syntactically correct but not admissible for this resource: outside the canonical catalogue of the field, or inconsistent with the rest of the payload. |
parameter_missing | invalid_request_error | 400 | The endpoint requires a parameter that the request did not carry. error.param names it. |
parameter_unknown | invalid_request_error | 400 | The request carries a parameter the endpoint does not accept: a filter outside its allowlist, a sort field that is not sortable, or the offset-style page — v1 paginates by cursor. |
payload_too_large | invalid_request_error | 413 | The request body exceeds the accepted size: 1 MB as a rule, 6 MB on the endpoints that accept files. |
profile_not_found | not_found_error | 404 | The X-Active-Profile header names a company that does not exist or does not belong to the accounting-firm tree of the authenticated key. Both cases answer the same so that the API never reveals companies of other tenants. |
resource_already_exists | conflict_error | 409 | Creating the object would duplicate one that already exists under a unique key — tax id, SKU, external id. error.details.existing_resource_id points at the object that already holds the value. |
resource_conflict | conflict_error | 409 | The operation collided with the current state of the resource and no more specific conflict code applies. |
resource_immutable | invalid_request_error | 422 | The object is closed to changes for this operation: its state or its accounting record forbids modifying it. |
resource_locked | conflict_error | 409 | Another operation holds the resource until it finishes: concurrent writes on the same object are serialised instead of interleaved. |
resource_not_deletable | invalid_request_error | 422 | The object exists but its state or its dependants block the deletion. In bulk deletions this is the per-row code of every entry that could not be removed. |
resource_not_found | not_found_error | 404 | The identifier resolves to nothing visible to the authenticated company. Objects belonging to another company answer exactly the same way, by design. |
route_not_found | not_found_error | 404 | The path does not match any v1 endpoint. It is usually a typo, a missing /v1 prefix, or a path from a different area of the API. |
unknown_filter | invalid_request_error | 422 | A listing received a filter it does not know. The canonical v1 parsers report this as parameter_unknown; this code survives for endpoints that have not migrated yet. |
unsupported_api_version | invalid_request_error | 400 | The Factuarea-Version header is well formed but names a version outside the supported set. |
unsupported_media_type | invalid_request_error | 415 | A request with a body declared a Content-Type other than application/json. |
Series
| Code | Type | HTTP | Description |
|---|---|---|---|
cannot_archive_last_default_series | invalid_request_error | 422 | The series is the only active one for its document type. Archiving it would leave the company with no numbering available and freeze that kind of document. |
document_type_required_for_ambiguous_code | invalid_request_error | 422 | That series code exists for more than one document type, so on its own it does not identify a single series. |
invalid_series_code | invalid_request_error | 422 | The series code is empty, too long, or carries characters that do not belong in a fiscal prefix. |
invalid_series_name | invalid_request_error | 422 | The series name is empty or exceeds the allowed length. |
invalid_series_number | invalid_request_error | 422 | The starting number is not valid: it is not a positive integer, or it falls at or below the last number already issued, which would re-issue numbers already in use. |
invalid_series_uuid | invalid_request_error | 400 | The series identifier in the path or in the payload is not a valid UUID. |
invalid_series_year | invalid_request_error | 422 | The fiscal year is not a valid four-digit year for a numbering series. |
monthly_requires_month_segmented_format | invalid_request_error | 422 | The counter resets monthly but the numbering mask does not segment by month, so two months would start on the same correlative and produce duplicate numbers within the year. |
series_already_archived | invalid_request_error | 422 | The series was already archived, and archiving is not repeated: a second call means the client is out of sync with the real state. |
series_code_immutable_with_documents | invalid_request_error | 422 | Changing the prefix of a series that already issued documents would retroactively rewrite their fiscal identifier, while customers and AEAT hold the original number. |
series_has_documents | invalid_request_error | 422 | The series already numbered documents, so it cannot be removed: the correlative sequence has to stay auditable. |
series_immutable | invalid_request_error | 405 | Series are not editable nor deletable through the API: legal numbering continuity requires their prefix, year and counter to stay put. |
series_initial_number_creates_gap | invalid_request_error | 422 | The starting number jumps beyond the next natural correlative while documents already exist for the current year, and that gap in the sequence is not acceptable to AEAT. |
series_locked_by_verifactu | invalid_request_error | 422 | At least one invoice of the series holds a billing record accepted by AEAT, which freezes the prefix, the year and the numbering base of the series. |
series_not_found | not_found_error | 404 | The identifier does not resolve to any numbering series of the authenticated company. |
series_type_invalid | invalid_request_error | 422 | The document type of the series is outside the catalogue invoice, quote, delivery_note, proforma, purchase_invoice, recurring_invoice. |
series_year_locked | invalid_request_error | 422 | The series already issued documents in its current year. Moving the year would leave those documents pointing at an empty year while their taxable base sits in another. |
Server
| Code | Type | HTTP | Description |
|---|---|---|---|
dependency_unavailable | service_unavailable_error | 503 | An external service the operation relies on did not answer in time. |
face_transmission_failed | api_error | 502 | The FACe platform — the public administration entry point — was unreachable or answered with a fault. The failure is upstream, not in your request. |
facturae_signing_failed | api_error | 500 | The XAdES signature of the Facturae file could not be produced, usually because the signing certificate is unusable at that moment. |
internal_error | api_error | 500 | Something broke on our side while processing the request. The condition is not caused by your payload. |
maintenance | service_unavailable_error | 503 | The platform is in a maintenance window and writes are held back on purpose. |
pdf_generation_failed | service_unavailable_error | 503 | The rendering service could not produce the PDF. The document and its data are intact — what failed is the file. |
register_sealing_failed | api_error | 500 | The cryptographic sealing of the record did not complete, so the closure was left unsigned rather than sealed with a broken signature. |
send_failed | api_error | 500 | The document was not delivered by email: the mail provider rejected the message or was unreachable. |
service_unavailable | service_unavailable_error | 503 | The service, or a dependency it needs, is temporarily unable to answer. |
Suppliers
| Code | Type | HTTP | Description |
|---|---|---|---|
supplier_has_documents | invalid_request_error | 422 | The supplier is referenced by registered purchase invoices, and deleting it would leave those expenses without the party that issued them. |
supplier_not_found | not_found_error | 404 | The identifier does not resolve to any supplier of the authenticated company. |
Tax Reports
| Code | Type | HTTP | Description |
|---|---|---|---|
insufficient_data_for_report | invalid_request_error | 422 | The period has no data to file, or an invoice of the period lacks a mandatory field for this model — typically the customer tax id. |
invalid_period | invalid_request_error | 422 | The period does not identify a filing: the year is outside the accepted range, or the quarter is missing or out of the range 1 to 4 for a quarterly model. |
report_format_invalid | invalid_request_error | 422 | The format is outside the catalogue txt_aeat, pdf, excel. |
tax_report_not_found | not_found_error | 404 | The identifier does not resolve to any tax report of the authenticated company. |
tax_report_type_invalid | invalid_request_error | 422 | The report type is outside the catalogue modelo_303, modelo_347, modelo_130. |
unsupported_format | invalid_request_error | 422 | The requested format is not available for this model: not every filing produces every output. |
Taxes
| Code | Type | HTTP | Description |
|---|---|---|---|
custom_tax_creation_disabled | authorization_error | 403 | Creating custom taxes is disabled for this company. |
duplicate_tax_default_for_document_type | invalid_request_error | 422 | Another tax of the same type is already the default for that document type, and the pair (tax type, document type) admits a single default. |
indirect_tax_regime_invalid | invalid_request_error | 422 | The indirect regime is outside the catalogue iva, igic, ipsi. |
invalid_aeat_code | invalid_request_error | 422 | The AEAT operation code is outside the closed catalogue S1, S2, S3, E1-E6, N1, N2 used by VeriFactu and SII. |
invalid_country_aeat_zone | invalid_request_error | 422 | The AEAT territorial zone is outside the catalogue peninsula, canarias, ceuta, melilla. |
invalid_country_code | invalid_request_error | 422 | The country code is not exactly two characters, so it is not a valid ISO 3166-1 alpha-2 code. |
invalid_customer_visible_label | invalid_request_error | 422 | The label shown to the customer on the document exceeds the allowed length. |
invalid_description | invalid_request_error | 422 | The description exceeds the maximum length allowed for the field. |
invalid_document_type | invalid_request_error | 422 | The document type is outside the catalogue: invoice, quote, delivery_note, proforma, purchase_invoice, recurring_invoice. |
invalid_rate_for_tax_regime | invalid_request_error | 422 | The rate does not belong to the legal grid of its regime: IGIC admits 0, 3, 5, 7, 9.5, 15 and 20%; IPSI admits 0, 0.5, 1, 2, 4, 8 and 10%. |
invalid_tax_code | invalid_request_error | 422 | The tax code is empty or longer than 50 characters. |
invalid_tax_name | invalid_request_error | 422 | The tax name is empty or longer than 255 characters. |
invalid_tax_rate | invalid_request_error | 422 | The rate falls outside the range allowed for its type: VAT 0-27%, withholding 0-47%, equivalence surcharge 0-10%, other 0-100%. |
invalid_tax_type_filter | invalid_request_error | 422 | The type filter of the by-type listing carries a value outside the enum vat, retention, surcharge, other. |
invalid_validity_window | invalid_request_error | 422 | The validity window is inverted: valid_until falls before valid_from. |
system_tax_default_modification_forbidden | authorization_error | 403 | Defaults of the shared catalogue taxes are not set on the tax itself: the catalogue is global and the preference belongs to your company. |
system_tax_immutable | invalid_request_error | 422 | The tax belongs to the canonical AEAT catalogue shipped with the product. Its rate, code and name are fixed so that every company shares the same fiscal reference. |
system_tax_immutable_field | invalid_request_error | 422 | The update touches a field that is frozen on a system tax; error.param names it. |
system_tax_undeletable | invalid_request_error | 422 | System taxes are part of the shared fiscal catalogue and cannot be removed: deleting one would break the documents that reference it. |
tax_applies_to_invalid | invalid_request_error | 422 | The scope of the tax is outside the catalogue sale, purchase, both. |
tax_code_already_exists | conflict_error | 409 | Another tax of the catalogue already uses that code, and codes identify taxes unambiguously. |
tax_id_required | invalid_request_error | 422 | The operation needs the tax identification number (NIF, CIF or NIE) of the party involved and the record does not carry one. |
tax_in_use | invalid_request_error | 422 | The tax is referenced by documents, products or suppliers. Removing it would leave historical documents without their fiscal reference. |
tax_inactive_cannot_be_default | invalid_request_error | 422 | A deactivated tax cannot become the default, either globally or for a document type — it would offer a hidden default that no form can pick. |
tax_not_found | not_found_error | 404 | The identifier does not match any tax of the catalogue reachable by this company. |
tax_type_invalid | invalid_request_error | 422 | The tax type is outside the catalogue vat, retention, surcharge, other. |
VeriFactu
| Code | Type | HTTP | Description |
|---|---|---|---|
alta_record_not_found | not_found_error | 404 | The invoice has no registration record, so the operation that depends on it has nothing to work with. |
anulacion_record_already_exists | conflict_error | 409 | The invoice already carries an annulment record in the chain, and annulment is reported only once. |
certificate_expired | invalid_request_error | 422 | The certificate is outside its validity window: it has expired, or it is not valid yet. |
certificate_nif_mismatch | invalid_request_error | 422 | The tax id of the certificate holder does not match the company tax id. AEAT records are signed on behalf of the company, so both must be the same. |
certificate_not_found | not_found_error | 404 | The company has no FNMT certificate matching the identifier, or none uploaded at all. |
certificate_too_large | invalid_request_error | 422 | The file exceeds the 100 KB limit, while a real FNMT certificate weighs a few kilobytes. |
clock_drift_exceeded | invalid_request_error | 422 | The server clock drifted from NTP beyond the allowed margin. The generation timestamp is part of the AEAT fingerprint, so an unsynchronised clock would produce records AEAT rejects. |
declaracion_already_exists | conflict_error | 409 | The company already filed its SIF responsibility statement for that period. |
declaracion_not_found | not_found_error | 404 | The company has no SIF responsibility statement filed for the requested period. |
event_already_processed | invalid_request_error | 422 | That SIF event is already recorded in the event chain, and each event is processed exactly once. |
invalid_certificate_format | invalid_request_error | 422 | The file is not a PKCS#12 container: its first bytes do not match the ASN.1 structure the format requires, whatever its extension says. |
invalid_certificate_password | invalid_request_error | 422 | The password does not open the certificate file. |
max_retries_exceeded | invalid_request_error | 422 | The record exhausted the technical retry budget for resending the stored XML. Retrying the same content again would fail the same way. |
mode_switch_blocked_until_year_end | invalid_request_error | 422 | VeriFactu mode was activated during this fiscal year and at least one billing record was issued. Stepping back would degrade the integrity of a chain already reported to AEAT. |
record_already_accepted | invalid_request_error | 422 | AEAT already accepted the record. Acceptance is terminal and its content is frozen as part of the fingerprint chain. |
record_immutable | invalid_request_error | 422 | The record belongs to an append-only ledger: once written, its fiscal content is closed to changes and to deletion. |
record_not_rejected | invalid_request_error | 422 | The correction flow only applies to records AEAT rejected on data grounds. This record is in another state — a technical failure, for instance, is covered by the automatic retry. |
record_not_subsanable | invalid_request_error | 422 | The record cannot be amended: it is not a registration record, or it has no source invoice from which its content could be regenerated. |
requires_annulment | invalid_request_error | 422 | The regenerated content changes a field that takes part in the fingerprint — issuer tax id, series and number, issue date, invoice type, tax amount or total — and the chain cannot be rewritten. |
sii_excluded | invalid_request_error | 422 | The company is registered with SII, and SII filers are excluded from the VeriFactu regulation. |
verifactu_already_submitted | invalid_request_error | 422 | The invoice already has its registration record. Exactly one registration exists per invoice, so a second one would break the idempotency of the chain. |
verifactu_mode_invalid | invalid_request_error | 422 | The mode is outside the catalogue verifactu / no_verifactu. |
verifactu_not_eligible | invalid_request_error | 422 | The invoice cannot be registered with AEAT right now: the company is not on VeriFactu mode, it has no active certificate, or the certificate is revoked or issued for a different tax id. |
verifactu_record_not_found | not_found_error | 404 | The identifier does not match any billing record of the authenticated company. |
verifactu_transmission_failed | invalid_request_error | 422 | The transmission of the record to AEAT did not complete: the endpoint was unreachable or answered with an incident. |
Webhooks
| Code | Type | HTTP | Description |
|---|---|---|---|
addon_required | payment_required_error | 402 | Creating webhook endpoints belongs to the Developer API add-on, and the company does not have it active — the free tier allows zero endpoints. |
api_version_invalid_format | invalid_request_error | 422 | The payload version of the endpoint is not a YYYY-MM-DD date. |
api_version_unsupported | invalid_request_error | 422 | The payload version is well formed but is not among the ones the platform serves. |
custom_header_blocklisted | invalid_request_error | 422 | One of the custom headers is reserved: the HTTP layer manages it (host, content-type, content-length, user-agent), Factuarea sends it as part of the signed contract (factuarea-*), or the proxy owns it (x-forwarded-*). |
custom_header_value_too_long | invalid_request_error | 422 | The value of a custom header exceeds 1024 characters. |
replay_delivery_not_retryable | invalid_request_error | 422 | Only failed deliveries can be replayed. A delivery that succeeded, or one still in flight, has nothing to resend. |
replay_event_expired | invalid_request_error | 422 | The event behind the delivery was purged by the 30-day retention policy, so there is no payload left to resend. |
timeout_seconds_out_of_range | invalid_request_error | 422 | timeout_seconds falls outside the range 1 to 30 seconds. |
too_many_custom_headers | invalid_request_error | 422 | The endpoint declares more than 20 custom headers. |
webhook_delivery_not_found | not_found_error | 404 | The identifier does not match any delivery attempt, or the delivery falls outside the retention window kept for the history. |
webhook_endpoint_degraded | invalid_request_error | 422 | The endpoint is degraded after repeated delivery failures, so test pings are refused while it stays in that state. |
webhook_endpoint_not_found | not_found_error | 404 | The identifier does not resolve to any webhook endpoint of the authenticated company. |
webhook_secret_recently_rotated | rate_limit_error | 429 | The signing secret was rotated less than five minutes ago. The grace window lets your receiver accept both secrets during the switch; rotating again inside it would invalidate signatures still in flight. |