Faxtal
Facturas

Facturas recibidas

Las facturas recibidas son las que te emiten tus proveedores. Puedes registrarlas con el formato canónico, importarlas desde un XML o pedir una propuesta a partir de un PDF o una imagen.

Todas las llamadas usan la URL base https://app.faxtal.com/api/v1.1 y la cabecera X-API-Key (ver Autenticación).

OperaciónScope de la API key
Consultar, listar, validar, ver eventos, descargar documentos y PDFinvoices:read
Registrar, importar, reconocer, eliminar, y añadir o eliminar documentosreceived:write

Sin el scope necesario, la API responde 403 con el código scope_missing.

Estados

statusSignificado
receivedRegistrada y válida.
draftPendiente de revisar, por ejemplo porque se registró con errores de validación.

Registrar o actualizar con JSON canónico

PUT /api/v1.1/received-invoices

Qué enviar, en el formato canónico:

  • meta.source_system. meta.direction se fija siempre a received.
  • invoice.supplier: el proveedor.
  • invoice.customer: tu empresa.
  • header.invoice_number: el número completo, tal como lo pone el proveedor. invoice_series_code es opcional.
  • header.invoice_type_code.
  • issue_data.issue_date: la fecha de expedición. No puede ser futura.
  • issue_data.receipt_date: la fecha en que registras la factura. Si falta, se usa la de hoy.
  • No envíes los campos que deduce el sistema (ver Borradores). Si llegan, responde 422 inferred_fields_not_allowed.

Una factura usa un solo grupo de impuesto, el de issue_data.tax_group_code. Si está en otra divisa, se convierte a euros. Si no se puede determinar el tipo de cambio, la petición se rechaza con 422.

:::info Aún no disponible El grupo IGIC (Canarias) todavía no está disponible. Hoy el grupo es siempre IVA. :::

recibida.json:

{
  "schema_version": "json_1_1",
  "meta": {
    "direction": "received",
    "source_system": "mi-erp"
  },
  "invoice": {
    "supplier": {
      "person_type_code": "J",
      "tax_id": "B10000024",
      "name": "Proveedor Ejemplo S.L."
    },
    "customer": {
      "person_type_code": "J",
      "tax_id": "B10000008",
      "name": "Empresa Demo S.L."
    },
    "header": {
      "invoice_number": "FV-2026-0315",
      "invoice_type_code": "01"
    },
    "issue_data": {
      "issue_date": "2026-10-28",
      "receipt_date": "2026-11-02",
      "tax_currency_code": "EUR"
    },
    "totals": {
      "total_gross_amount_before_taxes": 250.0,
      "total_tax_outputs": 52.5,
      "invoice_total": 302.5
    },
    "lines": [
      {
        "item_description": "Material de oficina",
        "quantity": 1,
        "unit_price_without_tax": 250.0,
        "tax_treatment_code": "TAXABLE_NON_EXEMPT",
        "tax_output_rate": 21.0
      }
    ]
  }
}
curl -X PUT "https://app.faxtal.com/api/v1.1/received-invoices" \
  -H "X-API-Key: fctXXXXXXXX_YYYYYYYYYYYYYYYY" \
  -H "Content-Type: application/json" \
  -d @recibida.json

Respuesta 201, también cuando actualiza:

{
  "success": true,
  "id": "00000000-0000-0000-0000-000000000003",
  "errors": []
}

La validación no bloquea: la factura se registra aunque tenga errores. En ese caso success es false, los errores vienen en errors y la factura queda en draft.

Duplicados y actualizaciones

  • Una recibida se identifica por el NIF del proveedor, el número y el año de la fecha de expedición. La serie no cuenta.
  • Si envías otra factura con esa misma clave, se actualiza la existente en lugar de crear un duplicado. La API no responde 409 por duplicado.
  • Con ?invoice_id=<id> actualizas esa factura concreta. Si el id es de una factura emitida, responde 409 invoice_update_not_allowed.
  • Si la factura ya consta en un modelo presentado, no admite cambios en sus datos fiscales. Si solo fue aceptada en el SII, el cambio se admite y queda pendiente de reenviarse al SII.

Errores

HTTPcodeCausa
422missing_required_fieldsFalta header.invoice_number o issue_data.issue_date. El detalle trae missing.
422future_issue_dateLa fecha de expedición es futura.
422inferred_fields_not_allowedHas enviado campos que deduce el sistema.
409invoice_update_not_allowedEl invoice_id es de una factura emitida.
409received_invoice_fiscally_lockedLa factura ya consta en un modelo presentado. El detalle trae reasons y locked_fields_changed.
409invoice_race_conditionOtra petición ha escrito la misma factura a la vez. Reintenta.

Importar un XML (Facturae, UBL o CII)

POST /api/v1.1/received-invoices/import?format=<formato>

formatFormato
facturae_3_2_2Facturae 3.2.2
facturae_3_2_1Facturae 3.2.1
facturae_3_2Facturae 3.2
ubl_2_1UBL 2.1
cii_d16bCII D16B
  • El cuerpo es el XML tal cual, no un formulario.
  • La cabecera Content-Type tiene que ser application/xml o text/xml.
  • El XML puede ocupar hasta 10 MB.
  • La validación es estricta: si el XML tiene errores, no se registra nada.
  • Se registra igual que con JSON canónico: queda en received y, si ya existe una recibida del mismo proveedor con ese número en el mismo año, la actualiza.
  • El comprador del XML tiene que ser tu empresa (salvo en facturas simplificadas).
  • Si el XML no trae fecha de recepción, no se usa la de hoy: la factura se imputa por su fecha de expedición. Al volver a importarla se conserva la fecha de recepción que ya tuviera.
curl -X POST "https://app.faxtal.com/api/v1.1/received-invoices/import?format=facturae_3_2_2" \
  -H "X-API-Key: fctXXXXXXXX_YYYYYYYYYYYYYYYY" \
  -H "Content-Type: application/xml" \
  --data-binary @factura-proveedor.xml

Respuesta 201:

{
  "success": true,
  "id": "00000000-0000-0000-0000-000000000004",
  "errors": []
}

Errores

HTTPcodeCausa
400empty_bodyEl cuerpo está vacío.
413payload_too_largeEl XML supera 10 MB. El detalle trae max_bytes.
415unsupported_media_typeEl Content-Type no es XML. El detalle trae expected.
422unsupported_invoice_source_transformEl formato indicado no se puede convertir.
422—El XML no se puede leer o no pasa la validación. El detalle describe los errores.
422missing_required_fieldsEl XML no trae número o fecha de expedición. El detalle trae missing.
422future_issue_dateLa fecha de expedición es futura.
422recipient_tax_id_mismatchEl NIF del comprador no es el de tu empresa.
422recipient_tax_id_requiredEl XML no trae el NIF del comprador.
409received_invoice_fiscally_lockedLa factura ya consta en un modelo presentado. El detalle trae reasons y locked_fields_changed.
409invoice_race_conditionOtra petición ha escrito la misma factura a la vez. Reintenta.

Reconocer un PDF o una imagen

POST /api/v1.1/received-invoices/recognize

Lee el documento y devuelve una propuesta de factura en formato canónico. No registra nada: la revisas y la registras tú.

  • Envía el fichero como multipart/form-data en el campo file.
  • Admite PDF, JPEG, PNG y TIFF, de hasta 10 MB. Un PDF puede tener hasta 8 páginas.
  • La llamada espera al resultado.
  • Cada documento cuenta para el límite mensual de reconocimientos de tu plan.
  • Un mismo fichero solo se reconoce una vez. Si lo vuelves a enviar, se rechaza.
curl -X POST "https://app.faxtal.com/api/v1.1/received-invoices/recognize" \
  -H "X-API-Key: fctXXXXXXXX_YYYYYYYYYYYYYYYY" \
  -F "file=@factura-proveedor.pdf;type=application/pdf"

Respuesta 200, resumida:

{
  "job_id": "00000000-0000-0000-0000-0000000000a1",
  "status": "recognized_pending_review",
  "canonical_draft": {
    "schema_version": "json_1_1",
    "meta": {
      "direction": "received",
      "recognition_status": "recognized_pending_review",
      "recognition_score": 0.82
    },
    "invoice": { "...": "proveedor, cabecera, fechas, líneas y totales" },
    "recognition": {
      "requires_human_review": true,
      "review_reasons": ["..."],
      "field_scores": { "...": 0.9 }
    }
  }
}
statusSignificado
recognized_readyConfianza alta. Revisa igualmente antes de registrar.
recognized_pending_reviewHay datos dudosos: revísalos.
recognized_rejectedNo parece una factura o la confianza es demasiado baja. canonical_draft puede venir vacío.

La confianza global está en canonical_draft.meta.recognition_score, de 0 a 1. El detalle por campo y los motivos de revisión están en canonical_draft.recognition.

Registrar la propuesta

La API no tiene un paso de confirmación: reconoces el documento y después registras la factura con PUT /api/v1.1/received-invoices. La propuesta no se puede enviar tal cual: trae campos que el alta rechaza con 422 inferred_fields_not_allowed. Antes de enviarla:

  1. Revisa y corrige los datos: proveedor, número, fechas e importes.
  2. Quita header.is_simplified y header.is_corrective, que vienen siempre.
  3. Quita, si aparecen, taxable, exempt, tax_category_code, tax_output_code y tax_withheld_code de las líneas; taxable, exempt, tax_category_code y tax_type_code de taxes_outputs[] y taxes_withheld[]; y subdivision_type de las direcciones.
  4. Envía el resultado con PUT /api/v1.1/received-invoices.

Errores

HTTPcodeCausa
402quota_exceededHas llegado al límite mensual de reconocimientos de tu plan.
422recognition_file_invalidEl fichero está vacío o supera el tamaño máximo.
503recognition_disabledEl reconocimiento no está disponible.

Validar

  • POST /api/v1.1/received-invoices/validate: valida un JSON canónico sin guardarlo. Responde is_valid, errors y data, igual que la validación de borradores.
  • POST /api/v1.1/received-invoices/{invoice_id}/validate: vuelve a validar una recibida registrada. Responde id, is_valid, status y errors.
curl -X POST "https://app.faxtal.com/api/v1.1/received-invoices/validate" \
  -H "X-API-Key: fctXXXXXXXX_YYYYYYYYYYYYYYYY" \
  -H "Content-Type: application/json" \
  -d @recibida.json

Consultar y listar

Una factura

GET /api/v1.1/received-invoices/{invoice_id}

curl "https://app.faxtal.com/api/v1.1/received-invoices/00000000-0000-0000-0000-000000000003" \
  -H "X-API-Key: fctXXXXXXXX_YYYYYYYYYYYYYYYY"

Devuelve la factura con los mismos campos que una emitida (id, direction, status, number, issue_date, supplier_tax_id, supplier_name, totales y corrections), con direction a received.

El canónico

GET /api/v1.1/received-invoices/{invoice_id}/canonical

Devuelve el JSON canónico tal y como lo guardó Faxtal: normalizado y con los campos que el sistema infiere (clasificación fiscal, taxable, exempt, is_simplified…). Es lo que se declara a Hacienda, y lleva las líneas y los impuestos que la ficha resumida no trae.

curl "https://app.faxtal.com/api/v1.1/received-invoices/00000000-0000-0000-0000-000000000001/canonical" \
  -H "X-API-Key: fctXXXXXXXX_YYYYYYYYYYYYYYYY"

:::warning No se reenvía tal cual La respuesta no vale como cuerpo de PUT /api/v1.1/drafts: ese endpoint rechaza los campos inferidos con 422 inferred_fields_not_allowed. Úsalo para leer y para conciliar, no para reeditar. :::

Si la factura no tiene canónico guardado, responde 409 canonical_not_available.

La lista

GET /api/v1.1/received-invoices

ParámetroDescripción
statusreceived, draft, issued, sent o cancelled.
supplier_tax_idNIF del proveedor.
seriesCódigo de serie, si la factura lo trae.
numberNúmero de factura exacto. Sirve para recuperar una factura cuyo id has perdido.
external_refTu referencia (meta.external_ref), exacta.
issue_date_from, issue_date_toRango de fecha de expedición (YYYY-MM-DD).
limitDe 1 a 500. Por defecto, 50.
offsetDesplazamiento. Por defecto, 0.
curl -G "https://app.faxtal.com/api/v1.1/received-invoices" \
  -H "X-API-Key: fctXXXXXXXX_YYYYYYYYYYYYYYYY" \
  -d supplier_tax_id=B10000024

Respuesta 200: items, total, limit y offset.


Eliminar

DELETE /api/v1.1/received-invoices/{invoice_id}

curl -X DELETE "https://app.faxtal.com/api/v1.1/received-invoices/00000000-0000-0000-0000-000000000003" \
  -H "X-API-Key: fctXXXXXXXX_YYYYYYYYYYYYYYYY"

Respuesta 204, sin cuerpo. Se borran también sus documentos adjuntos.

Si la factura ya consta en un modelo presentado o fue aceptada en el SII, responde 409 invoice_delete_not_allowed con los motivos en reasons.


Ver el histórico

GET /api/v1.1/received-invoices/{invoice_id}/events

Devuelve la lista de eventos con la misma forma que en las emitidas: event_type, event_code, occurred_at, actor, from_status, to_status y details.


Documentos adjuntos

OperaciónRutaScope
ListarGET /api/v1.1/received-invoices/{invoice_id}/documentsinvoices:read
AñadirPOST /api/v1.1/received-invoices/{invoice_id}/documentsreceived:write
DescargarGET /api/v1.1/received-invoices/{invoice_id}/documents/{doc_id}invoices:read
EliminarDELETE /api/v1.1/received-invoices/{invoice_id}/documents/{doc_id}received:write

Es útil para guardar el original del proveedor junto a la factura registrada:

curl -X POST "https://app.faxtal.com/api/v1.1/received-invoices/00000000-0000-0000-0000-000000000003/documents" \
  -H "X-API-Key: fctXXXXXXXX_YYYYYYYYYYYYYYYY" \
  -F "file=@factura-proveedor.pdf;type=application/pdf"

Las reglas son las mismas que en las emitidas: campo file, hasta 16 MB, respuesta 201 con public_id (el doc_id) y doc_type.


Descargar el PDF

GET /api/v1.1/received-invoices/{invoice_id}/pdf

curl "https://app.faxtal.com/api/v1.1/received-invoices/00000000-0000-0000-0000-000000000003/pdf" \
  -H "X-API-Key: fctXXXXXXXX_YYYYYYYYYYYYYYYY" \
  -o recibida.pdf

Genera un PDF con los datos registrados; no es el documento original del proveedor. El parámetro template funciona igual que en las emitidas.


Ver también

On this page