Browse documentation
Public API

Public API overview

The Nanaade API brings career intelligence — job search and matching, résumé analysis, career pathways and, soon, AI interviews — to your own product over HTTPS. It is separate from tenant SSO: you do not need a tenant or a Nanaade user to call it.

https://backend.nanaade.ai/v1

The machine-readable contract is served at GET /v1/openapi.json. Try every endpoint in the sandbox — with a sandbox key or with mock data.

Authentication

Send your secret key as a bearer token on every request.

curl https://backend.nanaade.ai/v1/me \
  -H "Authorization: Bearer $NANAADE_API_KEY"
KeyPurposeBilling
sk_test_…Sandbox. Same engines, same responses.Free quota of engine calls per app per month (default 200). Reads are free.
sk_live_…Production.Credits deducted per call.

Keys are scoped. A key without the scope an endpoint needs receives 403 insufficient_scope.

ScopeEndpoints
jobs:readGET /jobs, GET /jobs/{id}
jobs:matchPOST /jobs/match
resumes:analyzePOST /resumes/analyze, GET /resumes/analyses/{id}
candidates:deleteDELETE /candidates/{external_candidate_id}
pathways:generatePOST /career-pathways/generate
pathways:readGET /career-pathways, GET /career-pathways/{id}
webhooks:manage/webhooks and everything under it

Keys are secrets: use them only from server-side code, never in a browser or mobile app.

Endpoints

Method & pathCostWhat it does
GET /jobs0.1Paginated feed of published, active, unexpired jobs. Filters: q, skills, country, region, is_remote, employment_type, experience_level, industry, company, salary_min, posted_after, page, per_page (≤ 50).
GET /jobs/{id}0.1One job with description and requirements.
POST /jobs/match1{ "skills": [...] } or { "resume_text": "..." } → up to 25 jobs ranked by fit_score, with matched_skills and missing_skills.
POST /resumes/analyze2Resume (file_url or resume_text) vs target_job → scores, matched / missing / additional skills, written assessment. Synchronous, typically 5–25 s.
GET /resumes/analyses/{analysis_id}freeRe-read a stored analysis.
DELETE /candidates/{external_candidate_id}freeErase everything stored under your candidate id. Always 202.
POST /career-pathways/generate3Asynchronous. Target role + current skills → readiness score, skill checklist and a months-phased roadmap. See Career pathways.
GET /career-pathways/{pathway_id}freePoll a pathway; full roadmap once completed.
/webhooksfreeRegister HTTPS endpoints and receive signed events. See Webhooks.

Resume analysis example

curl https://backend.nanaade.ai/v1/resumes/analyze \
  -H "Authorization: Bearer $NANAADE_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: cand_839210-2026-09-17" \
  -d '{
    "external_candidate_id": "cand_839210",
    "file_url": "https://cdn.partnerapp.com/resumes/candidate_resume.pdf",
    "target_job": {
      "title": "Senior Frontend Engineer",
      "skills": ["React", "TypeScript", "GraphQL", "CI/CD"]
    }
  }'

file_url must be https, on a publicly reachable host, and point to a PDF or DOCX of at most 10 MB. The response shape is documented in the sandbox and the OpenAPI document.

Idempotency

Send an Idempotency-Key header (≤ 255 characters) on any POST or DELETE. For 24 hours, the same key with the same body replays the original response with Idempotent-Replayed: true; the same key with a different body returns 422 idempotency_key_reused.

Rate limits

Limits are per key and per minute: 60 for reads, 20 for AI endpoints. Every response carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset; a 429 adds Retry-After.

Errors

Every error uses one envelope. Log request_id and quote it when contacting support.

{
  "error": {
    "code": "validation_error",
    "message": "Request validation failed",
    "request_id": "6ca31bc4-a402-4530-b325-bf819b9cd098",
    "details": [{ "field": "per_page", "message": "must be 1–50" }]
  }
}
StatuscodeMeaning
400validation_error, invalid_request, no_skills_found, resume_unreadableFix the request. details lists fields.
401missing_api_key, unauthorized, wrong_key_typeKey missing, invalid, revoked or publishable.
402insufficient_creditsTop up the app's credits.
403insufficient_scope, ip_not_allowedKey lacks the scope, or IP allowlist mismatch.
404not_foundUnknown or not publicly visible resource.
409 / 422request_in_progress, idempotency_key_reusedIdempotency conflicts.
429rate_limited, sandbox_quota_exceededBack off per Retry-After; sandbox quota resets monthly.
502upstream_errorAI engine failed; safe to retry with the same Idempotency-Key.

Data protection

Nanaade processes resumes on your behalf. Send an external_candidate_id with every analysis so you can honour deletion requests with one call to DELETE /candidates/{external_candidate_id}. Stored results expire automatically after your app's retention period (default 12 months; uploaded files 30 days). Resume text itself is never retained.