Skip to main content

Create Candidate

NL EN

Updated April 22, 2026

POST /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

  1. Upload: You submit the resume via the API
  2. Accepted: The API returns 202 Accepted with a processing_id
  3. Processing: AI extracts candidate information from the resume in the background
  4. Notification: The user specified by user_id receives 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

}'


<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 create_intake 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

FieldTypeDescription
user_idintegerRequired. The tenant user ID to associate the candidate with. This user will receive the assistant request notification.
resumeobjectRequired. The resume document to process
resume.filenamestringRequired. Original filename (max 255 chars)
resume.contentstringRequired. Base64 encoded file content
resume.mime_typestringRequired. MIME type of the file

Optional Fields

FieldTypeDescription
create_intakebooleanRequest automatic intake creation for the new candidate (requires Intake feature)

Resume Document

The resume must be base64 encoded and include metadata:

json

{

"filename": "resume.pdf",

"content": "base64_encoded_content_here",

"mime_type": "application/pdf"

}


Supported Document Types

Allowed MIME TypesMax Size
application/pdf10MB
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:

  1. Resume Analysis: AI extracts personal information, work experience, education, and skills from the resume
  2. Duplicate Detection: The system checks if a candidate with the same email already exists
  3. Candidate Creation: If the candidate is new, their profile is created with the extracted data
  4. Enrichment Workflow: Additional AI processing enriches the candidate profile (tag analysis, summary generation)
  5. Notification: The user specified by user_id receives an assistant request with the result

Possible Outcomes

ScenarioWhat Happens
New candidateCandidate is created, user receives "candidate created" notification
Existing candidate (same email)Resume is attached for review, user receives "resume review" notification
Missing email in resumeCandidate is saved as "pending", user receives "needs completion" notification
Processing failureUser 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