# Evaluate a candidate

> POST /evaluate/ scores one to 10 CVs (PDF or DOCX) against a job and returns suitability, fit analysis and gaps. Send the job as text, a file or a job_id.

**Source:** /docs/api/evaluate/ (Curriculo Docs)  
**Updated:** 12 October 2026  
**Contact:** hello@curriculo.me

```http
POST https://api.curriculo.me/public/evaluate/
```

**Stateless.** Scores CVs against a job and returns, for each CV, a suitability score with written reasoning, matched skills, gaps and summary points. Each CV is assessed individually against the same job.

**Price:** $0.01 per request, whether it carries one CV or ten.

## Request

`multipart/form-data`

| Field | Type | Notes |
|---|---|---|
| `resume_pdfs` | file[] | One to 10 CVs, PDF or DOCX (despite the field name), 10 MB each. Every CV is evaluated against the same job. |
| `resume_pdf` | file | Single-document alias. PDF or DOCX. |
| `job_details` | string | The job as plain text pasted from your careers page, or a JSON object if you hold structured requirements. |
| `job_file` | file | The job description as a PDF or DOCX. |
| `job_id` | string | A job registered earlier through [`POST /jobs/`](/docs/api/jobs/), sent instead of repeating the description across a backlog. |
| `language` | string | ISO 639-1 code for the candidate-facing prose. Empty means English. |

> [!NOTE]
> Supply the job exactly one way: `job_details`, `job_file` or `job_id`. Sending the description inline always works. Registering a job first is an optimisation, never a required step.

## Examples

Inline job description:

```bash
curl -X POST https://api.curriculo.me/public/evaluate/ \
  -H 'Authorization: Bearer key_abc123_yoursecret' \
  -F 'resume_pdf=@candidate.docx' \
  -F 'job_details=Senior backend engineer, Python and FastAPI, Seoul'
```

A list of CVs against a registered job:

```bash
curl -X POST https://api.curriculo.me/public/evaluate/ \
  -H 'Authorization: Bearer key_abc123_yoursecret' \
  -F 'resume_pdfs=@candidate_a.pdf' \
  -F 'resume_pdfs=@candidate_b.pdf' \
  -F 'job_id=job_abc123'
```

## Response

One CV returns that CV's evaluation object. Several CVs return a `results` array, one entry per CV, in input order. See [Batching](/docs/batching/).

## Timing

30 to 60 seconds per evaluation. Keep your client timeout above five minutes. For a backlog, use [`POST /evaluate/async`](/docs/background-processing/) with up to 25 links per task.

## Errors

| Status | Typical cause |
|---|---|
| `400` | Unreadable CV or malformed `job_details`. |
| `404` | Unknown `job_id`, or one registered by a different account. Register the job again. |
| `413` | A CV over 10 MB, more than 10 CVs, or a request body over 12 MB. |
| `422` | A required field is missing or misnamed. |
| `504` | Processing exceeded 300 seconds. Send fewer CVs per request. |
