Crea una clave
Empieza con una clave odym_test_ y los permisos mínimos.
Emite comprobantes electrónicos, consulta el resultado fiscal y descarga PDF, XML y CDR desde el backend de tu POS, ERP o ecommerce.
curl --request POST \ https://odymfactura.com/api/v1/submissions \ --header 'Authorization: Bearer $ODYM_API_KEY' \ --header 'Idempotency-Key: venta-9851-v1' \ --header 'Content-Type: application/json' \ --data '@comprobante.json' HTTP/1.1 202 Accepted
La integración se ejecuta siempre desde tu backend. ODYM valida, numera y procesa el documento sin exponer credenciales de SUNAT ni del proveedor fiscal.
Empieza con una clave odym_test_ y los permisos mínimos.
Consulta GET /company antes de habilitar la emisión.
Registra una submission con una clave de idempotencia estable.
Haz polling sobre el mismo ID hasta recibir un resultado fiscal.
Obtén PDF, XML y CDR desde el backend con la misma clave.
Confirma el resultado consultando la submission. Nunca crees otra emisión por una demora de procesamiento, descarga o correo.
Envía la API key como Bearer token. Cada RUC y cada ambiente debe usar una clave independiente.
Authorization: Bearer odym_test_REEMPLAZAR Accept: application/json X-Request-ID: erp-operacion-000001
odym_test_ opera en sandbox. odym_live_ realiza emisiones reales en producción. La clave nunca debe llegar al navegador, una app móvil o un repositorio.
Todos los recursos están aislados por cuenta, empresa, API key y ambiente.
Devuelve el RUC, régimen tributario, plan, cupo, conexión fiscal, preparación de producción, series configuradas y capacidades de entrega.
Valida el sobre v1, reserva la numeración de ODYM cuando corresponde y almacena la solicitud para su procesamiento asíncrono.
Retorna el estado fiscal, número asignado, referencias del proveedor, siguiente consulta recomendada y archivos disponibles.
Descarga privada y auditada. Los valores admitidos para {artifact} son pdf, xml y cdr.
Usa numbering_mode: "odym" para que ODYM asigne la serie fiscal configurada y reserve el correlativo de forma segura.
{
"schema_version": "1.0",
"numbering_mode": "odym",
"document_type": "invoice",
"external_id": "ERP-FACTURA-12345",
"document": {
"issue_date": "2026-09-10",
"currency": "PEN",
"operation_type": "0101",
"customer": {
"document_type": "6",
"document_number": "20100070970",
"legal_name": "CLIENTE EMPRESA S.A.C."
},
"payment": { "type": "cash" },
"items": [{
"code": "SERV-001",
"description": "Servicio de consultoría",
"unit_code": "ZZ",
"quantity": "1",
"unit_value": "100.000000",
"line_value": "100.00",
"tax": { "category": "taxable", "rate": "18", "amount": "18.00" },
"icbper_amount": "0.00",
"line_total": "118.00"
}],
"totals": {
"taxable": "100.00", "exempt": "0.00", "unaffected": "0.00",
"export": "0.00", "free": "0.00", "igv": "18.00",
"icbper": "0.00", "total": "118.00"
}
}
}
{
"data": {
"submission_id": "01K4EXAMPLE7R4YQ9C2D6J8M",
"external_id": "ERP-FACTURA-12345",
"document_type": "invoice",
"environment": "sandbox",
"status": "queued",
"operational_status": "queued",
"requires_reconciliation": false,
"document_number": {
"managed_by": "odym",
"series": "F001",
"correlative": "25",
"formatted": "F001-00000025"
},
"artifacts": []
},
"meta": {
"request_id": "erp-operacion-000001",
"api_version": "v1"
}
}
invoiceFactura electrónicareceiptBoleta de ventacredit_noteNota de créditodebit_noteNota de débitodespatchGuía de remisiónretentionComprobante de retenciónperceptionComprobante de percepciónsummaryResumen diariovoidedComunicación de bajareversionReversiónLos campos específicos de notas, guías, retenciones, percepciones y lotes están definidos en la especificación OpenAPI oficial.
Cada POST /submissions requiere un Idempotency-Key de 8 a 128 caracteres. Reutiliza la misma clave y el mismo cuerpo cuando no sepas si recibiste la respuesta.
| Situación | Resultado | Acción |
|---|---|---|
| Misma clave + mismo cuerpo | Idempotency-Replayed: true | Usar la respuesta recuperada. |
| Misma clave + otro cuerpo | 409 idempotency_conflict | Corregir el cliente; no cambies el cuerpo bajo esa clave. |
| Primera solicitud en proceso | 409 request_in_progress | Esperar el tiempo indicado y repetir exactamente la solicitud. |
external_id ya utilizado | 409 duplicate_external_id | Reconciliar con details.submission_id. |
Consulta el mismo submission_id. Un intervalo sugerido es 2 s, 3 s, 5 s, 8 s, 13 s y luego cada 30 s, respetando siempre Retry-After y next_check_at.
Si hay un fallo, failure_diagnosis informa el código, el motivo original y la siguiente acción. automatic y next_attempt_at indican la recuperación programada; requires_action señala cuándo debes revisar datos o configuración. ODYM puede sincronizar el token automáticamente, pero conserva los datos fiscales y el motivo de un CDR rechazado.
queued / processingEspera. No vuelvas a emitir.
accepted / observedDescarga y verifica los archivos.
pending_confirmationConciliación en curso. No reenvíes.
rejected / failedNo entregues el comprobante; registra el detalle.
curl "https://odymfactura.com/api/v1/submissions/{submission_id}/artifacts/pdf" \
--header "Authorization: Bearer $ODYM_API_KEY" \
--output comprobante.pdf
Descarga desde tu backend, verifica sha256 y tamaño, y no envíes el download_url al cliente final. Una falla de correo o descarga nunca justifica otra emisión.
Un sistema externo puede autenticar al usuario de ODYM, listar sus empresas y generar una API key sin pedirle que copie el secreto manualmente.
Recibe email, password y, cuando corresponde, two_factor_code. La sesión temporal debe mantenerse en el backend.
Devuelve las empresas activas, capacidad del plan, bloqueos productivos, conexión fiscal y preparación de numeración.
Consulta las capacidades y bloqueos actuales sin ampliar el alcance de empresas autorizado para la sesión.
Recibe un client_id estable para identificar al sistema integrador. ODYM elige el ambiente recomendado; la nueva API key se muestra una sola vez y debe guardarse de inmediato en un almacén de secretos.
Cierra explícitamente la sesión de conexión cuando el flujo termina o se cancela.
Todas las respuestas de error incluyen un código estable, un mensaje y el request_id para trazabilidad.
{
"error": {
"code": "validation_failed",
"message": "La solicitud no cumple el contrato de ODYM API v1.",
"details": { "fields": {} }
},
"meta": { "request_id": "erp-operacion-000001" }
}
| HTTP | Código | Qué hacer |
|---|---|---|
| 401 | missing_api_key, invalid_api_key | Revisar o rotar el secreto. |
| 403 | missing_ability, api_access_disabled | Revisar permisos, empresa y plan. |
| 409 | idempotency_conflict, duplicate_external_id | Reconciliar; no crear otra emisión automáticamente. |
| 413 | payload_too_large | Reducir el cuerpo de la solicitud. |
| 422 | validation_failed, document_validation_failed | Corregir el sobre o los campos fiscales indicados. |
| 422 | numbering_not_configured, numbering_mode_conflict | Revisar modo, series y ambiente. |
| 429 | rate_limit_exceeded | Esperar el valor de Retry-After. |
| 500–599 | Error temporal | Repetir el mismo POST con igual idempotencia y cuerpo. |
Completa el piloto en sandbox y conserva evidencia técnica sin guardar API keys ni documentos completos en logs.
GET /company confirma el RUC esperado y el ambiente sandbox.accepted u observed.odym_live_ tiene permisos mínimos y está guardada como secreto.Crea una clave de prueba, valida el preflight de la empresa y realiza tu primera emisión controlada.