Sesiones y claves publicables
Referencia de /v1/sessions y de las claves publicables pk_: tu backend crea una sesión de 15 minutos y el navegador sube cada documento directamente a Constaia con el client_secret, sin exponer tu clave secreta.
Las sesiones (sess_…) permiten que el navegador suba los documentos directamente a Constaia, sin pasar el
fichero por tu servidor y sin exponer tu clave secreta:
- Tu backend crea una sesión con la clave secreta (
ck_…) y decide qué se pide y qué se comprueba. - Tu página recibe solo el
client_secretde la sesión. - El navegador sube el documento a
POST /v1/analyzecon una clave publicable (pk_…) y eseclient_secret.
Guía completa con el widget, fetch y el SDK: Integración solo frontend.
| Método y ruta | Clave | Qué hace |
|---|---|---|
POST /v1/sessions | secreta | Crea una sesión y devuelve su client_secret. |
GET /v1/sessions/{id} | secreta | Recupera la sesión: estado y análisis de cada documento. |
POST /v1/analyze | publicable | Sube un documento de la sesión desde el navegador. |
Tu servidor (ck_) Navegador (pk_) Constaia
───────────────── ─────────────── ────────
POST /v1/sessions ──────────────────────────────────────────────────▶ sess_… + client_secret (15 min)
└─ client_secret ─────────────▶ <constaia-upload> / fetch
POST /v1/analyze ───────────────────▶ análisis con las opciones de la sesión
GET /v1/sessions/{id} ──────────────────────────────────────────────▶ documents[].analysis_id
GET /v1/analyses/{id} (o webhook analysis.completed) ─────────────▶ veredictoClaves publicables
Una clave publicable (pk_live_… o pk_test_…) puede ir en el código de tu web: solo sirve para subir documentos a
una sesión que ya creó tu servidor, y solo desde los dominios que autorices.
- Se crean en el panel: Desarrolladores → Claves de API, tipo Publicable. Como todas las claves, se muestran una sola vez.
- Dominios permitidos (1–20):
app.tuweb.com(ese host exacto),*.tuweb.com(cualquier subdominio, pero notuweb.coma secas: añádelo aparte) y, solo en claves de test,localhost:3000. El puerto forma parte del host. Los cambios de dominios se aplican al momento. - La petición del navegador debe llevar la cabecera
Originde uno de esos dominios (los navegadores la ponen solos). Si no:403 origin_not_allowed. - Solo sirven para
POST /v1/analyzeconclient_secret. Cualquier otra ruta responde403 publishable_key_not_allowed. - El modo va con la clave: una
pk_test_…solo abre sesiones creadas con unack_test_…, y unapk_live_…, las deck_live_….
Las claves secretas, nunca en el navegador
Una clave ck_… que llega desde una página de otro origen (cabecera Sec-Fetch-Site distinta de same-origin) se
rechaza con 403 secret_key_in_browser, aunque sea correcta. Si ya se ha publicado, revócala en el panel. Ver
Autenticación.
Crear una sesión
POST /v1/sessions
Authorization: Bearer ck_live_…
Content-Type: application/json| Campo | Tipo | Descripción |
|---|---|---|
template | string | Plantilla (tpl_…) con las opciones de análisis de todos los documentos. 422 template_not_found si no existe. |
documents | objeto[] (1–10) | Documentos que se pueden subir. Cada uno: key (1–40 caracteres: letras, números, - o _, única), label, expect (tipo o lista de tipos) y checks (como en analyze). Sin documents: uno, key: "document", con las opciones de la plantilla. |
reference | string | Tu referencia (hasta 200 caracteres). Llega a cada análisis como metadata.session_reference. |
metadata | objeto string → string | Hasta 20 claves. Se copia a cada análisis. Ponle el id del usuario para cruzar el resultado. |
language | es | en | pt | fr | Idioma de los mensajes del veredicto, si el navegador no manda otro. |
Las opciones de cada documento salen de la plantilla y, encima, del expect y los checks del documento (checks clave
a clave). Aquí es donde pones lo que no puede decidir el navegador: por ejemplo el titular esperado
(checks.holder) a partir del usuario autenticado.
curl https://api.constaia.com/v1/sessions \
-H "Authorization: Bearer $CONSTAIA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"template": "tpl_01J9Z8Q3K4M5N6P7Q8R9S0T1V2",
"reference": "user_42",
"metadata": { "user_id": "42" },
"documents": [
{ "key": "id_card", "label": "DNI o NIE", "expect": ["es_dni", "es_nie"], "checks": { "holder": { "full_name": "María García López" } } }
]
}'{
"id": "sess_01J9Z8Q3K4M5N6P7Q8R9S0T1V2",
"object": "session",
"client_secret": "sess_01J9Z8Q3K4M5N6P7Q8R9S0T1V2_secret_Xk2…",
"status": "open",
"livemode": true,
"template": "tpl_01J9Z8Q3K4M5N6P7Q8R9S0T1V2",
"reference": "user_42",
"metadata": { "user_id": "42" },
"documents": [
{ "key": "id_card", "label": "DNI o NIE", "expect": ["es_dni", "es_nie"], "analysis_id": null, "status": "pending" }
],
"expires_at": "2026-09-30T10:15:00Z",
"created_at": "2026-09-30T10:00:00Z"
}| Campo | Descripción |
|---|---|
client_secret | Solo en la creación. Pásalo a la página. Da acceso a subir los documentos de esta sesión y a nada más. |
status | open, completed (todos los documentos subidos) o expired (pasados 15 minutos sin completarse). |
documents[].status | pending (sin subir), processing (subida en curso) o submitted (ya tiene análisis). |
documents[].analysis_id | El análisis creado con la subida, o null. |
expires_at | 15 minutos después de crearla. Crea la sesión al pintar la página, no por adelantado. |
Subir desde el navegador
POST /v1/analyze
Authorization: Bearer pk_live_…
Content-Type: multipart/form-data| Campo | Descripción |
|---|---|
file | El documento. |
client_secret | El de la sesión. |
document_key | La key del documento de la sesión. Opcional si la sesión tiene uno solo. |
options | Opcional. JSON en el que solo se tiene en cuenta language. Todo lo demás (expect, checks, almacenamiento…) sale de la sesión y su plantilla. |
const form = new FormData();
form.append("file", input.files[0]);
form.append("client_secret", clientSecret);
form.append("document_key", "id_card");
const res = await fetch("https://api.constaia.com/v1/analyze", {
method: "POST",
headers: { Authorization: "Bearer pk_live_…" },
body: form,
});
const analysis = await res.json();Responde con el objeto analysis, igual que una llamada normal (200,
o 202 si tarda más de 30 s), con session_id y document_key. Se cobra a tu cuenta como cualquier análisis.
- Cada documento se analiza una vez. Una segunda subida del mismo documento devuelve
409 document_already_submitted. Si la subida falla antes de crear el análisis (fichero no válido, sin créditos, límite de peticiones), el documento queda libre para volver a intentarlo. - No hay resultados progresivos (
stream) niIdempotency-Keyen este modo. - El navegador no puede leer análisis ni sesiones: el resultado que ve sirve para la interfaz, no para decidir.
Recuperar una sesión
curl https://api.constaia.com/v1/sessions/sess_01J9Z8Q3K4M5N6P7Q8R9S0T1V2 \
-H "Authorization: Bearer $CONSTAIA_API_KEY"Devuelve la sesión sin client_secret. Cuando el usuario termina, tu backend lee aquí el analysis_id de cada
documento y el análisis con GET /v1/analyses/{id} (o lo recibe por el webhook
analysis.completed), y decide con ese veredicto. Solo ve sesiones del modo de la clave; si no existe,
404 resource_missing.
SDK
import { Constaia } from "@constaia/sdk";
// Backend (clave secreta)
const constaia = new Constaia();
const session = await constaia.sessions.create({
template: "tpl_01J9Z8Q3K4M5N6P7Q8R9S0T1V2",
reference: "user_42",
documents: [{ key: "id_card", expect: ["es_dni", "es_nie"] }],
});
// → session.client_secret a la página
// Navegador (clave publicable): solo permite sessions.submit()
const browser = new Constaia({ apiKey: "pk_live_…" });
const analysis = await browser.sessions.submit(file, { clientSecret, documentKey: "id_card" });Errores
| HTTP | code | Cuándo |
|---|---|---|
401 | session_invalid | El client_secret no existe, está mal formado o es de otro modo o cuenta. |
401 | session_expired | La sesión ha caducado (15 minutos). Crea otra. |
403 | origin_not_allowed | El origen de la página no está en los dominios permitidos de la clave publicable. |
403 | publishable_key_not_allowed | Una clave pk_ en una ruta que no es POST /v1/analyze. |
403 | secret_key_in_browser | Una clave ck_ usada desde un navegador. |
409 | document_already_submitted | Ese documento de la sesión ya se subió. |
422 | invalid_document_key | document_key no está en la sesión, o falta y la sesión tiene varios documentos. |
422 | duplicate_document_key | Al crear: dos documentos con la misma key. |
422 | template_not_found | Al crear: la plantilla no existe (param: "options.template"). |
Los mensajes de estos errores están pensados para enseñarse a la persona (en es, en, pt o fr). El resto de
errores de la subida (saldo, límites, fichero no válido) son los de analyze.
Siguientes pasos
Expedientes
Referencia de /v1/dossiers: agrupa varios documentos de una misma persona o trámite con requisitos, añade documentos por fichero o analysis_id y obtén un veredicto global con comprobaciones cruzadas de titular y fechas.
GET /v1/document-types
Referencia de GET /v1/document-types: catálogo público de tipos de documento con campos, JSON Schema, validadores y checks aplicables, sin clave de API.