Updated April 22, 2026
/api/v1/candidates
curl -X POST \
"https://app.recruitsome.com/api/v1/candidates" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Accept: application/json"
const response = await fetch('https://app.recruitsome.com/api/v1/candidates', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Accept': 'application/json',
},
});
const data = await response.json();
console.log(data);
use Illuminate\Support\Facades\Http;
$response = Http::withToken('YOUR_API_KEY')
->acceptJson()
->post('https://app.recruitsome.com/api/v1/candidates');
$data = $response->json();
Create Candidate
Create a new candidate by uploading their resume. The resume is processed asynchronously in the background — the API immediately returns a processing_id that can be used to track progress. Once processing is complete, the responsible user receives an assistant request notification within the application.
Endpoint
POST /api/v1/candidates
How It Works
The candidate creation process is asynchronous and follows this flow:
graph TD
A[Upload Resume via API] --> B[Resume Stored]
B --> C[202 Accepted + processing_id]
C --> D[Background Processing]
D --> E{Email Found?}
E -->|Yes| F{Existing Candidate?}
E -->|No| G[Manual Completion Required]
F -->|New| H[Candidate Created]
F -->|Exists| I[Resume Review]
H --> J[Assistant Request Sent]
I --> J
G --> J
- Upload: You submit the resume via the API
- Accepted: The API returns
202 Acceptedwith aprocessing_id - Processing: AI extracts candidate information from the resume in the background
- Notification: The user specified by
user_idreceives an assistant request in the application with the result
This is the same processing pipeline used when uploading a resume through the application UI. The candidate is created, enriched, and the user is notified through the normal assistant request flow.
Simple Example
``bash cURL
curl -X POST https://app.recruitsome.com/api/v1/candidates \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"user_id": 1,
"resume": {
"filename": "john_doe_cv.pdf",
"content": "JVBERi0xLjQKJeLj...",
"mime_type": "application/pdf"
}
}'
javascript JavaScript
// Read file and convert to base64
async function fileToBase64(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => resolve(reader.result.split(',')[1]);
reader.onerror = reject;
});
}
const resumeFile = document.getElementById('resume-input').files[0];
const resumeBase64 = await fileToBase64(resumeFile);
const response = await fetch('https://app.recruitsome.com/api/v1/candidates', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Content-Type': 'application/json'
},
body: JSON.stringify({
user_id: 1,
resume: {
filename: resumeFile.name,
content: resumeBase64,
mime_type: resumeFile.type
}
})
});
if (response.status === 202) {
const result = await response.json();
console.log('Processing started:', result.data.processing_id);
}
python Python
import requests
import base64
Read resume file
with open('resume.pdf', 'rb') as f:
resume_content = base64.b64encode(f.read()).decode('utf-8')
response = requests.post(
'https://app.recruitsome.com/api/v1/candidates',
headers={
'Authorization': 'Bearer YOUR_API_TOKEN',
'Content-Type': 'application/json'
},
json={
'user_id': 1,
'resume': {
'filename': 'resume.pdf',
'content': resume_content,
'mime_type': 'application/pdf'
}
}
)
if response.status_code == 202:
result = response.json()
print('Processing started:', result['data']['processing_id'])
Response Example
json
{
"message": "Resume uploaded successfully. The candidate will be created in the background.",
"data": {
"processing_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
}
With Intake Creation
If the tenant has the Intake feature enabled, you can request that an intake is automatically created for the new candidate:
bash
curl -X POST https://app.recruitsome.com/api/v1/candidates \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"user_id": 1,
"resume": {
"filename": "jane_smith_cv.pdf",
"content": "JVBERi0xLjQKJeLj...",
"mime_type": "application/pdf"
},
"create_intake": true
}'
jsoncreate_intake<div class="not-prose rounded-lg border border-gray-200 bg-gray-50 p-4 dark:border-gray-700 dark:bg-gray-800"><p class="mt-1 text-sm text-gray-700 dark:text-gray-300">The
flag is only effective when the tenant has the Intake feature enabled. If the feature is not enabled, this parameter is silently ignored.</p></div>Request Fields
Required Fields
Field Type Description user_id integer Required. The tenant user ID to associate the candidate with. This user will receive the assistant request notification. resume object Required. The resume document to process resume.filename string Required. Original filename (max 255 chars) resume.content string Required. Base64 encoded file content resume.mime_type string Required. MIME type of the file Optional Fields
Field Type Description create_intake boolean Request automatic intake creation for the new candidate (requires Intake feature) Resume Document
The resume must be base64 encoded and include metadata:
{
"filename": "resume.pdf",
"content": "base64_encoded_content_here",
"mime_type": "application/pdf"
}
Supported Document Types
Allowed MIME Types Max Size application/pdf 10MB application/msword (.doc) 10MB application/vnd.openxmlformats-officedocument.wordprocessingml.document (.docx) 10MB
<div class="not-prose rounded-lg border border-amber-200 bg-amber-50 p-4 dark:border-amber-800 dark:bg-amber-900/20"><p class="font-medium text-amber-800 dark:text-amber-300">Warning</p><p class="mt-1 text-sm text-amber-700 dark:text-amber-400">Base64 encoding increases file size by approximately 33%. A 10MB file will be approximately 13.3MB when base64 encoded.</p></div>
Error Handling
Validation Errors (422)
json
{
"message": "The given data was invalid.",
"errors": {
"user_id": ["The specified user does not exist."],
"resume": ["A resume document is required to create a candidate."],
"resume.mime_type": ["The resume must be a PDF or Word document."]
}
}
Invalid Base64 Content (422)
json
{
"message": "The resume content is not valid base64 encoded data.",
"error": "INVALID_RESUME_CONTENT"
}
File Size Exceeded (422)
json
{
"message": "The given data was invalid.",
"errors": {
"resume": ["The resume file size exceeds the maximum allowed limit of 10MB."]
}
}
Rate Limiting (429)
json
{
"message": "Too many requests. Please wait before trying again."
}
<div class="not-prose rounded-lg border border-amber-200 bg-amber-50 p-4 dark:border-amber-800 dark:bg-amber-900/20"><p class="font-medium text-amber-800 dark:text-amber-300">Warning</p><p class="mt-1 text-sm text-amber-700 dark:text-amber-400">Rate limit: 10 requests per minute per API key</p></div>
Server Error (500)
json
{
"message": "An unexpected error occurred while processing the resume.",
"error": "PROCESSING_FAILED"
}
`
What Happens After Submission
Once the API returns 202 Accepted, the following happens in the background:
- Resume Analysis: AI extracts personal information, work experience, education, and skills from the resume
- Duplicate Detection: The system checks if a candidate with the same email already exists
- Candidate Creation: If the candidate is new, their profile is created with the extracted data
- Enrichment Workflow: Additional AI processing enriches the candidate profile (tag analysis, summary generation)
- Notification: The user specified by user_id
receives an assistant request with the result
Possible Outcomes
| Scenario | What Happens |
|---|---|
| New candidate | Candidate is created, user receives "candidate created" notification |
| Existing candidate (same email) | Resume is attached for review, user receives "resume review" notification |
| Missing email in resume | Candidate is saved as "pending", user receives "needs completion" notification |
| Processing failure | User receives "processing failed" notification |
Tip
All outcomes result in an assistant request notification to the user — you don't need to poll for status. The user can take appropriate action directly in the application.
Notes
- The user_id
must reference a valid user within the tenant. This user becomes the "owner" of the candidate and receives all notifications. - Processing typically completes within 30 seconds to 2 minutes, depending on resume complexity
- The processing_id` is a UUID that can be stored for reference, though the primary notification mechanism is the assistant request
- Remember to handle personal data according to GDPR requirements