Skip to main content

Error Handling

The Fribl API uses standard HTTP status codes and returns JSON error bodies to indicate what went wrong.

Error response format

Most API errors follow this structure:
Update endpoints can also proxy structured validation errors from the ingestion service:
Schema mismatches on update use 422 Unprocessable Entity with structured details:

HTTP status codes

Common error examples

Invalid API key

Fix: Verify your x-api-key header contains a valid key.

Insufficient tokens

Billable endpoints return 402 Payment Required with a structured body when your workspace can’t cover the request. No work is performed and nothing is charged.
Fix: Switch on code (not the message), add tokens in the Fribl Console, confirm with GET /credits/balance, then retry — charging is idempotent, so re-sending the same request is safe. See Tokens & Billing for the full pricing and refund model.

Missing required field

Fix: Ensure your request body includes all required fields. For analyze endpoints, the inputs field must be a non-empty array of strings.

Update validation failure

Fix: On PUT /jobs/{id} and PUT /cvs/{id}, send content_language (or set the Accept-Language header — the API auto-forwards it), include at least one allowed dimension (information, experience/experience_preference, education/education_preference, hard_skills, soft_skills), and use split hard_skills / soft_skills arrays with canonical lowercase relationship values: required, optional, satisfies.

Resource not found

Fix: Verify the ID exists and that the resource has finished processing. Check with the status endpoint first.

Match weight validation

Fix: Ensure that experience + hardSkills + softSkills + education in your weights object does not exceed 1.0.

Matching against entities not in your workspace

Before running a match, the API verifies that the vacancy and every candidate in the request belong to your workspace. If any doesn’t, the request is rejected immediately with a coded error — nothing is charged, and the request is not retried. Switch on code (not the message).
For isolation, an entity that belongs to a different workspace is reported exactly as if it did not exist. The API never discloses that an ID exists in another workspace.
Vacancy not found404 Not Found. The vacancy ID does not exist in your workspace (it was never ingested here, was deleted, or belongs to another workspace).
Fix: Confirm the vacancy was analyzed in the same workspace whose API key you’re using, and that its ID is correct. Ingest the job into this workspace before matching. Candidates not found422 Unprocessable Entity. One or more candidate IDs are not in your workspace. The candidate_ids array lists every candidate that could not be used.
Fix: Ingest those candidates into this workspace first, or drop them from the request. Only candidates analyzed under the same workspace can be matched against its vacancies. Vacancy has no requirements422 Unprocessable Entity. The vacancy exists in your workspace but has no extractable skills or requirements, so there is nothing to score candidates against.
Fix: Improve the vacancy’s quality — provide a clearer job description with explicit required skills, responsibilities, and experience — re-analyze it, then re-run matching.

Processing statuses

CV and job analysis is asynchronous. After submitting a document, poll the status endpoint to track progress. The public API uses a single normalized vocabulary across POST /analyze, POST /analyze/files, POST /{cvs,jobs}/status, and GET /{cvs,jobs}/{id}:
Failed tasks are refunded. When a task ends in FAILED, the tokens charged for it are returned automatically — you only pay for work that completes. The same applies to server errors (5xx). See Tokens & Billing.
Poll the status endpoint at reasonable intervals (e.g., every 2–3 seconds) rather than in a tight loop. Continue polling while the status is PENDING. Typical analysis completes within a few seconds.
GET /cvs/{id} and GET /jobs/{id} use HTTP status codes to signal readiness: an in-flight task returns 404 with body { "message": "...", "status": "PENDING" } (keep polling), and a ready entity returns 200 with status: "COMPLETED". A 404 with an { "error": "..." } body means the ID does not exist.