All True Detection

RECURSOS PARA INTEGRADORES

API de All True Detection

Solicitudes, seguimiento, facturación y entregas. Un contrato común con el portal de servicios.

Su integración no entrega resultados antes de tiempo. Pago completo, trabajo terminado y publicación explícita se verifican en el servidor en cada consulta y descarga.

Integrar con All True Detection

La API v1 permite crear solicitudes de servicios, adjuntar documentos escritos, seguir casos, conversar con ATD, consultar facturas y recuperar entregas publicadas. La cuenta de cliente define el perímetro de datos. Solo los partners expresamente autorizados pueden iniciar identidad Didit a crédito y recibir automáticamente su conclusión técnica. La API no permite confirmar pagos ni publicar informes de otros servicios.

Entornos y contrato

Base de producción: https://SU_DOMINIO/api/v1. Base local predeterminada: http://127.0.0.1:8000/api/v1. En producción se exige HTTPS; HTTP devuelve 426. Registre por separado los tokens, endpoints y secretos de cada instalación. No mezcle datos o credenciales de pruebas con producción.

La versión de protocolo está en /v1; el contrato OpenAPI 3.0.3 describe rutas, parámetros y esquemas. Los identificadores de negocio son ULID opacos, nunca credenciales. Fechas de API en ISO 8601 UTC y vencimientos como YYYY-MM-DD. Dinero en unidades menores enteras: 1050 equivale a 10.50 de la moneda indicada. No use flotantes para conciliar importes.

Contrato 1.9.0 incorpora la entrevista remota con IA y su conclusión de revisión humana. La versión 1.8.0 desglosa las modalidades por persona en las partidas de factura y conserva sus importes y nombres al emitir. Los cuerpos de creación conservan service_code y people[].service_options. La versión 1.7.0 añadió categorías/modalidades del catálogo, credenciales de alguaciles, identificación de la cuenta cliente, filtros de solicitudes e instrucciones bancarias por factura. Conserva las garantías de 1.6.2: el enlace de captura requiere identity:read incluso al repetir POST y una consulta vinculada confirmada al proveedor. Una actualización de identidad pendiente de confirmar retiene el resultado anterior (409), también en las verificaciones recurrentes dependientes. No cambian rutas ni cuerpos de solicitud.

El límite general es de 60 peticiones/minuto por usuario y 600/minuto por IP antes de autenticar. Además, las cargas de documentos admiten 10 intentos/minuto y las operaciones costosas de identidad (iniciar sesión, registrar referencia o crear reverificación) comparten otra cuota de 10 intentos/minuto por usuario. Estos dos contadores son independientes; usan el mismo usuario aunque se rote el token. Los intentos con validación fallida también cuentan. Los cupos diarios de sesiones Didit por cuenta/global siguen aplicándose aparte. Ante 429 respete Retry-After; no cree otra clave idempotente para evadir el bloqueo.

Autenticación y permisos

Cree un usuario cliente eligiendo account_type=individual o business (empresa requiere nombre comercial), confirme su email e ingrese al portal. Las cuentas anteriores y los registros por Google sin clasificación deben confirmarla en Mi cuenta antes de crear solicitudes nuevas; una cuenta sin tipo recibe 422 con error account_type al crear por API. Elegir empresa no concede permisos de personal ni crédito. customer_account en solicitudes identifica la cuenta real y su tipo; estos valores son asignados por el servidor, no se aceptan como selección de otro cliente desde el JSON. Las facturas conservan recipient.account_type como instantánea al emitir; puede faltar en facturas anteriores. En Integraciones API puede emitir tokens temporales de 1 a 90 días (opción predeterminada), o elegir explícitamente un token persistente para una automatización servidor a servidor. Este último tiene expires_at=null, no caduca por fecha y no necesita renovación automática. No se amplía la vigencia de tokens existentes. Todos mantienen scopes mínimos y revocación inmediata; se exige confirmación reciente de identidad al emitir o revocar. Cada usuario admite hasta 10 tokens; el token completo se muestra una sola vez y el servidor conserva su hash.

Un token persistente robado también conserva su validez hasta revocarlo. Guárdelo exclusivamente en un gestor de secretos del backend, nunca en una app distribuida, navegador, URL o repositorio. Revise su último uso, rote la credencial según su política operativa y revóquela ante cualquier sospecha. Para rotar sin interrumpir trabajo: emita otro token con los mismos scopes, actualice su aplicación, compruebe una llamada y revoque el anterior. Cambiar/restablecer contraseña, desactivar la cuenta o cambiar sus permisos sigue invalidando el acceso; la integración debe manejar 401/403 y alertar al responsable, no reintentar indefinidamente.

Envíe Authorization: Bearer TOKEN en cada llamada. No se aceptan tokens en la URL ni sesiones web como sustituto. No existe un token administrativo de API. Un usuario desactivado, un token revocado/vencido o un cambio de acceso revocado deja de autorizar solicitudes. Cambiar/restablecer contraseña o modificar roles revoca tokens. Cada recurso comprueba pertenencia a cuenta, además del scope.

Permiso Uso
orders:read Catálogo, solicitudes y documentos aportados por el cliente.
orders:write Crear solicitudes y subir documentos a casos abiertos.
results:read Manifiestos, resultados y descargas después de pago y publicación.
invoices:read Facturas, pagos ya registrados, vencimientos y saldos.
messages:read Conversación de una solicitud.
messages:write Enviar seguimiento a una solicitud.
identity:verify Iniciar sesiones Didit a crédito; requiere aprobación comercial vigente de la cuenta.
identity:read Consultar enlace, estado y conclusión técnica de esas sesiones; requiere la misma aprobación vigente.

Los permisos de identidad no se emiten para cuentas sin aprobación y no sustituyen la comprobación de autorización por cuenta en cada llamada. Un token anterior con orders:write ya no autoriza estos endpoints: tras la aprobación, emita uno con los permisos específicos. Suspender el acceso bloquea también los tokens existentes. Los usuarios de una cuenta comercial comparten su autorización y cupo; no se concede acceso global al registrarse.

identity:verify permite iniciar o repetir una operación, pero no exportar su enlace privado: sin identity:read, incluso el POST devuelve verification_url=null. La consulta del enlace necesita siempre ese permiso de lectura.

En la vinculación documental solo se normalizan los guiones de una cédula con formato válido; letras, signos o puntuación arbitraria no se descartan para fabricar una coincidencia.

Si hay una actualización del proveedor pendiente de confirmar, ATD retiene la conclusión anterior: el resultado técnico responde 409 hasta reconciliar. Esto se aplica también a resultados recurrentes dependientes y a entregas web publicadas con identidad. Una caída al consultar Didit no permite seguir entregando una aprobación conocida como pendiente de reconfirmación; tampoco reescribe una comprobación histórica como una captura nueva.

Guardar el token en un gestor de secretos del backend. No colocarlo en JavaScript público, repositorios, logs o herramientas de analítica. Una integración servidor a servidor no necesita CORS. Para un consumidor de navegador, ATD debe autorizar orígenes exactos; no se habilitan cookies ni comodines de origen. Se recomienda un backend propio para no exponer credenciales a los usuarios del navegador.

Catálogo y modalidades

Familia Servicios activos (code)
Evaluaciones a personas Servicios poligráficos (polygraph), evaluaciones de perfiles (profile-verification), antidoping (drug-screening), psicometría (psychometric) y entrevista remota con IA (remote-interview-rppg).
Verificación de personas Visitas domiciliarias (home-visits), exequátur de abogados y notarios (exequatur), credenciales de alguaciles (bailiff-credentials), identidad (identity-verification), título universitario (university-degree).
Capacitación y equipos training-equipment, único servicio sin ficha por persona.

GET /services devuelve los servicios activos. Las modalidades de poligrafía y perfiles se indican en people[].service_options; cada modalidad puede tener su tarifa administrada por ATD. items[].service_code mantiene el código de la familia y su cantidad total. Las sustancias del antidoping se coordinan según requerimiento. deception-detection, applied-ai e investigations ya no se ofrecen de forma independiente ni se aceptan en solicitudes nuevas; sus órdenes, documentos, facturas y entregas históricas siguen accesibles con sus permisos habituales. Consulte el catálogo en vez de fijar una lista de códigos en su integración.

Crear una solicitud

Primero consulte GET /services para obtener los códigos activos y sus requisitos: category, category_name, options, per_person, requires_identity_number y required_evidence. Los precios administrativos no se publican en este catálogo. Luego envíe POST /orders con JSON, consentimiento e Idempotency-Key. details es opcional: se admite omitirlo, enviarlo como null o usar un texto de hasta 10.000 caracteres, sin longitud mínima.

{"subject":"Consulta de capacitación","external_reference":"RRHH-2026-001","consent":true,"items":[{"service_code":"training-equipment","quantity":1}]}

La clave debe contener entre 8 y 128 caracteres ASCII alfanuméricos o ._:-. Se aísla por usuario y se conserva durante la vida de la solicitud. Reutilice la misma clave y el mismo contenido tras timeout o error de red: recibirá la misma orden (201), sin crear una segunda. Reutilizar la clave con otros datos produce 409. Cree una clave nueva para otra solicitud de negocio. No genere claves nuevas indiscriminadamente al reintentar.

Cuenta, rol, precio, asignación y estado se determinan en el servidor. La referencia externa facilita conciliar su sistema; no es una clave de idempotencia ni se impone como única. Se aceptan hasta 12 servicios distintos y cantidades enteras entre 1 y 100. El consentimiento debe representar autorización real para tratar la información aportada.

Ejemplo para CMD de Windows, en una sola línea. Sustituya SU_TOKEN antes de ejecutarlo:

curl.exe --request POST "http://127.0.0.1:8000/api/v1/orders" --header "Authorization: Bearer SU_TOKEN" --header "Content-Type: application/json" --header "Idempotency-Key: solicitud-rrhh-2026-001" --data "{\"subject\":\"Consulta de capacitacion\",\"external_reference\":\"RRHH-2026-001\",\"consent\":true,\"items\":[{\"service_code\":\"training-equipment\",\"quantity\":1}]}"

Verificaciones por persona

Todos los servicios son por persona salvo training-equipment (Capacitación y Equipos). El portal y la API comparten el formato people: entre 1 y 10 fichas por orden, con una o varias entradas service_codes por persona. Cada servicio asignado debe figurar también en items; su quantity debe coincidir exactamente con el número de personas que lo reciben. Una misma persona puede combinar varios servicios sin duplicar su ficha. La orden, conversación y factura son únicas; las partidas facturan la cantidad correspondiente a cada servicio.

No existe un registro global de personas ni búsqueda de cédulas entre cuentas. ATD genera un identificador público por ficha al crear la orden; no acepte ni envíe identificadores internos de base de datos. Dos fichas con la misma cédula normalizada se rechazan: combine sus servicios en una sola ficha. Si un servicio no necesita cédula, no aporte este dato; el servidor lo rechaza.

Compatibilidad: person sigue disponible para una sola persona con título, exequátur o identidad, cantidad 1; no se combina con people. La creación API anterior sin ficha se conserva para los servicios existentes que ya la admitían. remote-interview-rppg requiere people desde su incorporación. Las integraciones nuevas deben usar people para servicios personales. Las solicitudes históricas conservan sus datos y requisitos de evidencia; no se inventan personas para órdenes antiguas.

Campo de cada entrada de people Requisito
first_name, last_name Obligatorios, hasta 100 caracteres cada uno.
service_codes Lista no vacía, sin códigos repetidos; servicios de esta orden, nunca training-equipment.
identity_number Obligatoria solo para título, exequátur, identidad o credenciales de alguacil. Cédula dominicana de 11 dígitos con o sin guiones; se guarda normalizada. El formato no acredita autenticidad. Prohibida en los demás servicios.
address Obligatoria para título, exequátur, identidad y visitas domiciliarias; opcional para los demás, hasta 1.000 caracteres.
purpose Finalidad autorizada obligatoria para título, exequátur, identidad y credenciales de alguacil, 5-1.000 caracteres; opcional en los otros servicios. No sustituye a details, que sigue siendo opcional.
authorization_confirmed Debe ser true y representar autorización real de la persona.
birth_date, phone, email Opcionales; fecha YYYY-MM-DD no futura.
degree.institution, degree.degree_name Obligatorios solo para título universitario.
degree.graduation_year, degree.registration_number Opcionales; año no futuro.
exequatur.profession Obligatorio solo para exequátur.
exequatur.number, exequatur.issuing_authority, exequatur.issued_on Opcionales; fecha no futura.
bailiff.credential_number, bailiff.issuing_authority, bailiff.jurisdiction Opcionales, solo para bailiff-credentials; no sustituyen la credencial escaneada obligatoria.
service_options Modalidad opcional por persona: polygraph admite pre_employment, routine, specific; profile-verification admite basic, routine, management, investigative. Solo claves de servicios elegidos. Omitir significa definirla con ATD.

Entrevista remota con IA

Incluya remote-interview-rppg en items y en los service_codes de cada participante. Para este servicio bastan nombre, apellidos y confirmación de autorización en cada ficha. El catálogo devuelve per_person=true, requires_identity_number=false, required_evidence=[] e identity_mode=null. ATD coordina la sesión y el consentimiento informado de cada participante por separado. Las grabaciones y lecturas de pulso pertenecen a esa sesión. Use los endpoints ordinarios de solicitudes, facturas y entregas; los endpoints Didit se reservan para identity-verification.

{
  "subject": "Entrevistas remotas de ejemplo",
  "consent": true,
  "items": [{"service_code": "remote-interview-rppg", "quantity": 2}],
  "people": [
    {"first_name": "Primera", "last_name": "Persona", "authorization_confirmed": true, "service_codes": ["remote-interview-rppg"]},
    {"first_name": "Segunda", "last_name": "Persona", "authorization_confirmed": true, "service_codes": ["remote-interview-rppg"]}
  ]
}

Ejemplo de verificación documental

Ejemplo completamente ficticio (la cédula es solo un marcador de pruebas):

{
  "subject": "Verificación de credenciales",
  "consent": true,
  "items": [
    {
      "service_code": "university-degree",
      "quantity": 1
    },
    {
      "service_code": "exequatur",
      "quantity": 1
    },
    {
      "service_code": "psychometric",
      "quantity": 1
    }
  ],
  "people": [{
    "service_codes": ["university-degree", "exequatur"],
    "first_name": "Persona",
    "last_name": "Ficticia",
    "identity_number": "00000000000",
    "address": "Dirección ficticia",
    "purpose": "Verificación autorizada de credenciales",
    "authorization_confirmed": true,
    "degree": {
      "institution": "Institución ficticia",
      "degree_name": "Título de prueba"
    },
    "exequatur": {
      "profession": "Profesión de prueba"
    }
  }, {
    "first_name": "Otra persona",
    "last_name": "Ficticia",
    "service_codes": ["psychometric"],
    "authorization_confirmed": true
  }]
}

La creación devuelve people[].id. Después suba cada evidencia a /orders/{order}/attachments mediante file, purpose y person_id de la ficha correspondiente. Si hay varias personas, person_id es obligatorio para evidencia clasificada. Con una sola persona se puede inferir por compatibilidad. Un identificador de otra orden devuelve 404, aunque ambas órdenes pertenezcan a la misma cuenta.

  • bailiff_credential: credencial de alguacil escaneada o fotografiada, obligatoria para bailiff-credentials; PDF, JPG, PNG o WebP. Requiere cédula escrita y finalidad, sin exigir foto de cédula ni dirección para este servicio.
  • identity_front: frente de la cédula, obligatorio para título/exequátur; una copia sirve para ambos. PDF, JPG, PNG o WebP, escaneada o fotografiada.
  • identity_back: reverso opcional, en los mismos formatos.
  • degree_document: título universitario escaneado en PDF o fotografiado, obligatorio para university-degree.
  • exequatur_document: exequátur escaneado en PDF o fotografiado, obligatorio para exequatur.
  • selfie: selfie frontal obligatoria para identidad manual. En modo Didit se captura directamente con el proveedor. Solo JPG, PNG o WebP; no se aceptan PDF/Word como selfie.
  • selfie_extra: segunda selfie opcional, solo para identidad.
  • supporting: autorizaciones y otros documentos de apoyo; no sustituye al título, exequátur, cédula ni selfie obligatorios. Puede ser general o vincularse a una persona. Admite DOCX además de PDF e imágenes.
curl.exe --request POST "http://127.0.0.1:8000/api/v1/orders/ID_ORDEN/attachments" --header "Authorization: Bearer SU_TOKEN" --header "Idempotency-Key: cedula-frente-001" --form "person_id=ID_PERSONA_DEVUELTO_POR_ATD" --form "purpose=identity_front" --form "file=@C:/ruta/cedula-frente.jpg"

GET /orders/{order} devuelve people y verification con method=manual o mixed_or_didit, ready_for_review, required, missing y el desglose por person_id en verification.people, con su método e indicador operativo identity_pending. person es el perfil anterior si existe una sola persona; con varias es null. El listado general omite fichas y estado documental para no exportar datos personales en bloque. ready_for_review solo indica documentación completa: NO significa identidad verificada ni que Didit haya terminado. No se cotiza ni se inicia la revisión/trabajo con evidencia obligatoria pendiente.

La clave idempotente protege el orden de las personas, sus datos y las asignaciones de servicios/documentos. Un reintento debe conservar el orden de people y el contenido original. Cambiar la persona, el contenido o la categoría de un documento con la misma clave devuelve 409. Una clave nueva no permite duplicar un archivo ya guardado: el contenido repetido se rechaza con 422, incluso si cambia el nombre. La comprobación compara bytes (SHA-256), no garantiza detectar recortes o imágenes reexportadas, ni prueba que una foto corresponda realmente al frente/reverso. La revisión humana sigue siendo necesaria.

El portal permite adjuntar evidencia al crear la orden, de forma atómica, con el límite conjunto de 20 archivos/20 MB entre todas las personas, incluidos documentos de apoyo. Si no caben los documentos obligatorios, divida las personas en solicitudes más pequeñas. La API conserva el flujo JSON + cargas individuales. Los límites, antivirus, almacenamiento privado, scopes y aislamiento existentes se aplican a todos los documentos. Una única copia PDF con ambas caras de la cédula puede aportarse como identity_front; no vuelva a cargar el mismo PDF como reverso.

ATD registra una conclusión por persona y servicio con notas. Para la entrevista remota, reviewed identifica una evaluación revisada por un analista e inconclusive un resultado sin conclusión suficiente. Los demás servicios conservan verified, not_verified o inconclusive. Los servicios manuales requieren criterio profesional; identidad Didit incorpora la comprobación del proveedor. No es una decisión automática de contratación ni una validación por acceso a registros oficiales. Después de pago total, finalización y publicación, /deliveries devuelve verification_findings con method=manual, didit o mixed, reviewed_at y checks[] (person_id, service_code, outcome, notes). Las comprobaciones Didit incluyen su referencia ATD y environment; sandbox no es una verificación real y no se publica en producción. Las entregas antiguas pueden no incluir person_id. No se filtra esa conclusión por estado, notificaciones, listados ni webhooks antes de la entrega ATD.

Las fichas y conclusiones se cifran en la base de datos. La huella de idempotencia de solicitudes con persona usa HMAC con una clave del servidor, no un hash simple de los datos personales. No use nombres/cédulas en asunto, referencia externa, nombres de archivos, claves de idempotencia, URLs o logs. Use referencias opacas. No envíe fotos en base64 dentro del JSON ni por correo. Aplique en su sistema acceso mínimo, cifrado y retención definida para estos datos sensibles. Las órdenes anteriores sin ficha siguen operando; no se inventan ni migran datos de personas.

Documentos de entrada

En API se crea la orden con JSON y luego se cargan los documentos por POST /orders/{order}/attachments, con multipart/form-data y un campo file y la categoría opcional purpose. Este diseño evita reintentar una solicitud entera al fallar la transferencia de un documento. Use una Idempotency-Key distinta por documento: el servidor devuelve el mismo adjunto si contenido/nombre/categoría coinciden; 409 si cambian. El header es opcional por compatibilidad, pero se recomienda en toda integración automática.

PDF, Word DOCX sin macros/objetos incrustados/cifrado y JPG, PNG o WebP. Máximo 10 MB por archivo, 30 documentos de entrada y 100 MB totales por solicitud, 1 GB por cuenta. Imágenes limitadas a 40 megapíxeles y 10.000 píxeles por lado. Audio, video, SVG y ZIP independientes no se admiten. Convertir .doc antiguo a DOCX o PDF. La extensión y el MIME deben coincidir; DOCX se inspecciona como contenedor y el antivirus es obligatorio en producción. No se acepta un archivo por cambiar su nombre/extensión. Error o timeout del escáner bloquea la carga. No se adjunta a casos completados/cancelados.

curl.exe --request POST "http://127.0.0.1:8000/api/v1/orders/ID_ORDEN/attachments" --header "Authorization: Bearer SU_TOKEN" --header "Idempotency-Key: documento-rrhh-2026-001" --form "file=@C:/ruta/evidencia.pdf"

GET /orders/{order}/attachments lista los adjuntos y devuelve sus metadatos y person_id cuando corresponde. download_url requiere Bearer y orders:read; nunca es una URL pública. Los nuevos archivos incluyen file_size y sha256. Comparar la huella con el contenido descargado permite comprobar integridad. La web puede crear una solicitud junto con hasta 20 documentos / 20 MB, con persistencia atómica. Los límites del proxy/PHP también se aplican: ante 413 reduzca el cuerpo, no repita la misma carga indefinidamente.

Para JPG/PNG/WebP se devuelve también preview_url: GET /orders/{order}/attachments/{attachment}/preview, con Bearer orders:read, comprobación de cuenta, MIME de imagen, disposición inline y caché privada deshabilitada. No use el enlace como URL pública ni coloque el token en el query string. Un backend consumidor puede descargar la imagen autenticada y servirla bajo sus propias autorizaciones. Para PDF/Word, preview_url=null; no se incrustan como imágenes y el endpoint de vista previa devuelve 415.

La UI muestra miniaturas y ampliación en modal. Antes de enviar, las miniaturas de los archivos seleccionados se generan localmente en el navegador, sin subirlos ni enviarlos a terceros. Una vista previa no implica validación del contenido ni análisis antivirus; este se ejecuta al cargar al servidor.

Seguimiento y conversación

GET /orders acepta q (hasta 100 caracteres: asunto, referencia externa, nombre de cuenta o ULID exacto), status, billing (pending, paid, unquoted, credit), from y to (YYYY-MM-DD). Ambos días son inclusivos respecto a la fecha de recepción de la solicitud en PORTAL_TIMEZONE (predeterminado America/Santo_Domingo), no a la fecha de un pago. to debe ser mayor o igual a from. external_reference mantiene su filtro exacto; per_page admite 1–100. Los filtros se combinan sin ampliar nunca el ámbito de la cuenta. mine=1 solo afecta al personal web; para el cliente API la cuenta ya define el ámbito.

GET /orders admite status, external_reference y per_page (1–100, por defecto 25). GET /orders/{order} devuelve el estado y los servicios. La propiedad invoice contiene información financiera solo si el token también tiene invoices:read; con orders:read únicamente es null.

Estados: submitted → reviewing → quoted → in_progress → completed; una cancelación puede cerrar el caso según las reglas de ATD. Completar el trabajo no equivale a publicar una entrega. El estado del pago es independiente.

GET /orders/{order}/messages consulta el historial; POST al mismo recurso envía JSON {"body":"Consulta sobre el avance del caso"} (1–10.000 caracteres). Los mensajes de seguimiento no sustituyen la entrega final. No envíe informes finales por mensajes ni espere que una respuesta al email se importe al portal: las respuestas se escriben en la UI o API.

Facturas, pagos y saldos

Con invoices:read, consulte GET /invoices, con filtros status=unpaid, status=paid o status=overdue; order_id permite limitar a una solicitud. Las colecciones paginan con per_page entre 1 y 100. GET /invoices/{invoice} agrega partidas y los pagos que ATD ha registrado.

Se devuelven subtotal, impuesto, total, paid_amount, outstanding, moneda, vencimiento y snapshots del emisor/receptor. unpaid incluye facturas sin abonos y parcialmente pagadas; use importes para distinguirlas. overdue significa no pagada y vencimiento anterior a hoy. Las facturas emitidas conservan sus datos y precios originales. Los eventos de factura y pago sirven para actualizar su sistema; vuelva a consultar para conocer el saldo vigente.

Las facturas con saldo pendiente incluyen payment_accounts: banco, account_type (checking/savings), titular, número como texto (conservar ceros iniciales) y moneda. Solo se devuelven cuentas ATD activas en la moneda de esa factura; pagada o sin cuentas configuradas devuelve []. Estas instrucciones son la configuración bancaria vigente, no un registro histórico de dónde se pagó. La referencia y el pago efectivo deben ser conciliados por ATD. No solicite depósitos en otra moneda solo porque la lista esté vacía.

Al emitir la cotización se notifica a los clientes habilitados/verificados y, cuando corresponde, al correo de facturación de la cuenta, con importe, vencimiento y enlace privado. El catálogo puede tener precios sugeridos administrados por ATD, pero solo la factura emitida confirma el monto. El administrador confirma o modifica estos precios antes de emitir; los servicios sin precio se cotizan manualmente. No existe endpoint cliente para cambiar tarifas, emitir facturas ni marcar quoted: este estado se alcanza al emitir una factura válida.

Las nuevas lines de factura agrupan por servicio y modalidad. Por ejemplo, dos personas con polygraph: pre_employment y una con polygraph: routine producen dos partidas: cantidades 2 y 1, con los importes unitarios confirmados para cada una. Use option_name cuando esté presente para mostrar la partida; service_name identifica su familia o servicio. option_code, option_name y service_code pueden faltar en facturas anteriores. Las modalidades omitidas se cotizan manualmente en una partida separada, sin aplicar una tarifa de la familia. Los importes y nombres emitidos se conservan si cambia el catálogo.

En orders.items se conserva una entrada agrupada por service_code; unit_price será null si se facturó con distintos precios unitarios. Para conciliación use invoices:read y las lines de factura: cada total es quantity × unit_price, en unidades menores enteras. No agrupe las partidas de factura únicamente por nombre de familia. GET /services sigue sin publicar precios.

GET /invoices/{invoice}/document descarga una representación HTML imprimible de la factura comercial. No es PDF ni un NCF/documento fiscal homologado. La API no confirma fondos, no cobra, no permite reembolsos y no puede marcar una factura pagada: esa confirmación corresponde al administrador general de ATD.

Recepción automática de entregas

  1. Registrar un webhook y suscribirse a result.published (y, si lo necesita, a los eventos de facturación).
  2. Validar la firma del evento y persistirlo en su propia cola con deduplicación por event_id.
  3. Consultar GET /orders/{order}/deliveries con results:read. Es un manifiesto paginado de entregas publicadas. /results conserva la misma colección por compatibilidad.
  4. Consultar GET /orders/{order}/results/{result} para el detalle individual, o usar el resultado del manifiesto.
  5. Descargar download_url con el mismo Bearer. Verificar sha256, guardar el archivo de forma privada y completar el procesamiento en su sistema.

La orden debe estar completada, la factura totalmente pagada según el registro de pagos y la entrega publicada explícitamente por un administrador. Si falta trabajo/pago se responde 409; una entrega aún no publicada no aparece en el manifiesto. La regla se comprueba de nuevo en cada consulta y descarga. Un aviso recibido no concede acceso ni evita estas verificaciones. Los eventos no contienen el resumen, el archivo, nombres ni datos del expediente. Pueden existir varias entregas; deduplicar por el ULID de resultado y mantener su fecha de publicación. Una entrega solo con resumen tendrá download_url=null.

Las entregas con imagen incluyen preview_url en /orders/{order}/results/{result}/preview. Exige results:read y las mismas comprobaciones de finalización, pago y publicación; no anticipa la entrega ni genera archivos públicos.

Si se pierde un webhook o está temporalmente fuera de servicio, concilie periódicamente solicitudes y entregas con paginación y un intervalo moderado. No dependa exclusivamente del orden de llegada de los eventos.

Verificación de identidad con Didit

GET /services informa el modo vigente. Cada persona de una orden conserva su identity_mode: manual o didit; el cambio administrativo solo afecta solicitudes nuevas. No envíe selfies a ATD para iniciar el modo Didit: la captura se realiza en la sesión del proveedor. Los documentos obligatorios de título/exequátur siguen siendo independientes.

Acceso autorizado y captura activa

Solicite a ATD aprobación comercial para identidad API a crédito. Un administrador la gestiona en Integraciones API → Identidad y crédito, por cuenta y con límite diario. Mientras el modo efectivo sea manual, una persona nueva no admite sesión Didit; la autorización del partner no convierte casos históricos ni activa el proveedor.

Cree con orders:write una orden exclusivamente de identity-verification, sin otros servicios ni factura individual; puede incluir hasta 10 personas. Para mezclar título, exequátur u otros servicios, cree otra orden con el flujo normal de cotización/pago. Después use el ULID de la persona para POST /orders/{order}/people/{person}/identity-session, con identity:verify y cuerpo {"consent":true,"notice_version":"didit-2026-10-v1"}. Debe haber mostrado el aviso y obtenido autorización para documento, captura facial, prueba de vida activa y tratamiento por Didit. ATD registra versión/fecha; el integrador conserva evidencia de consentimiento. Repetir devuelve la misma sesión, sin reservar otra. No requiere prepago. El canal queda fijado al iniciar la primera persona: no se puede convertir una sesión web en crédito ni mezclar ambos canales en la misma orden.

ATD comprueba el workflow publicado antes de crear: documento, ACTIVE_3D y comparación facial. Si no puede confirmar esa configuración, detiene la creación para atención operativa, sin sustituirla silenciosamente por vida pasiva. Para declarar verified, también exige que el informe confirme method=ACTIVE_3D, comprobaciones aprobadas y cédula DOM coincidente. El reto concreto en pantalla lo determina Didit; no se garantiza una misma secuencia de movimientos en cada dispositivo.

La respuesta es 202, con billing_mode=partner_credit, entorno y revisión. Consulte GET en la misma ruta con identity:read hasta state=awaiting_person; use su verification_url para presentar el flujo al titular. El enlace permanece nulo hasta confirmar por lectura de servidor la vinculación y el entorno de la sesión; tampoco se devuelve durante una actualización pendiente. Repetir POST con solo identity:verify nunca permite recuperar ese enlace: también requiere identity:read. El backend conserva el Bearer ATD y entrega únicamente ese enlace privado a su frontend. No lo registre, almacene públicamente ni envíe por correo/webhooks. El enlace ya entregado no queda revocado automáticamente al suspender la cuenta ATD; operaciones debe coordinar su cierre con Didit si corresponde. No se admiten callbacks arbitrarios del cliente: el retorno alojado vuelve a una página neutra ATD, que no confirma ni modifica decisiones. Puede usar el enlace con iframe/SDK oficial, sujeto a HTTPS, cámara y política de seguridad de su sitio; compruebe origen/ventana de postMessage y nunca lo use como aprobación.

Estados públicos: preparing, awaiting_person, processing, received, attention_required. received solo significa que ATD obtuvo una conclusión; no revela si fue aprobada. Los casos con comprobaciones insuficientes, cédula diferente, vencimiento o revisión pueden ser no concluyentes. Un fallo incierto al crear la sesión necesita conciliación operativa, no repetir con nuevos identificadores. Consulte cada 10–30 segundos durante la captura, con backoff; se aplican los límites compartidos de la API.

Un rechazo de creación del proveedor también se muestra como attention_required; no es un rechazo de identidad de la persona. Repetir la llamada ATD devuelve la reserva existente y no reintenta el POST remoto. ATD distingue operativamente rechazos explícitos de respuestas perdidas o inciertas. Puede recuperar una sesión existente por lectura vinculada; una búsqueda vacía no autoriza automáticamente otra creación. Contacte con operaciones y conserve los identificadores originales.

Conclusión técnica automática y correcciones

ATD verifica callbacks Didit y reconcilia por API en segundo plano. No acepte decisiones de parámetros URL, navegador o cuerpos enviados por usuarios. Reciba identity.verification.updated y consulte GET /orders/{order}/people/{person}/identity-session/result con identity:read, o siga consultando con backoff. No requiere factura pagada ni publicación manual: es una excepción exclusiva de las sesiones api_credit y partners aprobados en el momento de consultar. No se devuelve desde el portal web ni desde /results o /deliveries.

La respuesta privada incluye id, order_id, person_id, provider, environment, billing_mode, revision, outcome, reason, reviewed_at y requires_review. outcome puede ser verified, not_verified o inconclusive; el último requiere revisión. No incluye cédula, fotos, biometría ni informe bruto. No constituye una decisión de elegibilidad ni garantiza ausencia de fraude. sandbox es simulación y este endpoint bloquea sus resultados en una instalación de producción. Sin conclusión confirmada, devuelve 409; sin aprobación/scope/cuenta correcta, 403.

revision aumenta cuando cambia o se retira una conclusión, no por cada consulta. El evento solo contiene referencias locales, entorno, estado, revisión y links.result: no contiene conclusión ni datos personales. Conserve la revisión mayor e ignore avisos obsoletos; consulte siempre el estado actual. Tras un evento de retirada, GET puede volver a 409: invalide su conclusión local anterior. Al reanudar un partner suspendido, reconcilie por GET; no se generan automáticamente avisos retroactivos. Una orden se completa cuando todas sus personas tienen conclusión técnica, incluso no concluyente; si alguna conclusión se retira, vuelve a en proceso.

Crédito, consumo y flujo web

El panel concilia sesiones aceptadas por Didit por fecha UTC de aceptación, separando sandbox/live. Las reservas sin aceptación confirmada se muestran por fecha de creación. Una fila por sesión/persona; reintentos del mismo expediente, polls y callbacks no agregan consumo. Un POST incierto puede haber tenido coste en Didit: no cree otra orden para reintentar ni lo trate como gratis. Este registro no es una factura ni un cálculo monetario; las tarifas, corte, impuestos y cobro posterior se acuerdan con ATD. Las órdenes a crédito no admiten factura individual. No se ha implementado aún la emisión automática de facturas consolidadas por corte.

En la web, incluso si el cliente es partner, la captura requiere factura totalmente pagada, tanto en live como en sandbox. En pruebas se registra un pago ficticio para ensayar el mismo flujo; no se procesa dinero. El informe ATD normal conserva finalización/publicación y descarga protegida. La pantalla de Didit puede mostrar su propio estado al titular: eso no es un cobro ni una entrega ATD publicada. No se utiliza Didit como pasarela de pago.

Por defecto se admiten 200 reservas nuevas/día UTC globales y 20 por cuenta/canal. El cupo API es configurable por cuenta aprobada; el de web y el global se configuran por operaciones. Superar el cupo responde 429; repetir una sesión existente no consume otra reserva. La suspensión impide iniciar sesiones remotas pendientes y se vuelve a comprobar tras el preflight. No cancela llamadas ya en curso ni sesiones aceptadas: estas siguen conciliándose, sin entregar resultados mientras la cuenta esté suspendida.

Identidades reutilizables y reverificación facial

Contrato 1.6.0: la verificación inicial sigue pidiendo documento. Después de una conclusión documental Didit aprobada y entregada, puede registrar una referencia consentida y solicitar nuevas capturas activas sin volver a enviar la cédula. Las revisiones manuales y las propias autenticaciones recurrentes no sirven como una nueva referencia documental. El resultado recurrente indica verification_kind=recurring, document_reverified=false e identity_id: acredita el cotejo facial realizado en esa fecha, no una nueva validación documental ni una decisión de elegibilidad.

  1. Complete la solicitud inicial normal de identidad. Si fue web, debe estar pagada, completada y publicada; si fue API crédito, mantiene su autorización de partner vigente.
  2. Con autorización adicional, llame POST /orders/{order}/people/{person}/reusable-identity con identity:verify + identity:read y cuerpo {"consent":true,"notice_version":"didit-reuse-2026-10-v1"}. ATD vuelve a consultar al proveedor, registra consentimiento/vínculo y responde 201 con data.id. Repetir devuelve la misma referencia, no otra ni una vigencia renovada.
  3. Consulte GET /identities con identity:read: referencias de su propia cuenta, 20 por página, q por ULID exacto. Devuelve nombre, últimos cuatro dígitos, entorno, vigencia y estado (available, expired, revoked, unavailable), nunca retratos o número completo. No existe búsqueda de personas entre clientes.
  4. Llame POST /identities/{identity}/verifications con identity:verify + orders:write, Idempotency-Key y el mismo consentimiento versionado. Puede añadir subject, details opcionales, external_reference y purpose (5–1.000 caracteres; si se omite, sigue la finalidad original autorizada). ATD crea orden/persona/sesión recurrente a crédito y devuelve 202 con sus identificadores e identity_session_url, sin exportar el perfil. Consulte esa URL con identity:read para recuperar el enlace privado; entrega técnica y eventos siguen el flujo de crédito anterior.

Didit conserva la referencia facial bajo su retención aplicable; ATD conserva perfil básico cifrado —incluido el número escrito de cédula—, identificador opaco vinculado a la cuenta, consentimiento y conclusiones. No descarga ni reenvía retratos o copias de documento para esta función. Los adjuntos aportados directamente a ATD tienen su ciclo independiente. El servidor fija la referencia y el workflow; portrait_image, reference_image, identity_number, workflow_id o decision en la petición recurrente se rechazan (422). Biometric Authentication.

La vigencia operativa es de 90 días desde la verificación original, no desde el registro ni desde la última selfie. Caducidad o referencia no disponible devuelve 409 y requiere otro KYC completo. La retención de Didit puede diferir: no se configuró borrado automático o conservación de plantillas tras borrar sesiones. El resultado histórico conserva su fecha; caducar una referencia no convierte un informe anterior en una comprobación nueva. Una corrección que invalide la aprobación documental original bloquea inmediatamente las conclusiones recurrentes dependientes (409 mientras se reconcilian); se solicita su conciliación para actualizar revisión y emitir identity.verification.updated con metadatos. Consultar después el resultado actual, que puede ser inconclusive.

Solo se admite una captura sin cierre confirmado por referencia. Otra clave para crear simultáneamente devuelve 409; un timeout de creación requiere conciliación, no otra orden. ATD distingue el identificador estable de persona de la referencia única de cada sesión en metadatos, y confirma ambos con el proveedor. Usa ACTIVE_3D + Face Match contra referencia; solo presencia no basta. La referencia no se reutiliza entre aplicaciones, entornos o cuentas.

POST /identities/{identity}/revoke, con identity:verify, devuelve 204 de forma idempotente y bloquea nuevas capturas en ATD. No reactiva la referencia, no borra comprobaciones históricas ni datos de Didit y no cancela enlaces ya entregados. Para supresión o retirada completa de datos, contacte con ATD para coordinar el procedimiento con Didit. Una revocación requiere otra verificación completa si se desea registrar una referencia nueva.

En la web: abra el expediente aprobado/publicado y seleccione «Registrar referencia reutilizable», aceptando el aviso adicional. Desde «Identidades reutilizables» solicite la nueva comprobación, sin volver a escribir la cédula ni adjuntar fotos. Cada solicitud web conserva su factura, prepago y publicación, incluso si la referencia se registró por API. No se muestra por esta vía la conclusión técnica API original sin sus permisos.

Webhooks y firma

Configure endpoints, eventos y secreto desde Integraciones API. ATD debe autorizar cada hostname exacto en WEBHOOK_ALLOWED_HOSTS. Solo HTTPS en puerto 443, sin credenciales, fragmentos o IP literal. El destino se vuelve a resolver y su IP pública se fija en cada intento, sin redirecciones ni proxies de entorno. El endpoint recibe POST JSON y debe responder 2xx rápidamente, después de guardar el evento de forma durable. No realice análisis de documentos dentro de esa respuesta HTTP.

Eventos de negocio: order.created, order.updated, invoice.issued, payment.recorded, invoice.paid, result.published e identity.verification.updated (solo crédito autorizado). Un envío de prueba genera endpoint.test, sin expediente. Payload: id, type, created_at y data con identificadores/estado/enlaces relativos de API. invoice_id/result_id pueden ser nulos cuando no aplican. Identidad usa el sobre especializado descrito arriba. Las credenciales de API y la clave HMAC son secretos distintos.

Headers: X-ATD-Event-ID, X-ATD-Timestamp (segundos Unix) y X-ATD-Signature. Cada firma v1=HEX es HMAC-SHA256 de timestamp + "." + cuerpo_HTTP_original con el secreto del endpoint. Verificar los bytes originales antes de parsear JSON, comparar en tiempo constante y rechazar diferencias de más de cinco minutos. Durante la rotación puede haber dos firmas v1, separadas por coma; acepte una firma válida para una clave que tenga autorizada.

Núcleo de validación para un backend Node.js (es código de archivo, no un comando para pegar en CMD):

import { createHmac, timingSafeEqual } from 'node:crypto';
export function validATDWebhook(rawBody, timestamp, signature, secret) {
  if (!Buffer.isBuffer(rawBody) || rawBody.length > 65536) return false;
  if (!/^\d{10}$/.test(String(timestamp))) return false;
  if (Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) return false;
  const expected = createHmac('sha256', secret).update(String(timestamp) + '.').update(rawBody).digest();
  return String(signature).split(',').slice(0, 2).some(part => {
    const match = /^v1=([a-f0-9]{64})$/.exec(part.trim());
    return match && timingSafeEqual(expected, Buffer.from(match[1], 'hex'));
  });
}

Después de validar, parsear JSON, comprobar que id coincide con X-ATD-Event-ID, deduplicar de manera transaccional y encolar el trabajo. No volver a ejecutar acciones por un duplicado ya aceptado. Si responde 2xx antes de persistir, una caída podría perder el evento sin que ATD lo reintente.

La entrega es al menos una vez y puede llegar fuera de orden. Hay hasta 8 intentos con esperas de 1, 5, 15, 60, 360, 1440 y 1440 minutos. No se siguen 3xx. El timeout HTTP es 15 s y se limita la respuesta a 64 KB. El panel muestra intentos, códigos HTTP, fechas y errores de transporte sin registrar cuerpos remotos. Puede probar el endpoint, desactivarlo, rotar el secreto con 24 h de solapamiento y reencolar una entrega agotada conservando su event_id y payload. Desactivar detiene nuevos eventos y descarta pendientes; no borra los registros. Volver a consultar el estado vigente al recibir un replay.

Errores, límites y reintentos

Enviar Content-Type: application/json en escrituras, excepto la carga multipart. Cuerpo JSON de hasta 1 MB y profundidad máxima de 64 niveles. Toda respuesta de error API es JSON, aunque no se envíe Accept. Las colecciones siguen data, links y meta. Los mensajes de error contienen error.code, error.message, error.fields y meta.request_id. Las respuestas incluyen X-Request-ID para soporte.

HTTP Interpretación y acción
400 JSON malformado o profundidad excesiva. Corregir el cuerpo.
401 Bearer ausente, inválido, revocado o vencido. Renovar credenciales.
403 Cuenta/rol/permisos insuficientes o recurso de otra cuenta. Revisar acceso.
404 Identificador o archivo no disponible. Revisar el recurso.
409 Clave reutilizada con otros datos, caso cerrado o entrega sin habilitar. Conciliar el estado.
413 Cuerpo demasiado grande; reducirlo.
415 Tipo de contenido incorrecto.
422 Datos, documento o cuota inválidos; consultar error.fields.
426 Usar HTTPS en producción.
429 Respetar Retry-After; no abrir más tokens para evadir el límite.
500 / 503 Error interno o servicio temporalmente no disponible (incluye escáner). Reintentar de forma acotada.

Límite de 60 solicitudes/minuto por usuario, compartido entre sus tokens; protección adicional de 600/minuto por IP y 10 cargas/minuto. Revisar X-RateLimit-Limit, X-RateLimit-Remaining y Retry-After cuando estén presentes. Para red, 429 o 5xx aplicar espera exponencial con jitter y un máximo de intentos. Reutilizar claves de idempotencia para escrituras; nunca reintentar con nuevas claves sin conciliar. Un error 4xx de validación/permisos no se corrige repitiendo la misma llamada.

Operación y seguridad

Integraciones API muestra actividad por ruta, códigos, latencia y request ID, tokens y su último uso/vencimiento, endpoints e historial de entregas. El cliente ve su cuenta; ATD administra el conjunto con autorización reforzada. Las métricas se conservan 30 días; no guardan cuerpos, query strings, archivos ni Authorization. El historial de negocio permanece separado. El contador p95 se calcula con una muestra de hasta 1.000 solicitudes recientes y se identifica como tal en el panel.

En el servidor se requieren worker y scheduler: el outbox se guarda con la transacción de negocio y el scheduler encola pendientes/reintentos. Los envíos HTTP no mantienen abierta una transacción de base de datos. Los procesos usan leases para evitar entregar simultáneamente el mismo evento. Configurar escáner, cuotas del servidor web, TLS, respaldos privados y protección de APP_KEY según el runbook de operación.

Antes de activar una integración: probar scopes mínimos, aislamiento entre cuentas, expiración/revocación, clave repetida y conflicto, MIME/tamaño rechazado, pagos parciales, bloqueo de entregas, firma/replay y recuperación ante timeouts. Solicitar a soporte el diagnóstico con X-Request-ID, fecha/hora UTC y operación; nunca enviar el token, la clave HMAC ni el contenido del expediente.

La sección web «Identidades reutilizables» permanece oculta durante el piloto biométrico. Las rutas API existentes mantienen sus permisos, consentimientos, vigencia y comprobaciones; ocultar el módulo web no certifica ni cierra las pruebas Live.

Referencia de endpoints

Rutas relativas a /api/v1. Los cuerpos y respuestas completos están en el contrato descargable.

GET/identitieslistReusableIdentities

Partner autorizado, identity:read. Referencias de la misma cuenta, 20 por página. Nunca devuelve retratos, número completo de cédula ni referencias internas Didit. q filtra por ULID exacto; estado available, expired, revoked o unavailable. No busca identidades de otras cuentas.

Permisos: identity:read

Parámetros

NombreUbicaciónUso
pagequeryinteger
qquerystring

Respuestas

200
Referencias paginadas
Ver estructura
{
    "application/json": {
        "schema": {
            "type": "object",
            "properties": {
                "data": {
                    "type": "array",
                    "items": {
                        "$ref": "#/components/schemas/ReusableIdentity"
                    }
                },
                "meta": {
                    "type": "object"
                }
            }
        }
    }
}
default
401, 403, 422 o 429
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
POST/orders/{order}/people/{person}/reusable-identityenrollReusableIdentity

Registra una referencia después de una verificación documental Didit initial y verified, confirmada de nuevo por API. Consentimiento adicional obligatorio; no sirve revisión manual, solo presencia o una reautenticación. Fuente web requiere pago/completado/publicación; fuente api_credit requiere aprobación vigente. Una referencia por sesión inicial; repetir no extiende caducidad ni reactiva revocaciones. Vigencia máxima 90 días desde la captura original. No envía fotos ni cambia retención de Didit.

Permisos: identity:verify identity:read

Parámetros

NombreUbicaciónUso
orderpathObligatorio. string
personpathObligatorio. string

Cuerpo de la solicitud

{
    "required": true,
    "content": {
        "application/json": {
            "schema": {
                "$ref": "#/components/schemas/IdentityReuseConsent"
            }
        }
    }
}

Respuestas

201
Referencia creada o ya existente
Ver estructura
{
    "application/json": {
        "schema": {
            "type": "object",
            "properties": {
                "data": {
                    "$ref": "#/components/schemas/ReusableIdentity"
                }
            }
        }
    }
}
default
401 sin token; 403 cuenta/scope/rol; 404 inexistente; 409 fuente no apta/no publicada/vencida/revocada; 422 consentimiento; 429 límite; 503 configuración o confirmación remota indisponible.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
POST/identities/{identity}/verificationscreateRecurringIdentityVerification

Partner aprobado. Crea una orden exclusiva de identidad y sesión recurrente a crédito, sin pedir cédula ni imágenes. ATD usa el perfil cifrado y referencia Didit de su propia cuenta. Requiere Idempotency-Key: repetir mismo cuerpo/clave devuelve la misma orden; conflicto 409. Solo una captura pendiente por identidad; no reintentar con otra clave tras incertidumbre. Devuelve referencias, no perfil. Consultar identity_session_url con identity:read. Exige ACTIVE_3D y FACE_MATCH; no renueva la validación del documento ni los 90 días de referencia.

Permisos: identity:verify orders:write

Parámetros

NombreUbicaciónUso
identitypathObligatorio. string
Idempotency-KeyheaderObligatorio. string

Cuerpo de la solicitud

{
    "required": true,
    "content": {
        "application/json": {
            "schema": {
                "allOf": [
                    {
                        "$ref": "#/components/schemas/IdentityReuseConsent"
                    },
                    {
                        "type": "object",
                        "properties": {
                            "subject": {
                                "type": "string",
                                "maxLength": 200
                            },
                            "purpose": {
                                "type": "string",
                                "minLength": 5,
                                "maxLength": 1000,
                                "description": "Si se omite se conserva la finalidad original; confirmar que sigue autorizada."
                            },
                            "details": {
                                "type": "string",
                                "nullable": true,
                                "maxLength": 10000
                            },
                            "external_reference": {
                                "type": "string",
                                "nullable": true,
                                "maxLength": 100
                            }
                        }
                    }
                ]
            }
        }
    }
}

Respuestas

202
Solicitud aceptada/existente
Ver estructura
{
    "application/json": {
        "schema": {
            "type": "object",
            "properties": {
                "data": {
                    "type": "object",
                    "properties": {
                        "order_id": {
                            "type": "string"
                        },
                        "person_id": {
                            "type": "string"
                        },
                        "identity_id": {
                            "type": "string"
                        },
                        "verification_kind": {
                            "type": "string",
                            "enum": [
                                "recurring"
                            ]
                        },
                        "identity_session_url": {
                            "type": "string",
                            "format": "uri"
                        }
                    }
                }
            }
        }
    }
}
default
401 sin token; 403 cuenta/permiso; 404 referencia inexistente; 409 referencia no apta/captura pendiente/clave en conflicto; 422 consentimiento/campos prohibidos; 429 cuota; 503 configuración/confirmación remota.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
POST/identities/{identity}/revokerevokeReusableIdentity

Revoca el uso futuro en ATD, de forma idempotente y auditada. No elimina datos Didit, no cancela enlaces remotos ya entregados ni borra comprobaciones históricas. Una referencia revocada no se reactiva: requiere nueva verificación documental y consentimiento. Para supresión, coordinar el procedimiento de privacidad con ATD.

Permisos: identity:verify

Parámetros

NombreUbicaciónUso
identitypathObligatorio. string

Respuestas

204
Referencia revocada
default
401, 403, 404 o 429
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
POST/orders/{order}/people/{person}/identity-sessionrequestIdentitySession

Solo partners autorizados a crédito y scope identity:verify. Cuenta activa/verificada y aprobación vigente comprobada en servidor. Requiere solicitud exclusiva de identity-verification, sin factura ni sesiones web, y persona identity_mode=didit. Consentimiento versionado obligatorio. No exige prepago. Una sesión por persona; repetir devuelve la existente sin nueva creación. Asíncrono. No acepta portrait_image, reference_image, workflow_id ni decision. No convierte casos manuales. Cuotas globales y por partner; preflight ACTIVE_3D obligatorio.

Permisos: identity:verify

Cuerpo de la solicitud

{
    "required": true,
    "content": {
        "application/json": {
            "schema": {
                "type": "object",
                "required": [
                    "consent",
                    "notice_version"
                ],
                "properties": {
                    "consent": {
                        "type": "boolean",
                        "enum": [
                            true
                        ]
                    },
                    "notice_version": {
                        "type": "string",
                        "enum": [
                            "didit-2026-10-v1",
                            "didit-reuse-2026-10-v1"
                        ],
                        "description": "La versión debe corresponder al tipo de verificación fijado en la persona: initial o recurring."
                    }
                }
            }
        }
    }
}

Respuestas

202
Sesión aceptada/existente. Enlace nulo sin identity:read o sin lectura vinculada y confirmada del proveedor; consultar GET.
Ver estructura
{
    "application/json": {
        "schema": {
            "type": "object",
            "properties": {
                "data": {
                    "$ref": "#/components/schemas/IdentitySession"
                }
            }
        }
    }
}
default
401 sin token; 403 cuenta no autorizada/otro tenant/scope/rol; 404 persona ajena/manual; 409 cancelada, mezcla de servicios/canales o factura individual; 422 consentimiento/versión/campos prohibidos; 429 cuota; 503 configuración no disponible.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
GET/orders/{order}/people/{person}/identity-sessiongetIdentitySession

Partner con aprobación vigente y identity:read. Solo sesiones api_credit de su cuenta. No devuelve decisión ni media. El enlace privado habilita la captura; no debe registrarse ni compartirse fuera de la persona. Poll moderado; received no significa verified. Consulte links.result para la conclusión técnica automática.

Permisos: identity:read

Respuestas

200
Estado operativo y enlace privado cuando se requiere participación.
Ver estructura
{
    "application/json": {
        "schema": {
            "type": "object",
            "properties": {
                "data": {
                    "$ref": "#/components/schemas/IdentitySession"
                }
            }
        }
    }
}
default
401, 403, 404, 409 cancelada o 429.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
GET/orders/{order}/people/{person}/identity-session/resultgetIdentityTechnicalResult

Excepción de crédito exclusiva para partner autorizado actualmente, misma cuenta y sesión api_credit. Resultado Didit confirmado automáticamente en servidor, sin prepago ni publicación manual. Nunca entrega documentos, fotos, biometría o informe bruto. No es una decisión de elegibilidad ni garantía de ausencia de fraude. No válido como identidad real si environment=sandbox. Revocar autorización bloquea incluso tokens existentes. Conserve la revisión mayor; una corrección puede cambiar o retirar una conclusión previa.

Permisos: identity:read

Respuestas

200
Conclusión técnica privada
Ver estructura
{
    "application/json": {
        "schema": {
            "type": "object",
            "properties": {
                "data": {
                    "$ref": "#/components/schemas/IdentityTechnicalResult"
                }
            }
        }
    }
}
default
401 sin token; 403 sin aprobación/scope/tenant o sesión web; 404 inexistente; 409 pendiente, actualización del proveedor sin confirmar (también de la fuente recurrente) o sandbox en producción; 429 cuota.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
GET/orders/{order}/attachments/{attachment}/previewpreviewAttachment

Requiere orders:read y acceso a la cuenta de la orden. Solo JPG/PNG/WebP, inline y sin caché. PDF/Word devuelven 415; no es una URL pública.

Parámetros

NombreUbicaciónUso
orderpathObligatorio. string
attachmentpathObligatorio. string

Respuestas

200
Imagen privada
Ver estructura
{
    "image/jpeg": {
        "schema": {
            "type": "string",
            "format": "binary"
        }
    },
    "image/png": {
        "schema": {
            "type": "string",
            "format": "binary"
        }
    },
    "image/webp": {
        "schema": {
            "type": "string",
            "format": "binary"
        }
    }
}
default
401 sin token; 403 sin permiso; 404 inexistente; 415 formato no visualizable; 429 límite de uso.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
GET/orders/{order}/results/{result}/previewpreviewResult

Requiere results:read, acceso a la cuenta, orden completada, factura totalmente pagada y entrega publicada. Mismas restricciones que la descarga; nunca anticipa resultados.

Parámetros

NombreUbicaciónUso
orderpathObligatorio. string
resultpathObligatorio. string

Respuestas

200
Imagen privada publicada
Ver estructura
{
    "image/jpeg": {
        "schema": {
            "type": "string",
            "format": "binary"
        }
    },
    "image/png": {
        "schema": {
            "type": "string",
            "format": "binary"
        }
    },
    "image/webp": {
        "schema": {
            "type": "string",
            "format": "binary"
        }
    }
}
default
401 sin token; 403 sin permiso; 404 inexistente/no publicado; 409 no completado/pagado; 415 formato no visualizable; 429 límite de uso.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
GET/serviceslistServices

Requiere orders:read. Incluye remote-interview-rppg, entrevista remota por persona con pulso por cámara y revisión humana. Consulte los códigos y requisitos activos en cada instalación.

Permisos: orders:read

Respuestas

200
Respuesta
Ver estructura
{
    "application/json": {
        "schema": {
            "type": "object",
            "properties": {
                "data": {
                    "type": "array",
                    "items": {
                        "$ref": "#/components/schemas/Service"
                    }
                }
            }
        }
    }
}
401
Error de autenticación, autorización, conflicto, validación o servidor
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
403
Error de autenticación, autorización, conflicto, validación o servidor
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
404
Error de autenticación, autorización, conflicto, validación o servidor
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
409
Error de autenticación, autorización, conflicto, validación o servidor
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
422
Error de autenticación, autorización, conflicto, validación o servidor
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
426
HTTPS requerido.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
429
Error de autenticación, autorización, conflicto, validación o servidor
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
500
Error de autenticación, autorización, conflicto, validación o servidor
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
503
Servicio temporalmente no disponible (incluido escáner de documentos)
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
GET/orderslistOrders

Requiere orders:read

Permisos: orders:read

Parámetros

NombreUbicaciónUso
per_pagequeryinteger
statusquery
external_referencequerystring
qqueryTexto en asunto, referencia externa o nombre de cuenta; ULID exacto. Siempre limitado a su cuenta.string
billingquerySituación de facturación. credit identifica órdenes con sesiones api_credit.string
fromqueryPrimer día local de creación inclusive en PORTAL_TIMEZONE (predeterminado America/Santo_Domingo).string
toqueryÚltimo día local de creación inclusive; debe ser >= from.string
minequeryReservado a personal web; no restringe adicionalmente al cliente API.string

Respuestas

200
Respuesta
Ver estructura
{
    "application/json": {
        "schema": {
            "type": "object",
            "properties": {
                "data": {
                    "type": "array",
                    "items": {
                        "$ref": "#/components/schemas/Order"
                    }
                },
                "links": {
                    "type": "object"
                },
                "meta": {
                    "type": "object"
                }
            }
        }
    }
}
401
Error de autenticación, autorización, conflicto, validación o servidor
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
403
Error de autenticación, autorización, conflicto, validación o servidor
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
404
Error de autenticación, autorización, conflicto, validación o servidor
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
409
Error de autenticación, autorización, conflicto, validación o servidor
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
422
Error de autenticación, autorización, conflicto, validación o servidor
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
426
HTTPS requerido.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
429
Error de autenticación, autorización, conflicto, validación o servidor
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
500
Error de autenticación, autorización, conflicto, validación o servidor
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
503
Servicio temporalmente no disponible (incluido escáner de documentos)
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
POST/orderscreateOrder

Requiere orders:write. Misma clave y payload reproduce la orden; cambios o reordenar people producen 409. Hasta 10 personas por orden, cada una con service_codes; quantity coincide con las personas asignadas. Todos los servicios son personales salvo training-equipment. remote-interview-rppg exige people con autorización por participante. La sesión se coordina por separado y la entrega sigue el flujo ordinario de pago y publicación. person se conserva por compatibilidad para una sola persona. details es opcional. Cree con JSON y cargue evidencia por attachments con person_id; el detalle informa verification.people[].missing.

Permisos: orders:write

Parámetros

NombreUbicaciónUso
Idempotency-KeyheaderObligatorio. string

Cuerpo de la solicitud

{
    "required": true,
    "content": {
        "application/json": {
            "schema": {
                "$ref": "#/components/schemas/CreateOrder"
            }
        }
    }
}

Respuestas

201
Respuesta
Ver estructura
{
    "application/json": {
        "schema": {
            "type": "object",
            "properties": {
                "data": {
                    "$ref": "#/components/schemas/Order"
                },
                "meta": {
                    "type": "object"
                }
            }
        }
    }
}
400
Formato de contenido o JSON no válido / límite de tamaño
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
401
Error de autenticación, autorización, conflicto, validación o servidor
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
403
Error de autenticación, autorización, conflicto, validación o servidor
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
404
Error de autenticación, autorización, conflicto, validación o servidor
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
409
Error de autenticación, autorización, conflicto, validación o servidor
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
413
Formato de contenido o JSON no válido / límite de tamaño
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
415
Formato de contenido o JSON no válido / límite de tamaño
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
422
Error de autenticación, autorización, conflicto, validación o servidor
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
426
HTTPS requerido.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
429
Error de autenticación, autorización, conflicto, validación o servidor
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
500
Error de autenticación, autorización, conflicto, validación o servidor
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
503
Servicio temporalmente no disponible (incluido escáner de documentos)
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
GET/orders/{order}getOrder

Requiere orders:read

Permisos: orders:read

Respuestas

200
Respuesta
Ver estructura
{
    "application/json": {
        "schema": {
            "type": "object",
            "properties": {
                "data": {
                    "$ref": "#/components/schemas/Order"
                },
                "meta": {
                    "type": "object"
                }
            }
        }
    }
}
401
Error de autenticación, autorización, conflicto, validación o servidor
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
403
Error de autenticación, autorización, conflicto, validación o servidor
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
404
Error de autenticación, autorización, conflicto, validación o servidor
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
409
Error de autenticación, autorización, conflicto, validación o servidor
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
422
Error de autenticación, autorización, conflicto, validación o servidor
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
426
HTTPS requerido.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
429
Error de autenticación, autorización, conflicto, validación o servidor
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
500
Error de autenticación, autorización, conflicto, validación o servidor
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
503
Servicio temporalmente no disponible (incluido escáner de documentos)
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
GET/orders/{order}/resultslistResults

Requiere results:read. Solo orden completada, factura pagada y entregas publicadas.

Permisos: results:read

Respuestas

200
Respuesta
Ver estructura
{
    "application/json": {
        "schema": {
            "type": "object",
            "properties": {
                "data": {
                    "type": "array",
                    "items": {
                        "$ref": "#/components/schemas/Result"
                    }
                },
                "links": {
                    "type": "object"
                },
                "meta": {
                    "type": "object"
                }
            }
        }
    }
}
401
Error de autenticación, autorización, conflicto, validación o servidor
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
403
Error de autenticación, autorización, conflicto, validación o servidor
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
404
Error de autenticación, autorización, conflicto, validación o servidor
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
409
Error de autenticación, autorización, conflicto, validación o servidor
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
422
Error de autenticación, autorización, conflicto, validación o servidor
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
426
HTTPS requerido.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
429
Error de autenticación, autorización, conflicto, validación o servidor
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
500
Error de autenticación, autorización, conflicto, validación o servidor
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
503
Servicio temporalmente no disponible (incluido escáner de documentos)
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
GET/orders/{order}/results/{result}/downloaddownloadResult

Requiere results:read; comprueba autorización y pago en cada descarga.

Permisos: results:read

Respuestas

200
Archivo privado
Ver estructura
{
    "application/octet-stream": {
        "schema": {
            "type": "string",
            "format": "binary"
        }
    }
}
401
Error de autenticación, autorización, conflicto, validación o servidor
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
403
Error de autenticación, autorización, conflicto, validación o servidor
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
404
Error de autenticación, autorización, conflicto, validación o servidor
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
409
Error de autenticación, autorización, conflicto, validación o servidor
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
422
Error de autenticación, autorización, conflicto, validación o servidor
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
426
HTTPS requerido.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
429
Error de autenticación, autorización, conflicto, validación o servidor
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
500
Error de autenticación, autorización, conflicto, validación o servidor
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
503
Servicio temporalmente no disponible (incluido escáner de documentos)
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
GET/orders/{order}/messageslistMessages

Requiere messages:read

Permisos: messages:read

Respuestas

200
Respuesta
Ver estructura
{
    "application/json": {
        "schema": {
            "type": "object",
            "properties": {
                "data": {
                    "type": "array",
                    "items": {
                        "$ref": "#/components/schemas/Message"
                    }
                },
                "links": {
                    "type": "object"
                },
                "meta": {
                    "type": "object"
                }
            }
        }
    }
}
401
Error de autenticación, autorización, conflicto, validación o servidor
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
403
Error de autenticación, autorización, conflicto, validación o servidor
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
404
Error de autenticación, autorización, conflicto, validación o servidor
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
409
Error de autenticación, autorización, conflicto, validación o servidor
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
422
Error de autenticación, autorización, conflicto, validación o servidor
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
426
HTTPS requerido.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
429
Error de autenticación, autorización, conflicto, validación o servidor
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
500
Error de autenticación, autorización, conflicto, validación o servidor
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
503
Servicio temporalmente no disponible (incluido escáner de documentos)
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
POST/orders/{order}/messagessendMessage

Requiere messages:write

Permisos: messages:write

Cuerpo de la solicitud

{
    "required": true,
    "content": {
        "application/json": {
            "schema": {
                "type": "object",
                "required": [
                    "body"
                ],
                "properties": {
                    "body": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 10000
                    }
                }
            }
        }
    }
}

Respuestas

201
Respuesta
Ver estructura
{
    "application/json": {
        "schema": {
            "type": "object",
            "properties": {
                "data": {
                    "$ref": "#/components/schemas/Message"
                }
            }
        }
    }
}
400
Formato de contenido o JSON no válido / límite de tamaño
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
401
Error de autenticación, autorización, conflicto, validación o servidor
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
403
Error de autenticación, autorización, conflicto, validación o servidor
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
404
Error de autenticación, autorización, conflicto, validación o servidor
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
409
Error de autenticación, autorización, conflicto, validación o servidor
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
413
Formato de contenido o JSON no válido / límite de tamaño
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
415
Formato de contenido o JSON no válido / límite de tamaño
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
422
Error de autenticación, autorización, conflicto, validación o servidor
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
426
HTTPS requerido.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
429
Error de autenticación, autorización, conflicto, validación o servidor
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
500
Error de autenticación, autorización, conflicto, validación o servidor
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
503
Servicio temporalmente no disponible (incluido escáner de documentos)
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
GET/orders/{order}/attachmentslistAttachments

Requiere orders:read. Documentos de entrada de la cuenta.

Permisos: orders:read

Respuestas

200
Documentos privados
Ver estructura
{
    "application/json": {
        "schema": {
            "type": "object",
            "properties": {
                "data": {
                    "type": "array",
                    "items": {
                        "$ref": "#/components/schemas/Attachment"
                    }
                },
                "links": {
                    "type": "object"
                },
                "meta": {
                    "type": "object"
                }
            }
        }
    }
}
401
Error
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
403
Error
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
404
Error
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
409
Error
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
413
Error
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
415
Error
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
422
Error
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
426
HTTPS requerido.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
429
Error
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
500
Error
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
503
Servicio temporalmente no disponible (incluido escáner de documentos)
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
POST/orders/{order}/attachmentsuploadAttachment

Requiere orders:write. PDF/DOCX sin macros/JPG/PNG/WebP hasta 10 MB. 30 documentos y 100 MB por solicitud, 1 GB por cuenta. Solo órdenes abiertas; análisis antivirus obligatorio en producción. Audio, video, SVG y Word antiguo se rechazan.

Permisos: orders:write

Parámetros

NombreUbicaciónUso
Idempotency-KeyheaderRecomendado para reintentos: misma clave y contenido devuelve el mismo documento; otro contenido produce 409.string

Cuerpo de la solicitud

{
    "required": true,
    "content": {
        "multipart/form-data": {
            "schema": {
                "type": "object",
                "required": [
                    "file"
                ],
                "properties": {
                    "file": {
                        "type": "string",
                        "format": "binary"
                    },
                    "purpose": {
                        "type": "string",
                        "enum": [
                            "supporting",
                            "identity_front",
                            "identity_back",
                            "selfie",
                            "selfie_extra",
                            "degree_document",
                            "exequatur_document",
                            "bailiff_credential"
                        ],
                        "default": "supporting",
                        "description": "identity_front obligatorio para título/exequátur; degree_document para título; exequatur_document para exequátur; bailiff_credential para credenciales de alguacil; selfie para identidad. Selfies solo JPG/PNG/WebP; documentos clasificados PDF o imágenes, no DOCX. El mismo archivo no puede repetirse."
                    },
                    "person_id": {
                        "type": "string",
                        "minLength": 26,
                        "maxLength": 26,
                        "description": "Identificador público de people[].id, siempre perteneciente a esta orden. Obligatorio para evidencia clasificada si hay varias personas; con una se infiere."
                    }
                }
            }
        }
    }
}

Respuestas

201
Documento privado agregado
Ver estructura
{
    "application/json": {
        "schema": {
            "type": "object",
            "properties": {
                "data": {
                    "$ref": "#/components/schemas/Attachment"
                }
            }
        }
    }
}
401
Error
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
403
Error
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
404
Error
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
409
Error
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
413
Error
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
415
Error
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
422
Error
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
426
HTTPS requerido.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
429
Error
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
500
Error
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
503
Servicio temporalmente no disponible (incluido escáner de documentos)
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
GET/orders/{order}/attachments/{attachment}/downloaddownloadAttachment

Requiere orders:read. Revalida autorización de cuenta.

Permisos: orders:read

Respuestas

200
Documento privado
Ver estructura
{
    "application/octet-stream": {
        "schema": {
            "type": "string",
            "format": "binary"
        }
    }
}
401
Error
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
403
Error
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
404
Error
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
409
Error
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
413
Error
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
415
Error
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
422
Error
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
426
HTTPS requerido.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
429
Error
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
500
Error
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
503
Servicio temporalmente no disponible (incluido escáner de documentos)
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
GET/invoiceslistInvoices

Requiere invoices:read. Facturas de la cuenta del token, con saldos en unidades menores.

Permisos: invoices:read

Parámetros

NombreUbicaciónUso
statusquerystring
per_pagequeryinteger
order_idquerystring

Respuestas

200
Respuesta
Ver estructura
{
    "application/json": {
        "schema": {
            "type": "object",
            "properties": {
                "data": {
                    "type": "array",
                    "items": {
                        "$ref": "#/components/schemas/Invoice"
                    }
                },
                "links": {
                    "type": "object"
                },
                "meta": {
                    "type": "object"
                }
            }
        }
    }
}
400
Consulte error.code, error.message y meta.request_id.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
401
Consulte error.code, error.message y meta.request_id.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
403
Consulte error.code, error.message y meta.request_id.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
404
Consulte error.code, error.message y meta.request_id.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
409
Consulte error.code, error.message y meta.request_id.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
413
Consulte error.code, error.message y meta.request_id.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
415
Consulte error.code, error.message y meta.request_id.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
422
Consulte error.code, error.message y meta.request_id.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
426
HTTPS requerido.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
429
Consulte error.code, error.message y meta.request_id.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
500
Consulte error.code, error.message y meta.request_id.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
503
Consulte error.code, error.message y meta.request_id.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
GET/invoices/{invoice}getInvoice

Requiere invoices:read. Incluye partidas, snapshots de facturación, pagos y saldo. No permite confirmar pagos.

Permisos: invoices:read

Respuestas

200
Respuesta
Ver estructura
{
    "application/json": {
        "schema": {
            "type": "object",
            "properties": {
                "data": {
                    "$ref": "#/components/schemas/Invoice"
                }
            }
        }
    }
}
400
Consulte error.code, error.message y meta.request_id.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
401
Consulte error.code, error.message y meta.request_id.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
403
Consulte error.code, error.message y meta.request_id.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
404
Consulte error.code, error.message y meta.request_id.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
409
Consulte error.code, error.message y meta.request_id.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
413
Consulte error.code, error.message y meta.request_id.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
415
Consulte error.code, error.message y meta.request_id.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
422
Consulte error.code, error.message y meta.request_id.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
426
HTTPS requerido.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
429
Consulte error.code, error.message y meta.request_id.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
500
Consulte error.code, error.message y meta.request_id.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
503
Consulte error.code, error.message y meta.request_id.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
GET/invoices/{invoice}/documentdownloadInvoiceDocument

Requiere invoices:read. Documento comercial HTML imprimible, entregado como attachment, sin NCF.

Permisos: invoices:read

Respuestas

200
Factura HTML imprimible
Ver estructura
{
    "text/html": {
        "schema": {
            "type": "string"
        }
    }
}
400
Consulte error.code, error.message y meta.request_id.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
401
Consulte error.code, error.message y meta.request_id.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
403
Consulte error.code, error.message y meta.request_id.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
404
Consulte error.code, error.message y meta.request_id.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
409
Consulte error.code, error.message y meta.request_id.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
413
Consulte error.code, error.message y meta.request_id.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
415
Consulte error.code, error.message y meta.request_id.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
422
Consulte error.code, error.message y meta.request_id.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
426
HTTPS requerido.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
429
Consulte error.code, error.message y meta.request_id.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
500
Consulte error.code, error.message y meta.request_id.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
503
Consulte error.code, error.message y meta.request_id.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
GET/orders/{order}/deliverieslistPublishedDeliveries

Manifiesto paginado de entregas publicadas; requiere results:read, orden completada y factura pagada. Descargue cada archivo con Bearer y compare SHA-256.

Permisos: results:read

Respuestas

200
Respuesta
Ver estructura
{
    "application/json": {
        "schema": {
            "type": "object",
            "properties": {
                "data": {
                    "type": "array",
                    "items": {
                        "$ref": "#/components/schemas/Result"
                    }
                },
                "links": {
                    "type": "object"
                },
                "meta": {
                    "type": "object"
                }
            }
        }
    }
}
401
Error de autenticación, autorización, conflicto, validación o servidor
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
403
Error de autenticación, autorización, conflicto, validación o servidor
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
404
Error de autenticación, autorización, conflicto, validación o servidor
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
409
Error de autenticación, autorización, conflicto, validación o servidor
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
422
Error de autenticación, autorización, conflicto, validación o servidor
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
426
HTTPS requerido.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
429
Error de autenticación, autorización, conflicto, validación o servidor
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
500
Error de autenticación, autorización, conflicto, validación o servidor
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
503
Servicio temporalmente no disponible (incluido escáner de documentos)
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
GET/orders/{order}/results/{result}getPublishedResult

Requiere results:read y acceso a la cuenta. Solo resultados publicados con pago confirmado.

Permisos: results:read

Respuestas

200
Respuesta
Ver estructura
{
    "application/json": {
        "schema": {
            "type": "object",
            "properties": {
                "data": {
                    "$ref": "#/components/schemas/Result"
                }
            }
        }
    }
}
400
Consulte error.code, error.message y meta.request_id.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
401
Consulte error.code, error.message y meta.request_id.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
403
Consulte error.code, error.message y meta.request_id.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
404
Consulte error.code, error.message y meta.request_id.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
409
Consulte error.code, error.message y meta.request_id.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
413
Consulte error.code, error.message y meta.request_id.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
415
Consulte error.code, error.message y meta.request_id.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
422
Consulte error.code, error.message y meta.request_id.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
426
HTTPS requerido.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
429
Consulte error.code, error.message y meta.request_id.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
500
Consulte error.code, error.message y meta.request_id.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}
503
Consulte error.code, error.message y meta.request_id.
Ver estructura
{
    "application/json": {
        "schema": {
            "$ref": "#/components/schemas/Error"
        }
    }
}

Esquemas de datos

Los valores $ref en operaciones remiten a estos esquemas del contrato OpenAPI.

IdentityReuseConsent
{
    "type": "object",
    "required": [
        "consent",
        "notice_version"
    ],
    "properties": {
        "consent": {
            "type": "boolean",
            "enum": [
                true
            ]
        },
        "notice_version": {
            "type": "string",
            "enum": [
                "didit-reuse-2026-10-v1"
            ]
        }
    }
}
ReusableIdentity
{
    "type": "object",
    "properties": {
        "id": {
            "type": "string"
        },
        "display_name": {
            "type": "string"
        },
        "identity_number_hint": {
            "type": "string",
            "description": "Solo últimos cuatro dígitos."
        },
        "environment": {
            "type": "string",
            "enum": [
                "sandbox",
                "live"
            ]
        },
        "state": {
            "type": "string",
            "enum": [
                "available",
                "expired",
                "revoked",
                "unavailable"
            ]
        },
        "expires_at": {
            "type": "string",
            "format": "date-time"
        },
        "consented_at": {
            "type": "string",
            "format": "date-time"
        },
        "notice_version": {
            "type": "string"
        }
    }
}
IdentitySession
{
    "type": "object",
    "properties": {
        "id": {
            "type": "string"
        },
        "order_id": {
            "type": "string"
        },
        "person_id": {
            "type": "string"
        },
        "provider": {
            "type": "string",
            "enum": [
                "didit"
            ]
        },
        "verification_kind": {
            "type": "string",
            "enum": [
                "initial",
                "recurring"
            ]
        },
        "identity_id": {
            "type": "string",
            "nullable": true
        },
        "state": {
            "type": "string",
            "enum": [
                "preparing",
                "awaiting_person",
                "processing",
                "received",
                "attention_required"
            ]
        },
        "environment": {
            "type": "string",
            "enum": [
                "sandbox",
                "live"
            ]
        },
        "billing_mode": {
            "type": "string",
            "enum": [
                "partner_credit"
            ]
        },
        "revision": {
            "type": "integer",
            "minimum": 0
        },
        "verification_url": {
            "type": "string",
            "format": "uri",
            "nullable": true,
            "description": "Enlace secreto Didit, solo awaiting_person con identity:read y lectura vinculada confirmada, sin actualización pendiente. También exige identity:read al repetir POST. Puede permanecer nulo tras crear. No enviarlo por logs, correo ni webhooks; no exponer Bearer ATD al navegador."
        },
        "consented_at": {
            "type": "string",
            "format": "date-time"
        },
        "notice_version": {
            "type": "string"
        },
        "links": {
            "type": "object",
            "properties": {
                "self": {
                    "type": "string"
                },
                "result": {
                    "type": "string"
                }
            }
        }
    }
}
IdentityTechnicalResult
{
    "type": "object",
    "properties": {
        "verification_kind": {
            "type": "string",
            "enum": [
                "initial",
                "recurring"
            ]
        },
        "identity_id": {
            "type": "string",
            "nullable": true
        },
        "document_reverified": {
            "type": "boolean",
            "description": "Indica el alcance del flujo, no éxito documental: true en flujo inicial con comprobación de documento; false en autenticación recurrente sin nueva cédula. Consultar outcome/reason para saber la conclusión."
        },
        "id": {
            "type": "string"
        },
        "order_id": {
            "type": "string"
        },
        "person_id": {
            "type": "string"
        },
        "provider": {
            "type": "string",
            "enum": [
                "didit"
            ]
        },
        "environment": {
            "type": "string",
            "enum": [
                "sandbox",
                "live"
            ]
        },
        "billing_mode": {
            "type": "string",
            "enum": [
                "partner_credit"
            ]
        },
        "revision": {
            "type": "integer",
            "minimum": 1
        },
        "outcome": {
            "type": "string",
            "enum": [
                "verified",
                "not_verified",
                "inconclusive"
            ]
        },
        "reason": {
            "type": "string",
            "description": "Referencia técnica; no contiene datos personales."
        },
        "reviewed_at": {
            "type": "string",
            "format": "date-time"
        },
        "requires_review": {
            "type": "boolean"
        }
    }
}
OrderStatus
{
    "type": "string",
    "enum": [
        "submitted",
        "reviewing",
        "quoted",
        "in_progress",
        "completed",
        "cancelled"
    ]
}
Service
{
    "type": "object",
    "required": [
        "code",
        "name",
        "description"
    ],
    "properties": {
        "identity_mode": {
            "type": "string",
            "nullable": true,
            "enum": [
                "manual",
                "didit",
                null
            ]
        },
        "per_person": {
            "type": "boolean",
            "description": "Todos salvo training-equipment."
        },
        "requires_identity_number": {
            "type": "boolean"
        },
        "required_evidence": {
            "type": "array",
            "items": {
                "type": "string"
            }
        },
        "code": {
            "type": "string"
        },
        "name": {
            "type": "string"
        },
        "description": {
            "type": "string"
        },
        "category": {
            "type": "string",
            "nullable": true,
            "enum": [
                "assessments",
                "verifications",
                "additional",
                null
            ]
        },
        "category_name": {
            "type": "string",
            "nullable": true
        },
        "options": {
            "type": "array",
            "items": {
                "type": "object",
                "required": [
                    "code",
                    "name"
                ],
                "properties": {
                    "code": {
                        "type": "string"
                    },
                    "name": {
                        "type": "string"
                    }
                }
            }
        }
    }
}
CreateOrder
{
    "type": "object",
    "required": [
        "subject",
        "consent",
        "items"
    ],
    "properties": {
        "subject": {
            "type": "string",
            "maxLength": 200
        },
        "details": {
            "type": "string",
            "nullable": true,
            "maxLength": 10000
        },
        "external_reference": {
            "type": "string",
            "nullable": true,
            "maxLength": 100
        },
        "consent": {
            "type": "boolean",
            "enum": [
                true
            ]
        },
        "items": {
            "type": "array",
            "minItems": 1,
            "maxItems": 12,
            "items": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                    "service_code",
                    "quantity"
                ],
                "properties": {
                    "service_code": {
                        "type": "string"
                    },
                    "quantity": {
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 100,
                        "description": "Con people, debe coincidir con el número de personas asignadas a este servicio. Con el campo anterior person, se acepta 1."
                    }
                }
            }
        },
        "person": {
            "$ref": "#/components/schemas/VerificationPerson"
        },
        "people": {
            "type": "array",
            "minItems": 1,
            "maxItems": 10,
            "description": "Una o varias personas, cada una con sus servicios. No se combina con person. Todos los servicios son por persona salvo training-equipment. remote-interview-rppg exige people. Se conserva la creación anterior sin ficha para los servicios que ya la admitían; para integraciones nuevas use people.",
            "items": {
                "$ref": "#/components/schemas/OrderPerson"
            }
        }
    }
}
PaymentAccount
{
    "type": "object",
    "required": [
        "bank_name",
        "account_type",
        "account_holder",
        "account_number",
        "currency"
    ],
    "properties": {
        "bank_name": {
            "type": "string"
        },
        "account_type": {
            "type": "string",
            "enum": [
                "checking",
                "savings"
            ]
        },
        "account_holder": {
            "type": "string"
        },
        "account_number": {
            "type": "string",
            "description": "Conservar como texto, incluidos ceros iniciales."
        },
        "currency": {
            "type": "string",
            "pattern": "^[A-Z]{3}$"
        }
    }
}
Invoice
{
    "type": "object",
    "properties": {
        "id": {
            "type": "string"
        },
        "number": {
            "type": "string"
        },
        "currency": {
            "type": "string"
        },
        "subtotal": {
            "type": "integer"
        },
        "tax_basis_points": {
            "type": "integer"
        },
        "tax": {
            "type": "integer"
        },
        "total": {
            "type": "integer"
        },
        "outstanding": {
            "type": "integer"
        },
        "status": {
            "type": "string",
            "enum": [
                "unpaid",
                "paid"
            ]
        },
        "issued_at": {
            "type": "string",
            "format": "date-time"
        },
        "paid_at": {
            "type": "string",
            "nullable": true,
            "format": "date-time"
        },
        "order_id": {
            "type": "string"
        },
        "paid_amount": {
            "type": "integer",
            "minimum": 0
        },
        "due_date": {
            "type": "string",
            "format": "date",
            "nullable": true
        },
        "is_overdue": {
            "type": "boolean"
        },
        "issuer": {
            "type": "object"
        },
        "recipient": {
            "type": "object",
            "properties": {
                "account_type": {
                    "type": "string",
                    "nullable": true,
                    "enum": [
                        "individual",
                        "business",
                        null
                    ],
                    "description": "Instantánea al emitir; puede faltar en facturas históricas."
                }
            }
        },
        "lines": {
            "type": "array",
            "description": "Partidas confirmadas al emitir. Una familia puede aparecer varias veces con modalidades, cantidades y tarifas diferentes. Las facturas históricas conservan sus partidas originales.",
            "items": {
                "type": "object",
                "properties": {
                    "service_name": {
                        "type": "string"
                    },
                    "service_code": {
                        "type": "string",
                        "description": "Código del servicio agrupador; puede faltar en facturas anteriores."
                    },
                    "option_code": {
                        "type": "string",
                        "nullable": true,
                        "description": "Modalidad de esta partida, si fue especificada. Puede faltar en facturas anteriores."
                    },
                    "option_name": {
                        "type": "string",
                        "nullable": true,
                        "description": "Nombre de modalidad fijado al emitir. Úselo para mostrar la partida cuando esté presente."
                    },
                    "quantity": {
                        "type": "integer",
                        "minimum": 0
                    },
                    "unit_price": {
                        "type": "integer",
                        "minimum": 0
                    },
                    "total": {
                        "type": "integer",
                        "minimum": 0
                    }
                }
            }
        },
        "payments": {
            "type": "array",
            "description": "Solo en la ficha individual.",
            "items": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string"
                    },
                    "amount": {
                        "type": "integer",
                        "minimum": 0
                    },
                    "method": {
                        "type": "string"
                    },
                    "reference": {
                        "type": "string"
                    },
                    "received_at": {
                        "type": "string",
                        "format": "date-time"
                    }
                }
            }
        },
        "document_url": {
            "type": "string",
            "format": "uri"
        },
        "payment_accounts": {
            "type": "array",
            "description": "Cuentas ATD activas, de la misma moneda, para facturas con saldo pendiente. Lista vacía si pagada o sin cuentas configuradas. Son instrucciones vigentes, no una instantánea histórica. No equivale a pago registrado.",
            "items": {
                "$ref": "#/components/schemas/PaymentAccount"
            }
        }
    }
}
Order
{
    "type": "object",
    "properties": {
        "id": {
            "type": "string"
        },
        "subject": {
            "type": "string"
        },
        "details": {
            "type": "string",
            "nullable": true
        },
        "external_reference": {
            "type": "string",
            "nullable": true
        },
        "status": {
            "$ref": "#/components/schemas/OrderStatus"
        },
        "items": {
            "type": "array",
            "items": {
                "type": "object",
                "properties": {
                    "service_code": {
                        "type": "string"
                    },
                    "service_name": {
                        "type": "string"
                    },
                    "quantity": {
                        "type": "integer"
                    },
                    "unit_price": {
                        "type": "integer",
                        "nullable": true,
                        "description": "Precio unitario común de la partida agrupada. null si aún no se factura o si sus modalidades tienen precios diferentes; concilie con invoice.lines mediante invoices:read."
                    }
                }
            }
        },
        "invoice": {
            "allOf": [
                {
                    "$ref": "#/components/schemas/Invoice"
                }
            ],
            "nullable": true,
            "description": "Solo se incluye información de factura si el token tiene invoices:read; en otro caso es null."
        },
        "created_at": {
            "type": "string",
            "format": "date-time"
        },
        "updated_at": {
            "type": "string",
            "format": "date-time"
        },
        "links": {
            "type": "object"
        },
        "person": {
            "allOf": [
                {
                    "$ref": "#/components/schemas/VerificationPerson"
                }
            ],
            "nullable": true,
            "description": "Compatibilidad: solo creación/detalle, perfil si hay una persona; null si hay varias o no hay ficha. Ausente del listado."
        },
        "people": {
            "type": "array",
            "description": "Solo creación y detalle autorizado; ausente del listado, notificaciones y webhooks.",
            "items": {
                "$ref": "#/components/schemas/OrderPerson"
            }
        },
        "verification": {
            "$ref": "#/components/schemas/VerificationEvidence"
        },
        "customer_account": {
            "type": "object",
            "nullable": true,
            "readOnly": true,
            "description": "Cuenta determinada por el servidor a partir del usuario autenticado; nunca permite seleccionar otra cuenta desde el cuerpo.",
            "properties": {
                "id": {
                    "type": "string",
                    "description": "ULID público de la cuenta."
                },
                "name": {
                    "type": "string"
                },
                "account_type": {
                    "type": "string",
                    "nullable": true,
                    "enum": [
                        "individual",
                        "business",
                        null
                    ],
                    "description": "null solo en cuentas anteriores pendientes de clasificación."
                }
            }
        }
    }
}
Result
{
    "type": "object",
    "properties": {
        "preview_url": {
            "type": "string",
            "nullable": true,
            "description": "Solo imágenes; requiere results:read y las mismas condiciones de pago/publicación que la descarga."
        },
        "id": {
            "type": "string"
        },
        "summary": {
            "type": "string"
        },
        "published_at": {
            "type": "string",
            "format": "date-time"
        },
        "file_name": {
            "type": "string",
            "nullable": true
        },
        "download_url": {
            "type": "string",
            "nullable": true
        },
        "file_size": {
            "type": "integer",
            "minimum": 0,
            "nullable": true
        },
        "sha256": {
            "type": "string",
            "nullable": true,
            "pattern": "^[a-f0-9]{64}$",
            "description": "SHA-256 del archivo para verificar su integridad."
        },
        "order_id": {
            "type": "string"
        },
        "mime_type": {
            "type": "string",
            "nullable": true
        },
        "verification_findings": {
            "$ref": "#/components/schemas/VerificationFindings"
        }
    }
}
Message
{
    "type": "object",
    "properties": {
        "id": {
            "type": "integer"
        },
        "body": {
            "type": "string"
        },
        "sender": {
            "type": "string",
            "enum": [
                "ATD",
                "client"
            ]
        },
        "created_at": {
            "type": "string",
            "format": "date-time"
        }
    }
}
Error
{
    "type": "object",
    "required": [
        "error",
        "meta"
    ],
    "properties": {
        "error": {
            "type": "object",
            "required": [
                "code",
                "message",
                "fields"
            ],
            "properties": {
                "code": {
                    "type": "string"
                },
                "message": {
                    "type": "string"
                },
                "fields": {
                    "type": "object"
                }
            }
        },
        "meta": {
            "type": "object",
            "properties": {
                "request_id": {
                    "type": "string",
                    "format": "uuid"
                }
            }
        }
    }
}
Attachment
{
    "type": "object",
    "required": [
        "id",
        "file_name",
        "mime_type",
        "created_at",
        "download_url"
    ],
    "properties": {
        "person_id": {
            "type": "string",
            "nullable": true,
            "description": "Identificador público de la persona, nunca el ID interno."
        },
        "preview_url": {
            "type": "string",
            "nullable": true,
            "description": "Solo imágenes; requiere Bearer orders:read, no es un enlace público."
        },
        "id": {
            "type": "string"
        },
        "file_name": {
            "type": "string"
        },
        "mime_type": {
            "type": "string"
        },
        "created_at": {
            "type": "string",
            "format": "date-time"
        },
        "download_url": {
            "type": "string"
        },
        "file_size": {
            "type": "integer",
            "minimum": 0,
            "nullable": true
        },
        "sha256": {
            "type": "string",
            "nullable": true,
            "pattern": "^[a-f0-9]{64}$",
            "description": "SHA-256 del archivo para verificar su integridad."
        },
        "purpose": {
            "type": "string",
            "enum": [
                "supporting",
                "identity_front",
                "identity_back",
                "selfie",
                "selfie_extra",
                "degree_document",
                "exequatur_document",
                "bailiff_credential"
            ],
            "default": "supporting"
        }
    }
}
WebhookEvent
{
    "type": "object",
    "required": [
        "id",
        "type",
        "created_at",
        "data"
    ],
    "properties": {
        "id": {
            "type": "string",
            "format": "uuid"
        },
        "type": {
            "type": "string",
            "enum": [
                "order.created",
                "order.updated",
                "invoice.issued",
                "payment.recorded",
                "invoice.paid",
                "result.published",
                "endpoint.test"
            ]
        },
        "created_at": {
            "type": "string",
            "format": "date-time"
        },
        "data": {
            "type": "object",
            "properties": {
                "order_id": {
                    "type": "string",
                    "nullable": true
                },
                "status": {
                    "$ref": "#/components/schemas/OrderStatus"
                },
                "invoice_id": {
                    "type": "string",
                    "nullable": true
                },
                "result_id": {
                    "type": "string",
                    "nullable": true
                },
                "endpoint_id": {
                    "type": "string"
                },
                "links": {
                    "type": "object"
                }
            }
        }
    }
}
OrderPerson
{
    "type": "object",
    "additionalProperties": false,
    "required": [
        "first_name",
        "last_name",
        "authorization_confirmed",
        "service_codes"
    ],
    "description": "Ficha cifrada por solicitud. Cédula y finalidad obligatorias para título, exequátur, identidad y credenciales de alguacil. No aportar cédula para otros servicios. Dirección obligatoria para título, exequátur, identidad y visitas domiciliarias. Los códigos retirados se conservan en respuestas históricas, pero no se aceptan en solicitudes nuevas. No acepta decisiones ni identificadores del cliente.",
    "properties": {
        "identity_mode": {
            "type": "string",
            "enum": [
                "manual",
                "didit"
            ],
            "readOnly": true
        },
        "identity_session_url": {
            "type": "string",
            "format": "uri",
            "nullable": true,
            "readOnly": true
        },
        "id": {
            "type": "string",
            "readOnly": true,
            "description": "ULID público generado por ATD; úselo en person_id al cargar evidencia."
        },
        "service_codes": {
            "type": "array",
            "minItems": 1,
            "maxItems": 12,
            "uniqueItems": true,
            "items": {
                "type": "string",
                "enum": [
                    "polygraph",
                    "deception-detection",
                    "profile-verification",
                    "applied-ai",
                    "home-visits",
                    "investigations",
                    "drug-screening",
                    "psychometric",
                    "university-degree",
                    "exequatur",
                    "identity-verification",
                    "bailiff-credentials"
                ]
            }
        },
        "first_name": {
            "$ref": "#/components/schemas/VerificationPerson/properties/first_name"
        },
        "last_name": {
            "$ref": "#/components/schemas/VerificationPerson/properties/last_name"
        },
        "identity_number": {
            "$ref": "#/components/schemas/VerificationPerson/properties/identity_number"
        },
        "address": {
            "$ref": "#/components/schemas/VerificationPerson/properties/address"
        },
        "birth_date": {
            "$ref": "#/components/schemas/VerificationPerson/properties/birth_date"
        },
        "phone": {
            "$ref": "#/components/schemas/VerificationPerson/properties/phone"
        },
        "email": {
            "$ref": "#/components/schemas/VerificationPerson/properties/email"
        },
        "purpose": {
            "$ref": "#/components/schemas/VerificationPerson/properties/purpose"
        },
        "authorization_confirmed": {
            "$ref": "#/components/schemas/VerificationPerson/properties/authorization_confirmed"
        },
        "degree": {
            "$ref": "#/components/schemas/VerificationPerson/properties/degree"
        },
        "exequatur": {
            "$ref": "#/components/schemas/VerificationPerson/properties/exequatur"
        },
        "bailiff": {
            "type": "object",
            "nullable": true,
            "additionalProperties": false,
            "description": "Solo con bailiff-credentials. Los campos son opcionales; la credencial escaneada se aporta aparte.",
            "properties": {
                "credential_number": {
                    "type": "string",
                    "maxLength": 100,
                    "nullable": true
                },
                "issuing_authority": {
                    "type": "string",
                    "maxLength": 200,
                    "nullable": true
                },
                "jurisdiction": {
                    "type": "string",
                    "maxLength": 200,
                    "nullable": true
                }
            }
        },
        "service_options": {
            "type": "object",
            "nullable": true,
            "additionalProperties": false,
            "description": "Modalidades opcionales por persona. Cada clave debe corresponder a un servicio seleccionado; consulte options del catálogo. Omitir equivale a definirlo con ATD.",
            "properties": {
                "polygraph": {
                    "type": "string",
                    "nullable": true,
                    "enum": [
                        "pre_employment",
                        "routine",
                        "specific",
                        null
                    ]
                },
                "profile-verification": {
                    "type": "string",
                    "nullable": true,
                    "enum": [
                        "basic",
                        "routine",
                        "management",
                        "investigative",
                        null
                    ]
                }
            }
        }
    }
}
VerificationPerson
{
    "type": "object",
    "additionalProperties": false,
    "description": "Campo anterior compatible para una sola persona, cantidad=1. No combinar con people; se recomienda people para nuevas integraciones. Solo creación/detalle autorizado, nunca listados ni webhooks. También compatible con bailiff-credentials; para ese servicio address es opcional.",
    "required": [
        "first_name",
        "last_name",
        "identity_number",
        "address",
        "purpose",
        "authorization_confirmed"
    ],
    "properties": {
        "first_name": {
            "type": "string",
            "maxLength": 100
        },
        "last_name": {
            "type": "string",
            "maxLength": 100
        },
        "identity_number": {
            "type": "string",
            "pattern": "^[0-9]{3}-?[0-9]{7}-?[0-9]$",
            "description": "Cédula dominicana de 11 dígitos. Se normaliza sin guiones; validar formato no demuestra autenticidad."
        },
        "address": {
            "type": "string",
            "maxLength": 1000
        },
        "birth_date": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "Opcional, no futura."
        },
        "phone": {
            "type": "string",
            "maxLength": 40,
            "nullable": true
        },
        "email": {
            "type": "string",
            "format": "email",
            "maxLength": 254,
            "nullable": true
        },
        "purpose": {
            "type": "string",
            "maxLength": 1000,
            "minLength": 5
        },
        "authorization_confirmed": {
            "type": "boolean",
            "enum": [
                true
            ]
        },
        "degree": {
            "type": "object",
            "additionalProperties": false,
            "description": "Obligatorio solo con university-degree.",
            "required": [
                "institution",
                "degree_name"
            ],
            "properties": {
                "institution": {
                    "type": "string",
                    "maxLength": 200
                },
                "degree_name": {
                    "type": "string",
                    "maxLength": 200
                },
                "graduation_year": {
                    "type": "integer",
                    "minimum": 1900,
                    "nullable": true,
                    "description": "No posterior al año actual."
                },
                "registration_number": {
                    "type": "string",
                    "maxLength": 100,
                    "nullable": true
                }
            }
        },
        "exequatur": {
            "type": "object",
            "additionalProperties": false,
            "description": "Obligatorio solo con exequatur.",
            "required": [
                "profession"
            ],
            "properties": {
                "profession": {
                    "type": "string",
                    "maxLength": 200
                },
                "number": {
                    "type": "string",
                    "maxLength": 100,
                    "nullable": true
                },
                "issuing_authority": {
                    "type": "string",
                    "maxLength": 200,
                    "nullable": true
                },
                "issued_on": {
                    "type": "string",
                    "format": "date",
                    "nullable": true,
                    "description": "No futura."
                }
            }
        },
        "bailiff": {
            "type": "object",
            "nullable": true,
            "additionalProperties": false,
            "description": "Solo con bailiff-credentials. Los campos son opcionales; la credencial escaneada se aporta aparte.",
            "properties": {
                "credential_number": {
                    "type": "string",
                    "maxLength": 100,
                    "nullable": true
                },
                "issuing_authority": {
                    "type": "string",
                    "maxLength": 200,
                    "nullable": true
                },
                "jurisdiction": {
                    "type": "string",
                    "maxLength": 200,
                    "nullable": true
                }
            }
        },
        "service_options": {
            "type": "object",
            "nullable": true,
            "additionalProperties": false,
            "description": "Modalidades opcionales por persona. Cada clave debe corresponder a un servicio seleccionado; consulte options del catálogo. Omitir equivale a definirlo con ATD.",
            "properties": {
                "polygraph": {
                    "type": "string",
                    "nullable": true,
                    "enum": [
                        "pre_employment",
                        "routine",
                        "specific",
                        null
                    ]
                },
                "profile-verification": {
                    "type": "string",
                    "nullable": true,
                    "enum": [
                        "basic",
                        "routine",
                        "management",
                        "investigative",
                        null
                    ]
                }
            }
        }
    }
}
VerificationEvidence
{
    "type": "object",
    "nullable": true,
    "required": [
        "method",
        "ready_for_review",
        "required",
        "missing"
    ],
    "properties": {
        "people": {
            "type": "array",
            "items": {
                "type": "object",
                "required": [
                    "person_id",
                    "ready_for_review",
                    "required",
                    "missing"
                ],
                "properties": {
                    "person_id": {
                        "type": "string"
                    },
                    "method": {
                        "type": "string",
                        "enum": [
                            "manual",
                            "didit"
                        ]
                    },
                    "identity_pending": {
                        "type": "boolean",
                        "description": "Estado operativo, nunca aprobación/rechazo."
                    },
                    "ready_for_review": {
                        "type": "boolean"
                    },
                    "required": {
                        "type": "array",
                        "items": {
                            "type": "string"
                        }
                    },
                    "missing": {
                        "type": "array",
                        "items": {
                            "type": "string"
                        }
                    }
                }
            }
        },
        "method": {
            "type": "string",
            "enum": [
                "manual",
                "mixed_or_didit"
            ]
        },
        "ready_for_review": {
            "type": "boolean",
            "description": "Solo completitud de evidencias, NO decisión sobre identidad."
        },
        "required": {
            "type": "array",
            "items": {
                "type": "string",
                "enum": [
                    "identity_front",
                    "selfie",
                    "degree_document",
                    "exequatur_document",
                    "bailiff_credential"
                ]
            }
        },
        "missing": {
            "type": "array",
            "items": {
                "type": "string",
                "enum": [
                    "identity_front",
                    "selfie",
                    "degree_document",
                    "exequatur_document",
                    "bailiff_credential"
                ]
            }
        }
    }
}
VerificationFindings
{
    "type": "object",
    "nullable": true,
    "description": "Solo entregas publicadas tras pago total y finalización. Conclusiones manuales, Didit o mixtas. No es una decisión de elegibilidad. Una corrección del proveedor invalida la publicación anterior.",
    "required": [
        "method",
        "reviewed_at",
        "checks"
    ],
    "properties": {
        "method": {
            "type": "string",
            "enum": [
                "manual",
                "didit",
                "mixed"
            ]
        },
        "reviewed_at": {
            "type": "string",
            "format": "date-time"
        },
        "checks": {
            "type": "array",
            "items": {
                "type": "object",
                "required": [
                    "service_code",
                    "outcome",
                    "notes"
                ],
                "properties": {
                    "person_id": {
                        "type": "string",
                        "description": "Persona de la comprobación. Siempre incluido en conclusiones nuevas agrupadas por persona; puede faltar en entregas anteriores."
                    },
                    "method": {
                        "type": "string",
                        "enum": [
                            "didit"
                        ],
                        "description": "Incluido en comprobaciones automáticas."
                    },
                    "session_id": {
                        "type": "string",
                        "description": "Referencia ATD, no token ni identificador secreto del proveedor."
                    },
                    "environment": {
                        "type": "string",
                        "enum": [
                            "sandbox",
                            "live"
                        ],
                        "description": "Sandbox no es una verificación real ni puede publicarse en producción."
                    },
                    "service_code": {
                        "type": "string"
                    },
                    "outcome": {
                        "type": "string",
                        "enum": [
                            "verified",
                            "not_verified",
                            "inconclusive",
                            "reviewed"
                        ],
                        "description": "Para remote-interview-rppg se devuelve reviewed (evaluación revisada por un analista) o inconclusive. Los demás servicios conservan sus valores anteriores."
                    },
                    "notes": {
                        "type": "string",
                        "maxLength": 5000
                    }
                }
            }
        }
    }
}