Factuarea APIDevelopers

Gestió d'errors

Embolcall d'error normalitzat, catàleg de type i code amb àncores estables, i estratègia de reintents.

Tota resposta d'error de l'API pública usa un embolcall JSON consistent. L'estat HTTP indica la categoria general; el camp type desambigua i el camp code apunta a la causa específica.

Embolcall

{
  "error": {
    "type": "invalid_request_error",
    "code": "parameter_invalid",
    "message": "El campo client_id es obligatorio.",
    "param": "client_id",
    "request_id": "req_01HKQS5N8VR7QXJ9K3T6BWPMZA",
    "doc_url": "https://docs.factuarea.com/guides/errors#parameter_invalid"
  }
}

Camps:

  • type — categoria general de l'error. Estable i enumerada (llista a sota).
  • code — causa específica. Estable i enumerada.
  • subcode — opcional. Present quan el code per si sol és ambigu: en els conflictes de duplicació 409 assenyala la clau duplicada exacta (p. ex. subcode: "tax_id_already_exists"), i en els errors de pagament 402 assenyala quin gate ha rebutjat la crida (p. ex. subcode: "webhooks_addon_required"). Com el code, és estable i invariant entre idiomes i versions de l'API.
  • message — text per a persones en castellà. No es garanteix estable entre versions; útil per a logging i visualització.
  • param — opcional, present en errors de validació. Apunta al primer camp problemàtic. En errors de validació de diversos camps el conjunt complet és a errors[] (vegeu a sota).
  • errors[] — opcional, present en errors de validació 422. Llista tots els camps fallits (vegeu Errors de validació de diversos camps).
  • details — opcional. Porta existing_resource_id en els conflictes de duplicació 409 (vegeu Conflictes de duplicació) i payment_setup_url en els errors 402 que necessiten un mètode de pagament configurat (vegeu payment_required_error).
  • doc_url — opcional. Enllaç a aquesta guia amb àncora al code específic (#{code}).
  • request_id — identificador únic de la petició (req_<ULID>). Inclou-lo sempre quan contactis amb suport. També es retorna al header de resposta X-Request-Id.

L'objecte error sempre porta type, code i message; la resta de camps són presents quan és rellevant.

Errors de validació de diversos camps

Un error de validació 422 reporta tots els camps fallits, no només el primer. Els param/message plans continuen reflectint el primer camp (per retrocompatibilitat), i errors[] porta un ítem per camp fallit — així corregeixes tots en una sola petició en lloc d'una petició per camp.

{
  "error": {
    "type": "invalid_request_error",
    "code": "invalid_param_value",
    "message": "El campo client_id es obligatorio.",
    "param": "client_id",
    "errors": [
      { "param": "client_id", "code": "parameter_missing", "message": "El campo client_id es obligatorio." },
      { "param": "issue_date", "code": "parameter_invalid_format", "message": "El formato de la fecha no es válido.", "expected_format": "YYYY-MM-DD" },
      { "param": "status", "code": "parameter_invalid_enum", "message": "El valor no es válido.", "allowed_values": ["draft", "sent", "paid"] }
    ],
    "request_id": "req_01HKQS5N8VR7QXJ9K3T6BWPMZA",
    "doc_url": "https://docs.factuarea.com/guides/errors#invalid_param_value"
  }
}

Cada ítem de errors[] porta:

  • param — el nom del camp fallit.
  • code — un codi estable i machine-readable derivat de la regla de validació fallida (p. ex. parameter_missing, parameter_invalid_format, parameter_invalid_enum, parameter_invalid_integer).
  • message — descripció llegible de l'error del camp.
  • expected_format — opcional. Present només en errors de format; el patró esperat (p. ex. YYYY-MM-DD, uuid, email, url).
  • allowed_values — opcional. Present només en errors d'enum; la llista de valors legals.

errors[] és purament additiu — les integracions que només llegeixen param, code i message continuen funcionant sense canvis.

Conflictes de duplicació

Un conflicte de duplicació 409 pot incloure details.existing_resource_id si l’operació el proporciona. Tracta’l com a opcional. Els conflictes fiscals de contactes canònics retornen resource_already_exists amb subcode: tax_id_already_exists; un conflicte de referència externa pot retornar external_id_already_exists. Cap dels dos garanteix l’UUID del recurs existent a l’error.

{
  "error": {
    "type": "conflict_error",
    "code": "resource_already_exists",
    "subcode": "tax_id_already_exists",
    "message": "Ya existe un contacto con esa identidad fiscal en la empresa.",
    "request_id": "req_01HKQS5NKW1C6W9T4G5HAIBZVM",
    "doc_url": "https://docs.factuarea.com/guides/errors#resource_already_exists"
  }
}

Si es proporciona l’UUID del recurs existent, recupera’l amb la seva operació GET documentada. Per a contactes sense aquest detall, fes servir POST /v1/companies/{company}/contacts/find-by-tax-id o POST /v1/companies/{company}/contacts/find-by-external-id i revisa la identitat trobada abans d’actualitzar o assignar un rol. Les consultes queden limitades a l’empresa que anomena el segment {company}.

Detalls del problema — Problem Details (RFC 9457)

Envia Accept: application/problem+json per rebre el mateix error com un document Problem Details de RFC 9457 amb Content-Type: application/problem+json. Amb Accept: application/json, Accept: */* o sense header Accept obtens l'embolcall pla de dalt.

{
  "type": "https://docs.factuarea.com/errors/resource_already_exists",
  "title": "Resource already exists",
  "status": 409,
  "detail": "Ya existe un contacto con esa identidad fiscal en la empresa.",
  "instance": "/v1/companies/{company}/contacts",
  "code": "resource_already_exists",
  "subcode": "tax_id_already_exists",
  "request_id": "req_01HKQS5NKW1C6W9T4G5HAIBZVM"
}
  • type — la pàgina de documentació d'aquest code concret, per exemple https://docs.factuarea.com/errors/resource_already_exists. El code és l'únic segment variable, així que pots construir i comparar la URI pel teu compte. Abans era una sola URI compartida per tots els problemes: si hi compares, compara millor contra code, que no es mou mai.
  • title — un resum humà breu del tipus de problema.
  • status — el codi d'estat HTTP.
  • detail — el missatge llegible.
  • instance — el path del recurs afectat.

La variant problem+json no descarta cap dada estesa: code, subcode, param, errors[], details, doc_url i request_id es conserven com a membres d'extensió RFC 9457.

Missatges localitzats

El message (i el detail de problem+json) es localitza via el header Accept-Language per als codis del catàleg estable. Els idiomes suportats són es, en i ca, amb fallback a es quan el header és absent o demana un idioma no suportat. El code i el subcode són invariants entre idiomes — ramifica sempre per code, mai per message.

Accept-Language: en        → missatge en anglès
Accept-Language: ca-ES     → missatge en català
(absent / Accept-Language: de) → missatge en castellà (fallback)

Els missatges dinàmics emesos per excepcions de domini queden en castellà; només es localitzen els missatges del catàleg estable.

Tipus d'error

typeHTTPDescripció
invalid_request_error400, 405, 411, 413, 415 o 422Payload malformat o massa gran, mètode o tipus de mitjà no suportat, paràmetres absents/invàlids o fallada de validació de negoci.
authentication_error401 o 429L'API key falta, és invàlida, està revocada, ha expirat o la IP no és a la llista d'accés; 429 (too_many_auth_failures) quan fallen massa intents d'autenticació.
payment_required_error402Falta un requisit comercial: ha fallat un càrrec, no hi ha mètode de pagament configurat, no hi ha cap pla al qual facturar o el pla actual concedeix capacitat zero per a l'operació.
authorization_error403 o 422La key és vàlida però l'operació no li és oberta: el scope no cobreix l'endpoint, una key de proves intenta canviar un compte real, el nivell d'accés és de només lectura, l'operació pertany a un altre compte o el pla de l'empresa no inclou la funcionalitat. Un topall del teu pla (keys, endpoints de webhook) o un scope que no admet respon 422.
not_found_error404El recurs sol·licitat no existeix o no pertany a l'empresa de la key.
conflict_error409Conflicte de creació, modificació concurrent o recurs duplicat (p. ex. un tax_id ja registrat).
idempotency_error422 o 409Reutilització d'Idempotency-Key amb un payload diferent (422, idempotency_key_reused) o mentre la seva primera petició encara és en curs (409, idempotency_key_in_use).
rate_limit_error429Superada una quota per minut o mensual, o un altre pressupost de l'API.
api_error500Error inesperat del backend. Els reintents poden ajudar; reporta a suport amb el request_id.
service_unavailable_error503API pública deshabilitada via kill-switch, o caiguda d'una dependència (Stripe, mailer).

402 i 403 no són intercanviables. Un 402 (payment_required_error) significa que l'operació és al teu abast i que l'única cosa que s'hi interposa són els diners: configura un mètode de pagament, resol el càrrec denegat, o contracta el pla o l'add-on al qual es factura. Un 403 significa que l'accés mateix està denegat —o la key no té el scope o el pla de l'empresa no inclou la funcionalitat (tots dos són authorization_error)— i cap reintent de pagament no ho canvia. La parella addon_required (402, el pla actual concedeix capacitat zero per a l'operació) i addon_not_active (403, no hi ha cap pla actiu vàlid) és la que convé llegir dues vegades. El gate del NIF addicional traça la mateixa línia: additional_nif_plan_required (402, no hi ha cap pla vigent al qual facturar) i additional_nif_not_in_plan (403, el pla és vigent però no inclou NIF addicionals).

Les violacions de regles de negoci (transició d'estat invàlida, una acció no permesa en l'estat actual del document) responen 422 amb type: invalid_request_error i code: invalid_status_transition — no 409. 409 conflict_error es reserva per a creació duplicada i conflictes de concurrència; una Idempotency-Key encara en ús és 409 idempotency_error.

Catàleg de codes

L'àncora de cada encapçalament H3 coincideix exactament amb el valor del camp code de l'embolcall. El doc_url que retorna l'API resol a la secció específica. La llista de sota cobreix els codes que trobaràs a la pràctica; la referència OpenAPI en viu documenta els codes exactes per endpoint.

Per a la referència completa de cada error code agrupat per bounded context, amb el seu estat HTTP i type, consulta Tots els error codes.

invalid_request_error

parameter_invalid

Un paràmetre de la petició falta o és invàlid. param apunta al camp problemàtic (p. ex. client_id, lines[0].quantity).

Pàgina de referència: parameter_invalid.

parameter_invalid_format

El format d'un valor és incorrecte per a la seva semàntica (regex, longitud, codificació, un UUID malformat, una data fora de format).

Pàgina de referència: parameter_invalid_format.

parameter_invalid_range

Un valor numèric o de data està fora del rang permès (p. ex. limit fora d'1..100).

Pàgina de referència: parameter_invalid_range.

parameter_invalid_cursor

El cursor starting_after / ending_before no és un id de recurs vàlid. Consulta Paginació.

Pàgina de referència: parameter_invalid_cursor.

parameter_unknown

La petició porta un paràmetre que l'endpoint no accepta: un camp de body no documentat en un endpoint estricte, un filtre fora de la seva allowlist, un camp de sort no ordenable, el page de paginació per offset —v1 pagina per cursor— o una capçalera retirada de la v1. param anomena el que sobra i subcode distingeix la causa: la capçalera retirada X-Active-Profile retorna subcode: retired_active_profile_header. Consulta Actuar en nom d'una empresa.

Pàgina de referència: parameter_unknown.

invalid_param_format

Va fallar una restricció de format en un camp tipat — p. ex. el header Idempotency-Key o el header Factuarea-Version està malformat.

Pàgina de referència: invalid_param_format.

invalid_param_value

El valor no compleix una restricció (enum, format, regla semàntica).

Pàgina de referència: invalid_param_value.

invalid_period

El període de report sol·licitat és invàlid (p. ex. un trimestre/any que no existeix).

Pàgina de referència: invalid_period.

invalid_status_transition

La transició sol·licitada està prohibida per la màquina d'estats del document (p. ex. enviar una factura que no està en un estat enviable). Les violacions de regles de negoci com aquesta són 422, no 409.

Pàgina de referència: invalid_status_transition.

invoice_already_paid

mark-paid sobre una factura ja pagada.

Pàgina de referència: invoice_already_paid.

quote_already_accepted

Acció que entra en conflicte amb un pressupost ja acceptat.

Pàgina de referència: quote_already_accepted.

business_rule_violation

Una invariant de domini va bloquejar l'operació. El subcode identifica la regla i param el camp infractor. El fa servir el ledger de pagaments (Registrar pagaments):

  • payment_exceeds_pending_amount (param: "amount") — l'import del pagament és més gran que el saldo pendent de la factura. S'aplica tant a POST /v1/companies/{company}/invoices/{id}/payments com a POST /v1/companies/{company}/purchase-invoices/{id}/payments.
  • invalid_payment_date (param: "paid_on") — la data d'un pagament de despesa (POST /v1/companies/{company}/purchase-invoices/{id}/payments) és posterior a avui. Una data anterior a la d'emissió s'accepta com a pagament anticipat. Les altres operacions que reben una data de pagament responen d'una altra manera a una data futura; consulta Pagaments anticipats i validació de la data de pagament.
  • purchase_invoice_not_payable (param: "status") — la despesa està cancel·lada i ja no admet pagaments.
  • max_webhook_endpoints_reached — s'ha assolit el topall d'endpoints de webhook d'empresa derivat del pla. Elimina'n un que no utilitzis o canvia a un pla amb un topall superior. Els endpoints de compte tenen el seu propi topall, que respon account_webhook_endpoint_limit_reached.
  • webhook_secret_recently_rotated — el secret de signatura d'un endpoint de webhook d'empresa o de compte es va rotar fa menys de cinc minuts. És un 422, no un límit de peticions: espera, desplega el secret nou al teu receptor i rota de nou.
  • additional_nif_limit_reached — afegir el NIF deixaria el compte per sobre del seu topall de NIF addicionals. Es comprova abans de qualsevol càrrec. Consulta NIF addicionals.
  • offer_package_loss_unconfirmed (param: "accept_offer_package_loss") — reduir les places contractades, o cancel·lar l'add-on, trencaria un paquet d'oferta aplicat i no vas confirmar la pèrdua. details porta product, package_id, name, effective_at i lines, cada línia amb concept, from_price, to_price i interval. Reenvia la petició amb accept_offer_package_loss: true per acceptar la pèrdua. REST i MCP retornen la mateixa resposta. Consulta Reduir places i NIF addicionals.
  • contracted_seats_selection_required (param: "deactivate") — reduir les places contractades per sota de les ocupades exigeix triar a deactivate exactament ocupades - quantitat entitats actives del compte. A cancel només es retorna amb una llista que no quadra amb totes les places ocupades, perquè sense llista s'entenen totes. details porta product, requested, occupied, required, selected i invalid. REST i MCP retornen la mateixa resposta. Consulta Reduir places i NIF addicionals.
  • contracted_seats_exhausted — només l'aplicació web: rebutja crear o reactivar un empleat o un NIF quan no queda cap plaça contractada lliure. L'API v1 i el MCP no el retornen mai: compren les places que falten (consulta Compra automàtica). details porta product, contracted, occupied, free, required i missing.

contracted_seats_below_minimum està retirat: l'esborrany del contracte el preveia, però mai no es va arribar a emetre. Reduir les places per sota del mínim d'una oferta ja no dona error; demana confirmar la pèrdua del paquet (offer_package_loss_unconfirmed).

{
  "error": {
    "type": "invalid_request_error",
    "code": "business_rule_violation",
    "subcode": "payment_exceeds_pending_amount",
    "message": "El importe del pago (1.500,00 €) supera el importe pendiente de la factura (710,00 €).",
    "param": "amount",
    "doc_url": "https://docs.factuarea.com/guides/errors#business_rule_violation",
    "request_id": "req_..."
  }
}

Pàgina de referència: business_rule_violation.

unsupported_format

El format d'exportació/report sol·licitat no està suportat.

Pàgina de referència: unsupported_format.

insufficient_data_for_report

No hi ha prou dades per generar el report d'impostos sol·licitat.

Pàgina de referència: insufficient_data_for_report.

signature_payload_too_large

La imatge de signatura de l'albarà supera la mida màxima.

Pàgina de referència: signature_payload_too_large.

managed_account_plan_not_self_serve

Vas demanar el pla enterprise per a un compte gestionat. Un compte gestionat es crea o es canvia a emprendedor o empresario; enterprise només l'assigna Factuarea per contracte. Tria un dels dos, o contacta amb Factuarea per acordar el contracte. Consulta Tria el pla.

Pàgina de referència: managed_account_plan_not_self_serve.

managed_account_provider_in_trial

El teu compte és en el seu període de prova i va demanar un compte gestionat real, que es cobra des del primer dia. Durant el trial només pots crear comptes gestionats de proves, amb una key fact_test_. Crea'l amb una key de proves, o comença una subscripció de pagament i repeteix l'aprovisionament. Consulta El teu compte en trial o amb un problema de pagament.

Pàgina de referència: managed_account_provider_in_trial.

managed_accounts_limit_reached

El teu compte ja té tants comptes gestionats reals sota gestió vigent com permet el seu topall (max_managed_accounts). Els comptes gestionats de proves no compten. Acaba la gestió d'un que ja no portis, o contacta amb Factuarea per ampliar el topall. Consulta El topall.

Pàgina de referència: managed_accounts_limit_reached.

managed_account_not_claimable

El compte gestionat és un compte de proves, i un compte de proves mai no es reclama: no té cap val de reclamació que emetre ni reemetre. Reemet el val només per a comptes gestionats reals. Consulta Provar comptes gestionats.

Pàgina de referència: managed_account_not_claimable.

access_level_raise_forbidden

Vas intentar pujar el nivell d'accés a un compte gestionat que el seu titular ja va reclamar. Abans de la reclamació el proveïdor pot pujar o baixar el seu nivell; des de la reclamació només el titular el pot pujar, i el proveïdor només el pot baixar. Demana al titular que el pugi des de la seva app, o repeteix l'operació amb un nivell igual o inferior a l'actual. Consulta El teu nivell d'accés.

Pàgina de referència: access_level_raise_forbidden.

enterprise_contract_transition_required

El compte gestionat té un contracte enterprise, i acabar-ne la gestió traslladaria el seu pagament al titular abans que Factuarea hagi fixat el pla amb què continua. Mai no es crea una subscripció sense preu, així que no ha canviat res i la gestió continua vigent. Contacta amb Factuarea perquè fixem el pla i repeteix l'operació. Consulta Enterprise per contracte.

Pàgina de referència: enterprise_contract_transition_required.

import_file_invalid

Un dels fitxers de la importació no es pot llegir amb el format de la plantilla: no és un CSV llegible, la seva capçalera no apareix a les seves 20 primeres línies, li falta una columna obligatòria o té una línia trencada. param diu quin fitxer falla (accounts_file o customers_file) i el missatge anomena la columna o la línia. No s'ha escrit res. Un valor invàlid en una fila no és aquest error: surt com a error d'aquesta fila a la vista prèvia. Consulta El fitxer de comptes.

Pàgina de referència: import_file_invalid.

import_file_too_large

Un dels fitxers de la importació supera els 5 MB. Respon 413, i la mida es comprova abans de llegir cap fila, així que no s'ha processat ni escrit res. param diu quin fitxer falla. Redueix el fitxer, o parteix-lo en diverses importacions de menys de 5 MB i aplica-les una darrere l'altra. Consulta Límits.

Pàgina de referència: import_file_too_large.

import_row_limit_exceeded

Un dels fitxers de la importació porta més files de les que admet una sola importació: 100 a accounts_file i 1.000 a customers_file. Les files es compten abans de llegir-les, així que no s'ha escrit res. param diu quin fitxer falla. Parteix el fitxer i aplica les parts una darrere l'altra: la importació es pot repetir, així que una fila ja importada no crea res de nou. Consulta Límits.

Pàgina de referència: import_row_limit_exceeded.

account_webhook_endpoint_limit_reached

El compte ha assolit el nombre d'endpoints de webhook de compte que el seu tier permet en aquest entorn. El topall es compta per compte i per entorn (live o test), inclou els endpoints deshabilitats i és independent del topall dels endpoints d'empresa: només esborrar un endpoint allibera un lloc. Esborra'n un que ja no facis servir o passa a un tier superior; un mateix endpoint es pot subscriure a diversos tipus d'esdeveniment. Un tier que no en permet cap respon, en canvi, 402 addon_required. Consulta El topall per tier.

Pàgina de referència: account_webhook_endpoint_limit_reached.

authentication_error

missing_api_key

No hi ha header d'autenticació present (Authorization: Bearer o X-API-Key).

Pàgina de referència: missing_api_key.

invalid_api_key

La key no existeix o el secret no coincideix amb el hash emmagatzemat.

Pàgina de referència: invalid_api_key.

api_key_revoked

La key va ser revocada, i una key revocada no torna a autenticar mai. Crea'n una de nova al dashboard.

Pàgina de referència: api_key_revoked.

api_key_expired

El secret és correcte, però la key va superar la seva data de caducitat (expires_at). Emet una key nova; si fixes dates de caducitat, planifica la rotació abans d'aquesta data perquè la integració no es quedi mai sense servei.

Pàgina de referència: api_key_expired.

ip_not_allowed

La key restringeix les adreces que accepta i la petició va arribar des d'una fora d'aquesta llista. Afegeix l'adreça de sortida del teu servidor a la llista d'accés de la key, o fes servir una key sense restricció d'IP si la teva adreça canvia.

Pàgina de referència: ip_not_allowed.

too_many_auth_failures

S'han limitat fallades d'autenticació repetides des del teu client. Espera (back off) i verifica les teves credencials.

Pàgina de referència: too_many_auth_failures.

payment_required_error

Un 402 significa que falta un requisit comercial. La crida pot comprar places de NIF addicionals o d'empleats, o cobrar un compte gestionat, pot ser que no hi hagi un pla al qual facturar-la, o que el pla actual li concedeixi capacitat zero. No es pot reintentar tal com està: resol el pagament o canvia de pla i després repeteix la mateixa petició. Les altres dues respostes del gate del NIF addicional són 403: additional_nif_not_in_plan i billing_managed_by_provider.

Nota de versió. Tres d'aquests codis es van publicar abans que existís aquesta categoria i se servien com a invalid_request_error. Porten payment_required_error des de Factuarea-Version: 2026-09-01 endavant: payment_method_required, employee_seat_payment_method_required i employee_seat_charge_failed. Les peticions en una versió anterior conserven el type de sempre. Els codis del NIF addicional (additional_nif_plan_required i additional_nif_charge_failed) i addon_required són posteriors i porten payment_required_error a totes les versions. error.code, error.subcode i l'estat 402 són idèntics a totes les versions: ramifica per code i no hauràs de pensar en això.

payment_method_required

Comprar places de NIF addicionals les cobra immediatament: l'endpoint PATCH /v1/accounts/{account}/additional-nif-seats, i també POST /v1/accounts/{account}/companies, els endpoints d'activació i acceptar un traspàs de NIF en un compte que ja té titular quan no queda cap plaça lliure i la crida compra les que falten (Compra automàtica). El compte opera en mode real, amb una subscripció de pagament i sense mètode de pagament configurat. Aprovisionar un compte gestionat de pagament el llança igual, quan el compte proveïdor que el paga no té mètode de pagament. La resposta porta details.payment_setup_url: obre'l, registra una targeta i repeteix la crida. Consulta NIF addicionals i Comptes gestionats: quan es cobra.

{
  "error": {
    "type": "payment_required_error",
    "code": "payment_method_required",
    "message": "La cuenta no tiene un método de pago configurado para cobrar el NIF adicional: configúralo y vuelve a intentarlo.",
    "details": { "payment_setup_url": "https://billing.stripe.com/p/session/live_YWNjdF8xS2ZHM0RLb0h4RXBGV3lY" },
    "request_id": "req_01HKQS5NPAYMENTMETHODREQ01",
    "doc_url": "https://docs.factuarea.com/guides/errors#payment_method_required"
  }
}

Pàgina de referència: payment_method_required.

additional_nif_charge_failed

El càrrec immediat de les places de NIF addicional va ser denegat —targeta rebutjada, autenticació requerida o el proveïdor de pagament inaccessible—. Si el càrrec falla, les places no es compren, el NIF no s'afegeix ni s'activa, i no queda cap càrrec. Arregla el mètode de pagament al portal de facturació i repeteix la mateixa crida; consulta amb el teu banc si la targeta es continua denegant.

Pàgina de referència: additional_nif_charge_failed.

additional_nif_plan_required

El compte no té un pla vigent, així que no hi ha cap subscripció a la qual cobrar el NIF addicional. No s'ha cobrat res ni s'ha escrit cap canvi. Contracta un pla empresario o enterprise, o reprèn el que vas cancel·lar, i repeteix la mateixa crida.

Pàgina de referència: additional_nif_plan_required.

employee_seat_payment_method_required

Comprar places d'empleat les cobra immediatament: els endpoints de compra de places, i l'alta o la reactivació d'un empleat a la v1 i al MCP quan no queda cap plaça contractada lliure i la crida compra les que falten (Compra automàtica). L'empresa opera en mode real sense mètode de pagament configurat. El remei és el mateix que a payment_method_required, i la resposta també porta details.payment_setup_url. Ocupar una plaça contractada lliure mai no cobra.

Pàgina de referència: employee_seat_payment_method_required.

employee_seat_charge_failed

El càrrec prorratejat de les places d'empleat va ser denegat. Les places no es compren, així que l'empleat no es crea ni s'activa quan la crida comprava les que falten. Arregla el mètode de pagament i reintenta; consulta amb el teu banc si la targeta es continua denegant. Consulta Errors de pagament.

Pàgina de referència: employee_seat_charge_failed.

employee_seats_not_in_plan

El compte té un pla vigent, però no inclou el control horari (el mòdul control_horario: empresario, integral i enterprise), així que no es poden comprar places d'empleat. És un límit de pla i no un pagament pendent, per això és un 403 i no un 402. No s'ha cobrat res ni s'ha escrit cap canvi; baixar o mantenir les places contractades continua permès. Passa el compte a Profesional o superior i repeteix la mateixa crida. Consulta Errors de pagament.

Pàgina de referència: employee_seats_not_in_plan.

addon_required

El tier derivat del pla actual permet zero endpoints de webhook, per la qual cosa POST /v1/companies/{company}/webhook-endpoints retorna 402 amb el subcode heretat webhooks_addon_required. Canvia a un pla que inclogui webhooks i repeteix la crida. No falta cap scope ni existeix un add-on Developer API independent que es pugui contractar. POST /v1/accounts/{account}/webhooks respon el mateix 402 amb subcode: account_webhooks_addon_required quan el tier del pagador del compte no admet cap endpoint de compte; quan n'admet algun, assolir el topall és un 422: account_webhook_endpoint_limit_reached.

Pàgina de referència: addon_required.

authorization_error

insufficient_scope

La key no té el scope que requereix l'endpoint. Consulta el catàleg a Autenticació › Scopes. El super-scope * no cobreix els scopes privilegiats accounts:read i accounts:write: una key que només tingui * respon insufficient_scope en una operació d'aprovisionament. Consulta el super-scope.

Pàgina de referència: insufficient_scope.

privileged_scope_required

L'operació exigeix un scope privilegiat (accounts:read o accounts:write) i no es compleix: o el compte de la key no té concedit el privilegi de proveïdor de comptes, o la persona que va emetre la key ja no és titular ni administradora del compte. Les dues causes responen igual, a propòsit. Demana a Factuarea el privilegi per al teu compte, o emet una key nova amb una persona que sigui titular o administradora i repeteix l'operació. Consulta Scopes privilegiats.

Pàgina de referència: privileged_scope_required.

live_credential_required

Una key de proves (fact_test_) va intentar canviar un compte real. Només passa a les operacions que canvien el propi compte (equip, invitacions, titularitat, traspassos de NIF, cartera de NIF, keys i places): una key de proves no pot alterar dades reals. Repeteix l'operació amb una key real (fact_live_) d'aquest compte; les lectures continuen disponibles amb la key que ja fas servir. Consulta Provar comptes gestionats.

Pàgina de referència: live_credential_required.

company_read_only

El nivell d'accés efectiu al NIF és view, així que la key el pot llegir però no escriure-hi, i no s'ha creat ni canviat res. El nivell és el menor entre el guardat a la key i el que té avui la persona que la va emetre: un grant view al compte, o un accés cedit view d'un altre compte. Limita la integració a lectures sobre aquest NIF, o demana a qui gestiona aquest accés que el pugi a operate i emet la key de nou. Consulta El sostre de nivell per NIF.

Pàgina de referència: company_read_only.

forbidden_action

L'acció es rebutja encara que el scope sigui el correcte. error.message diu quin cas aplica:

  • La key arriba al NIF per una relació entre comptes —un accés cedit o un compte gestionat— i l'operació és del compte amo del NIF: els registres de peticions, els esdeveniments, els endpoints de webhook d'empresa, la facturació del compte, el consum d'automatitzacions i les escriptures de les credencials de pagament connectades. Una relació mai no les obre, amb qualsevol nivell i també en lectures. Fes servir una credencial del compte amo.
  • El NIF és d'un compte gestionat que el seu titular ja paga: el seu proveïdor el pot llegir i editar-ne les dades, però és el titular qui decideix quan activar-lo, desactivar-lo o arxivar-lo.
  • La persona que va emetre la key no és titular ni administradora del compte, o la key no arriba a tots els NIF del compte, en una operació del propi compte.

Consulta Resolució i errors.

Pàgina de referència: forbidden_action.

company_inactive

L'empresa que anomena el segment {company} de la ruta és dins l'àmbit de la credencial, però el seu NIF no és active: el seu estat és inactive (desactivat) o archived, així que no es pot operar. Un NIF inactive conserva totes les seves dades i es pot reactivar; un d'archived és terminal. suspension_reason diu per què el sistema va suspendre un NIF, i val null quan el va desactivar el mateix compte. Reactiva el NIF, o apunta la ruta a una altra empresa del teu àmbit. Consulta L'estat d'un NIF i Resolució i errors.

Pàgina de referència: company_inactive.

additional_nif_not_in_plan

El compte té un pla vigent, però no inclou NIF addicionals: només empresario i enterprise (trial inclòs) els admeten. És un límit del pla i no un pagament pendent, per això és un 403 i no un 402. No s'ha cobrat res ni s'ha escrit cap canvi. Passa el compte a un d'aquests plans i repeteix la mateixa crida. Consulta El gate i els seus quatre codis.

Pàgina de referència: additional_nif_not_in_plan.

billing_managed_by_provider

Un altre compte paga la facturació d'aquest compte (és un compte gestionat que el seu proveïdor paga), així que no pot comprar pel seu compte un NIF addicional ni una plaça d'empleat. No s'ha cobrat res ni s'ha escrit cap canvi. Demana al compte que paga que afegeixi, activi o accepti el NIF. Consulta El que el client no pot comprar mentre pagues.

Pàgina de referència: billing_managed_by_provider.

max_api_keys_exceeded

L'empresa ha assolit el seu nombre màxim d'API keys actives. Respon 422, com els altres topalls del teu pla.

Pàgina de referència: max_api_keys_exceeded.

feature_not_available_in_plan

El pla actual no inclou el mòdul requerit (p. ex. recurring_invoices).

Pàgina de referència: feature_not_available_in_plan.

addon_not_active

L'empresa no té un pla de Factuarea actiu que inclogui accés a l'API pública — per exemple, el trial de 10 dies va caducar o la subscripció va vèncer fora del seu període de gràcia. Contracta o renova un pla per continuar fent servir l'API.

Pàgina de referència: addon_not_active.

not_found_error

resource_not_found

El recurs no existeix o no pertany a la teva empresa.

Pàgina de referència: resource_not_found.

profile_not_found

El segment {company} de la ruta anomena una empresa que no existeix o que no és dins l'àmbit de NIFs de la credencial. Tots dos casos responen igual perquè l'API mai reveli empreses d'altres comptes. Fes servir l'id d'una de les empreses que llista GET /v1/accounts/{account}/companies; l'identificador viatja a la ruta, no a cap capçalera.

Pàgina de referència: profile_not_found.

tax_report_not_found

El report d'impostos sol·licitat no existeix.

Pàgina de referència: tax_report_not_found.

conflict_error

resource_already_exists

Intent de crear un duplicat (p. ex. un tax_id ja registrat). El subcode (p. ex. tax_id_already_exists) assenyala la clau duplicada.

Pàgina de referència: resource_already_exists.

resource_conflict

L'operació entra en conflicte amb l'estat actual del recurs (p. ex. una modificació concurrent).

Pàgina de referència: resource_conflict.

provisioning_account_claimed

El titular ja ha reclamat aquest compte gestionat i el porta pel seu compte: ja no es pot reclamar, reemetre'n el val de reclamació ni aprovisionar de nou amb el mateix external_ref. Comprova'n l'estat en lloc de reintentar; per a un altre compte gestionat, fes servir un external_ref diferent. Consulta La reclamació.

Pàgina de referència: provisioning_account_claimed.

managed_account_external_ref_in_other_environment

L'external_ref ja l'utilitza un compte gestionat de l'altre entorn (live o test). És únic en tots dos, i la resposta no anomena aquest compte perquè aquest entorn no el llista. No s'ha escrit res. Fes servir un external_ref diferent, per exemple amb un prefix diferent a cada entorn. Consulta Idempotència.

Pàgina de referència: managed_account_external_ref_in_other_environment.

import_in_progress

Ja hi ha una importació massiva del teu compte en curs. Les importacions d'un mateix compte s'apliquen d'una en una, perquè cap compte, càrrec ni NIF es creï dues vegades; aquesta no s'ha aplicat i no s'ha escrit res. Espera que acabi la importació en curs i repeteix aquesta amb el mateix fitxer: es pot repetir, i les files que va crear l'altra importació surten com a ja existents, sense comptes ni càrrecs nous. Consulta Una importació alhora.

Pàgina de referència: import_in_progress.

idempotency_error

idempotency_key_reused

Mateix Idempotency-Key, body de petició diferent. Usa una key nova. Consulta Idempotència.

Pàgina de referència: idempotency_key_reused.

rate_limit_error

rate_limit_exceeded

Vas superar la quota per minut o mensual del teu tier. El header Retry-After indica els segons a esperar. Consulta Límits de peticions.

Pàgina de referència: rate_limit_exceeded.

api_error

internal_error

Error inesperat. Ja està capturat per la nostra banda, però comparteix el request_id amb suport.

Pàgina de referència: internal_error.

service_unavailable_error

service_unavailable

L'API pública no està disponible temporalment — deshabilitada globalment via kill-switch, en una finestra de manteniment, o una dependència (base de dades, mailer, Stripe) no està sana. Reintenta després d'un back-off curt.

Pàgina de referència: service_unavailable.

Errors tipats amb el SDK oficial

Els SDKs de TypeScript i PHP mapegen aquest embolcall a una jerarquia d'excepcions tipada, així ramifiques segons una classe (i llegeixes code, type, param, request_id) en lloc de parsejar JSON. La teva API key mai no s'inclou en cap excepció.

import {
  FactuareaError,
  ValidationError,
  RateLimitError,
} from "@factuarea/sdk";

try {
  await factuarea.invoices.create(body);
} catch (error) {
  if (error instanceof ValidationError) {
    console.error(error.fields);     // { client_id: ["obligatorio"], … }
  } else if (error instanceof RateLimitError) {
    console.error(error.retryAfter); // seconds to wait
  } else if (error instanceof FactuareaError) {
    console.error(error.code, error.type, error.requestId);
  }
}

La jerarquia també exporta AuthenticationError, NotFoundError, ConflictError, ServerError i ConnectionError.

use Factuarea\Sdk\Models\Errors\ErrorThrowable;

try {
    $factuarea->invoices->publicApiV1InvoicesCreate($body);
} catch (ErrorThrowable $e) {
    $error = $e->container->error;
    echo $error->type->value;  // e.g. "invalid_request_error"
    echo $error->code;         // e.g. "parameter_invalid"
    echo $error->param;        // e.g. "client_id"
    echo $error->requestId;    // quote this to support
}

Consulta SDKs › Gestió d'errors per veure la jerarquia completa. La política de reintents de sota l'apliquen automàticament ambdós SDKs.

request_id i suport

Tota resposta inclou un request_id. Adjunta'l a qualsevol tiquet o petició a support@factuarea.com:

Subject: 422 on POST /v1/companies/{company}/invoices — request_id req_01JBVH7K9Y4N3CDQ2EHJB1AGSV

Amb el request_id correlacionem logs, mètriques i traces per investigar ràpid.

Estratègia de reintents

  • 4xx excepte 429 → no reintentis: l'error és a la petició. Corregeix-lo i reenvia.
  • 429 → respecta el header Retry-After. Implementa back-off exponencial amb jitter.
  • 5xx → back-off exponencial (2^n * 100ms) amb jitter, màxim 5 intents.

Stripe publica un patró canònic que també aplica aquí: stripe.com/docs/error-handling.

En aquesta pàgina

EmbolcallErrors de validació de diversos campsConflictes de duplicacióDetalls del problema — Problem Details (RFC 9457)Missatges localitzatsTipus d'errorCatàleg de codesinvalid_request_errorparameter_invalidparameter_invalid_formatparameter_invalid_rangeparameter_invalid_cursorparameter_unknowninvalid_param_formatinvalid_param_valueinvalid_periodinvalid_status_transitioninvoice_already_paidquote_already_acceptedbusiness_rule_violationunsupported_formatinsufficient_data_for_reportsignature_payload_too_largemanaged_account_plan_not_self_servemanaged_account_provider_in_trialmanaged_accounts_limit_reachedmanaged_account_not_claimableaccess_level_raise_forbiddenenterprise_contract_transition_requiredimport_file_invalidimport_file_too_largeimport_row_limit_exceededaccount_webhook_endpoint_limit_reachedauthentication_errormissing_api_keyinvalid_api_keyapi_key_revokedapi_key_expiredip_not_allowedtoo_many_auth_failurespayment_required_errorpayment_method_requiredadditional_nif_charge_failedadditional_nif_plan_requiredemployee_seat_payment_method_requiredemployee_seat_charge_failedemployee_seats_not_in_planaddon_requiredauthorization_errorinsufficient_scopeprivileged_scope_requiredlive_credential_requiredcompany_read_onlyforbidden_actioncompany_inactiveadditional_nif_not_in_planbilling_managed_by_providermax_api_keys_exceededfeature_not_available_in_planaddon_not_activenot_found_errorresource_not_foundprofile_not_foundtax_report_not_foundconflict_errorresource_already_existsresource_conflictprovisioning_account_claimedmanaged_account_external_ref_in_other_environmentimport_in_progressidempotency_erroridempotency_key_reusedrate_limit_errorrate_limit_exceededapi_errorinternal_errorservice_unavailable_errorservice_unavailableErrors tipats amb el SDK oficialrequest_id i suportEstratègia de reintents
Et donem un cop de mà?Contactar amb suport