Lía Partner API
Última actualización: 23 jul 2026
La Partner API permite a un integrador registrar vacantes, analizar CVs contra ellas y leer los resultados del análisis de compatibilidad, todo por HTTP. Es un producto server-to-server: se consume con una API key propia, no con usuarios finales.
Base URL: https://jvbhqvbapwoyveeoiyii.supabase.co/functions/v1/partner-api
El acceso a la Partner API se habilita mediante acuerdo comercial.
Solicitar acceso a la API →Autenticación
Todas las llamadas requieren el header:
Authorization: Bearer lia_live_xxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx- La key tiene el formato
lia_<ambiente>_<prefijo>_<secreto>, donde<ambiente>estestolive. - Las keys test y live son clientes distintos: sus vacantes y análisis están aislados entre sí. El prefijo identifica el ambiente de la credencial.
- Se entrega una sola vez al dar de alta el cliente; Lía no la almacena en claro y no puede volver a mostrarla. Guárdala en un gestor de secretos.
- Cada key tiene scopes asignados por contrato (
jobs:write,analyses:write,analyses:read).
Si la key falta, es inválida o está inactiva, la respuesta es 401 con el envelope de error estándar:
{ "error": { "code": "unauthorized", "message": "API key inválida o inactiva", "request_id": "b1f2..." } }Endpoints
1. Crear vacante — POST /v1/jobs
Registra una vacante y genera su perfil de evaluación con IA. Scope: jobs:write.
Headers: Authorization, Content-Type: application/json
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
title | string | sí | Título de la vacante. |
description | string | no | Descripción / responsabilidades. |
requirements | object | no | Requisitos estructurados (formato libre). |
external_job_id | string | no | Id de la vacante en tu sistema, para correlación. |
Ejemplo:
curl -X POST "https://jvbhqvbapwoyveeoiyii.supabase.co/functions/v1/partner-api/v1/jobs" \
-H "Authorization: Bearer lia_live_ab12cd34_..." \
-H "Content-Type: application/json" \
-d '{
"title": "Ejecutivo de Ventas Inmobiliarias",
"description": "Cierre consultivo de propiedades de alto valor.",
"requirements": { "experiencia_min_anios": 3, "idiomas": ["es"] },
"external_job_id": "JOB-4471"
}'Respuesta 201 Created:
{ "job_id": "a3d9c1e0-...", "status": "active" }Guarda el job_id: lo necesitas para analizar CVs. La misma vacante (mismo contenido) enviada de nuevo reutiliza el perfil ya generado y responde 200 con el mismo job_id.
2. Analizar un CV — POST /v1/jobs/{job_id}/analyses
Sube un CV en PDF y encola su análisis contra la vacante. Scope: analyses:write.
Headers: Authorization, Idempotency-Key: <único-por-CV> (obligatorio), Content-Type: multipart/form-data
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
cv | file (PDF) | sí | El CV. Solo PDF, máximo 10 MB. |
external_candidate_id | string | no | Id del candidato en tu sistema (recomendado). |
Ejemplo:
curl -X POST "https://jvbhqvbapwoyveeoiyii.supabase.co/functions/v1/partner-api/v1/jobs/a3d9c1e0-.../analyses" \
-H "Authorization: Bearer lia_live_ab12cd34_..." \
-H "Idempotency-Key: cand-8891-job-4471" \
-F "cv=@/ruta/al/cv.pdf;type=application/pdf" \
-F "external_candidate_id=CAND-8891"Respuesta 202 Accepted:
{ "analysis_id": "7f4c...", "status": "pending" }El análisis es asíncrono: consulta el resultado con el endpoint 3.
3. Leer un análisis — GET /v1/analyses/{analysis_id}
Devuelve el estado y, si terminó, el resultado. Scope: analyses:read.
Headers: Authorization
curl "https://jvbhqvbapwoyveeoiyii.supabase.co/functions/v1/partner-api/v1/analyses/7f4c..." \
-H "Authorization: Bearer lia_live_ab12cd34_..."Mientras procesa (200):
{ "analysis_id": "7f4c...", "status": "processing", "external_candidate_id": "CAND-8891" }Completado (200):
{
"analysis_id": "7f4c...",
"status": "completed",
"external_candidate_id": "CAND-8891",
"completed_at": "2026-07-22T00:12:41.220Z",
"model_version": "lia-match-v1",
"result": {
"score": 82,
"recommendation": "recommended",
"summary": "Perfil con cierre consultivo sólido en alto valor...",
"strengths": ["Cierre de alto ticket", "Prospección consultiva"],
"gaps": ["Sin experiencia inmobiliaria directa"]
}
}recommendation es uno de: recommended, review, not_recommended. score es un entero de 0 a 100. model_version (lia-match-v<N>) identifica la versión del motor que produjo ese análisis.
Fallido (200):
{
"analysis_id": "7f4c...",
"status": "failed",
"external_candidate_id": "CAND-8891",
"error": { "code": "pdf_no_text", "message": "El PDF no contiene texto extraíble (posible escaneo o imagen)." }
}Un análisis ajeno a tu key o inexistente responde 404.
Idempotencia
El header Idempotency-Key es obligatorio en POST /analyses. Reintentar con la misma key (por ejemplo, tras un timeout de red) devuelve el mismo analysis_id sin crear un segundo análisis ni generar un cargo doble. Usa una key única y estable por CV (por ejemplo candidato-job).
Flujo asíncrono (polling)
POST /analyses→ 202 constatus: "pending".- Haz polling de
GET /v1/analyses/{id}hasta questatusseacompletedofailed. - Cadencia recomendada: cada 10–15 segundos. El análisis típico completa en menos de 60 segundos.
Códigos de error
Todos los errores HTTP usan el envelope:
{ "error": { "code": "<code>", "message": "<humano>", "request_id": "<id>" } }Incluye siempre el request_id al reportar un problema a soporte.
| HTTP | code | Cuándo | Qué hacer |
|---|---|---|---|
| 400 | idempotency_key_required | Falta el header Idempotency-Key en POST /analyses. | Agrega el header. |
| 400 | validation_error | Falta un campo requerido (title, cv). | Corrige el body/multipart. |
| 400 | invalid_json / invalid_multipart | El body no es JSON / multipart válido. | Corrige el Content-Type y el cuerpo. |
| 401 | unauthorized | Key ausente, inválida o inactiva. | Revisa el header Authorization. |
| 403 | forbidden | La key no tiene el scope del endpoint. | Solicita el scope por contrato. |
| 404 | not_found | Vacante/análisis inexistente o de otra key. | Verifica el id. |
| 409 | job_not_analyzable | La vacante está en estado error o archived. | Crea/usa una vacante active. |
| 413 | file_too_large | El PDF excede 10 MB. | Reduce el archivo. |
| 415 | unsupported_media_type | El archivo no es un PDF válido. | Envía un PDF. |
| 429 | rate_limited | Se excedió el límite de requests por minuto. | Reintenta con backoff. |
| 500 | internal_error / persist_error / storage_upload_failed | Error del servidor. | Reintenta; si persiste, reporta con el request_id. |
error_codes de un análisis fallido (campo error.code en el GET cuando status: "failed"):
code | Significado | Qué hacer |
|---|---|---|
pdf_no_text | El PDF no tiene texto extraíble (escaneo o imagen). | Reenvía el CV como PDF con texto seleccionable. |
score_malformed | El modelo devolvió un resultado inválido. | Reintenta el análisis (nueva Idempotency-Key). |
job_profile_missing | La vacante no tiene un perfil válido para evaluar. | Verifica que la vacante se creó correctamente. |
file_missing | El CV ya no está disponible (venció su retención de 24h). | Vuelve a subir el CV en un nuevo análisis. |
Límites
- Formato: solo PDF.
- Tamaño: máximo 10 MB por CV.
- Rate limit: existe un límite de requests por minuto por key; al excederlo la API responde 429
rate_limited. El valor es configurable por contrato.
Retención de datos
- Archivo original (PDF): se conserva máximo 24 horas desde el upload; luego se elimina automáticamente.
- Texto extraído del CV: mismo trato — se elimina junto con el archivo (≤24h).
- Resultados del análisis: se conservan 30 días y luego se anonimizan.
- Registro de consumo: se conserva para verificación de uso por ambas partes.
external_candidate_id
Campo opcional pero recomendado en POST /analyses. Lía lo guarda y lo devuelve tal cual en el GET, para que puedas correlacionar cada análisis con el candidato en tu propio sistema sin mantener un mapeo aparte.
¿Listo para integrar? El acceso se habilita mediante acuerdo comercial.
Solicitar acceso a la API →