ODYM Factura API v1
Menú
Documentación pública · REST

Integra tu sistema con ODYM API v1

Emite comprobantes electrónicos, consulta el resultado fiscal y descarga PDF, XML y CDR desde el backend de tu POS, ERP o ecommerce.

JSON sobre HTTPS Sandbox y producción Procesamiento asíncrono
crear-emision.sh
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
URL base https://odymfactura.com/api/v1
Flujo recomendado

De tu primera clave al comprobante

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.

Crea una clave

Empieza con una clave odym_test_ y los permisos mínimos.

Valida la empresa

Consulta GET /company antes de habilitar la emisión.

Envía el documento

Registra una submission con una clave de idempotencia estable.

Consulta el estado

Haz polling sobre el mismo ID hasta recibir un resultado fiscal.

Descarga archivos

Obtén PDF, XML y CDR desde el backend con la misma clave.

La respuesta 202 no es una aceptación de SUNAT.

Confirma el resultado consultando la submission. Nunca crees otra emisión por una demora de procesamiento, descarga o correo.

Seguridad

Autenticación y ambientes

Envía la API key como Bearer token. Cada RUC y cada ambiente debe usar una clave independiente.

HTTP
Authorization: Bearer odym_test_REEMPLAZAR
Accept: application/json
X-Request-ID: erp-operacion-000001
company:read

Consulta RUC, plan, ambiente, capacidades y series configuradas.

submissions:write

Registra solicitudes de emisión de comprobantes electrónicos.

submissions:read

Consulta estados y descarga los artefactos autorizados.

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.

Referencia

Endpoints principales

Todos los recursos están aislados por cuenta, empresa, API key y ambiente.

GET/companyPreflight de la empresa autenticada

Devuelve el RUC, régimen tributario, plan, cupo, conexión fiscal, preparación de producción, series configuradas y capacidades de entrega.

company:read200401 · 403 · 429
POST/submissionsRegistrar una solicitud de emisión

Valida el sobre v1, reserva la numeración de ODYM cuando corresponde y almacena la solicitud para su procesamiento asíncrono.

submissions:writeIdempotency-Key obligatorio202
GET/submissions/{submission}Consultar estado y artefactos

Retorna el estado fiscal, número asignado, referencias del proveedor, siguiente consulta recomendada y archivos disponibles.

submissions:read200404 para recursos ajenos
GET/submissions/{submission}/artifacts/{artifact}Descargar PDF, XML o CDR

Descarga privada y auditada. Los valores admitidos para {artifact} son pdf, xml y cdr.

submissions:readprivate, no-store404 si aún no está disponible
Ejemplo completo

Emitir una factura

Usa numbering_mode: "odym" para que ODYM asigne la serie fiscal configurada y reserve el correlativo de forma segura.

POST /submissions · JSON
{
  "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"
    }
  }
}

Respuesta inicial

202 Accepted
{
  "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"
  }
}

Tipos documentales admitidos

invoiceFactura electrónica
receiptBoleta de venta
credit_noteNota de crédito
debit_noteNota de débito
despatchGuía de remisión
retentionComprobante de retención
perceptionComprobante de percepción
summaryResumen diario
voidedComunicación de baja
reversionReversión

Los campos específicos de notas, guías, retenciones, percepciones y lotes están definidos en la especificación OpenAPI oficial.

Operación segura

Idempotencia sin duplicados

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ónResultadoAcción
Misma clave + mismo cuerpoIdempotency-Replayed: trueUsar la respuesta recuperada.
Misma clave + otro cuerpo409 idempotency_conflictCorregir el cliente; no cambies el cuerpo bajo esa clave.
Primera solicitud en proceso409 request_in_progressEsperar el tiempo indicado y repetir exactamente la solicitud.
external_id ya utilizado409 duplicate_external_idReconciliar con details.submission_id.
Procesamiento asíncrono

Estados, polling y artefactos

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 / processing

Espera. No vuelvas a emitir.

accepted / observed

Descarga y verifica los archivos.

pending_confirmation

Conciliación en curso. No reenvíes.

rejected / failed

No entregues el comprobante; registra el detalle.

Descarga autenticada
curl "https://odymfactura.com/api/v1/submissions/{submission_id}/artifacts/pdf" \
  --header "Authorization: Bearer $ODYM_API_KEY" \
  --output comprobante.pdf
Los enlaces de descarga son privados.

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.

Para integradores

Conexión automática

Un sistema externo puede autenticar al usuario de ODYM, listar sus empresas y generar una API key sin pedirle que copie el secreto manualmente.

POST/integrations/external/loginIniciar sesión temporal de integración

Recibe email, password y, cuando corresponde, two_factor_code. La sesión temporal debe mantenerse en el backend.

Sin API key2FA compatible200
GET/integrations/external/companiesListar empresas autorizadas

Devuelve las empresas activas, capacidad del plan, bloqueos productivos, conexión fiscal y preparación de numeración.

Sesión externa200
GET/integrations/external/companies/{ruc}Actualizar el preflight de una empresa

Consulta las capacidades y bloqueos actuales sin ampliar el alcance de empresas autorizado para la sesión.

Sesión externa200 · 404
POST/integrations/external/companies/{ruc}/connectCrear la clave automática

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.

Sesión externa201Secreto de una sola lectura
POST/integrations/external/logoutRevocar la sesión temporal

Cierra explícitamente la sesión de conexión cuando el flujo termina o se cancela.

Sesión externa200
Respuestas consistentes

Manejo de errores

Todas las respuestas de error incluyen un código estable, un mensaje y el request_id para trazabilidad.

Error JSON
{
  "error": {
    "code": "validation_failed",
    "message": "La solicitud no cumple el contrato de ODYM API v1.",
    "details": { "fields": {} }
  },
  "meta": { "request_id": "erp-operacion-000001" }
}
HTTPCódigoQué hacer
401missing_api_key, invalid_api_keyRevisar o rotar el secreto.
403missing_ability, api_access_disabledRevisar permisos, empresa y plan.
409idempotency_conflict, duplicate_external_idReconciliar; no crear otra emisión automáticamente.
413payload_too_largeReducir el cuerpo de la solicitud.
422validation_failed, document_validation_failedCorregir el sobre o los campos fiscales indicados.
422numbering_not_configured, numbering_mode_conflictRevisar modo, series y ambiente.
429rate_limit_exceededEsperar el valor de Retry-After.
500–599Error temporalRepetir el mismo POST con igual idempotencia y cuerpo.
Checklist

Antes de pasar a producción

Completa el piloto en sandbox y conserva evidencia técnica sin guardar API keys ni documentos completos en logs.

  1. GET /company confirma el RUC esperado y el ambiente sandbox.
  2. Una boleta y una factura válidas terminan en accepted u observed.
  3. PDF y XML se descargan desde el backend y coinciden con sus hashes.
  4. Repetir un POST con la misma idempotencia no crea otro documento.
  5. Un total incorrecto responde 422 y no genera una emisión.
  6. Una falla de descarga o correo reintenta solo esa entrega.
  7. La clave odym_live_ tiene permisos mínimos y está guardada como secreto.
  8. La empresa está habilitada, su numeración está lista y las series productivas son correctas.

Empieza tu integración en sandbox

Crea una clave de prueba, valida el preflight de la empresa y realiza tu primera emisión controlada.

Ingresar a ODYM