Requests and responses
On this page
Requests are JSON or multipart/form-data; responses are JSON. Every response carries an X-Curriculo-Request-Id header. Quote it when you contact support so we can find the exact call.
Paths
- Synchronous operations end in a trailing slash:
/parse/,/evaluate/,/jobs/,/translate/,/detect-language/,/summary/,/transcribe/,/prompt/. - Background task paths are documented without one:
/{op}/asyncand/{op}/tasks/{task_id}. - Screening paths are documented without one:
/screening-interviewand/screening-interview/{screening_id}.
Content types
| Operation | Accepts |
|---|---|
/parse/, /evaluate/, /prompt/, /transcribe/ | multipart/form-data |
/detect-language/, /jobs/, /screening-interview | application/json |
/translate/ | application/json for text, or multipart/form-data to send PDF or DOCX documents |
/summary/ | application/json for transcripts, or multipart/form-data to send recordings or transcript documents |
/{op}/async | application/json with a list of links, or multipart/form-data with uploads (a link field can be repeated or sent one per line) |
Request size limits
| Limit | Value | Applies to |
|---|---|---|
| Request body | 12 MB | Every call, except /summary/. Larger requests are rejected at the edge with 413 before authentication. |
| One document | 10 MB | files, file, resume_pdfs, resume_pdf, job_file, and documents sent to /translate/ |
| Documents per request | 10 | /parse/, /evaluate/, /translate/ (files), /summary/ (interviews or media files) |
| Texts per request | 200 | /translate/, /detect-language/ |
| Characters | 50,000 | /translate/ (total across texts, and per document), /detect-language/ (per text) |
| Transcript text | 200,000 characters | /summary/ transcript_text |
| Transcript document | 50 MB | /summary/ PDF or DOCX transcript |
| Recording, synchronous | 100 MB | /summary/ media |
| Recording, synchronous | 12 MB | /transcribe/ media |
| Upload to a background task | 12 MB per file | /{op}/async multipart |
| Links per background task | 25 | file_urls, resume_urls |
| Recording by link | 1 GB and 2 hours | /summary/async, /transcribe/async media_url |
Over any ceiling, the API returns 413. Split the workload, or send long recordings by link to the async lane.
A synchronous call is also bounded by the 300-second request timeout. A large recording that takes longer to process returns
504, so prefer/summary/asyncfor long interviews.
Response shapes
Every operation that takes a list follows one rule: send one item, get that item's object; send several, get one result per item, in input order.
Several items return one entry per input:
{
"results": [
{ "index": 0, "status": "ok", "data": { … } },
{ "index": 1, "status": "error", "error": { "status": 400, "detail": "…" } },
{ "index": 2, "status": "ok", "data": { … } }
]
}The HTTP status stays 200 when the batch itself was accepted, so read status per item. One unreadable CV never costs you the other nine. See Batching.
Usage and spend
Responses do not carry cost data. Calls, errors, latency and estimated charge are in Console → Usage, filterable by key. See Pricing and billing.
Input hygiene
- Duplicate keys in a JSON body (
/translate/,/summary/,/detect-language/) are rejected with400naming the key. - Password-protected PDFs are rejected with
400. Remove the password and resend. - Field names are case-sensitive.
Versioning
There is no API version header. The surface is versioned by path, and additive changes (new optional fields, new operations) ship without breaking existing calls. Write clients that ignore unknown response fields.
Updated