Create and manage candidates with structured CV data for personalized interviews.
The Candidates API allows you to:
Candidate CV data follows this structure:
{
summary?: string; // Professional summary
workExperiences: WorkExperience[]; // Employment history
education: Education[]; // Educational background
skills: Skill[]; // Technical and soft skills
certifications: Certification[]; // Professional certifications
linkedinUrl?: string; // LinkedIn profile URL
portfolioUrl?: string; // Personal website or portfolio
}
{
company: string; // Company name
title: string; // Job title
startDate?: string; // Start date (YYYY-MM format)
endDate?: string; // End date (YYYY-MM format, omit if current)
isCurrent?: boolean; // Whether this is current position
description?: string; // Role description and achievements
}
{
institution: string; // School/university name
degree?: string; // Degree type (Bachelor, Master, PhD, etc.)
field?: string; // Field of study
startDate?: string; // Start date
endDate?: string; // Graduation date
}
{
name: string; // Skill name
category?: 'technical' | 'soft' | 'language'; // Skill category
proficiency?: 'beginner' | 'intermediate' | 'advanced' | 'expert';
}
{
name: string; // Certification name
issuer?: string; // Issuing organization
issueDate?: string; // Date issued
expiryDate?: string; // Expiration date (if applicable)
credentialId?: string; // Credential ID
credentialUrl?: string; // Verification URL
}
Retrieve a paginated list of all candidates.
GET /api/v1/candidates
Headers:
Authorization: Bearer rz_live_...
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
page | integer | 1 | Page number |
limit | integer | 50 | Items per page (max: 100) |
search | string | - | Filter by candidate name |
200 OK:
{
"data": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "John Doe",
"title": "Senior Developer",
"cv": {
"summary": "Experienced software engineer...",
"workExperiences": [...],
"education": [...],
"skills": [...],
"certifications": []
},
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-15T10:30:00Z"
}
],
"pagination": {
"page": 1,
"limit": 50,
"total": 25,
"total_pages": 1
}
}
# List all candidates
curl https://rz-app-omega.vercel.app/api/v1/candidates \
-H "Authorization: Bearer rz_live_..."
# With pagination and search
curl "https://rz-app-omega.vercel.app/api/v1/candidates?page=1&limit=20&search=john" \
-H "Authorization: Bearer rz_live_..."
Create a new candidate with optional CV data.
POST /api/v1/candidates
Headers:
Authorization: Bearer rz_live_...
Content-Type: application/json
Body:
{
"name": "Jane Smith",
"title": "Product Manager",
"cv": {
"summary": "Product manager with 5+ years experience in B2B SaaS",
"workExperiences": [
{
"company": "TechStartup Inc",
"title": "Senior Product Manager",
"startDate": "2021-03",
"isCurrent": true,
"description": "Lead product strategy for enterprise platform"
},
{
"company": "BigCorp",
"title": "Product Manager",
"startDate": "2018-06",
"endDate": "2021-02",
"description": "Managed B2B product line with $5M ARR"
}
],
"education": [
{
"institution": "State University",
"degree": "MBA",
"field": "Business Administration",
"endDate": "2018"
}
],
"skills": [
{ "name": "Product Strategy", "category": "technical", "proficiency": "expert" },
{ "name": "Agile/Scrum", "category": "technical", "proficiency": "advanced" },
{ "name": "Leadership", "category": "soft" }
],
"certifications": [
{
"name": "Certified Scrum Product Owner",
"issuer": "Scrum Alliance",
"issueDate": "2020-05"
}
],
"linkedinUrl": "https://linkedin.com/in/janesmith"
}
}
Parameters:
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Candidate's full name (1-200 characters) |
title | string | No | Job title (max 100 characters) |
cv | object | No | CV data object (see structure above) |
201 Created:
{
"data": {
"id": "660f9511-f30c-52e5-b827-557766551111",
"name": "Jane Smith",
"title": "Product Manager",
"cv": {
"summary": "Product manager with 5+ years experience in B2B SaaS",
"workExperiences": [...],
"education": [...],
"skills": [...],
"certifications": [...],
"parsedAt": "2024-01-15T10:30:00Z",
"parseSource": "manual"
},
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-15T10:30:00Z"
}
}
curl -X POST https://rz-app-omega.vercel.app/api/v1/candidates \
-H "Authorization: Bearer rz_live_..." \
-H "Content-Type: application/json" \
-d '{
"name": "Jane Smith",
"title": "Product Manager",
"cv": {
"summary": "Product manager with 5+ years experience",
"skills": [
{ "name": "Product Strategy", "category": "technical" }
]
}
}'
const response = await fetch('https://rz-app-omega.vercel.app/api/v1/candidates', {
method: 'POST',
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: 'Jane Smith',
title: 'Product Manager',
cv: {
summary: 'Product manager with 5+ years experience',
workExperiences: [
{
company: 'TechStartup Inc',
title: 'Senior Product Manager',
startDate: '2021-03',
isCurrent: true
}
],
skills: [
{ name: 'Product Strategy', category: 'technical', proficiency: 'expert' }
]
}
})
});
const candidate = await response.json();
console.log('Candidate created:', candidate.data.id);
Retrieve details for a specific candidate.
GET /api/v1/candidates/:id
Headers:
Authorization: Bearer rz_live_...
Path Parameters:
id: Candidate UUID200 OK:
{
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Jane Smith",
"title": "Product Manager",
"cv": {
"summary": "Product manager with 5+ years experience in B2B SaaS",
"workExperiences": [
{
"company": "TechStartup Inc",
"title": "Senior Product Manager",
"startDate": "2021-03",
"isCurrent": true,
"description": "Lead product strategy for enterprise platform"
}
],
"education": [...],
"skills": [...],
"certifications": [...],
"linkedinUrl": "https://linkedin.com/in/janesmith",
"parsedAt": "2024-01-15T10:30:00Z",
"parseSource": "manual"
},
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-15T10:30:00Z"
}
}
404 Not Found:
{
"error": "Candidate not found"
}
curl https://rz-app-omega.vercel.app/api/v1/candidates/550e8400-e29b-41d4-a716-446655440000 \
-H "Authorization: Bearer rz_live_..."
Update a candidate's information.
PATCH /api/v1/candidates/:id
Headers:
Authorization: Bearer rz_live_...
Content-Type: application/json
Path Parameters:
id: Candidate UUIDBody:
{
"name": "Jane M. Smith",
"title": "Senior Product Manager",
"cv": {
"summary": "Updated professional summary",
"workExperiences": [
{
"company": "TechStartup Inc",
"title": "VP of Product",
"startDate": "2024-01",
"isCurrent": true
}
],
"skills": [
{ "name": "Product Strategy", "category": "technical", "proficiency": "expert" },
{ "name": "Team Leadership", "category": "soft", "proficiency": "advanced" }
]
}
}
Parameters (all optional):
| Field | Type | Description |
|---|---|---|
name | string | Updated name (1-200 characters) |
title | string | null | Updated title (null to remove) |
cv | object | null | Updated CV data (null to remove all CV data) |
cv: null.200 OK:
{
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Jane M. Smith",
"title": "Senior Product Manager",
"cv": {
"summary": "Updated professional summary",
"workExperiences": [...],
"skills": [...],
"parsedAt": "2024-01-15T11:00:00Z",
"parseSource": "manual"
},
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-15T11:00:00Z"
}
}
# Update name and title
curl -X PATCH https://rz-app-omega.vercel.app/api/v1/candidates/550e8400... \
-H "Authorization: Bearer rz_live_..." \
-H "Content-Type: application/json" \
-d '{
"title": "Senior Product Manager"
}'
# Remove CV data
curl -X PATCH https://rz-app-omega.vercel.app/api/v1/candidates/550e8400... \
-H "Authorization: Bearer rz_live_..." \
-H "Content-Type: application/json" \
-d '{
"cv": null
}'
Permanently delete a candidate.
DELETE /api/v1/candidates/:id
Headers:
Authorization: Bearer rz_live_...
Path Parameters:
id: Candidate UUID200 OK:
{
"success": true
}
404 Not Found:
{
"error": "Candidate not found"
}
curl -X DELETE https://rz-app-omega.vercel.app/api/v1/candidates/550e8400... \
-H "Authorization: Bearer rz_live_..."
When creating interview invitations, you can include candidate CV data directly in the request. This allows for personalized interview experiences without needing to create a separate candidate record first.
{
"job_id": "550e8400-e29b-41d4-a716-446655440000",
"candidate_name": "John Doe",
"candidate_cv": {
"summary": "Software engineer with 5+ years experience",
"workExperiences": [
{
"company": "Tech Corp",
"title": "Senior Developer",
"startDate": "2020-01",
"isCurrent": true
}
],
"skills": [
{ "name": "React", "category": "technical" },
{ "name": "TypeScript", "category": "technical" }
]
}
}
See Invitations API for more details.
400 Bad Request - Validation error:
{
"error": "Validation error",
"details": [
{
"path": ["name"],
"message": "String must contain at least 1 character(s)"
}
]
}
401 Unauthorized - Invalid API key:
{
"error": {
"type": "authentication_error",
"message": "Invalid API key"
}
}
404 Not Found - Candidate doesn't exist:
{
"error": "Candidate not found"
}
500 Internal Server Error:
{
"error": "Failed to create candidate"
}
For better interview personalization:
ATS Integration:
// Sync candidates from your ATS
async function syncCandidateFromATS(atsCandidate) {
const candidate = await fetch('https://rz-app-omega.vercel.app/api/v1/candidates', {
method: 'POST',
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: atsCandidate.name,
title: atsCandidate.currentTitle,
cv: {
summary: atsCandidate.summary,
workExperiences: atsCandidate.experience.map(exp => ({
company: exp.company,
title: exp.title,
startDate: exp.startDate,
endDate: exp.endDate,
isCurrent: exp.isCurrent
})),
skills: atsCandidate.skills.map(s => ({
name: s,
category: 'technical'
}))
}
})
}).then(r => r.json());
// Store mapping for later use
await db.candidateMappings.create({
ats_id: atsCandidate.id,
round0_id: candidate.data.id
});
return candidate;
}
Create Interview with Candidate:
// After creating a candidate, create an interview
async function createInterviewForCandidate(candidateId, jobId) {
// First get the candidate
const candidate = await fetch(`https://rz-app-omega.vercel.app/api/v1/candidates/${candidateId}`, {
headers: { 'Authorization': `Bearer ${apiKey}` }
}).then(r => r.json());
// Create invitation with candidate's CV
const interview = await fetch('https://rz-app-omega.vercel.app/api/v1/invitations', {
method: 'POST',
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
job_id: jobId,
candidate_name: candidate.data.name,
candidate_cv: candidate.data.cv
})
}).then(r => r.json());
return interview;
}