API Documentation
Welcome to the Rebee.AI API documentation. Our REST API allows you to integrate intelligent resume parsing into your applications. Upload PDFs, poll for completion, and retrieve structured data (personalInfo, experience, education, skills, certifications).
Fast & Reliable
99.9% uptime with sub-second response times
Secure
Enterprise-grade security and encryption
Developer Friendly
RESTful design with comprehensive examples
Base URL
https://api.rebee.ai/api/v1Paste your API key and a resume path — this runs the complete matching pipeline end-to-end.
curl -X POST https://api.rebee.ai/api/v1/pipeline/match \
-H "X-API-Key: identifier:secret" \
-F "jd_text=We're hiring a Senior React engineer..." \
-F "resumes=@./resume.pdf"
# → { data: { pipelineJobId, status: "created" } }
# Poll GET /pipeline/{pipelineJobId} every few seconds until
# status is "completed", then GET /pipeline/{pipelineJobId}/resultsAuthentication
All API requests require authentication using an API key. Use either the X-API-Key header or Authorization: Bearer. The key format is identifier:secret (e.g. rbee_live_xxx:secret).
API Key Headers
Use X-API-Key or Authorization: Bearer with identifier:secret
curl -s https://api.rebee.ai/api/v1/resumes \
-H "X-API-Key: identifier:secret"Keep your API key secure
Never share your API key publicly or commit it to version control. Store it securely as an environment variable.
Resume Parsing
Upload a PDF resume (max 10MB). Parsing is asynchronous: 1 credit is deducted on upload, then poll job status until completed. Fetch parsed JSON when ready.
/resumesRequest
multipart/form-data with field file (PDF)
curl -X POST https://api.rebee.ai/api/v1/resumes \
-H "X-API-Key: identifier:secret" \
-F "file=@resume.pdf"Upload Response (201)
{
"success": true,
"data": {
"processId": "proc_1734567890_abc123",
"stage": "queued",
"source": "api"
}
}Check Job Status
Poll until status is completed or failed
curl -s https://api.rebee.ai/api/v1/resumes/jobs/PROCESS_ID \
-H "X-API-Key: identifier:secret"Get Parsed Output
When status is completed:
curl -s https://api.rebee.ai/api/v1/resumes/PROCESS_ID \
-H "X-API-Key: identifier:secret"Parsed Output
{
"success": true,
"data": {
"processId": "proc_1734567890_abc123",
"personalInfo": {
"name": "John Doe",
"email": "john@example.com",
"phone": "+1234567890",
"personal_location": "New York, NY"
},
"experience": [
{"company", "position", "description"}
],
"education": [...],
"skills": ["JavaScript", "React"],
"certifications"
}
}Optional: Real-time updates
GET /resumes/:processId/events — Server-Sent Events stream for live stage updates.
Credits & Billing
Each resume parse costs 1 credit. Check your balance before uploading and view transaction history.
/billing/creditsReturns current credit balance.
curl -s https://api.rebee.ai/api/v1/billing/credits \
-H "X-API-Key: identifier:secret"Response: { success: true, data: { credits: 99 } }
/billing/transactions?page=1&limit=20List usage and refund transactions.
curl -s "https://api.rebee.ai/api/v1/billing/transactions?page=1&limit=20" \
-H "X-API-Key: identifier:secret"Job Matching Pipeline
End-to-end matching API: upload a JD + resumes + weights + priorities, then poll for a ranked list of candidates. Uses the same classify → parse → match → rank pipeline as the web app. The pipeline runs asynchronously — you get a pipelineJobId immediately and poll for status + results.
/pipeline/match — Step 1: classify JD + upload first resume batchMultipart form. Send the JD (PDF or text), up to 100 resume PDFs, matching weights, and hiring priorities. Returns pipelineJobId and jdId after classification completes.
Required fields
jd(file) ORjd_text(string) — one is requiredresumes(files, 1-100 PDFs)
Matching weights & priorities (optional)
weights_semantics,weights_keyword(numbers that sum to 100; default 60/40)priorities_textual,priorities_technical,priorities_experience,priorities_leadership,priorities_industry,priorities_education(enabled ones must sum to 100)priorities_enabled_leadership,priorities_enabled_industry,priorities_enabled_education(true/false)auto_start(true/false, defaulttrue) — when true the pipeline runs end-to-end in one call; set to false if you need to upload more than 100 resumes via follow-up /resumes calls
JD configuration (optional — improves match quality)
These feed the matching-worker's scoring endpoints. Missing fields fall back to classifier defaults or empty arrays. Array / object fields take JSON strings.
experience_min(number, years),experience_max(number ornull)experience_tiers(JSON):[{label:"Primary"|"Secondary"|"Tertiary", fromYr, toYr, percentage}]user_skills(JSON):[{name, priority:"high"|"medium"|"low"}]user_soft_skills(JSON):[{name, label, percentage, sentences?}]priority_universities,preferred_domains,priority_companies,preferred_locations(JSON string arrays)is_remote(true/false)
curl -X POST https://api.rebee.ai/api/v1/pipeline/match \
-H "X-API-Key: identifier:secret" \
-F "jd_text=Senior Software Engineer role..." \
-F "weights_semantics=60" \
-F "weights_keyword=40" \
-F "priorities_textual=25" \
-F "priorities_technical=30" \
-F "priorities_experience=30" \
-F "priorities_leadership=15" \
-F "resumes=@resume_1.pdf" \
-F "resumes=@resume_2.pdf"Response: 201 { data: { pipelineJobId, status: "created" } }
/pipeline/{pipelineJobId}/resumes — Step 2 (optional): add more resume batchesMulter caps each request at 100 files. For 2,000+ resumes, call this endpoint repeatedly with batches of up to 100 PDFs. Wait for pipeline status to be awaiting_start before calling.
curl -X POST https://api.rebee.ai/api/v1/pipeline/$PIPELINE_ID/resumes \
-H "X-API-Key: identifier:secret" \
-F "resumes=@batch2_01.pdf" \
-F "resumes=@batch2_02.pdf"/pipeline/{pipelineJobId}/start — Step 3: trigger matching + rankingCall once all resume batches are uploaded. Transitions the pipeline into waiting_parse → matching → ranking → completed.
curl -X POST https://api.rebee.ai/api/v1/pipeline/$PIPELINE_ID/start \
-H "X-API-Key: identifier:secret"/pipeline/{pipelineJobId} — Poll status + progressPoll every 3-5 seconds. Returns current status, parse and match progress, and the ranked summary when status is completed.
curl -s https://api.rebee.ai/api/v1/pipeline/$PIPELINE_ID \
-H "X-API-Key: identifier:secret"{
"success": true,
"data": {
"pipelineJobId": "65a...",
"status": "matching",
"jdId": "65b...",
"parseProgress": { "total": 50, "completed": 50, "failed": 0 },
"matchProgress": { "total": 50, "completed": 24, "failed": 0 },
"rankedResults": null
}
}/pipeline/{pipelineJobId}/results — Full ranked resultsReturns the ranked list with every candidate's scores, ranking breakdown, and the full matching payload (phase3 / phase4 / soft-skill coverage). Sorted by rankingScore descending.
curl -s https://api.rebee.ai/api/v1/pipeline/$PIPELINE_ID/results \
-H "X-API-Key: identifier:secret"/pipeline — List your pipeline jobsPaginated list (most recent first). Supports ?page=1&limit=20.
/pipeline/{pipelineJobId} — Cancel a running / stuck pipelineCancels in-flight parse and matching jobs, refunds unprocessed per-page credits (parse + match) via idempotent guards, and marks the pipeline failed with error "Cancelled by user". Completed match results are preserved — only in-flight / queued work is cancelled. The JD analysis credit (10) is not refunded (matches GUI behaviour).
curl -X DELETE https://api.rebee.ai/api/v1/pipeline/$PIPELINE_ID \
-H "X-API-Key: identifier:secret"Idempotent: calling DELETE on an already-terminal pipeline returns the current status without side effects.
/jd/{jdId}/ranking — Change priorities & re-rank candidatesRe-orders the already-matched candidates using a new set of hiring priorities. Recomputes rankingScore for every completed row, persists it (so the dashboard & Results page both reflect the new ordering), and returns the sorted list. The underlying component scores (finalScore, skillScore, experienceScore, etc.) are NOT recomputed — matching doesn't run again.
0.05 credits × completed-candidate-count. e.g. 20 candidates = 1 credit per re-rank call.Body (application/json)
textual,technical,experience,leadership,industry,education(integers)enabled:{ leadership, industry, education }booleans. A slot withenabled: falseis treated as 0.- The effective priorities must sum to 100 (±1).
curl -X POST https://api.rebee.ai/api/v1/jd/$JD_ID/ranking \
-H "X-API-Key: identifier:secret" \
-H "Content-Type: application/json" \
-d '{
"textual": 25,
"technical": 30,
"experience": 30,
"leadership": 15,
"industry": 0,
"education": 0,
"enabled": { "leadership": true, "industry": false, "education": false }
}'Returns { data: [...sorted candidates], priorities: {...} }. Each candidate carries rankingScore, scores, and matchingWeights.
/jd/{jdId}/matching/results — Fetch ranked candidates with full detailsReturns all completed match rows for this JD, sorted by rankingScore descending. Includes every candidate's component scores and the priority breakdown that produced the current rank. Free to call — no credits deducted.
Tip: pipe to jq to slice the top N candidates locally. The API returns them all; you filter client-side.
# Fetch and keep only the top 5
N=5
curl -s -H "X-API-Key: identifier:secret" \
https://api.rebee.ai/api/v1/jd/$JD_ID/matching/results \
| jq ".data | sort_by(-.rankingScore) | .[:$N] | map({
rank: .rankingScore,
name: .fileName,
processId: .processId,
scores: .scores,
rankingBreakdown: .rankingBreakdown,
matchingWeights: .matchingWeights
})"Per-candidate shape
{
"processId": "proc_...",
"fileName": "Vaibhav Sharma",
"rankingScore": 65.5, // 0-100 priority-weighted
"scores": {
"finalScore": 0.82, // semantic + keyword
"semanticScore": 0.80,
"skillScore": 0.88, // technical skills
"leadershipScore": 0.60, // soft skills
"experienceScore": 0.75,
"educationScore": 0.30,
"industryScore": 0.20
},
"rankingBreakdown": {
"textual": 20.50,
"technical": 26.40,
"experience": 22.50,
"leadership": 9.00,
"industry": 0.00,
"education": 0.00
},
"matchingWeights": { "semantics": 60, "keyword": 40 },
"phase3": { ... }, // detailed analysis
"phase4": { ... }, // strengths/gaps
"softSkillCoverage": { ... }
}/jd/{jdId}/weights — Re-match with new semantic/keyword weightsUnlike ranking (which only re-sorts), this actually re-runs matching for every candidate with new semantic-vs-keyword weights. All previous match results for this JD are cancelled and a fresh matching run is queued.
pages × 1.5 per resume) are reserved. Net zero if the candidate set is unchanged. Returns 402 if insufficient credits for the fresh reservation (old credits are NOT refunded in that case — the request fails cleanly).curl -X PUT https://api.rebee.ai/api/v1/jd/$JD_ID/weights \
-H "X-API-Key: identifier:secret" \
-H "Content-Type: application/json" \
-d '{ "semantics": 70, "keyword": 30 }'After this call the JD's matchingStatus becomes in_progress. Poll GET /jd/{jdId}/matching/status (or the pipeline status endpoint) until the new run finishes.
Additional endpoints
Utility endpoints for polling, recovery, queue monitoring, and fine-grained control. All accept the same X-API-Key header.
/jd/{jdId}/matching/status — Matching progress by JD (alternative to pipeline status)Poll match progress when you only have a jdId (e.g. after a PUT /weights re-match, or when tracking a JD that wasn't created via /pipeline/match). Returns counters + per-resume status.
curl -s -H "X-API-Key: identifier:secret" \
https://api.rebee.ai/api/v1/jd/$JD_ID/matching/status | jqResponse: { data: { total, completed, processing, failed, pending, canProceed, resumes: [...] } }
/jd/{jdId}/matching/start — Idempotent catch-up: enqueue any parsed resume missing a matchEnqueues every parsed resume in the session that doesn't yet have a match result. Safe to call any number of times — it only queues gaps. Useful when a matching worker was restarted or when a resume slipped through. Does not deduct credits (credits were already reserved at parse time).
curl -X POST https://api.rebee.ai/api/v1/jd/$JD_ID/matching/start \
-H "X-API-Key: identifier:secret"/jd/{jdId}/matching — Cancel all in-flight match jobs for this JDCancels every in-flight BullMQ match job for the JD and wipes non-completed match rows. Refunds match credits via the idempotent guard (completed rows are preserved). Does NOT touch the resume session — parsed resumes stay linked and can be re-matched with /matching/start or /weights.
curl -X DELETE https://api.rebee.ai/api/v1/jd/$JD_ID/matching \
-H "X-API-Key: identifier:secret"/jd/{jdId}/matching/{processId} — Cancel a single resume's match jobCancels one resume's match (by its processId) and removes its match-result row. Match credits for that row are refunded.
curl -X DELETE https://api.rebee.ai/api/v1/jd/$JD_ID/matching/$PROCESS_ID \
-H "X-API-Key: identifier:secret"/matching/queue-position — Global matching-lock FIFO positionThe matching pipeline serializes across users (one user's matching jobs run at a time). If you're waiting, this endpoint tells you your position and who's currently holding the lock. Other user IDs are masked for privacy.
curl -s -H "X-API-Key: identifier:secret" \
https://api.rebee.ai/api/v1/matching/queue-position | jqResponse: { holder: { userId: masked, isYou, acquiredAt }, you: { isHolder, position }, ahead, total }
/resumes/parser-queue-position — Global parser-lock FIFO positionSame shape as /matching/queue-position but for the standalone parser lock (one user parses resumes through the VM at a time, with a quota of 5 parses per hold before fair-sharing to the next waiter).
curl -s -H "X-API-Key: identifier:secret" \
https://api.rebee.ai/api/v1/resumes/parser-queue-position | jq/jd-classifier — List every JD you've created (most recent first)Useful when you've lost a pipelineJobId or want to jump straight to per-JD endpoints. Each item includes jdId, roles, candidate count, matching status, and top-scoring candidate percent.
curl -s -H "X-API-Key: identifier:secret" \
https://api.rebee.ai/api/v1/jd-classifier \
| jq '.data | map({jdId, roles, matchingStatus, candidateCount, topScore, createdAt})'/jd-classifier/{jdId} — Full JD detail + saved weights/priorities/configReturns everything stored on the JD: classification result, roles, user skills, soft skills, experience tiers, priority companies/universities/domains, matchingWeights, hiringPriorities, credit tracking fields, and more.
curl -s -H "X-API-Key: identifier:secret" \
https://api.rebee.ai/api/v1/jd-classifier/$JD_ID | jq/jd/{jdId}/priorities — Save hiring priorities without re-ranking (free)Persists the priority weights onto the JD so later POST /ranking calls can use them as defaults. Does not re-rank existing results and does not charge credits. Use this if you want to save priorities for later without re-running ranking (which charges 0.05/resume).
curl -X PUT https://api.rebee.ai/api/v1/jd/$JD_ID/priorities \
-H "X-API-Key: identifier:secret" \
-H "Content-Type: application/json" \
-d '{
"textual": 25,
"technical": 30,
"experience": 30,
"leadership": 15,
"industry": 0,
"education": 0,
"enabled": { "leadership": true, "industry": false, "education": false }
}'/jd/{jdId}/priorities — Read saved prioritiescurl -s -H "X-API-Key: identifier:secret" \
https://api.rebee.ai/api/v1/jd/$JD_ID/priorities | jq/jd/{jdId}/resumes/existing — Match already-parsed resumes against a new JDAvoids re-parsing. Takes a list of processIds from resumes you've previously parsed (via /resumes or an earlier JD), links them to this JD, and queues matching. Only match credits charged (pages × 1.5) — parse was already paid.
curl -X POST https://api.rebee.ai/api/v1/jd/$JD_ID/resumes/existing \
-H "X-API-Key: identifier:secret" \
-H "Content-Type: application/json" \
-d '{ "processIds": ["proc_abc123", "proc_def456"] }'Response: { linked: [...], alreadyLinked: [...], invalid: [...] }. Returns 402 if insufficient match credits (atomic — no partial charge).
HTTP doesn't have a native concept of folders — your client enumerates the files and attaches each as a multipart part. Each POST call accepts up to 100 resume PDFs. For larger batches, set auto_start=false on the first call, add more batches via /pipeline/{id}/resumes, then trigger matching with /pipeline/{id}/start.
All resumes fit in one call (≤ 100 PDFs)
# Uses shell glob; auto_start=true (default) runs the pipeline end-to-end
curl -X POST https://api.rebee.ai/api/v1/pipeline/match \
-H "X-API-Key: identifier:secret" \
-F "jd_text=$(cat jd.txt)" \
$(for f in ./resumes/*.pdf; do echo -F resumes=@"$f"; done)More than 100 PDFs — multi-batch
# 1. First 100 resumes + opt out of auto-start
PID=$(curl -s -X POST https://api.rebee.ai/api/v1/pipeline/match \
-H "X-API-Key: identifier:secret" \
-F "auto_start=false" \
-F "jd_text=$(cat jd.txt)" \
$(for f in $(ls ./resumes/*.pdf | head -100); do echo -F resumes=@"$f"; done) \
| jq -r .data.pipelineJobId)
# 2. Wait until status is awaiting_start
while true; do
S=$(curl -s -H "X-API-Key: identifier:secret" https://api.rebee.ai/api/v1/pipeline/$PID | jq -r .data.status)
[ "$S" = "awaiting_start" ] && break; sleep 2
done
# 3. Upload remaining batches of up to 100 each
i=0
ls ./resumes/*.pdf | tail -n +101 | split -l 100 - batch_
for batch in batch_*; do
curl -X POST https://api.rebee.ai/api/v1/pipeline/$PID/resumes \
-H "X-API-Key: identifier:secret" \
$(for f in $(cat $batch); do echo -F resumes=@"$f"; done)
done
# 4. Trigger matching
curl -X POST https://api.rebee.ai/api/v1/pipeline/$PID/start \
-H "X-API-Key: identifier:secret"Rate Limits
API requests are rate-limited per hour to ensure fair usage and system stability.
API Key
1,000,000 requests/hour
When using X-API-Key or Bearer token
GUI (Session)
Unlimited
When using session cookie
Separate rate-limit buckets: GUI usage never consumes your API key quota and vice versa.
Error Codes
The API uses standard HTTP status codes to indicate success or failure.
| Code | Status | Description |
|---|---|---|
| 200 | OK | Request successful |
| 400 | Bad Request | Invalid request parameters |
| 402 | Payment Required | Insufficient credits for parse |
| 401 | Unauthorized | Invalid or missing API key (X-API-Key or Bearer identifier:secret) |
| 404 | Not Found | Job or resume not found |
| 429 | Too Many Requests | Rate limit exceeded |
| 500 | Internal Server Error | Server error occurred |