Procesamiento en segundo plano y devoluciones de llamada
On this page
Analizar una lista de espera de CVs o analizar una entrevista de una hora de duración no debe mantener una conexión abierta. Los puntos de conexión asíncronos aceptan enlaces o cargas, responden de inmediato con un task_idy ejecutan el trabajo en nuestro lado. Recopilar el resultado mediante sondeo o recibirlo en su servidor.
Puntos de conexión asíncronos
| Punto de conexión | Entrada | Resultado |
|---|---|---|
POST /parse/async | Hasta 25 enlaces CV (file_urls), o cargados files | Un resultado de análisis por CV, en orden, misma forma que POST /parse/ |
POST /evaluate/async | Hasta 25 CV enlaces (resume_urls), o subidos resume_pdfs, más job_details o job_id | Una evaluación por CV, en orden, misma forma que POST /evaluate/ |
POST /summary/async | Un enlace de grabación (media_url), o un archivo subido media ; opcional interview_id y language | transcript_text, transcript_entries y summary |
POST /transcribe/async | Un enlace de grabación (media_url), o un archivo subido media | transcript_text y transcript_entries |
POST /translate/async | text, texts o enlaces de documentos (file_urls), o subidos files;source_language y target_language | Misma forma que POST /translate/ |
Cada solicitud asíncrona también puede incluir un callback_url.
| Punto de conexión de sondeo | Devuelve |
|---|---|
GET /{op}/tasks/{task_id} | El estado de la tarea y, una vez finalizada, su resultado. {op} es parse,evaluate,summary,transcribe o translate. |
Enviar una tarea
Enviar application/json con una lista de enlaces, o multipart/form-data con subidas. En multipart, un campo de enlace puede repetirse o enviarse un enlace por línea.
curl -X POST https://api.curriculo.me/public/parse/async \
-H 'Authorization: Bearer key_abc123_yoursecret' \
-H 'Content-Type: application/json' \
-d '{"file_urls": ["https://example.com/cvs/candidate_a.pdf", "https://example.com/cvs/candidate_b.pdf"], "callback_url": "https://example.com/curriculo/callback"}'curl -X POST https://api.curriculo.me/public/summary/async \
-H 'Authorization: Bearer key_abc123_yoursecret' \
-H 'Content-Type: application/json' \
-d '{"media_url": "https://example.com/interviews/interview.mp4", "interview_id": "int_0042", "language": "ko"}'curl -X POST https://api.curriculo.me/public/translate/async \
-H 'Authorization: Bearer key_abc123_yoursecret' \
-H 'Content-Type: application/json' \
-d '{"texts": ["Senior backend engineer", "Remote within Europe"], "source_language": "en", "target_language": "fr"}'Para solicitudes a
/translate/async, se requieresource_language. Para/evaluate/async, enviar el trabajo comojob_detailsojob_id.
La respuesta API de una vez con 202:
{ "task_id": "…", "status": "queued", "callback_secret": "whsec_…" }callback_secret se devuelve solo cuando se envía una callback_url. Se muestra exactamente una vez, como una clave API, así que guárdala.
Obtener el resultado
Sondeo
curl https://api.curriculo.me/public/parse/tasks/<task_id> \
-H 'Authorization: Bearer key_abc123_yoursecret'Una tarea es legible con la misma clave que la creó, ya sea que se haya entregado una devolución de llamada o no. La respuesta nunca incluye la devolución de llamada URL o secreto.
| Campo | Significado |
|---|---|
task_id | El id de la tarea. |
op | Qué operación ejecuta la tarea. |
status | queued, processing, succeeded o failed. |
status_code | El estado HTTP de la operación en sí, una vez finalizada. |
result | El cuerpo de la respuesta de la operación una vez que status es succeeded;null antes. |
error | El mensaje de error cuando la tarea falló. |
delivery | Estado de entrega de devolución de llamada: not_requested,pending,delivered o dead, con el recuento de intentos. |
created_at, completed_at | Marcas de tiempo. |
Devoluciones de llamada
Si envió un callback_url, la tarea finalizada se publica allí como application/json con estos encabezados:
| Encabezado | Valor |
|---|---|
X-Curriculo-Signature | sha256=<hex>: el hexadecimal en minúsculas HMAC-SHA256 del cuerpo de la solicitud exacta y sin procesar, con clave de su callback_secret |
X-Curriculo-Task-Id | El id de la tarea |
Content-Type | application/json |
El cuerpo es {task_id, op, status, status_code, result, error, completed_at}.
No hay encabezado de marca de tiempo, por lo que se deben deduplicar las entregas en task_id: la misma tarea puede llegar más de una vez si el servidor respondió lentamente o con un error.
Verificar la firma
Calcular el HMAC-SHA256 del cuerpo de la solicitud sin procesar, utilizando la clave callback_secret exactamente como se devolvió (incluyendo el prefijo whsec_ ) como clave. Comparar sha256= más el resumen hexadecimal en minúsculas con X-Curriculo-Signature en tiempo constante. Utilizar los bytes sin procesar tal como se recibieron, antes de cualquier análisis JSON, y rechazar cualquier cosa que no coincida.
Python:
import hashlib
import hmac
def is_valid(raw_body: bytes, signature_header: str, callback_secret: str) -> bool:
# callback_secret is used as-is, including the "whsec_" prefix
expected = "sha256=" + hmac.new(
callback_secret.encode(), raw_body, hashlib.sha256
).hexdigest()
return hmac.compare_digest(expected, signature_header or "")JavaScript (Node.js):
import crypto from "node:crypto";
// rawBody must be the unparsed request body (a Buffer)
export function isValid(rawBody, signatureHeader, callbackSecret) {
const expected =
"sha256=" +
crypto.createHmac("sha256", callbackSecret).update(rawBody).digest("hex");
const a = Buffer.from(expected);
const b = Buffer.from(signatureHeader || "");
return a.length === b.length && crypto.timingSafeEqual(a, b);
}Luego, deduplicar en el encabezado X-Curriculo-Task-Id (o task_id en el cuerpo) y responder 2xx.
Entrega y reintentos
- Cualquier respuesta no
2xxse considera una entrega fallida, y no se siguen las redirecciones. - Reintentos de entrega con retrasos crecientes (1, 5, 15 y 60 minutos, luego 4 horas), durante aproximadamente 5 horas y 21 minutos en total, antes de que la entrega se marque
dead. - El resultado sigue siendo legible en
GET /{op}/tasks/{task_id}de cualquier manera, por lo que nada se pierde por una entrega perdida.
Requisitos para las URLs
Las URLs de devolución de llamada deben ser
https, accesibles públicamente y no contener credenciales. Las direcciones en redes privadas son rechazadas.
- Los enlaces que envíe (
file_urls,resume_urls,media_url) deben ser enlaces públicoshttps. Un enlace público o un almacenamiento pre-firmado URL (por ejemplo S3) funcionan ambos. - Los enlaces que redirigen son rechazados.
- Las grabaciones por enlace pueden tener una duración de hasta 1 GB y 2 horas. Los archivos subidos tienen un límite de 12 MB cada uno.
Facturación
- Una tarea se factura una vez, en su resultado final, como una solicitud de su operación: un análisis asíncrono de 25 enlaces cuesta $0.01.
- Una tarea que falla (un enlace muerto, un archivo ilegible) nunca es cobrada.
- Las tareas de grabación (
/summary/async,/transcribe/async) reservan el cargo para el máximo de 2 horas cuando la tarea es aceptada. Sin suficiente crédito para esa reserva, la solicitud devuelve400. La reserva se libera si la tarea falla.
Consulte Precios y facturación.
Datos mantenidos por las tareas
A diferencia de las operaciones síncronas, una tarea en segundo plano mantiene su resultado para que puedas consultar su estado, y los archivos subidos se almacenan en tu cuenta. Consulta Manejo de datos.
Updated