Factuarea APIDevelopers

Dades de negoci de la factura

Calendari de pagaments, referències de capçalera i de línia, període de facturació, literals legals i centres administratius DIR3 en una factura — ometre davant de null, versions i com canviar-los després d'emetre.

A més del seu contingut fiscal, una factura pot portar dades de negoci estructurades: el calendari de pagaments acordat, les referències que el client demana veure (contracte, transacció, expedient, albarans), el període de facturació, literals legals comercials i els centres administratius DIR3 que l'encaminen al sector públic. Aquestes dades són additives: una factura sense elles es comporta exactament com abans.

Tot viu als mateixos cossos que ja fas servir (POST /v1/companies/{company}/invoices, PATCH /v1/companies/{company}/invoices/{invoice} i les files de bulk-create) i torna al recurs de la factura. Totes les rutes d'aquesta guia pengen de /v1/companies/{company}/…: {company} és l'id (UUID v7) del NIF amb què operes, i als exemples curl és $COMPANY_ID. Arribar a un NIF explica com resoldre'l.

El cicle de vida té dues fases:

  • Mentre la factura és un esborrany pots crear, reemplaçar i treure cada camp.
  • En emetre-la les dades es congelen amb ella. Editar-les es rebutja amb 422 business_rule_violation i subcode invoice_not_editable_in_current_state. L'única cosa que encara pots canviar és l'encaminament administratiu, afegint una revisió administrativa.
BlocCamps de la peticióEs congela en emetre
Calendari de pagamentspayment_terms, expected_payment_terms_versionSí. Es valida i es congela una sola vegada.
Referènciesbusiness_references, lines[].business_references, lines[].delivery_notes_references, lines[].sequence_numberSí
Període de facturació i literalsinvoicing_period, legal_literalsSí
Centres DIR3administrative_centresL'encaminament capturat, més les revisions

Ometre, null i []

L'API distingeix una clau absent d'una null o buida, i la diferència importa. La mateixa regla val per a tots els camps d'aquesta guia:

EnviesEn crearEn actualitzar (PATCH)
La clau és absentNo es desa res (el calendari queda desconegut). A DIR3 s'hereten els centres del destinatari.Conserva el valor actual.
nullIgual que absent.El treu (a administrative_centres, elimina la teva substitució i torna als centres heretats). Només en un esborrany.
[] (llistes)«Cap» explícit. A payment_terms: un calendari buit conegut.Reemplaça tota la llista per una de buida.
Una llistaEs desa tal qual, amb el seu ordre i els seus duplicats.Reemplaça tota la llista.
Un objecteEs desa tal qual.Combina per clau: només canvien les claus que envies (business_references, business_references de línia). {} no canvia res.

No es retalla, ni es dedupliquen ni es reordenen elements. Els límits de text compten caràcters Unicode.

Calendari de pagaments

payment_terms és el calendari acordat de terminis. És informació contractual i no registra cobraments.

Amb terminis, la factura venç el dia del seu últim termini.

  • Per emetre-la, due_on ha de ser aquesta data. Un due_on absent o diferent respon 422 invoice_due_date_not_last_instalment (param: due_on) abans d'assignar número, i no s'emet res. S'aplica a issue, a una creació que emet a l'acte mitjançant options i a qualsevol altra via d'emissió.
  • Un esborrany conserva el due_on que enviïs, encara que sigui diferent; la comprovació es fa en emetre'l.
  • Una actualització (PATCH) que substitueix payment_terms i omet due_on porta due_on a l'últim termini. Si envies tots dos i no coincideixen, l'esborrany els conserva i emetre'l respon el mateix 422.
  • Programar o reprogramar l'emissió (schedule, reschedule) comprova la mateixa regla: la factura conserva el seu estat i la seva data i la petició respon el mateix 422.
  • Duplicar una factura emet l'esborrany amb data d'avui: cada termini conserva el seu import i es desplaça els dies que hi ha entre les dues dates d'emissió, i due_on és l'últim termini desplaçat.
  • Sense calendari, due_on és la data que enviïs.
CampTipusNotes
idstring (UUID v7)Opcional. Si s'omet, el backend n'assigna un en crear. En actualitzar, envia'l per conservar la identitat d'un termini existent. null i buit no són vàlids.
due_datestring (YYYY-MM-DD)Una data real. Les dates mai no decreixen al llarg de la llista; es permeten dates iguals.
amountstringDecimal amb signe i exactament dos decimals, diferent de zero: "40.00", "-20.00". Mai un número JSON.
payment_meansstringDe "01" a "19", els mitjans de pagament de Facturae 3.2.2.
accountobjecte o null{ "iban": "...", "bic": "..." }. Només per a 02 (rebut domiciliat) i 04 (transferència). bic és opcional.

Els imports han de sumar exactament total_to_pay (el total més els suplerts), amb el signe d'aquest import, de manera que un total negatiu porta terminis negatius. Factuarea mai no converteix, reparteix ni arrodoneix imports per tu. Un import a pagar de zero només admet null o [].

curl -X POST https://api.factuarea.com/v1/companies/$COMPANY_ID/invoices \
  -H "Authorization: Bearer fact_test_3pXnR2VbY7TcA9eFmN5z8KqW" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "client_id": "0197c5a0-4d2b-7c18-9f63-1a8e5b3d7c24",
    "issued_on": "2026-10-14",
    "due_on": "2026-12-13",
    "lines": [
      { "description": "Mantenimiento mensual", "quantity": 1, "unit_price": 100, "tax_rate": 21 }
    ],
    "payment_terms": [
      { "due_date": "2026-11-13", "amount": "60.50", "payment_means": "01" },
      {
        "due_date": "2026-12-13",
        "amount": "60.50",
        "payment_means": "04",
        "account": { "iban": "ES9121000418450200051332", "bic": "CAIXESBBXXX" }
      }
    ]
  }'

La resposta retorna payment_terms amb les identitats, a més de:

CampSignificat
payment_terms_versionVersió del calendari. 0 quan no n'hi ha cap, 1 després de la primera escriptura.
payment_terms_sourcenone, explicit (l'has enviat tu) o legacy (l'ha capturat Factuarea d'una factura emesa anterior).
payment_terms_currency, payment_terms_captured_at, payment_terms_frozen_atLa moneda (EUR) i els moments en què es va capturar i es va congelar.

Aquests cinc camps són de només lectura: enviar-los respon 422.

Canviar el calendari d'una factura existent exigeix expected_payment_terms_version, un valor JSON enter (0 o més), fins i tot quan envies null, [] o la mateixa llista. És el compare-and-set del calendari, independent de qualsevol altra cosa. Sense ell reps 428 invoice_payment_terms_precondition_required; amb un d'obsolet, 409 invoice_payment_terms_version_conflict amb details.current_version. Per recuperar-te, torna a llegir la factura i reaplica el teu canvi sobre la seva payment_terms_version.

curl -X PATCH https://api.factuarea.com/v1/companies/$COMPANY_ID/invoices/0197c5b1-7e90-7a42-b5d8-3c6f2e1a9b07 \
  -H "Authorization: Bearer fact_test_3pXnR2VbY7TcA9eFmN5z8KqW" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "payment_terms": [],
    "expected_payment_terms_version": 1
  }'

Regles que convé conèixer:

  • Editar només descripcions, o reordenar línies mentre l'import a pagar no canvia, no demana un calendari nou. Canviar l'import a pagar mentre existeix un calendari sí: has d'enviar el reemplaçament complet i equilibrat i la seva versió.
  • Un termini amb 02 o 04 pot no tenir account mentre la factura és un esborrany. En emetre (directa, programada o per canvi d'estat) es comproven tots els comptes i que el calendari suma, i es congela. Un error desfà tota l'emissió: no es consumeix cap número.
  • Els IBAN es validen (format i dígits de control, de qualsevol país) i es normalitzen els espais; el BIC, si s'envia, conserva els seus 8 o 11 caràcters.
  • Duplicar una factura copia el calendari amb identitats noves. Una rectificativa comença sense calendari tret que n'enviïs un (allà els terminis negatius són vàlids).
  • En un POST /v1/companies/{company}/invoices amb un external_id que ja existeix, la petició és una actualització i segueix les regles d'actualització.

Referències, període i literals

Les referències de capçalera van a business_references, un objecte tancat amb tres claus, de fins a 20 caràcters cadascuna: receiver_contract_reference, receiver_transaction_reference i file_reference.

Les referències de línia van a lines[].business_references: cinc parells de referència (fins a 20 caràcters) i data (YYYY-MM-DD):

ReferènciaData
issuer_contract_referenceissuer_contract_date
issuer_transaction_referenceissuer_transaction_date
receiver_contract_referencereceiver_contract_date
receiver_transaction_referencereceiver_transaction_date
file_referencefile_date

Una referència sense data és vàlida; una data sense la seva referència no ho és, un cop combinada l'edició parcial. Els objectes de capçalera no admeten dates.

Cada línia admet també delivery_notes_references, una llista de { "number": "ALB-2026-014", "date": "2026-10-02" } (number de fins a 30 caràcters, date opcional), i sequence_number: null o un enter de 0 a 2147483647 (0 és vàlid; un string, un decimal o un booleà no).

invoicing_period és un objecte amb les dues dates, start_date i end_date, dates reals amb l'inici igual o anterior al final. legal_literals és una llista ordenada de textos comercials de fins a 250 caràcters, que conserva els duplicats. Són independents de les legal_mentions fiscals que la factura ja calcula i mai no les substitueixen.

{
  "business_references": { "file_reference": "EXP-2026-0042" },
  "invoicing_period": { "start_date": "2026-10-01", "end_date": "2026-10-31" },
  "legal_literals": ["Operación sujeta al convenio marco 2026."],
  "lines": [
    {
      "description": "Mantenimiento mensual",
      "quantity": 1,
      "unit_price": 100,
      "tax_rate": 21,
      "business_references": {
        "issuer_contract_reference": "C-1",
        "issuer_contract_date": "2026-01-15"
      },
      "delivery_notes_references": [{ "number": "ALB-2026-014", "date": "2026-10-02" }],
      "sequence_number": 0
    }
  ]
}

Identitat de línia. A la resposta cada línia té un id (UUID v7). En un PATCH, envia aquest id per indicar quina línia vols dir: pots reordenar les línies i cadascuna conserva les seves referències. Una línia sense id és nova. En crear, lines[].id es rebutja, igual que un id que pertanyi a una altra factura, una línia retirada o un duplicat. Les rectificatives hereten les referències de línia només de la línia que anomenes amb lines[].source_line_id, mai per posició; les dades de capçalera (business_references, invoicing_period, legal_literals i administrative_centres) no s'accepten en una rectificativa.

Centres administratius DIR3

Les factures a l'administració pública porten fins a quatre centres DIR3, cadascun amb un rol. Són els que fa servir la facturació a FACe per encaminar:

role_codeRol
01Oficina comptable
02Òrgan gestor
03Unitat tramitadora
04Proponent (opcional)

administrative_centres és una llista de { "role_code", "code", "name" }. Els rols són únics. code es retalla i es passa a majúscules, i ha de complir ^[A-Z][A-Z0-9]{8,9}$ (per exemple L01280796); name és un text opcional de fins a 40 caràcters, que es conserva tal qual. La resposta ordena els centres per rol.

D'on surten els centres, per ordre:

  1. La substitució de la factura (el que envies a administrative_centres).
  2. La instantània que la factura va capturar del perfil del client en crear-se (i que s'actualitza mentre és un esborrany i canvies el client).
  3. Només en una factura anterior l'encaminament capturat de la qual és desconegut, els codis actuals del client.

La resposta exposa els tres: administrative_centres (efectius), administrative_snapshot i administrative_override, amb administrative_version i administrative_revision_id. Fixa't en els dos tipus de buit:

ValorSignifica
administrative_snapshot: nullDesconegut (legacy). Es permet recórrer al client.
administrative_snapshot: []Conegut i sense centres. Mai s'omple amb el client actual.
administrative_override: nullSense substitució: s'aplica la instantània.
administrative_override: []Substitució explícita sense cap centre.

En actualitzar, null elimina la teva substitució i [] la reemplaça per una de buida. El rol 04 sobreviu encara que 01 a 03 estiguin buits. L'encaminament capturat no es reescriu quan el client canvia després.

Els codis del client (decisió DEC-06)

Els codis surten del perfil de client: PATCH /v1/companies/{company}/contacts/{contact}/customer-profile accepta dir3_accounting_office, dir3_managing_body, dir3_processing_unit i dir3_proponent, cadascun amb el mateix format de codi. Els quatre codis segueixen una mateixa regla d'omissió: l'operació reemplaça el perfil de client, de manera que un codi DIR3 que deixis fora s'esborra, dir3_proponent inclòs. Envia sempre els quatre que vulguis conservar. Canviar-los mai no toca factures ni enviaments a FACe ja creats.

curl -X PATCH https://api.factuarea.com/v1/companies/$COMPANY_ID/contacts/0197a2a8-4cf0-7a31-9a5e-3f2b8c1d6e42/customer-profile \
  -H "Authorization: Bearer fact_test_3pXnR2VbY7TcA9eFmN5z8KqW" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "dir3_accounting_office": "L01280796",
    "dir3_managing_body": "L01280796",
    "dir3_processing_unit": "L01280796",
    "dir3_proponent": "L01280797"
  }'

Revisa l'encaminament després d'emetre

Una factura en estat issued o overdue no pot canviar les seves dades de negoci, però el seu encaminament administratiu sí que es pot corregir. Cada correcció és una addició: una revisió nova amb la seva identitat, versió, motiu i autor. No torna a emetre, no envia ni altera imports, dates, identitats legals, el calendari de pagaments ni el PDF.

curl https://api.factuarea.com/v1/companies/$COMPANY_ID/invoices/0197c5b1-7e90-7a42-b5d8-3c6f2e1a9b07/administrative-revisions \
  -H "Authorization: Bearer fact_test_3pXnR2VbY7TcA9eFmN5z8KqW"
{
  "data": {
    "invoice_id": "0197c5b1-7e90-7a42-b5d8-3c6f2e1a9b07",
    "version": 1,
    "snapshot": [
      { "role_code": "01", "code": "L01280796", "name": null },
      { "role_code": "02", "code": "L01280796", "name": null },
      { "role_code": "03", "code": "L01280796", "name": null }
    ],
    "override": null,
    "revisions": []
  }
}

Per corregir l'encaminament, envia la llista completa i la versió que has llegit:

curl -X POST https://api.factuarea.com/v1/companies/$COMPANY_ID/invoices/0197c5b1-7e90-7a42-b5d8-3c6f2e1a9b07/administrative-revisions \
  -H "Authorization: Bearer fact_test_3pXnR2VbY7TcA9eFmN5z8KqW" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "administrative_centres": [
      { "role_code": "01", "code": "L01280796", "name": null },
      { "role_code": "02", "code": "L01280796", "name": null },
      { "role_code": "03", "code": "L01280798", "name": "Unidad corregida" },
      { "role_code": "04", "code": "L01280797", "name": null }
    ],
    "reason": "La unidad tramitadora indicada por el cliente era otra.",
    "expected_version": 1
  }'

Respon 201 amb la revisió acabada de crear i la seva versió, encara que es confirmi una altra revisió just després:

{
  "data": {
    "id": "0197c5c2-0f31-7b74-8d29-6e4a1c7b3d58",
    "version": 2,
    "administrative_centres": [
      { "role_code": "01", "code": "L01280796", "name": null },
      { "role_code": "02", "code": "L01280796", "name": null },
      { "role_code": "03", "code": "L01280798", "name": "Unidad corregida" },
      { "role_code": "04", "code": "L01280797", "name": null }
    ],
    "reason": "La unidad tramitadora indicada por el cliente era otra.",
    "created_at": "2026-10-14T10:05:41.000000Z",
    "actor_id": "0197a001-3c5d-7e12-8a47-5b9c2d1f6e80",
    "correlation_id": null
  },
  "administrative_version": 2
}
  • expected_version és un camp del cos (un enter d'1 o més) i l'única protecció: un If-Match de la factura no s'aplica. Sense ell, 428 invoice_administrative_precondition_required; obsolet, 409 invoice_administrative_version_conflict amb details.current_version. Torna a llegir l'historial i reintenta sobre aquesta versió.
  • reason és obligatori, d'1 a 500 caràcters. administrative_centres és obligatori i pot ser [] per registrar «sense encaminament».
  • Només les factures issued i overdue accepten una revisió; un esborrany, una factura programada, cancel·lada o anul·lada respon 422 business_rule_violation amb subcode invoice_not_editable_in_current_state (un esborrany s'edita amb PATCH).
  • La revisió forma part de l'historial de la factura; un enviament a FACe que ja estava preparat conserva l'encaminament que va congelar, i l'intent següent fa servir el nou.

Scopes: invoices:read per llistar, invoices:write per afegir. El servidor MCP ofereix list_invoice_administrative_revisions i revise_invoice_administrative_routing.

Errors

HTTPcodeQuan
422invalid_invoice_business_dataUna referència, el període, un literal, un centre, l'id d'una línia o un sequence_number no és vàlid. param és la ruta exacta, per exemple lines.0.business_references.issuer_contract_date.
422invalid_invoice_payment_termsUn termini no és vàlid (payment_terms.N.amount, .id, .account…), el calendari no suma o s'ha enviat un camp de només lectura.
422invoice_due_date_not_last_instalmentLa factura té calendari de pagaments i s'emet amb un due_on absent o diferent de la data de l'últim termini (param: due_on). Posa aquesta data, o ajusta els terminis, i torna a emetre. Consulta Calendari de pagaments.
428invoice_payment_terms_precondition_requiredCanvies el calendari d'una factura existent sense expected_payment_terms_version.
409invoice_payment_terms_version_conflictexpected_payment_terms_version està obsolet (details.current_version).
428invoice_administrative_precondition_requiredUna revisió administrativa sense expected_version.
409invoice_administrative_version_conflictexpected_version està obsolet (details.current_version).
422business_rule_violation / invoice_not_editable_in_current_stateEdites les dades d'una factura emesa, o revises l'encaminament d'un esborrany.
404invoice_not_foundLa factura no existeix o pertany a una altra empresa.
403insufficient_scopeA la clau li falta invoices:read o invoices:write.
{
  "error": {
    "type": "invalid_request_error",
    "code": "invalid_invoice_business_data",
    "message": "Los datos comerciales de la factura no son válidos.",
    "param": "lines.0.business_references.issuer_contract_date",
    "request_id": "req_01JBVH7K9Y4N3CDQ2EHJB1AGSV",
    "doc_url": "https://docs.factuarea.com/guides/errors#invalid_invoice_business_data"
  }
}

A bulk-create cada fila es valida per separat i una fila incorrecta s'informa a results[] sense fer fallar les altres; consulta Operacions massives.

Relacionat

En aquesta pàgina

Et donem un cop de mà?Contactar amb suport