Constaia

Empieza en 5 minutos

Crea una cuenta gratis, copia tu clave de test y valida tu primer DNI con curl, JavaScript o PHP en menos de cinco minutos.

En esta guía harás tres llamadas en modo test y verás los tres veredictos posibles: valid, invalid y review. El modo test no consume créditos y responde siempre lo mismo para el mismo nombre de fichero, así que puedes seguirla sin gastar nada.

Crea una cuenta gratis

Regístrate en app.constaia.com/signup. El plan gratis incluye 250 créditos al mes que se renuevan cada mes, sin tarjeta.

Copia tu clave de test

Al crear la cuenta se genera una clave de test. La encontrarás en Claves de API dentro del panel. Empieza por ck_test_. Guárdala en una variable de entorno:

export CONSTAIA_API_KEY="ck_test_..."

Las claves se muestran una sola vez. Si la pierdes, crea otra en el panel y revoca la anterior. Más en Autenticación.

Valida tu primer DNI

En modo test, la respuesta depende del nombre del fichero. Guarda cualquier imagen JPEG como dni_valid.jpg y envíala indicando que esperas un DNI español:

curl https://api.constaia.com/v1/analyze \
  -H "Authorization: Bearer $CONSTAIA_API_KEY" \
  -F file=@dni_valid.jpg \
  -F 'options={"expect":"es_dni"}'

La respuesta completa tiene este aspecto:

200 OK
{
  "id": "an_01J…",
  "object": "analysis",
  "status": "completed",
  "livemode": false,
  "created_at": "2026-09-29T10:00:00Z",
  "completed_at": "2026-09-29T10:00:02Z",
  "file": { "name": "dni_valid.jpg", "mime_type": "image/jpeg", "pages": 2, "size_bytes": 482133 },
  "document": { "type": "es_dni", "label": "DNI (España)", "confidence": 0.97, "side": "both", "country": "ESP" },
  "verdict": {
    "expected": ["es_dni"],
    "match": true,
    "status": "valid",
    "reasons": [
      { "code": "type_match", "severity": "info", "message": "El documento es un DNI español." },
      { "code": "not_expired", "severity": "info", "message": "Vigente hasta el 12/03/2031." }
    ]
  },
  "fields": {
    "document_number": { "value": "12345678Z", "confidence": 0.99, "validated": true, "source": { "page": 1, "bbox": [0.61, 0.12, 0.83, 0.16] } },
    "first_name": { "value": "MARÍA", "confidence": 0.98, "validated": null, "source": { "page": 1, "bbox": [0.3, 0.2, 0.5, 0.24] } }
  },
  "checks": [
    { "code": "nif_check_digit", "passed": true, "message": "La letra del DNI es correcta." },
    { "code": "mrz_checksums", "passed": true, "message": "Los dígitos de control de la MRZ son correctos." },
    { "code": "mrz_matches_visual", "passed": true, "message": "La MRZ coincide con los datos impresos." }
  ],
  "warnings": [],
  "exports": {},
  "storage": { "mode": "none", "file_deleted_at": "2026-09-29T10:00:02Z", "expires_at": null },
  "usage": { "credits": 1, "pages": 2 },
  "metadata": {}
}

Lo importante:

  • verdict.status es valid: es un DNI y está vigente.
  • fields trae los datos extraídos, cada uno con su confianza y la zona de la página de la que sale.
  • checks son comprobaciones hechas en código (letra del NIF, MRZ), no opiniones del modelo.
  • storage.file_deleted_at confirma que el fichero ya se ha borrado.
  • livemode: false indica que es una respuesta de test: no se ha descontado nada de tu saldo.

Prueba un DNI caducado y una foto borrosa

Repite la llamada con dni_expired.jpg:

curl https://api.constaia.com/v1/analyze \
  -H "Authorization: Bearer $CONSTAIA_API_KEY" \
  -F file=@dni_expired.jpg \
  -F 'options={"expect":"es_dni"}' | jq '.verdict'

El tipo coincide, pero el documento está caducado, así que el veredicto es No válido y entre los motivos aparece el código expired:

{
  "expected": ["es_dni"],
  "match": true,
  "status": "invalid",
  "reasons": [
    { "code": "type_match", "severity": "info", "message": "El documento es un DNI español." },
    { "code": "expired", "severity": "error", "message": "El documento está caducado." }
  ]
}

Ahora con blurry.jpg:

curl https://api.constaia.com/v1/analyze \
  -H "Authorization: Bearer $CONSTAIA_API_KEY" \
  -F file=@blurry.jpg \
  -F 'options={"expect":"es_dni"}' | jq '{status: .verdict.status, warnings: .warnings}'
{ "status": "review", "warnings": ["blurry"] }

La imagen no se puede leer con seguridad, así que Constaia no decide por ti: devuelve Revisar y el aviso blurry. En tu aplicación, lo normal es pedir al usuario otra foto o pasar el caso a una persona.

Tienes la lista completa de ficheros de prueba en Modo test.

Hazlo desde tu código

El mismo flujo con los SDKs oficiales. En JavaScript las opciones van en camelCase; en PHP, en snake_case como en la API.

npm i @constaia/sdk
verify.ts
import { Constaia } from "@constaia/sdk";
import { fromPath } from "@constaia/sdk/node";

const constaia = new Constaia(); // lee CONSTAIA_API_KEY

for (const name of ["dni_valid.jpg", "dni_expired.jpg", "blurry.jpg"]) {
  const analysis = await constaia.analyze(await fromPath(name), {
    expect: "es_dni",
    checks: { notExpired: true },
    language: "es",
  });

  console.log(name, analysis.verdict?.status, analysis.warnings);
  for (const reason of analysis.verdict?.reasons ?? []) {
    console.log(`  ${reason.code}: ${reason.message}`);
  }
}

Pasa a producción

Cuando tu integración funcione en test:

  1. Crea una clave ck_live_ en el panel.
  2. Cámbiala en la variable de entorno de tu servidor. El código no cambia.
  3. Cada análisis consumirá créditos de tu plan gratis o de los packs que compres.

A partir de aquí, livemode será true y los documentos se analizan de verdad.

Siguientes pasos

En esta página