Facturiadocs
Referencia API

Documentos

Emisión de DTE, lectura, artefactos PDF y XML, enlaces públicos y acciones sobre un documento.

Base: https://api.facturia.cl/v1. Todos los endpoints de este capítulo se autentican con Authorization: Bearer salvo que se diga lo contrario, y el sobre de error es el de Errores.

MétodoRutaQué hace
GET/documentsLista los documentos emitidos
POST/documentsEmite un DTE
POST/documents/previewsCotiza y valida un documento sin emitirlo
GET/documents/previews/{preview_id}Lee una previsualización guardada
GET/documents/{document_id}Devuelve un documento
GET/documents/{document_id}/pdfDescarga el PDF
GET/documents/{document_id}/xmlDescarga el XML firmado, exactamente como se envió al SII
GET/documents/{document_id}/eventsEventos del ciclo de vida de un documento
POST/documents/{document_id}/retryReintenta un documento en failed
POST/documents/{document_id}/sendEnvía el documento por correo al receptor
POST/documents/{document_id}/cesionPregúntale al SII si esta factura es cedible
POST/documents/{document_id}/cedeCede esta factura a un factoring, inscribiéndola en el RTC del SII
POST/documents/{document_id}/credit_noteEmite una nota de crédito contra este documento
POST/documents/{document_id}/public_linksCrea o rota los enlaces públicos de los artefactos de este documento
DELETE/documents/{document_id}/public_linksRevoca todos los enlaces públicos de este documento

GET /documents

Lista los documentos emitidos

Lista los documentos de la empresa, del más nuevo al más antiguo, filtrable por tipo_dte, status y rango de fechas.

curl -sS https://api.facturia.cl/v1/documents \
  -H "Authorization: Bearer $FACTURIA_KEY" \
  -H "Facturia-Empresa: $EMPRESA"

Parámetros

ParámetroEnRequeridoTipoNotas
Facturia-Empresaheader—stringLa empresa destino: RUT canónico (77928532-4) o id de empresa (emp_…). Obligatorio en toda llamada con alcance de empresa, salvo que la llave sea un token de empresa. Este header es el ÚNICO mecanismo: no hay parámetro ?empresa= ni campo empresa en el cuerpo. Omitido donde se requiere → 400 empresa_required; fuera de la lista blanca → 403 empresa_not_allowed.
limitquery—integer
cursorquery—stringCursor opaco tomado del next_cursor de una respuesta anterior.
expandquery—stringSeparados por coma, aplicados a la página devuelta. En un LISTADO el vocabulario es más angosto que en GET /documents/\{document_id\}: solo events, references y received_document. xml y pdf_base64 incorporan un artefacto completo por fila y aquí son 400 invalid_field — pídelos en el documento individual, o en /pdf y /xml (§5.4).
statusquery—queued · sent · accepted · reparo · rejected · failed · annulled
tipo_dtequery—33 · 34 · 39 · 41 · 46 · 52 · 56 · 61
folioquery—integer
receptor_rutquery—Rut
external_idquery—string
issue_date[gte]query—string
issue_date[lte]query—string
created_at[gte]query—string

Respuestas

CódigoSignificadoCuerpo
200Una lista de documentos.lista de Document
400Entrada mal formada o incompleta.ErrorResponse
401Llave ausente, mal formada o revocada.ErrorResponse
403Llave válida pero sin permiso: scope, lista blanca de empresas o modo.ErrorResponse
429Demasiadas solicitudes.ErrorResponse
defaultUn error no enumerado aparte para esta operación, en el mismo sobre §5.5 que cualquier otro rechazo. Ramifica por error.code, nunca solo por el estado HTTP ni por error.message — un código que esta operación aún no se ha visto lanzar sigue siendo más seguro para decidir que un texto pensado para una persona.ErrorResponse

POST /documents

Emite un DTE

Responde 201 con status: queued y folio: null. El folio llega cuando el documento pasa a sent: lo asigna el motor después de que la fila existe, así que ningún 201 puede traerlo. Ese null es una ESPERA, no una falla y no un marcador de posición — obsérvalo con document.sent, o releyendo el documento a la cadencia que te da Facturia-Poll-After.

La ida y vuelta al SII que viene después es una máquina de estados que se mira igual. Todo lo que no mandas se rellena con el perfil de la empresa (bloque emisor, giro, dirección), el registro de receptores y las reglas tributarias del tipo.

curl -sS -X POST https://api.facturia.cl/v1/documents \
  -H "Authorization: Bearer $FACTURIA_KEY" \
  -H "Facturia-Empresa: $EMPRESA" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"tipo_dte":33,"items":[{"description":"Consultoría","quantity":1,"unit_price":1200000}]}'

Parámetros

ParámetroEnRequeridoTipoNotas
Facturia-Empresaheader—stringLa empresa destino: RUT canónico (77928532-4) o id de empresa (emp_…). Obligatorio en toda llamada con alcance de empresa, salvo que la llave sea un token de empresa. Este header es el ÚNICO mecanismo: no hay parámetro ?empresa= ni campo empresa en el cuerpo. Omitido donde se requiere → 400 empresa_required; fuera de la lista blanca → 403 empresa_not_allowed.
Idempotency-Keyheader—stringLlave que genera el cliente, única por operación lógica, retenida 24 h y con alcance (cuenta, empresa, endpoint). Un replay devuelve la respuesta original con Facturia-Idempotent-Replay: true. Misma llave y cuerpo distinto → 409.

Cuerpo

CampoTipoRequeridoNotas
preview_idstring—Emite una previsualización ya calculada (POST /documents/previews). La solicitud guardada se reproduce por el mismo camino de creación, así que la emisión no difiere en nada de una directa. Solo puedes acompañarla de external_id y metadata — nada que cambie un monto, un receptor o una fecha. Emitir dos veces la misma previsualización devuelve el documento original con 200, no un segundo 201. Ej.: "prev_01K2R9M3D8V5QW7N".
tipo_dte33 · 34 · 39 · 41 · 46 · 52 · 56 · 61sí33 factura afecta · 34 factura exenta · 39 boleta afecta · 41 boleta exenta · 46 factura de compra · 52 guía de despacho · 56 nota de débito · 61 nota de crédito. Las boletas (39/41) viajan por otro transporte del SII; eso es invisible desde esta API.
external_idstring—Tu propio identificador. Único por empresa; uno duplicado devuelve 409 external_id_exists.
issue_datestring—Por defecto, hoy en America/Santiago.
prices_include_taxboolean—Por defecto true para 39/41 y false para todo otro tipo.
receptorParty—A quién se emite el documento. El giro de aquí es el GiroRecep del SII, topado en 40 caracteres — más estrecho que el GiroEmis del propio emisor (80), así que el mismo giro puede ser legal en un lado del documento e ilegal en el otro. legal_name va a 100 y address a 70/20/20. Los valores más largos se rechazan con 400 field_too_long antes de asignar folio, y nunca se truncan: acortar una razón social o un giro cambiaría lo que el documento dice de las partes. address tiene que ser un objeto; un string pelado es 400 invalid_field, porque no hay forma de partirlo en los tres componentes que pide el SII y descartarlo en silencio emitiría un documento sin dirección alguna. Y LA DIRECCIÓN NO ES OPCIONAL en 33, 34, 46, 52, 56 y 61: el SII acepta el SOBRE y después RECHAZA el documento cuyo <Receptor> no lleva GiroRecep/DirRecep/CmnaRecep, con el folio ya gastado. Así que giro, address.street y address.comuna se resuelven desde los documentos anteriores de esta misma empresa al mismo RUT y, si no hay ninguno, se rechazan con 400 receptor_incomplete antes de asignar folio. Tres excepciones: el tipo 52 no necesita giro (su receptor suele ser el propio emisor, cuyo giro pasa de 40 con frecuencia); emission_channel=sfg necesita además address.city, que exige el propio formulario del portal del SII; y 39/41 y un 46 extranjero (foreign: true, o 55555555-5) no necesitan ninguno.
itemsDocumentItem[]sí
global_discountsobject[]—El motor emite una sola línea de descuento global — el <DscRcgGlobal> del SII es un solo NroLinDR>1 hard-codeado — así que una segunda entrada se rechaza con 400 invalid_field antes de reservar folio, en vez de descartarse. SOLO EN EL CANAL MERCADO: en emission_channel=sfg se rechaza con 422 global_discount_not_available_for_channel, porque el formulario de emisión del portal del SII no tiene campo de descuento alguno — sus entradas EFXP_PCT_DESC/EFXP_MNT_DESC están comentadas en el formulario capturado, y items[].discount_percent se rechaza ahí por la misma razón. En ese canal, métele el descuento al items[].unit_price.
referencesDocumentReference[]—
dispatchobject—Obligatorio para el tipo 52, y sus campos transfer_type / dispatch_type se rechazan en cualquier otro tipo. Los dos canales de emisión emiten guía; lo que cambia es qué campos puede expresar cada uno. destination y dispatch_type se aceptan en emission_channel=mercado (el motor los escribe en el IdDoc/TipoDespacho y en el bloque Transporte del DTE) y se rechazan en emission_channel=sfg con 422 dispatch_not_available_for_channel, porque el formulario de guía del portal del SII no tiene dónde ponerlos: lleva una sola dirección — la del receptor, así que una distinta va en receptor.address — y su único selector de traslado es el de la clase de movimiento, sin ningún campo de TipoDespacho. Los dos canales también se diferencian en los montos: sfg rechaza una guía con cualquier línea a precio 0 o menor, o con total 0, con 422 sfg_guia_zero_amount — el portal valida la guía con las validaciones de la factura, sea cual sea la clase de traslado — mientras que mercado la acepta.
withholdingobject—Tipo 46 — tú eres el agente retenedor.
paymentobject—
totalsTotals + any—
pdfobject—
xmlobject—El artefacto XML comparte el mecanismo de enlace público del PDF en los mismos términos: es el archivo que el sistema contable del receptor realmente ingiere, así que dejarlo tras una llave obligaría a cada integrador a proxear un archivo que ya generamos.
notesstring—
metadataobject—Hasta 20 llaves de ≤500 caracteres cada una. Se guardan y se devuelven intactas; nunca llegan al SII.
testobject—Solo en modo test. Enviarlo con una llave live falla con 400 test_field_in_live_mode.
Respuestas
CódigoSignificadoCuerpo
200La previsualización que nombra preview_id YA se emitió, por un intento anterior de esta misma llamada o por una concurrente. Devuelve el documento original, sin cambios: esta llamada no creó nada y no gastó un segundo folio (§10.2). Solo se llega acá con un cuerpo \{"preview_id": "prev_…"\}.EmittedDocument
201Documento creado y encolado para transmisión. Trae Facturia-Poll-After cuando el documento no es terminal — que en el carril live es siempre el caso del 201, porque responde status: "queued". Hasta el 2026-09-04 lo adjuntaba solo GET /v1/documents/\{document_id\}, así que un agente que seguía «haz poll según Facturia-Poll-After» tenía que hacer una primera lectura solo para descubrir el número con el que le dijeron que hiciera poll (#522). Mismo valor, misma función, las dos puertas.EmittedDocument
400Entrada mal formada o incompleta.ErrorResponse
401Llave ausente, mal formada o revocada.ErrorResponse
402subscription_required - este acto real necesita una suscripción activa de la EMPRESA que el request nombra, y esa empresa no la tiene (se aplica de verdad). La suscripción es por empresa: las demás empresas de la misma cuenta no se ven afectadas, y error.details trae empresa, empresa_rut, empresa_name, account_plan, subscription_status, grace_until, blocked_by, un handoff next y un checkout_url que apunta a esa empresa. O bien plan_limit_reached - una cuota de plan agotada (declarado, todavía sin emisor). El modo de prueba nunca se bloquea por ninguno de los dos. LA ELEGIBILIDAD SE EVALÚA PRIMERO (2026-09-04, #475). Este rechazo ahora llega SOLO cuando la empresa por lo demás puede emitir: mientras su checklist está incompleto, su puesta en vivo pendiente o la empresa suspendida, el acto se rechaza con 422 empresa_not_emitting y el handoff del checklist. Así este 402 y Empresa.capabilities.blocked_by ya no pueden nombrar dos acciones siguientes distintas para un mismo estado — que es lo que hacían: el objeto decía «firma el mandato» y la puerta decía «paga».ErrorResponse
403Llave válida pero sin permiso: scope, lista blanca de empresas o modo.ErrorResponse
409Conflicto de estado: reutilización de idempotencia, external_id duplicado o artefacto no listo.ErrorResponse
422Bien formado, y rechazado por una regla del dominio. Los códigos que responde esta operación, en el orden en que los revisa la puerta: - empresa_not_emitting — solo en modo real: este endpoint exige onboarding.status = emitting y la empresa todavía no llega. En SANDBOX no se revisa: una empresa de prueba emite desde el primer minuto, que es lo que hace ejercitable toda la superficie antes de que el SII haya emitido nada. error.details es un EmissionRefusalDetails y trae el pending_action —quién tiene que actuar, dónde y con qué palabras—, así que el propio rechazo es el handoff. - empresa_not_active — la empresa está suspended o archived. - tipo_not_available_for_channel — este tipo_dte no se emite por el emission_channel de esta empresa (§6.2). - más las reglas del payload: folios_exhausted, totals_mismatch, receptor_incomplete, reference_required y sus hermanos — ver GET /error_codes. Esta lista nombraba folios_exhausted hasta el 2026-09-04. Ese código no existe ni existió nunca: quedarse sin folios no se rechaza en esta puerta — el rango se consume DESPUÉS de aceptar la petición, así que llega como documento rejected o, en POST /documents/previews, como la advertencia no bloqueante no_folios_available (#496 lo encontró cruzando cada código que estas frases nombran contra el diccionario publicado).ErrorResponse
429Demasiadas solicitudes.ErrorResponse
defaultUn error no enumerado aparte para esta operación, en el mismo sobre §5.5 que cualquier otro rechazo. Ramifica por error.code, nunca solo por el estado HTTP ni por error.message — un código que esta operación aún no se ha visto lanzar sigue siendo más seguro para decidir que un texto pensado para una persona.ErrorResponse

POST /documents/previews

Cotiza y valida un documento sin emitirlo

Corre el validador de emisión COMPLETO — los mismos rechazos, con las mismas palabras — y después no emite nada. folio es null porque no se tomó ninguno; folio_preview es el folio que se USARÍA, leído del contador y no reservado.

Se guarda una hora y se lee con GET /documents/previews/\{preview_id\}, que devuelve lo que se calculó en vez de volver a cotizar: que los totales cambien entre que se muestran y que se aprueban es justamente la falla que este flujo existe para evitar.

Para emitirla, manda \{"preview_id": "prev_…"\} a POST /documents. Emitir dos veces la misma previsualización devuelve el documento ORIGINAL con 200 y no gasta un segundo folio — una propiedad garantizada en la base de datos, porque un agente que reintenta una llamada de herramienta es el caso normal aquí y los agentes rara vez mandan Idempotency-Key.

curl -sS -X POST https://api.facturia.cl/v1/documents/previews \
  -H "Authorization: Bearer $FACTURIA_KEY" \
  -H "Facturia-Empresa: $EMPRESA" \
  -H "Content-Type: application/json" \
  -d '{"tipo_dte":33,"items":[{"description":"Consultoría","quantity":1,"unit_price":1200000}]}'

Parámetros

ParámetroEnRequeridoTipoNotas
Facturia-Empresaheader—stringLa empresa destino: RUT canónico (77928532-4) o id de empresa (emp_…). Obligatorio en toda llamada con alcance de empresa, salvo que la llave sea un token de empresa. Este header es el ÚNICO mecanismo: no hay parámetro ?empresa= ni campo empresa en el cuerpo. Omitido donde se requiere → 400 empresa_required; fuera de la lista blanca → 403 empresa_not_allowed.

Cuerpo

CampoTipoRequeridoNotas
preview_idstring—Emite una previsualización ya calculada (POST /documents/previews). La solicitud guardada se reproduce por el mismo camino de creación, así que la emisión no difiere en nada de una directa. Solo puedes acompañarla de external_id y metadata — nada que cambie un monto, un receptor o una fecha. Emitir dos veces la misma previsualización devuelve el documento original con 200, no un segundo 201. Ej.: "prev_01K2R9M3D8V5QW7N".
tipo_dte33 · 34 · 39 · 41 · 46 · 52 · 56 · 61sí33 factura afecta · 34 factura exenta · 39 boleta afecta · 41 boleta exenta · 46 factura de compra · 52 guía de despacho · 56 nota de débito · 61 nota de crédito. Las boletas (39/41) viajan por otro transporte del SII; eso es invisible desde esta API.
external_idstring—Tu propio identificador. Único por empresa; uno duplicado devuelve 409 external_id_exists.
issue_datestring—Por defecto, hoy en America/Santiago.
prices_include_taxboolean—Por defecto true para 39/41 y false para todo otro tipo.
receptorParty—A quién se emite el documento. El giro de aquí es el GiroRecep del SII, topado en 40 caracteres — más estrecho que el GiroEmis del propio emisor (80), así que el mismo giro puede ser legal en un lado del documento e ilegal en el otro. legal_name va a 100 y address a 70/20/20. Los valores más largos se rechazan con 400 field_too_long antes de asignar folio, y nunca se truncan: acortar una razón social o un giro cambiaría lo que el documento dice de las partes. address tiene que ser un objeto; un string pelado es 400 invalid_field, porque no hay forma de partirlo en los tres componentes que pide el SII y descartarlo en silencio emitiría un documento sin dirección alguna. Y LA DIRECCIÓN NO ES OPCIONAL en 33, 34, 46, 52, 56 y 61: el SII acepta el SOBRE y después RECHAZA el documento cuyo <Receptor> no lleva GiroRecep/DirRecep/CmnaRecep, con el folio ya gastado. Así que giro, address.street y address.comuna se resuelven desde los documentos anteriores de esta misma empresa al mismo RUT y, si no hay ninguno, se rechazan con 400 receptor_incomplete antes de asignar folio. Tres excepciones: el tipo 52 no necesita giro (su receptor suele ser el propio emisor, cuyo giro pasa de 40 con frecuencia); emission_channel=sfg necesita además address.city, que exige el propio formulario del portal del SII; y 39/41 y un 46 extranjero (foreign: true, o 55555555-5) no necesitan ninguno.
itemsDocumentItem[]sí
global_discountsobject[]—El motor emite una sola línea de descuento global — el <DscRcgGlobal> del SII es un solo NroLinDR>1 hard-codeado — así que una segunda entrada se rechaza con 400 invalid_field antes de reservar folio, en vez de descartarse. SOLO EN EL CANAL MERCADO: en emission_channel=sfg se rechaza con 422 global_discount_not_available_for_channel, porque el formulario de emisión del portal del SII no tiene campo de descuento alguno — sus entradas EFXP_PCT_DESC/EFXP_MNT_DESC están comentadas en el formulario capturado, y items[].discount_percent se rechaza ahí por la misma razón. En ese canal, métele el descuento al items[].unit_price.
referencesDocumentReference[]—
dispatchobject—Obligatorio para el tipo 52, y sus campos transfer_type / dispatch_type se rechazan en cualquier otro tipo. Los dos canales de emisión emiten guía; lo que cambia es qué campos puede expresar cada uno. destination y dispatch_type se aceptan en emission_channel=mercado (el motor los escribe en el IdDoc/TipoDespacho y en el bloque Transporte del DTE) y se rechazan en emission_channel=sfg con 422 dispatch_not_available_for_channel, porque el formulario de guía del portal del SII no tiene dónde ponerlos: lleva una sola dirección — la del receptor, así que una distinta va en receptor.address — y su único selector de traslado es el de la clase de movimiento, sin ningún campo de TipoDespacho. Los dos canales también se diferencian en los montos: sfg rechaza una guía con cualquier línea a precio 0 o menor, o con total 0, con 422 sfg_guia_zero_amount — el portal valida la guía con las validaciones de la factura, sea cual sea la clase de traslado — mientras que mercado la acepta.
withholdingobject—Tipo 46 — tú eres el agente retenedor.
paymentobject—
totalsTotals + any—
pdfobject—
xmlobject—El artefacto XML comparte el mecanismo de enlace público del PDF en los mismos términos: es el archivo que el sistema contable del receptor realmente ingiere, así que dejarlo tras una llave obligaría a cada integrador a proxear un archivo que ya generamos.
notesstring—
metadataobject—Hasta 20 llaves de ≤500 caracteres cada una. Se guardan y se devuelven intactas; nunca llegan al SII.
testobject—Solo en modo test. Enviarlo con una llave live falla con 400 test_field_in_live_mode.
Respuestas
CódigoSignificadoCuerpo
201La previsualización calculada. No se emitió nada ni se reservó folio.DocumentPreview
400Entrada mal formada o incompleta.ErrorResponse
401Llave ausente, mal formada o revocada.ErrorResponse
403Llave válida pero sin permiso: scope, lista blanca de empresas o modo.ErrorResponse
422Bien formado pero viola una regla del dominio: folios agotados, ventana de acuse cerrada.ErrorResponse
429Demasiadas solicitudes.ErrorResponse
defaultUn error no enumerado aparte para esta operación, en el mismo sobre §5.5 que cualquier otro rechazo. Ramifica por error.code, nunca solo por el estado HTTP ni por error.message — un código que esta operación aún no se ha visto lanzar sigue siendo más seguro para decidir que un texto pensado para una persona.ErrorResponse

GET /documents/previews/{preview_id}

Lee una previsualización guardada

Devuelve lo que se calculó, nunca un recálculo. Una previsualización ya emitida sigue siendo legible con emitted: true y un consumed_at; una sin usar desaparece una hora después de creada y responde 404.

curl -sS https://api.facturia.cl/v1/documents/previews/prev_01K2R9M3D8V5QW7N \
  -H "Authorization: Bearer $FACTURIA_KEY" \
  -H "Facturia-Empresa: $EMPRESA"

Parámetros

ParámetroEnRequeridoTipoNotas
preview_idpathsístring
Facturia-Empresaheader—stringLa empresa destino: RUT canónico (77928532-4) o id de empresa (emp_…). Obligatorio en toda llamada con alcance de empresa, salvo que la llave sea un token de empresa. Este header es el ÚNICO mecanismo: no hay parámetro ?empresa= ni campo empresa en el cuerpo. Omitido donde se requiere → 400 empresa_required; fuera de la lista blanca → 403 empresa_not_allowed.

Respuestas

CódigoSignificadoCuerpo
200The preview.DocumentPreview
401Llave ausente, mal formada o revocada.ErrorResponse
403Llave válida pero sin permiso: scope, lista blanca de empresas o modo.ErrorResponse
404No existe ese objeto bajo esta llave.ErrorResponse
429Demasiadas solicitudes.ErrorResponse
defaultUn error no enumerado aparte para esta operación, en el mismo sobre §5.5 que cualquier otro rechazo. Ramifica por error.code, nunca solo por el estado HTTP ni por error.message — un código que esta operación aún no se ha visto lanzar sigue siendo más seguro para decidir que un texto pensado para una persona.ErrorResponse

GET /documents/{document_id}

Devuelve un documento

Un documento: su status de ciclo de vida, los totales, public_links si tiene alguno vigente, y rejection_reasons si el SII lo rechazó.

curl -sS https://api.facturia.cl/v1/documents/doc_01K2R7Q4XW9M3B8ZC5YHTVJD6N \
  -H "Authorization: Bearer $FACTURIA_KEY" \
  -H "Facturia-Empresa: $EMPRESA"

Parámetros

ParámetroEnRequeridoTipoNotas
document_idpathsístring
Facturia-Empresaheader—stringLa empresa destino: RUT canónico (77928532-4) o id de empresa (emp_…). Obligatorio en toda llamada con alcance de empresa, salvo que la llave sea un token de empresa. Este header es el ÚNICO mecanismo: no hay parámetro ?empresa= ni campo empresa en el cuerpo. Omitido donde se requiere → 400 empresa_required; fuera de la lista blanca → 403 empresa_not_allowed.
expandquery—stringSeparados por coma. Uno o más de xml, pdf_base64, events, references, received_document. Un valor no reconocido es 400 invalid_field. received_document se puebla cuando este documento se emitió en respuesta al de un proveedor — calzado al emitir por referencia (tipo_dte, folio) más RUT emisor = RUT receptor, dentro de la misma empresa, y solo cuando ese calce es único (§5.4).

Respuestas

CódigoSignificadoCuerpo
200El documento.Document
400Entrada mal formada o incompleta.ErrorResponse
401Llave ausente, mal formada o revocada.ErrorResponse
403Llave válida pero sin permiso: scope, lista blanca de empresas o modo.ErrorResponse
404No existe ese objeto bajo esta llave.ErrorResponse
429Demasiadas solicitudes.ErrorResponse
defaultUn error no enumerado aparte para esta operación, en el mismo sobre §5.5 que cualquier otro rechazo. Ramifica por error.code, nunca solo por el estado HTTP ni por error.message — un código que esta operación aún no se ha visto lanzar sigue siendo más seguro para decidir que un texto pensado para una persona.ErrorResponse

GET /documents/{document_id}/pdf

Descarga el PDF

El PDF renderizado del documento (?copy=original o cedible donde la Ley 19.983 da una). 409 artifact_not_ready si el SII aún no acepta el documento — la representación impresa se renderiza al aceptarse, no antes.

curl -sS https://api.facturia.cl/v1/documents/doc_01K2R7Q4XW9M3B8ZC5YHTVJD6N/pdf \
  -H "Authorization: Bearer $FACTURIA_KEY" \
  -H "Facturia-Empresa: $EMPRESA"

Parámetros

ParámetroEnRequeridoTipoNotas
document_idpathsístring
Facturia-Empresaheader—stringLa empresa destino: RUT canónico (77928532-4) o id de empresa (emp_…). Obligatorio en toda llamada con alcance de empresa, salvo que la llave sea un token de empresa. Este header es el ÚNICO mecanismo: no hay parámetro ?empresa= ni campo empresa en el cuerpo. Omitido donde se requiere → 400 empresa_required; fuera de la lista blanca → 403 empresa_not_allowed.
copyquery—original · cedibleQué copia impresa servir. cedible está disponible para las facturas — tipo_dte 33 y 34 (Ley 19.983 art. 1; Res. Ex. SII N°14/2005 §1°; Manual de Muestras Impresas §1.4). Cualquier otro tipo devuelve 422 cedible_not_available. cedible no existe EN ABSOLUTO en una empresa emission_channel=sfg, en ningún tipo: el SII firma y proxea su propio PDF para ese canal, y sus bytes no llevan recuadro de acuse de recibo ni leyenda CEDIBLE que pueda servir como tal. copy=cedible ahí devuelve 422 cedible_not_available_for_channel; copy=original no se ve afectado. Las dos copias son dos archivos distintos: la original no lleva recuadro de acuse de recibo ni leyenda CEDIBLE, la cedible lleva ambos. both fue retirado en la wave 9 — el manual de muestras permite exactamente una página por archivo (p.12) — y ahora devuelve 400 invalid_field, igual que cualquier otro valor no reconocido. format (carta | 80mm) también fue retirado: no existe layout térmico y nunca se sirvió uno. Enviarlo devuelve 400 invalid_field. Omitirlo no siempre significa original. El valor por defecto se resuelve en este orden: el pdf.cedible propio de este documento (fijado en la emisión, §9.3) si dijo algo; si no, el branding.cedible_by_default de la empresa (§7.6); si no, original — y nunca cedible en el canal SFG, sea cual sea cualquiera de los dos valores por defecto. Envía ?copy= explícitamente para anular cualquiera de los dos en una lectura puntual.

Respuestas

CódigoSignificadoCuerpo
200El PDF generado.application/pdf
401Llave ausente, mal formada o revocada.ErrorResponse
403Llave válida pero sin permiso: scope, lista blanca de empresas o modo.ErrorResponse
404No existe ese objeto bajo esta llave.ErrorResponse
409Conflicto de estado: reutilización de idempotencia, external_id duplicado o artefacto no listo.ErrorResponse
422Bien formado pero viola una regla del dominio: folios agotados, ventana de acuse cerrada.ErrorResponse
429Demasiadas solicitudes.ErrorResponse
defaultUn error no enumerado aparte para esta operación, en el mismo sobre §5.5 que cualquier otro rechazo. Ramifica por error.code, nunca solo por el estado HTTP ni por error.message — un código que esta operación aún no se ha visto lanzar sigue siendo más seguro para decidir que un texto pensado para una persona.ErrorResponse

GET /documents/{document_id}/xml

Descarga el XML firmado, exactamente como se envió al SII

El XML exacto que Facturia envió al SII (o va a enviar), para quien quiere los bytes tal cual en vez del objeto ya interpretado.

curl -sS https://api.facturia.cl/v1/documents/doc_01K2R7Q4XW9M3B8ZC5YHTVJD6N/xml \
  -H "Authorization: Bearer $FACTURIA_KEY" \
  -H "Facturia-Empresa: $EMPRESA"

Parámetros

ParámetroEnRequeridoTipoNotas
document_idpathsístring
Facturia-Empresaheader—stringLa empresa destino: RUT canónico (77928532-4) o id de empresa (emp_…). Obligatorio en toda llamada con alcance de empresa, salvo que la llave sea un token de empresa. Este header es el ÚNICO mecanismo: no hay parámetro ?empresa= ni campo empresa en el cuerpo. Omitido donde se requiere → 400 empresa_required; fuera de la lista blanca → 403 empresa_not_allowed.

Respuestas

CódigoSignificadoCuerpo
200El XML EnvioDTE / EnvioBOLETA firmado (ISO-8859-1).application/xml
401Llave ausente, mal formada o revocada.ErrorResponse
403Llave válida pero sin permiso: scope, lista blanca de empresas o modo.ErrorResponse
404No existe ese objeto bajo esta llave.ErrorResponse
409Conflicto de estado: reutilización de idempotencia, external_id duplicado o artefacto no listo.ErrorResponse
429Demasiadas solicitudes.ErrorResponse
defaultUn error no enumerado aparte para esta operación, en el mismo sobre §5.5 que cualquier otro rechazo. Ramifica por error.code, nunca solo por el estado HTTP ni por error.message — un código que esta operación aún no se ha visto lanzar sigue siendo más seguro para decidir que un texto pensado para una persona.ErrorResponse

GET /documents/{document_id}/events

Eventos del ciclo de vida de un documento

El historial propio de eventos del documento — cada webhook document.* que Facturia publicó para él, en orden, sin importar si la entrega tuvo éxito.

curl -sS https://api.facturia.cl/v1/documents/doc_01K2R7Q4XW9M3B8ZC5YHTVJD6N/events \
  -H "Authorization: Bearer $FACTURIA_KEY" \
  -H "Facturia-Empresa: $EMPRESA"

Parámetros

ParámetroEnRequeridoTipoNotas
document_idpathsístring
Facturia-Empresaheader—stringLa empresa destino: RUT canónico (77928532-4) o id de empresa (emp_…). Obligatorio en toda llamada con alcance de empresa, salvo que la llave sea un token de empresa. Este header es el ÚNICO mecanismo: no hay parámetro ?empresa= ni campo empresa en el cuerpo. Omitido donde se requiere → 400 empresa_required; fuera de la lista blanca → 403 empresa_not_allowed.

Respuestas

CódigoSignificadoCuerpo
200Los eventos, del más antiguo al más nuevo.lista de DocumentEvent
401Llave ausente, mal formada o revocada.ErrorResponse
403Llave válida pero sin permiso: scope, lista blanca de empresas o modo.ErrorResponse
429Demasiadas solicitudes.ErrorResponse
defaultUn error no enumerado aparte para esta operación, en el mismo sobre §5.5 que cualquier otro rechazo. Ramifica por error.code, nunca solo por el estado HTTP ni por error.message — un código que esta operación aún no se ha visto lanzar sigue siendo más seguro para decidir que un texto pensado para una persona.ErrorResponse

POST /documents/{document_id}/retry

Reintenta un documento en failed

Reutiliza el folio ya asignado. Nunca crea un segundo documento.

curl -sS -X POST https://api.facturia.cl/v1/documents/doc_01K2R7Q4XW9M3B8ZC5YHTVJD6N/retry \
  -H "Authorization: Bearer $FACTURIA_KEY" \
  -H "Facturia-Empresa: $EMPRESA"

Parámetros

ParámetroEnRequeridoTipoNotas
document_idpathsístring
Facturia-Empresaheader—stringLa empresa destino: RUT canónico (77928532-4) o id de empresa (emp_…). Obligatorio en toda llamada con alcance de empresa, salvo que la llave sea un token de empresa. Este header es el ÚNICO mecanismo: no hay parámetro ?empresa= ni campo empresa en el cuerpo. Omitido donde se requiere → 400 empresa_required; fuera de la lista blanca → 403 empresa_not_allowed.

Respuestas

CódigoSignificadoCuerpo
200El documento, de vuelta en queued.Document
401Llave ausente, mal formada o revocada.ErrorResponse
403Llave válida pero sin permiso: scope, lista blanca de empresas o modo.ErrorResponse
409Conflicto de estado: reutilización de idempotencia, external_id duplicado o artefacto no listo.ErrorResponse
429Demasiadas solicitudes.ErrorResponse
defaultUn error no enumerado aparte para esta operación, en el mismo sobre §5.5 que cualquier otro rechazo. Ramifica por error.code, nunca solo por el estado HTTP ni por error.message — un código que esta operación aún no se ha visto lanzar sigue siendo más seguro para decidir que un texto pensado para una persona.ErrorResponse

POST /documents/{document_id}/send

Envía el documento por correo al receptor

202 cuando ESTA llamada creó el envío; 200 con el MISMO job cuando ya existe uno idéntico (mismo documento, mismas direcciones, mismos adjuntos) — un correo, un id de job, igual que en la §10.2 «emitir dos veces la misma previsualización devuelve el documento original». Los dos estados traen el mismo cuerpo, así que un cliente que solo maneja uno está manejando la mitad del endpoint.

curl -sS -X POST https://api.facturia.cl/v1/documents/doc_01K2R7Q4XW9M3B8ZC5YHTVJD6N/send \
  -H "Authorization: Bearer $FACTURIA_KEY" \
  -H "Facturia-Empresa: $EMPRESA" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"to":["pagos@andina.cl"],"attach":["pdf","xml"]}'

Parámetros

ParámetroEnRequeridoTipoNotas
document_idpathsístring
Facturia-Empresaheader—stringLa empresa destino: RUT canónico (77928532-4) o id de empresa (emp_…). Obligatorio en toda llamada con alcance de empresa, salvo que la llave sea un token de empresa. Este header es el ÚNICO mecanismo: no hay parámetro ?empresa= ni campo empresa en el cuerpo. Omitido donde se requiere → 400 empresa_required; fuera de la lista blanca → 403 empresa_not_allowed.
Idempotency-Keyheader—stringLlave que genera el cliente, única por operación lógica, retenida 24 h y con alcance (cuenta, empresa, endpoint). Un replay devuelve la respuesta original con Facturia-Idempotent-Replay: true. Misma llave y cuerpo distinto → 409.

Cuerpo

CampoTipoRequeridoNotas
tostring[]—
attachpdf · xml[]—Siempre la copia ORIGINAL del PDF — nunca la cedible, sea cual sea el valor por defecto del documento o de la empresa. §9.6: la copia cedible es un instrumento para ceder la deuda, no la factura que le envías a un cliente para que la pague. Por defecto: ["pdf","xml"].
Respuestas
CódigoSignificadoCuerpo
200Ya existe un envío idéntico. El job ORIGINAL — no hay un segundo correo.SendJob
202Encolado para envío.SendJob
401Llave ausente, mal formada o revocada.ErrorResponse
402subscription_required - este acto real necesita una suscripción activa de la EMPRESA que el request nombra, y esa empresa no la tiene (se aplica de verdad). La suscripción es por empresa: las demás empresas de la misma cuenta no se ven afectadas, y error.details trae empresa, empresa_rut, empresa_name, account_plan, subscription_status, grace_until, blocked_by, un handoff next y un checkout_url que apunta a esa empresa. O bien plan_limit_reached - una cuota de plan agotada (declarado, todavía sin emisor). El modo de prueba nunca se bloquea por ninguno de los dos. LA ELEGIBILIDAD SE EVALÚA PRIMERO (2026-09-04, #475). Este rechazo ahora llega SOLO cuando la empresa por lo demás puede emitir: mientras su checklist está incompleto, su puesta en vivo pendiente o la empresa suspendida, el acto se rechaza con 422 empresa_not_emitting y el handoff del checklist. Así este 402 y Empresa.capabilities.blocked_by ya no pueden nombrar dos acciones siguientes distintas para un mismo estado — que es lo que hacían: el objeto decía «firma el mandato» y la puerta decía «paga».ErrorResponse
403Llave válida pero sin permiso: scope, lista blanca de empresas o modo.ErrorResponse
409Conflicto de estado: reutilización de idempotencia, external_id duplicado o artefacto no listo.ErrorResponse
429Demasiadas solicitudes.ErrorResponse
defaultUn error no enumerado aparte para esta operación, en el mismo sobre §5.5 que cualquier otro rechazo. Ramifica por error.code, nunca solo por el estado HTTP ni por error.message — un código que esta operación aún no se ha visto lanzar sigue siendo más seguro para decidir que un texto pensado para una persona.ErrorResponse

POST /documents/{document_id}/cesion

Pregúntale al SII si esta factura es cedible

SOLO LECTURA (ticket #47). Encola una consulta al registro del propio SII (WSREGISTRORECLAMODTE.consultarDocDteCedible) y guarda la respuesta en el objeto cesion del documento. Acá no se cede nada, no se arma ningún AEC y no se escribe en el Registro de Cesión de Créditos — esa operación no lleva código de acción y no puede cambiar el estado en el SII.

Bajo la Ley 19.983 una factura se vuelve cedible cuando el receptor da acuse de recibo, o cuando pasan ocho días corridos sin reclamo; una que el emisor declaró pagada al contado no se vuelve cedible nunca (Circular N°35 de 23.06.2017). Cuál de esas aplica lo sabe solo el SII, así que esto es un reporte, nunca un cálculo nuestro.

202 cuando esta llamada encoló la pregunta, 200 cuando ya hay una idéntica en vuelo. Consulta GET /documents/\{document_id\} para la respuesta; no hay webhook.

Acepta una llave con documents:read: el integrador que necesita esto es un sistema de factoring, y no debería tener que cargar con una llave capaz de emitir facturas.

En modo de prueba la respuesta se simula en proceso contra el reloj simulado de la empresa y no se abre ningún socket al SII — 24 hasta ocho días después de la aceptación, 25 de ahí en adelante.

curl -sS -X POST https://api.facturia.cl/v1/documents/doc_01K2R7Q4XW9M3B8ZC5YHTVJD6N/cesion \
  -H "Authorization: Bearer $FACTURIA_KEY" \
  -H "Facturia-Empresa: $EMPRESA" \
  -H "Idempotency-Key: $(uuidgen)"

Parámetros

ParámetroEnRequeridoTipoNotas
document_idpathsístring
Facturia-Empresaheader—stringLa empresa destino: RUT canónico (77928532-4) o id de empresa (emp_…). Obligatorio en toda llamada con alcance de empresa, salvo que la llave sea un token de empresa. Este header es el ÚNICO mecanismo: no hay parámetro ?empresa= ni campo empresa en el cuerpo. Omitido donde se requiere → 400 empresa_required; fuera de la lista blanca → 403 empresa_not_allowed.
Idempotency-Keyheader—stringLlave que genera el cliente, única por operación lógica, retenida 24 h y con alcance (cuenta, empresa, endpoint). Un replay devuelve la respuesta original con Facturia-Idempotent-Replay: true. Misma llave y cuerpo distinto → 409.

Respuestas

CódigoSignificadoCuerpo
200Ya hay una consulta encolada contra esta misma respuesta (o, en modo de prueba, la respuesta simulada, ya aplicada). El documento, con su cesion actual.Document
202Encolada. El documento, con cesion mostrando todavía la respuesta conocida antes — todo en null si esta fue la primera consulta.Document
401Llave ausente, mal formada o revocada.ErrorResponse
403Llave válida pero sin permiso: scope, lista blanca de empresas o modo.ErrorResponse
409Conflicto de estado: reutilización de idempotencia, external_id duplicado o artefacto no listo.ErrorResponse
422Bien formado pero viola una regla del dominio: folios agotados, ventana de acuse cerrada.ErrorResponse
429Demasiadas solicitudes.ErrorResponse
defaultUn error no enumerado aparte para esta operación, en el mismo sobre §5.5 que cualquier otro rechazo. Ramifica por error.code, nunca solo por el estado HTTP ni por error.message — un código que esta operación aún no se ha visto lanzar sigue siendo más seguro para decidir que un texto pensado para una persona.ErrorResponse

POST /documents/{document_id}/cede

Cede esta factura a un factoring, inscribiéndola en el RTC del SII

LA ESCRITURA (ticket #60), a diferencia del POST …/cesion de más arriba (una lectura). Arma un Archivo Electrónico de Cesión — el DTE original firmado por el emisor, más los términos de la transferencia, firmados por el cedente — y lo sube al Registro Electrónico de Transferencia de Crédito del SII. Un acto real e irreversible.

Funciona igual sin importar el canal (ticket #60, resuelto 2026-09-06): el AEC lleva el sobre original firmado tal cual, así que no le importa si el DTE se emitió por emission_channel=sfg o emission_channel=mercado. cesion_channel_unsupported, el código que lanzaba la antigua barrera de canal, está RETIRADO del catálogo.

202 con un job cuando esta llamada encoló un intento NUEVO; 200 con el MISMO job cuando ya hay uno queued/submitted/aec_generated para este documento (un intento en vuelo a la vez). GET /documents/\{document_id\} trae el resultado del intento más nuevo en cesion.status.

UN ACUSE DE RECIBO NO ES UN REGISTRO (ticket #69). Lo más lejos que la subida misma puede llevar un intento es submitted — el SII respondió «Envío recibido OK» y entregó un TrackID. Su validación ocurre después, y un rechazo se avisa por correo al cedente horas más tarde, así que esta API declara confirmed solo cuando la propia consulta del registro, wsRPETCConsulta.getEstEnvio, responde EOK («Envío Aceptado») para ese TrackID. Los webhooks siguen exactamente eso: document.cesion_submitted significa «AEC recibido, anotación pendiente», document.cesion_confirmed es el que sirve para mover plata, y document.cesion_failed cubre un rechazo, una barrera, una respuesta que nadie reconoce y un registro que nunca se pudo confirmar.

409 cesion_attempt_may_have_registered cuando el intento más nuevo de este documento ya había puesto el AEC firmado en el cable al detenerse (ticket #76). Desde aquí no se puede decidir si alcanzó a inscribirse, así que una segunda cesión se rechaza en vez de arriesgar que el mismo crédito quede asignado dos veces. error.details trae la última respuesta que este sistema conoce del registro para ese intento (rtc_estado, rtc_track_id) cuando alguna vez se registró — leerla cuesta una columna, no una nueva llamada al SII; cuando nunca se registró ninguna, los detalles lo dicen así en vez de adivinar.

En modo de prueba esto se resuelve en la misma request (§4.1) — no se abre socket, el intento queda simulated, y se disparan LOS DOS document.cesion_submitted y document.cesion_confirmed, en ese orden, para que el evento sobre el que actúa una integración de factoring sea ejercitable en pruebas.

El envío en vivo sigue bloqueado por el dueño, y desde la resolución 2026-09-06 (R6) también por empresa: el armado del AEC y la subida al registro están construidos y verificados contra el propio esquema del SII — la primera subida en vivo (2026-09-03) fue aceptada por el registro con un TrackID real y luego rechazada en validación por un defecto de firma, ya corregido. Abrirlo exige LAS DOS cosas a la vez: ALLOW_LIVE_CESION_SUBMITS leído desde el propio shell de un operador (nunca de un deploy), Y que la conexión de la empresa cedente haya llegado a onboarding_status=emitting, esté active, en ambiente=palena y no sea una conexión sandbox. Un intento en vivo al que le falte cualquiera de las dos se acepta y se encola como cualquier otro, y termina failed sin reintento, nombrando cuál condición falta.

curl -sS -X POST https://api.facturia.cl/v1/documents/doc_01K2R7Q4XW9M3B8ZC5YHTVJD6N/cede \
  -H "Authorization: Bearer $FACTURIA_KEY" \
  -H "Facturia-Empresa: $EMPRESA" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"cesionario":{},"ultimo_vencimiento":"…"}'

Parámetros

ParámetroEnRequeridoTipoNotas
document_idpathsístring
Facturia-Empresaheader—stringLa empresa destino: RUT canónico (77928532-4) o id de empresa (emp_…). Obligatorio en toda llamada con alcance de empresa, salvo que la llave sea un token de empresa. Este header es el ÚNICO mecanismo: no hay parámetro ?empresa= ni campo empresa en el cuerpo. Omitido donde se requiere → 400 empresa_required; fuera de la lista blanca → 403 empresa_not_allowed.
Idempotency-Keyheader—stringLlave que genera el cliente, única por operación lógica, retenida 24 h y con alcance (cuenta, empresa, endpoint). Un replay devuelve la respuesta original con Facturia-Idempotent-Replay: true. Misma llave y cuerpo distinto → 409.

Cuerpo

CampoTipoRequeridoNotas
cesionarioobjectsí
montointeger—CLP, in [1, total]. Defaults to the document's total.
ultimo_vencimientostringsí
otras_condicionesstring—
email_deudorstring—
contactoobject—
Respuestas
CódigoSignificadoCuerpo
200Ya había un intento de cesión en vuelo para este documento. El mismo job.CesionJob
202Queued.CesionJob
401Llave ausente, mal formada o revocada.ErrorResponse
403Llave válida pero sin permiso: scope, lista blanca de empresas o modo.ErrorResponse
409Conflicto de estado: reutilización de idempotencia, external_id duplicado o artefacto no listo.ErrorResponse
422Bien formado pero viola una regla del dominio: folios agotados, ventana de acuse cerrada.ErrorResponse
429Demasiadas solicitudes.ErrorResponse
defaultUn error no enumerado aparte para esta operación, en el mismo sobre §5.5 que cualquier otro rechazo. Ramifica por error.code, nunca solo por el estado HTTP ni por error.message — un código que esta operación aún no se ha visto lanzar sigue siendo más seguro para decidir que un texto pensado para una persona.ErrorResponse

POST /documents/{document_id}/credit_note

Emite una nota de crédito contra este documento

En Chile no existe «borrar una factura». code: 1 anula el documento referenciado, 2 corrige texto y 3 corrige montos (con items para los valores corregidos).

curl -sS -X POST https://api.facturia.cl/v1/documents/doc_01K2R7Q4XW9M3B8ZC5YHTVJD6N/credit_note \
  -H "Authorization: Bearer $FACTURIA_KEY" \
  -H "Facturia-Empresa: $EMPRESA" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"code":1,"reason":"content"}'

Parámetros

ParámetroEnRequeridoTipoNotas
document_idpathsístring
Facturia-Empresaheader—stringLa empresa destino: RUT canónico (77928532-4) o id de empresa (emp_…). Obligatorio en toda llamada con alcance de empresa, salvo que la llave sea un token de empresa. Este header es el ÚNICO mecanismo: no hay parámetro ?empresa= ni campo empresa en el cuerpo. Omitido donde se requiere → 400 empresa_required; fuera de la lista blanca → 403 empresa_not_allowed.
Idempotency-Keyheader—stringLlave que genera el cliente, única por operación lógica, retenida 24 h y con alcance (cuenta, empresa, endpoint). Un replay devuelve la respuesta original con Facturia-Idempotent-Replay: true. Misma llave y cuerpo distinto → 409.

Cuerpo

CampoTipoRequeridoNotas
code1 · 2 · 3sí
reasonstringsí
itemsDocumentItem[]—
Respuestas
CódigoSignificadoCuerpo
201La nota de crédito (tipo 61).Document
401Llave ausente, mal formada o revocada.ErrorResponse
402subscription_required - este acto real necesita una suscripción activa de la EMPRESA que el request nombra, y esa empresa no la tiene (se aplica de verdad). La suscripción es por empresa: las demás empresas de la misma cuenta no se ven afectadas, y error.details trae empresa, empresa_rut, empresa_name, account_plan, subscription_status, grace_until, blocked_by, un handoff next y un checkout_url que apunta a esa empresa. O bien plan_limit_reached - una cuota de plan agotada (declarado, todavía sin emisor). El modo de prueba nunca se bloquea por ninguno de los dos. LA ELEGIBILIDAD SE EVALÚA PRIMERO (2026-09-04, #475). Este rechazo ahora llega SOLO cuando la empresa por lo demás puede emitir: mientras su checklist está incompleto, su puesta en vivo pendiente o la empresa suspendida, el acto se rechaza con 422 empresa_not_emitting y el handoff del checklist. Así este 402 y Empresa.capabilities.blocked_by ya no pueden nombrar dos acciones siguientes distintas para un mismo estado — que es lo que hacían: el objeto decía «firma el mandato» y la puerta decía «paga».ErrorResponse
403Llave válida pero sin permiso: scope, lista blanca de empresas o modo.ErrorResponse
422Bien formado pero viola una regla del dominio: folios agotados, ventana de acuse cerrada.ErrorResponse
429Demasiadas solicitudes.ErrorResponse
defaultUn error no enumerado aparte para esta operación, en el mismo sobre §5.5 que cualquier otro rechazo. Ramifica por error.code, nunca solo por el estado HTTP ni por error.message — un código que esta operación aún no se ha visto lanzar sigue siendo más seguro para decidir que un texto pensado para una persona.ErrorResponse

POST /documents/{document_id}/public_links

Crea o rota los enlaces públicos de los artefactos de este documento

Activa un link público después del hecho, o rota uno existente (lo que invalida la URL anterior). Un link expone exactamente un artefacto de un documento — nunca los demás documentos de la empresa, nunca datos de la cuenta — y no puede escalarse a una credencial de API.

cedible (ticket #18 wave 10) NO está en el conjunto por defecto: a diferencia de pdf/xml, no existe para todo documento, así que quien no lo pidió no recibe uno minteado en silencio — imitando ?copy= en GET …/pdf, que por defecto es original en vez de adivinar. Pedirlo para un tipo fuera de 33/34 es 422 cedible_not_available; pedirlo en una empresa emission_channel=sfg, en cualquier tipo, es 422 cedible_not_available_for_channel (#48) — el SII proxea su propio PDF para ese canal y nunca existe una copia cedible de él, así que esto rechaza el minteo en vez de devolver un link .cedible que solo podría resolver al archivo no-cedible.

curl -sS -X POST https://api.facturia.cl/v1/documents/doc_01K2R7Q4XW9M3B8ZC5YHTVJD6N/public_links \
  -H "Authorization: Bearer $FACTURIA_KEY" \
  -H "Facturia-Empresa: $EMPRESA" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"artifacts":["pdf","xml"]}'

Parámetros

ParámetroEnRequeridoTipoNotas
document_idpathsístring
Facturia-Empresaheader—stringLa empresa destino: RUT canónico (77928532-4) o id de empresa (emp_…). Obligatorio en toda llamada con alcance de empresa, salvo que la llave sea un token de empresa. Este header es el ÚNICO mecanismo: no hay parámetro ?empresa= ni campo empresa en el cuerpo. Omitido donde se requiere → 400 empresa_required; fuera de la lista blanca → 403 empresa_not_allowed.
Idempotency-Keyheader—stringLlave que genera el cliente, única por operación lógica, retenida 24 h y con alcance (cuenta, empresa, endpoint). Un replay devuelve la respuesta original con Facturia-Idempotent-Replay: true. Misma llave y cuerpo distinto → 409.

Cuerpo

CampoTipoRequeridoNotas
artifactspdf · xml · cedible[]síPor defecto: ["pdf","xml"].
expires_in_daysinteger,null—Null significa que el enlace no expira. Por defecto: 90.
expires_in_secondsinteger,null—La misma vigencia en segundos, acotada entre 30 s y 365 días. GANA cuando se mandan las dos unidades: los días no pueden expresar el enlace de diez minutos que necesita un agente, y la unidad más corta y específica es la lectura más segura de una solicitud ambigua.
Respuestas
CódigoSignificadoCuerpo
200Los enlaces recién creados. NO el documento: la mitad secreta de cada URL se guarda hasheada, así que esta respuesta es el único lugar donde una URL que funciona llega a existir. Guárdala.PublicLinks
401Llave ausente, mal formada o revocada.ErrorResponse
403Llave válida pero sin permiso: scope, lista blanca de empresas o modo.ErrorResponse
409Conflicto de estado: reutilización de idempotencia, external_id duplicado o artefacto no listo.ErrorResponse
429Demasiadas solicitudes.ErrorResponse
defaultUn error no enumerado aparte para esta operación, en el mismo sobre §5.5 que cualquier otro rechazo. Ramifica por error.code, nunca solo por el estado HTTP ni por error.message — un código que esta operación aún no se ha visto lanzar sigue siendo más seguro para decidir que un texto pensado para una persona.ErrorResponse

Revoca todos los enlaces públicos de este documento

Revoca todos los enlaces públicos vigentes acuñados para el documento. Las copias ya guardadas de la URL siguen funcionando hasta vencer; esto solo detiene descargas nuevas.

curl -sS -X DELETE https://api.facturia.cl/v1/documents/doc_01K2R7Q4XW9M3B8ZC5YHTVJD6N/public_links \
  -H "Authorization: Bearer $FACTURIA_KEY" \
  -H "Facturia-Empresa: $EMPRESA"

Parámetros

ParámetroEnRequeridoTipoNotas
document_idpathsístring
Facturia-Empresaheader—stringLa empresa destino: RUT canónico (77928532-4) o id de empresa (emp_…). Obligatorio en toda llamada con alcance de empresa, salvo que la llave sea un token de empresa. Este header es el ÚNICO mecanismo: no hay parámetro ?empresa= ni campo empresa en el cuerpo. Omitido donde se requiere → 400 empresa_required; fuera de la lista blanca → 403 empresa_not_allowed.

Respuestas

CódigoSignificadoCuerpo
204Revocados. Las URL existentes dejan de resolver de inmediato.—
401Llave ausente, mal formada o revocada.ErrorResponse
403Llave válida pero sin permiso: scope, lista blanca de empresas o modo.ErrorResponse
429Demasiadas solicitudes.ErrorResponse
defaultUn error no enumerado aparte para esta operación, en el mismo sobre §5.5 que cualquier otro rechazo. Ramifica por error.code, nunca solo por el estado HTTP ni por error.message — un código que esta operación aún no se ha visto lanzar sigue siendo más seguro para decidir que un texto pensado para una persona.ErrorResponse

En esta página