Factuarea APIDevelopers

Document de control (DeCA)

Emet des de l'API el document electrònic de control administratiu del transport de mercaderies per carretera — àmbit i exempcions, el flux emetre → còpia al conductor → modificar → tancar, la URL pública permanent per a la inspecció, albarans i pes brut.

Des del 5 d'octubre de 2026 el document de control administratiu del transport públic de mercaderies per carretera ha de ser digital. El DeCA (documento de control) identifica les parts, els enviaments, la mercaderia, el vehicle i les dates d'un transport, i viatja amb el conductor com un PDF el codi QR del qual obre una URL pública permanent. Tant el carregador contractual com el transportista efectiu estan obligats a formalitzar-lo (Ordre FOM/2861/2012, art. 4).

El recurs transport_documents cobreix tota la vida d'aquest document: esborranys (també emplenats des dels teus albarans), emissió, la còpia per al conductor, modificacions durant el servei, tancament, anul·lació i conservació dels fitxers per a la inspecció. Un DeCA no és una factura ni un registre VeriFactu, i mai no canvia la numeració, l'estoc ni la facturació dels teus albarans.

Tots els endpoints següents pengen de https://api.factuarea.com/v1 i fan servir el mateix embolcall d'error, la mateixa paginació per cursor, la mateixa idempotència i els mateixos scopes que la resta de l'API.

Quan el necessites

S'exigeix en el transport públic de mercaderies per carretera, nacional o de cabotatge, amb origen i destinació a Espanya. El transport internacional es documenta amb la carta de port CMR: un enviament amb origen o destinació fora d'Espanya no es pot emetre (transport_outside_spain).

No s'exigeix, amb la redacció de l'Ordre:

  • en el transport privat complementari, amb vehicles i conductors propis de l'empresa; la documentació a bord ha d'acreditar igualment que la mercaderia, el vehicle i el conductor són de l'empresa;
  • en la paqueteria de pocs paquets;
  • en les mudances;
  • en el transport de vehicles accidentats o avariats en vehicles especials;
  • en els transports que no necessiten una autorització de transport prèvia.

Fonts oficials (en castellà): Orden FOM/2861/2012, Resolución de 5 de junio de 2026, pàgina del Ministeri sobre el DeCA i les seves preguntes freqüents.

El mòdul transport_documents està inclòs allà on ho estan els albarans (plans Profesional, Avanzado i Enterprise) i requereix el mòdul delivery_notes. Scopes: transport_documents:read, transport_documents:write (esborranys i enviament per email), transport_documents:delete (només esborranys) i transport_documents:transition (emetre, modificar, tancar, reobrir, anul·lar i substituir). El PDF de cada versió exigeix pdfs:read; el justificant d'emissió exigeix transport_documents:read, com el registre d'emissió que conté.

El teu paper i les parts

Cada document declara si la teva empresa actua com a carregador contractual (company_role: "shipper") o com a transportista efectiu ("carrier"), inclòs el transportista que subcontracta el transport. La teva pròpia part s'omple amb les dades de la teva empresa; l'altra surt de contact_id o dels camps que enviïs. Un transportista estranger (cabotatge) s'identifica amb el seu propi tax_id i el seu tax_id_country.

Un NIF o un domicili que no supera la validació a les dades de la teva empresa o al contacte es deixa buit: l'esborrany l'admet i l'emissió el demana. El que envies a la petició es valida en desar-lo. Un domicili espanyol copiat de la teva empresa o d'un contacte sense província pren la del seu codi postal (les dues primeres xifres: 28001 és Madrid); un domicili que envies es desa tal com l'envies.

Mentre el document és un esborrany, cada part copiada segueix el seu origen, sense tornar a desar l'esborrany:

  • En actualitzar un contacte, el seu nom, el seu NIF (o identificador estranger amb el seu país) i el seu domicili es tornen a copiar als esborranys l'altra part dels quals hi està enllaçada.
  • En canviar el nom fiscal, la raó social, el NIF o el domicili fiscal de la teva empresa, es tornen a copiar a la teva pròpia part de tots els esborranys. La resta de canvis a les dades de la teva empresa (email, telèfon, web, compte bancari, idioma) no toquen cap esborrany.
  • El que l'origen té vàlid mana. Un NIF buit o no vàlid o un domicili incomplet a l'origen mai no esborra el que l'esborrany ja tenia, per exemple el que vas enviar a la petició. Una part escrita a mà o enllaçada a un altre contacte no canvia.
  • El refresc es fa uns segons després del canvi i, si alguna cosa canvia, publica transport_document.updated, de manera que el pots rebre d'un esborrany que no has tocat per l'API. Arxivar o esborrar el contacte deixa els seus esborranys com estaven.

Un document emès mai no segueix els seus orígens: conserva les dades amb què es va emetre.

Un cop emès, les parts no poden canviar: una modificació que les toqui retorna 422 transport_document_parties_immutable. Anul·la el document i emet-ne un altre.

El flux: emetre, lliurar la còpia, modificar, tancar

Crea un esborrany. Només company_role és obligatori: un esborrany admet dades incompletes i qualsevol data. Passa delivery_note_ids (d'1 a 50 dels teus albarans) per obtenir un enviament per albarà, amb la seva destinació, la seva data i la seva mercaderia, sense serveis i amb els pesos congelats. Un enviament que omet origin pren el teu lloc de càrrega per defecte o, si no en tens cap, el teu domicili fiscal (com a transportista, l'adreça del contacte carregador); un "origin": null explícit el deixa sense origen. Un albarà d'una altra empresa retorna 422 a delivery_note_ids.N.

curl -X POST https://api.factuarea.com/v1/transport_documents \
  -H "Authorization: Bearer $FACTUAREA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "company_role": "shipper",
    "carrier": { "contact_id": "01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8a10" },
    "vehicle": { "tractor_plate": "1234BCD", "trailer_plate": "R1234BCD" },
    "transport_date": "2026-10-06",
    "delivery_note_ids": [
      "01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8a11",
      "01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8a12"
    ]
  }'

Edita l'esborrany amb PUT /v1/transport_documents/{id} (un camp absent es conserva, un null explícit l'esborra i shipments substitueix la llista completa) o esborra'l amb DELETE /v1/transport_documents/{id}.

L'id del document el genera el servidor. shipments[].id és opcional: en crear, un identificador que ja està en ús, a la teva empresa o a qualsevol altra, retorna 422 a shipments.N.id; a PUT i a modify només identifica un enviament d'aquest mateix document (qualsevol altre retorna 422 parameter_invalid_value a shipments.N.id), i un enviament nou va sense id. Tot UUID que enviïs es normalitza a minúscules. Els enviaments, i les línies de mercaderia de cada enviament, es desen en l'ordre en què els envies en crear, editar, modificar i a la vista prèvia. Una línia de mercaderia amb un quantity × gross_weight_kg que arrodoneix a 0 kg o supera 9.999.999.999,9999 kg retorna 422 invalid_gross_weight a shipments.N.goods.M.gross_weight_kg en desar-la, no en emetre. Si una petició simultània ocupa el mateix identificador entre la comprovació i el desament, l'API retorna 409 resource_conflict: no s'ha desat res i la petició es pot reintentar tal qual.

Emet-lo abans que comenci el transport. POST /v1/transport_documents/{id}/issue comprova les dades mínimes: nom, NIF i domicili complet del carregador; nom i NIF del transportista; matrícula de la tractora; i a cada enviament, origen, destinació, mercaderia, magnitud declarada i una data de transport d'avui o posterior (Europe/Madrid). En una sola operació atòmica assigna el número següent de la sèrie DC (creada en la primera emissió), la URL pública permanent i la versió 1 del PDF. És irreversible: envia un Idempotency-Key.

Quan falta alguna cosa, l'error l'enumera a error.details.missing:

{
  "error": {
    "type": "invalid_request_error",
    "code": "transport_document_not_issuable",
    "message": "No se puede emitir el DeCA. Faltan 3 datos: el NIF del transportista efectivo; la matrícula de la tractora o del vehículo rígido; la magnitud declarada del envío 1 (peso u otra).",
    "details": {
      "missing": ["carrier.tax_id", "vehicle.tractor_plate", "shipments.1.measure"]
    }
  }
}

missing fa servir un vocabulari tancat: shipper.name, shipper.tax_id, shipper.address, carrier.name, carrier.tax_id, vehicle.tractor_plate, transport_date, shipments (cap enviament) i shipments.N.origin, shipments.N.destination, shipments.N.goods o shipments.N.measure, on N compta des d'1 (a diferència del param d'un error de validació, que compta des de 0). Si el PDF superés 5 MB (5.000.000 bytes), la petició retorna 422 transport_document_pdf_too_large i no s'emet res: escurça el contingut o reparteix els enviaments en diversos documents.

Una data de transport passada retorna transport_date_in_past: el document es crea abans del servei i no hi ha manera de regularitzar-lo després.

Lliura la còpia al conductor. Val qualsevol d'aquestes: l'enllaç public_url, el codi QR (GET /v1/transport_documents/{id}/qr?format=svg|png, amb la zona de silenci estàndard de 4 mòduls de la ISO/IEC 18004, perquè es llegeixi tal com es descarrega en imprimir-lo o enganxar-lo en un altre document), el PDF (GET /v1/transport_documents/{id}/pdf) o un email al transportista amb POST /v1/transport_documents/{id}/send (fins a 5 adreces diferents entre to, cc i bcc; una adreça repetida en qualsevol llista, sense distingir majúscules, compta i s'envia una sola vegada; sense to, l'email del contacte transportista). L'enviament és irreversible i queda al registre d'emissió. Si el proveïdor de correu rebutja el missatge o no el pot acceptar, l'API retorna 500 send_failed i no s'anota res al registre: torna-ho a provar amb una Idempotency-Key nova.

Modifica'l durant el servei. POST /v1/transport_documents/{id}/modify conserva el mateix número, la mateixa URL i el mateix QR, i desa una versió nova i completa del PDF amb les dades noves, el motiu i les dades anteriors marcades com a ja no vàlides. Envia només el que canvia, més reason (de 3 a 500 caràcters) i data_origin: company, o carrier_reported quan el canvi el va comunicar el transportista. Una petició que no canvia res retorna transport_document_no_changes. Un document té com a màxim 50 versions i l'última es reserva per anul·lar-lo o substituir-lo: amb 49 versions, una modificació retorna 422 transport_document_version_limit_reached, així que emet un document nou i marca aquest com a substituït. Una modificació que deixa sense alguna dada mínima retorna 422 transport_document_cannot_be_modified amb el mateix error.details.missing. Torna a enviar el PDF modificat al conductor.

{
  "reason": "Avería de la tractora",
  "data_origin": "carrier_reported",
  "vehicle": { "tractor_plate": "5678FGH" }
}

Tanca'l. POST /v1/transport_documents/{id}/close el tanca a mà. Si no, un procés diari el tanca automàticament 7 dies després del final de la seva última data de transport (Europe/Madrid). Un document tancat a mà es pot reobrir amb un reason fins a reopen_deadline; un tancament automàtic no es pot reobrir.

Un document emès té dues sortides terminals, totes dues irreversibles i totes dues conservant l'original: POST /v1/transport_documents/{id}/cancel (amb reason) desa una versió final marcada «ANULADO», i POST /v1/transport_documents/{id}/supersede (amb reference i reason) deixa constància que el document propi del transportista el substitueix. Un document emès no s'esborra mai. Igual que emetre i modificar, anul·lar i substituir retornen 422 transport_document_pdf_too_large sense canviar res quan el PDF superaria 5 MB.

La URL pública i la inspecció

La public_url té la forma https://app.factuarea.com/api/public/deca/{token}, amb un token opac de 43 caràcters. És la URL que codifica el codi QR (el PDF i el justificant d'emissió no la imprimeixen com a text) i no canvia entre versions.

  • GET i HEAD responen sense login, sense credencials i sense pàgina intermèdia: 200 amb el PDF de la versió vigent i Content-Type: application/pdf.
  • El fitxer se serveix exactament com es va desar, mai no es renderitza en la petició. L'ETag és el seu sha256, que coincideix amb versions[].sha256.
  • Les peticions tenen dos límits, i cap no depèn només de la IP, perquè la inspecció pot arribar a la URL a través d'una passarel·la amb una adreça compartida: un per token i prefix de xarxa (/24 en IPv4, /48 en IPv6; 60 per minut per defecte), que es comprova primer, i un altre per token (600 per minut per defecte, deu vegades el d'una xarxa, perquè dues xarxes que esgoten el seu no deixin sense el document una tercera). Una adreça IPv4 mapada en IPv6 (::ffff:a.b.c.d) compta com el seu /24. Superar qualsevol dels dos retorna 429 amb Retry-After.
  • Les peticions amb un token que no correspon a cap document, també un de mal format (d'una altra longitud o amb caràcters fora de base64url), compten en un límit per prefix de xarxa (30 per minut per defecte), mai per token: des d'una xarxa, el 31è intent del minut rep 429.
  • Una descàrrega s'anota al registre només després de comprovar que el fitxer existeix, amb la versió que realment s'ha servit. HEAD no s'anota.
  • Un token desconegut retorna 404, i un document els fitxers del qual es van purgar, 410.

Cada versió és un PDF de fins a 5 MB (5.000.000 bytes) la CreationDate del qual és la primera emissió i la ModDate del qual és la data de la versió. El seu historial mostra la data, el motiu, l'origen de la dada i les dades anteriors de cada modificació, però no qui la va fer: l'autor de cada versió només és al recurs autenticat, al registre i al justificant d'emissió. La URL continua servint el document com a mínim un any després de tancar-se, anul·lar-se o substituir-se (retention_until), encara que l'empresa canviï de pla. Passat aquest termini, els fitxers només es purguen si el compte està tancat: la subscripció està cancel·lada, o la seva gestoria va arxivar l'empresa gestionada. Un compte bloquejat (impagament, prova caducada) no està tancat. Després de la purga, el document i les seves dades es conserven, i els endpoints del PDF retornen 410 transport_document_file_unavailable. Demanar GET /v1/transport_documents/{id}/pdf?version=N amb una versió que el document no té retorna 404 transport_document_version_not_found amb error.param = version.

Prova d'emissió

GET /v1/transport_documents/{id}/evidence enumera, en ordre cronològic, les versions emeses o modificades, els tancaments manuals (closed) i automàtics (auto_closed), les reobertures, l'anul·lació o la substitució, els enviaments per email amb els seus destinataris i les descàrregues públiques amb la IP truncada i l'agent d'usuari. La resposta és { data, meta: { downloads_total, downloads_listed } }:

  • Cada entrada anomena el seu actor a actor_name, congelat amb el nom que tenia en aquell moment: l'usuari a l'app, la clau d'API a l'API REST i a MCP amb clau d'API, i el client OAuth a MCP per OAuth. Una clau mai no pren el nom de l'usuari que la va crear. actor_name és null només a auto_closed i a les descàrregues públiques; user_name és el nom actual de la persona, quan n'hi ha. occurred_at és ISO 8601 amb el seu desplaçament UTC.
  • Una descàrrega pública s'anota una vegada per hora per a cada combinació de versió i prefix de xarxa. L'agent d'usuari es desa però no compta, de manera que canviar-lo no afegeix entrades i escanejar diverses vegades el QR no les multiplica.
  • data porta sempre totes les entrades que no són descàrregues i, com a màxim, les 100 primeres descàrregues en ordre cronològic. meta.downloads_total és el nombre de descàrregues registrades i meta.downloads_listed, quantes n'hi ha a data.

La tool MCP get_transport_document_evidence retorna la mateixa forma. GET /v1/transport_documents/{id}/issuance_proof exporta el registre com un PDF generat a demanda, amb l'autor de cada versió. Exigeix transport_documents:read: una clau amb només pdfs:read rep 403 insufficient_scope. És la prova que eximeix el carregador que demostra haver-lo emès (art. 7.1 de l'Ordre). Cada versió es verifica recalculant el sha256 del seu PDF.

Albarans i pes brut

  • Enviaments des d'albarans. Filtra els documents d'un albarà amb GET /v1/transport_documents?delivery_note_id=…. Quan l'albarà canvia després de la versió vigent en alguna cosa que declara l'enviament (línies, quantitats, unitat, pes, adreça de lliurament o data), el seu enviament informa source_changed: true amb les diferències a source_changes; lliurar-lo o facturar-lo no compta, ni tampoc un pes afegit després al catàleg. Un albarà anul·lat o esborrat marca source_missing: true. Un albarà anul·lat no pot ser l'origen d'un esborrany nou (delivery_note_cancelled).
  • Pes brut al catàleg. Els productes, les variants i les presentacions fixes accepten gross_weight_kg, el que pesa una unitat tal com es carrega, embalatge inclòs. És opcional i només ajuda a omplir la magnitud declarada de cada enviament.
  • Pes als albarans. Cada línia d'albarà congela el seu pes en crear-se o editar-se en esborrany (gross_weight_kg de la línia); l'albarà publica total_gross_weight_kg i lines_without_weight_count, i imprimeix el total al seu PDF. Duplicar un albarà copia tal qual el pes congelat de cada línia.

Esdeveniments

transport_document.created, .updated, .issued, .modified, .closed, .reopened, .cancelled i .superseded porten el recurs complet a data.object. transport_document.closed distingeix un tancament manual d'un d'automàtic amb close_mode. transport_document.updated arriba també quan un esborrany segueix un canvi del seu contacte o de les dades de la teva empresa (parts). transport_document.email_sent i .email_failed informen de cada email del document amb els seus destinataris i la versió del PDF adjunta. Consulta Esdeveniments.

El que l'API pública no cobreix

Això es queda a l'app a propòsit:

  • Els llocs de càrrega. Són configuració de l'empresa. L'API pública i MCP identifiquen l'origen d'un enviament per la seva adreça.
  • La vista prèvia en viu d'un document sense desar, una ajuda de l'editor de l'app.
  • WebMCP, les accions d'automatització sobre el DeCA, els assistents d'IA i la importació massiva.

En aquesta pàgina

Et donem un cop de mà?Contactar amb suport