Lista los documentos del ambiente de la clave
curl https://api.boletura.com/v1/documents \ --header 'Authorization: Bearer bol_test_TU_CLAVE'$ch = curl_init("https://api.boletura.com/v1/documents");
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Authorization: Bearer bol_test_TU_CLAVE']);
curl_exec($ch);
curl_close($ch);import http.client
conn = http.client.HTTPSConnection("api.boletura.com")
headers = { "Authorization": "Bearer bol_test_TU_CLAVE"}
conn.request( "GET", "/v1/documents", headers=headers,)
response = conn.getresponse()print(response.read().decode())
conn.close()using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://api.boletura.com/v1/documents");request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", "bol_test_TU_CLAVE");
using var response = await client.SendAsync(request);HttpClient client = HttpClient.newHttpClient();HttpRequest request = HttpRequest.newBuilder() .uri(java.net.URI.create("https://api.boletura.com/v1/documents")) .header("Authorization", "Bearer bol_test_TU_CLAVE") .method("GET", HttpRequest.BodyPublishers.noBody()) .build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());System.out.println(response.body());fetch('https://api.boletura.com/v1/documents', { headers: { Authorization: 'Bearer bol_test_TU_CLAVE' }})Por defecto, el más reciente primero. Para sincronizar de forma incremental, usa order=updated_at, guarda el último updated_at visto, consulta desde ese valor con un solape de 2 minutos y descarta los repetidos por id. Los filtros se combinan. Sin items ni qr_image.
Requiere el scope documents:read.
Autorización
Sección titulada «Autorización»Parámetros
Sección titulada «Parámetros»Parámetros de la consulta
Sección titulada «Parámetros de la consulta»Filtra por empresa emisora, por su UUID; uno mal escrito responde 400 bad_request.
Filtra por tipo de comprobante. Un valor que no existe responde 422 filter_invalid con su param.
factura: factura electrónica.boleta: boleta de venta electrónica.nota_credito: nota de crédito sobre una factura o una boleta.nota_debito: nota de débito sobre una factura o una boleta.
Filtra por estado interno. Un valor que no existe responde 422 filter_invalid con su param.
issued: emitido, numerado y con XML firmado. Es el estado inicial y el habitual.void_requested: se pidió anularlo y se espera que SUNAT acepte la baja.voided: SUNAT aceptó la anulación. Es un estado final.expired: se confirmó que no hubo un envío válido dentro del plazo.
Filtra por estado fiscal. Un valor que no existe responde 422 filter_invalid con su param.
pending: pendiente de informar a SUNAT: una factura y sus notas se envían solas, y una boleta y sus notas van en el resumen diario. Se puede entregar al cliente aclarando que falta la validación.submitted: enviado, o conciliando un resultado desconocido. No se reemite mientras el resultado sea incierto.accepted: aceptado por SUNAT.accepted_with_observations: aceptado con observaciones, que están ensunat.notes.rejected: rechazado; el motivo está ensunat.descriptiony el número no se reutiliza. Una factura o una boleta se corrige emitiendo otro documento conreplaces_document_id. Una nota de crédito se corrige emitiendo otra nota, porquereplaces_document_idno aplica y la rechazada no cuenta en el saldo del afectado.deadline_missed: se confirmó que no hubo un envío válido en plazo. Contacta a soporte antes de pedir una baja o emitir otro documento.
Filtra por serie, como B001.
Fecha de emisión desde. Fecha YYYY-MM-DD de Lima, incluida en el rango; una fecha mal escrita responde 400 bad_request.
Fecha de emisión hasta. Fecha YYYY-MM-DD de Lima, incluida en el rango; una fecha mal escrita responde 400 bad_request.
Filtra por el identificador del integrador; sirve para recuperar una emisión. Uno en blanco responde 422 filter_invalid.
Creación desde. Timestamp RFC 3339, incluido en el rango; una fecha mal escrita responde 400 bad_request.
Creación hasta. Timestamp RFC 3339, incluido en el rango; una fecha mal escrita responde 400 bad_request.
Última modificación desde. Timestamp RFC 3339, incluido en el rango; una fecha mal escrita responde 400 bad_request.
Última modificación hasta. Timestamp RFC 3339, incluido en el rango; una fecha mal escrita responde 400 bad_request.
Cambia el orden. Un valor que no existe responde 422 filter_invalid con su param.
updated_at: por última modificación ascendente, para sincronizar.
Tamaño de la página, de 1 a 200; por defecto 50. Fuera de ese rango responde 422 limit_invalid, y un valor que no es un número, 400 bad_request.
El next_cursor de la página anterior. Es opaco y vale solo para el orden con el que se generó: otro responde 400 invalid_cursor.
Respuestas
Sección titulada «Respuestas»Solicitud correcta.
Una página de documentos.
object
Documentos de la página, sin items ni qr_image.
Comprobante electrónico: una boleta, una factura, una nota de crédito o una nota de débito.
object
UUID del documento.
Siempre document.
Ambiente del documento. Uno de test no se ve con una clave live, ni al revés.
UUID de la empresa emisora.
Tipo de comprobante.
Serie, como B001.
Correlativo dentro de la serie.
Serie y correlativo, como B001-125.
Fecha de emisión, en fecha civil de Lima.
Moneda; hoy siempre PEN.
Cliente del comprobante.
object
Tipo de documento del cliente.
Número de documento; nulo si el cliente no tiene.
Nombre o razón social.
Dirección.
Correo.
Líneas del comprobante. No aparece en el listado.
Línea del comprobante, con los importes calculados por la plataforma.
object
Número de línea, desde 1.
Código interno del integrador; nulo si el ítem no lo trajo.
Descripción de la línea.
Cantidad, sin ceros finales.
Código de unidad de medida.
Precio unitario con IGV, sin ceros finales.
Valor unitario sin IGV, sin ceros finales.
Afectación al IGV.
Tasa del IGV en porcentaje, como 18.
Valor de la línea sin IGV, con 2 decimales.
IGV de la línea, con 2 decimales.
Total de la línea con IGV, con 2 decimales.
Totales calculados por la plataforma.
object
Total de operaciones gravadas, sin IGV.
Total de operaciones exoneradas.
Total de operaciones inafectas.
Total de descuentos; hoy siempre 0.00.
IGV total.
Importe total con IGV.
Importe total en letras.
Estado interno.
Estado fiscal. Es el campo que dice si el documento es válido.
Estado de la entrega por webhook.
Detalle del envío a SUNAT.
object
Código de respuesta de SUNAT; nulo hasta que responde.
Descripción de la respuesta de SUNAT; nula hasta que responde.
Observaciones de SUNAT.
Fin del plazo de envío: la fecha de emisión más 3 días en facturas y sus notas, y más 7 en boletas y sus notas, al final del día de Lima. No limita la llegada del CDR.
Envío a SUNAT; nulo si aún no se envió. Timestamp RFC 3339 en UTC, con seis decimales.
Aceptación de SUNAT; nula si aún no se aceptó. Timestamp RFC 3339 en UTC, con seis decimales.
true si hay un envío con resultado desconocido y se está recuperando el CDR o el ticket. No reemitas mientras dure.
Valor de resumen de la firma del XML (DigestValue).
Texto del QR del comprobante, con sus campos separados por |.
PNG del QR como data URI. No aparece en el listado.
Enlaces de descarga.
object
Ruta del PDF.
Ruta del XML firmado.
Ruta del CDR; nula hasta que SUNAT responde, y en una boleta confirmada con una revisión manual de su resumen, que no tiene CDR.
En una nota de crédito o de débito, el documento que afecta; si no, nulo.
Motivo de la nota de crédito; nulo en los demás comprobantes.
object
Motivo de la nota.
Descripción libre del motivo.
Motivo de la nota de débito; nulo en los demás comprobantes.
object
Motivo de la nota.
Descripción libre del motivo.
Identificador del integrador; nulo si no se envió.
Documento rechazado que este reemplaza; nulo si no reemplaza a ninguno.
El objeto que envió el integrador; nulo si no envió ninguno.
Creación. Timestamp RFC 3339 en UTC, con seis decimales.
Última modificación. Timestamp RFC 3339 en UTC, con seis decimales.
Cursor de la página siguiente, para pasarlo en cursor; nulo en la última página.
Ejemplos
Una boleta
{ "data": [ { "id": "0192f1a2-7c3e-7d4b-9a8f-2b6c1d0e4f5a", "object": "document", "environment": "test", "company_id": "0192f0b1-2d4c-7a1e-8b3f-1c2d3e4f5a6b", "type": "boleta", "series": "B001", "number": 125, "full_number": "B001-125", "issue_date": "2026-10-09", "currency": "PEN", "customer": { "document_type": "dni", "document_number": "45678912", "name": "Juan Pérez", "address": null, "email": null }, "totals": { "taxable": 10.17, "exempt": 0, "unaffected": 0, "discount": 0, "igv": 1.83, "total": 12, "amount_in_words": "DOCE CON 00/100 SOLES" }, "status": "issued", "sunat_status": "pending", "delivery_status": "none", "sunat": { "response_code": null, "description": null, "notes": [], "deadline_at": "2026-10-17T04:59:59.000000Z", "submitted_at": null, "accepted_at": null, "reconciliation_required": false }, "hash": "2/tssig+2hIBSmZyIT0CWMhsTMnRKmApc0tdWRsDs4U=", "qr_text": "20100066603|03|B001|125|1.83|12.00|2026-10-09|1|45678912|2/tssig+2hIBSmZyIT0CWMhsTMnRKmApc0tdWRsDs4U=", "links": { "pdf": "/v1/documents/0192f1a2-7c3e-7d4b-9a8f-2b6c1d0e4f5a/pdf", "xml": "/v1/documents/0192f1a2-7c3e-7d4b-9a8f-2b6c1d0e4f5a/xml", "cdr": null }, "affected_document_id": null, "credit_note": null, "debit_note": null, "external_id": "venta-98231", "replaces_document_id": null, "metadata": { "placa": "ABC-123" }, "created_at": "2026-10-09T14:03:21.482913Z", "updated_at": "2026-10-09T14:03:21.482913Z" } ], "next_cursor": null}Cabeceras
Sección titulada «Cabeceras»El del cliente si tiene de 1 a 128 caracteres [A-Za-z0-9._-]; si no, uno generado. Es el request_id de los errores.
Solicitudes admitidas en la ventana de un minuto, de la clave o de la IP.
Solicitudes que quedan en la ventana.
Segundos hasta la ventana siguiente.
Solicitud mal formada. Códigos: invalid_cursor y bad_request, cuando un parámetro no tiene el formato de su tipo, como limit=abc. No se reintenta sin corregirla.
Formato único de los errores de la API.
object
El error principal.
object
Familia del error, como validation_error, conflict o unavailable.
Código estable, para programar contra él.
Mensaje en español, apto para mostrar a un operador. Puede cambiar: no se programa contra él.
Ruta del campo en el JSON, con índices entre corchetes, como items[2].unit_price. Solo cuando el error apunta a un campo.
Identificador de la solicitud, el mismo de X-Request-Id. Inclúyelo al escribir a soporte.
Documento con el que choca la solicitud. Solo en external_id_conflict y document_already_replaced.
Todos los problemas. Solo aparece cuando hay varios.
Uno de los problemas de la solicitud.
object
Código estable, para programar contra él.
Mensaje en español, apto para mostrar a un operador.
Ruta del campo en el JSON, si el error apunta a uno.
Ejemplos
invalid_cursor
{ "error": { "type": "bad_request", "code": "invalid_cursor", "message": "El cursor no es válido para este orden.", "param": "cursor", "request_id": "req_0192f1a27c3e7d4b9a8f2b6c1d0e4f5a" }}Cabeceras
Sección titulada «Cabeceras»El del cliente si tiene de 1 a 128 caracteres [A-Za-z0-9._-]; si no, uno generado. Es el request_id de los errores.
Solicitudes admitidas en la ventana de un minuto, de la clave o de la IP.
Solicitudes que quedan en la ventana.
Segundos hasta la ventana siguiente.
Sin una API key válida. Códigos: unauthorized, invalid_api_key, revoked_api_key, expired_api_key.
Formato único de los errores de la API.
object
El error principal.
object
Familia del error, como validation_error, conflict o unavailable.
Código estable, para programar contra él.
Mensaje en español, apto para mostrar a un operador. Puede cambiar: no se programa contra él.
Ruta del campo en el JSON, con índices entre corchetes, como items[2].unit_price. Solo cuando el error apunta a un campo.
Identificador de la solicitud, el mismo de X-Request-Id. Inclúyelo al escribir a soporte.
Documento con el que choca la solicitud. Solo en external_id_conflict y document_already_replaced.
Todos los problemas. Solo aparece cuando hay varios.
Uno de los problemas de la solicitud.
object
Código estable, para programar contra él.
Mensaje en español, apto para mostrar a un operador.
Ruta del campo en el JSON, si el error apunta a uno.
Ejemplos
invalid_api_key
{ "error": { "type": "unauthorized", "code": "invalid_api_key", "message": "La API key no es válida.", "request_id": "req_0192f1a27c3e7d4b9a8f2b6c1d0e4f5a" }}Cabeceras
Sección titulada «Cabeceras»El del cliente si tiene de 1 a 128 caracteres [A-Za-z0-9._-]; si no, uno generado. Es el request_id de los errores.
Solicitudes admitidas en la ventana de un minuto, de la clave o de la IP.
Solicitudes que quedan en la ventana.
Segundos hasta la ventana siguiente.
La clave no puede operar. Códigos: forbidden (no tiene el scope), tenant_suspended, plan_without_api (el plan de la cuenta no incluye la API), account_not_activated (emisión en live de una cuenta que Boletura todavía no activó).
Formato único de los errores de la API.
object
El error principal.
object
Familia del error, como validation_error, conflict o unavailable.
Código estable, para programar contra él.
Mensaje en español, apto para mostrar a un operador. Puede cambiar: no se programa contra él.
Ruta del campo en el JSON, con índices entre corchetes, como items[2].unit_price. Solo cuando el error apunta a un campo.
Identificador de la solicitud, el mismo de X-Request-Id. Inclúyelo al escribir a soporte.
Documento con el que choca la solicitud. Solo en external_id_conflict y document_already_replaced.
Todos los problemas. Solo aparece cuando hay varios.
Uno de los problemas de la solicitud.
object
Código estable, para programar contra él.
Mensaje en español, apto para mostrar a un operador.
Ruta del campo en el JSON, si el error apunta a uno.
Ejemplos
forbidden
{ "error": { "type": "forbidden", "code": "forbidden", "message": "La API key no tiene el scope documents:read que exige este endpoint.", "request_id": "req_0192f1a27c3e7d4b9a8f2b6c1d0e4f5a" }}Cabeceras
Sección titulada «Cabeceras»El del cliente si tiene de 1 a 128 caracteres [A-Za-z0-9._-]; si no, uno generado. Es el request_id de los errores.
Solicitudes admitidas en la ventana de un minuto, de la clave o de la IP.
Solicitudes que quedan en la ventana.
Segundos hasta la ventana siguiente.
Parámetros no válidos: error.param señala cuál y errors lista todos los problemas si hay varios. Códigos: filter_invalid, limit_invalid, field_invalid_characters.
Formato único de los errores de la API.
object
El error principal.
object
Familia del error, como validation_error, conflict o unavailable.
Código estable, para programar contra él.
Mensaje en español, apto para mostrar a un operador. Puede cambiar: no se programa contra él.
Ruta del campo en el JSON, con índices entre corchetes, como items[2].unit_price. Solo cuando el error apunta a un campo.
Identificador de la solicitud, el mismo de X-Request-Id. Inclúyelo al escribir a soporte.
Documento con el que choca la solicitud. Solo en external_id_conflict y document_already_replaced.
Todos los problemas. Solo aparece cuando hay varios.
Uno de los problemas de la solicitud.
object
Código estable, para programar contra él.
Mensaje en español, apto para mostrar a un operador.
Ruta del campo en el JSON, si el error apunta a uno.
Ejemplos
filter_invalid
{ "error": { "type": "validation_error", "code": "filter_invalid", "message": "El filtro admite: factura, boleta, nota_credito, nota_debito.", "param": "type", "request_id": "req_0192f1a27c3e7d4b9a8f2b6c1d0e4f5a" }}Cabeceras
Sección titulada «Cabeceras»El del cliente si tiene de 1 a 128 caracteres [A-Za-z0-9._-]; si no, uno generado. Es el request_id de los errores.
Solicitudes admitidas en la ventana de un minuto, de la clave o de la IP.
Solicitudes que quedan en la ventana.
Segundos hasta la ventana siguiente.
rate_limited: se superó el límite de 600 solicitudes por minuto por clave o 1200 por IP. Se reintenta después de Retry-After.
Formato único de los errores de la API.
object
El error principal.
object
Familia del error, como validation_error, conflict o unavailable.
Código estable, para programar contra él.
Mensaje en español, apto para mostrar a un operador. Puede cambiar: no se programa contra él.
Ruta del campo en el JSON, con índices entre corchetes, como items[2].unit_price. Solo cuando el error apunta a un campo.
Identificador de la solicitud, el mismo de X-Request-Id. Inclúyelo al escribir a soporte.
Documento con el que choca la solicitud. Solo en external_id_conflict y document_already_replaced.
Todos los problemas. Solo aparece cuando hay varios.
Uno de los problemas de la solicitud.
object
Código estable, para programar contra él.
Mensaje en español, apto para mostrar a un operador.
Ruta del campo en el JSON, si el error apunta a uno.
Ejemplos
rate_limited
{ "error": { "type": "rate_limited", "code": "rate_limited", "message": "Demasiadas solicitudes. Reintente después de los segundos que indica Retry-After.", "request_id": "req_0192f1a27c3e7d4b9a8f2b6c1d0e4f5a" }}Cabeceras
Sección titulada «Cabeceras»El del cliente si tiene de 1 a 128 caracteres [A-Za-z0-9._-]; si no, uno generado. Es el request_id de los errores.
Solicitudes admitidas en la ventana de un minuto, de la clave o de la IP.
Solicitudes que quedan en la ventana.
Segundos hasta la ventana siguiente.
Segundos que conviene esperar antes de reintentar.
Falla transitoria, como database_unavailable o storage_unavailable. Se reintenta con una espera creciente.
Formato único de los errores de la API.
object
El error principal.
object
Familia del error, como validation_error, conflict o unavailable.
Código estable, para programar contra él.
Mensaje en español, apto para mostrar a un operador. Puede cambiar: no se programa contra él.
Ruta del campo en el JSON, con índices entre corchetes, como items[2].unit_price. Solo cuando el error apunta a un campo.
Identificador de la solicitud, el mismo de X-Request-Id. Inclúyelo al escribir a soporte.
Documento con el que choca la solicitud. Solo en external_id_conflict y document_already_replaced.
Todos los problemas. Solo aparece cuando hay varios.
Uno de los problemas de la solicitud.
object
Código estable, para programar contra él.
Mensaje en español, apto para mostrar a un operador.
Ruta del campo en el JSON, si el error apunta a uno.
Ejemplos
database_unavailable
{ "error": { "type": "unavailable", "code": "database_unavailable", "message": "La base de datos no está disponible. Reintente en unos segundos.", "request_id": "req_0192f1a27c3e7d4b9a8f2b6c1d0e4f5a" }}Cabeceras
Sección titulada «Cabeceras»El del cliente si tiene de 1 a 128 caracteres [A-Za-z0-9._-]; si no, uno generado. Es el request_id de los errores.
Solicitudes admitidas en la ventana de un minuto, de la clave o de la IP.
Solicitudes que quedan en la ventana.
Segundos hasta la ventana siguiente.