# HireLayer API

This project calls the HireLayer recruiting APIs (resume parsing, job criteria extraction, candidate matching and ranking, skills normalization). Follow these rules when writing or changing that code.

## HireLayer integration rules

- Base URL: `https://hirelayer.co/api`. HTTPS only. There is no official SDK: in code, call the REST API directly (Python `requests`, Node.js 18+ `fetch`); working examples for every API are in https://github.com/HireLayer/resume-parser-examples. The official MCP server (hosted at https://hirelayer.co/mcp with OAuth sign-in, or locally with npm `hirelayer-mcp`; source: https://github.com/HireLayer/hirelayer-mcp) is for AI assistants such as Claude, ChatGPT, Cursor or VS Code, not for application code.
- Authentication: header `X-API-Key` on every request except `GET /api/v1/health`. Read the key from the `HIRELAYER_API_KEY` environment variable. Never hard-code it, log it, or send it from browser or mobile code. `Authorization: Bearer` is not supported.
- Every call is synchronous; there are no jobs to poll. Only for platforms that cannot wait (Zapier), `POST /api/v3/parser` accepts `Prefer: respond-async` with a `webhook_url` and answers 202, then posts the outcome to the webhook.
- Timeouts: use a client timeout of at least 150 s for `POST /api/v3/parser` and 65 s for `/api/v1/*`.
- Retries: retry 5xx responses and connection failures at most 3 times with exponential backoff and jitter; honour `Retry-After`. Never retry 4xx responses unchanged. There is no idempotency key.
- Errors: every error body has an `error` string. CV Extract errors add a `code` (`INVALID_MULTIPART_BODY`, `INVALID_FILE`, `DOCUMENT_NOT_A_RESUME`, `DOCUMENT_TEXT_EMPTY`, `DOCUMENT_UNREADABLE`, `DOCUMENT_TOO_LARGE`, `PARSER_UNAVAILABLE`). Job Extract, Match, Rank and Skills validation errors are `{"success": false, "error": "…"}` with status 400.
- Credits: each successful call costs 1 credit, whatever the API. `403` means no credit left.
- JSON bodies: Job Extract, Match, Rank and Skills reject unknown fields with 400. Job Extract, Match and Rank text fields are trimmed and limited to 50,000 characters. Skills (`POST /api/v1/skills/resolve`) takes one `text` (≤ 5,000 characters, a single skill or a whole skills section) and an optional `language` (`fr` by default, or `en`); store the returned skill `id`s, not the names.
- CV Extract: send the file as the multipart field `file` (about 4.5 MB max). On 200, `status` is always `"success"`; `upstream_status: "partial"` means optional steps were skipped. `info_resume.text` can reach 100,000 characters: truncate it to 50,000 before sending it to Match or Rank. Send `do_not_store_data=true` when the resume file must not be stored: HireLayer then does not store it and `info_resume.url` is `null`.
- Generated text (Job Extract labels and rationales, Match summaries and explanations, Rank rationales) is in French.
- Do not invent fields, endpoints or parameters. When unsure, read the OpenAPI document or the Markdown reference.

## Endpoints

- `POST /api/v3/parser` — HireLayer CV Extract: Upload one resume file and receive the structured candidate profile in the same response. (multipart/form-data, client timeout ≥ 150 s). Docs: https://hirelayer.co/api-docs/extract.md
- `POST /api/v1/jobs/extract-criteria` — HireLayer Job Extract: Turn a job description into weighted criteria that can be checked against a resume. (JSON body, client timeout ≥ 65 s). Docs: https://hirelayer.co/api-docs/job-extract.md
- `POST /api/v1/matching/job-candidate` — HireLayer Match: Evaluate one resume against each job criterion and get an explained 0–1 score. (JSON body, client timeout ≥ 65 s). Docs: https://hirelayer.co/api-docs/match.md
- `POST /api/v1/matching/job-candidates/rank` — HireLayer Rank: Order up to 10 candidates for one job description, with a score and a rationale for each. (JSON body, client timeout ≥ 65 s). Docs: https://hirelayer.co/api-docs/rank.md
- `POST /api/v1/skills/resolve` — HireLayer Skills: Turn free text, from one skill to a whole skills section, into taxonomy skills with their families and domains. (JSON body, client timeout ≥ 65 s). Docs: https://hirelayer.co/api-docs/skills.md
- `GET /api/v1/skills` — HireLayer Skills: Download every skill of the taxonomy with its families, domains and broader skill. (no body, client timeout ≥ 65 s). Docs: https://hirelayer.co/api-docs/skills.md
- `GET /api/v1/health` — Platform: Check that the Job Extract, Match, Skills and Rank service is up. No API key needed. (no body, client timeout ≥ 10 s, no API key). Docs: https://hirelayer.co/api-docs/health.md
- `GET /api/v1/me` — Platform: Check that an API key is valid and see the account and credit balance it belongs to. Integrations use it to test a connection. (no body, client timeout ≥ 10 s). Docs: https://hirelayer.co/api-docs/health.md
- `POST /api/v2/parser` — HireLayer CV Extract: Legacy asynchronous contract: the request is accepted with `202` and the result is posted to `webhook_url`. (multipart/form-data, client timeout ≥ 50 s, LEGACY, do not use for new code). Docs: https://hirelayer.co/api-docs/extract-v2.md

## References

- Index for agents: https://hirelayer.co/llms.txt
- Full documentation in one file: https://hirelayer.co/llms-full.txt
- OpenAPI 3.1: https://hirelayer.co/openapi.json
