Bijgewerkt 15 juni 2026
/api/v1/applications
curl -X POST \
"https://app.recruitsome.com/api/v1/applications" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Accept: application/json"
const response = await fetch('https://app.recruitsome.com/api/v1/applications', {
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/applications');
$data = $response->json();
Dien de sollicitatie van een kandidaat in op een gepubliceerde vacature. Dit gebeurt doorgaans via het sollicitatieformulier op je carrièrewebsite. Eén aanroep bevat de gegevens van de kandidaat, het cv en andere documenten, en trackinginformatie. Recruitsome maakt de sollicitatie aan, koppelt de documenten en start automatisch het parsen van het cv.
Authenticatie
Vereist een API sleutel met het applications:write scope (inbegrepen in de Carrièrewebsite-preset). Aanroepen met een sleutel zonder dit scope retourneren een 403 met foutcode INSUFFICIENT_SCOPE.
Tip
Een sollicitatie die een kandidaat heeft ingetypt is onvervangbaar. Laat deze niet verloren gaan door een netwerkstoring of rate limit. Sla de inzending lokaal op (queue, database of browserstorage) voordat je de API aanroept, en probeer het opnieuw met backoff bij elke fout. Verwijder je lokale kopie pas nadat je het 201-antwoord hebt ontvangen.
Body
| Veld | Type | Verplicht | Beschrijving |
|---|---|---|---|
vacancy | string of integer | ja | Vacature-identificatie: een publicatie-slug, een vacature-slug of een numeriek vacature-ID (zie hieronder) |
candidate | object | ja | De gegevens van de sollicitant |
candidate.given_name | string | ja | Voornaam (max. 255 tekens) |
candidate.family_name | string | ja | Achternaam (max. 255 tekens) |
candidate.email | string | ja | Geldig e-mailadres (max. 255 tekens) |
candidate.mobile_phone | string | nee | Mobiel nummer in internationaal formaat (zie opmerkingen over telefoonnummers hieronder) |
candidate.fixed_phone | string | nee | Vast nummer in internationaal formaat |
candidate.linkedin_url | string | nee | LinkedIn-profiel-URL, moet een geldige URL zijn (max. 255 tekens) |
documents | object | nee | Documenten om bij te voegen (zie hieronder) |
privacy_policy_accepted | boolean | nee | Of de kandidaat je privacybeleid heeft geaccepteerd; wordt vastgelegd als toestemming met een tijdstempel |
tracking | object | nee | Context van de inzending |
tracking.ip_address | string | nee | Het IP-adres van de kandidaat, moet een geldig IP-adres zijn |
tracking.user_agent | string | nee | Browser user agent (max. 1000 tekens) |
tracking.referrer | string | nee | Verwijzings-URL, moet een geldige URL zijn (max. 1000 tekens) |
Vacature-identificatie
Het veld vacancy accepteert drie identificatiewaarden, die in deze volgorde worden opgelost:
- Numeriek vacature-ID:
123 - Publicatie-slug:
"maintenance-engineer-amsterdam", zoals geretourneerd doorGET /vacancies - Vacature-slug:
"maintenance-engineer"
Tip
Gebruik de publicatie-slug uit de vacaturelijst-API. Dit is de enige identificatie waarmee Recruitsome de sollicitatie kan koppelen aan het specifieke publicatiekanaal waar deze vandaan komt.
Documenten
Elk document is een object met filename (max. 255 tekens), content (base64-gecodeerde bestandsdata) en mime_type:
| Veld | Toegestane MIME-types | Max. grootte (gedecodeerd) |
|---|---|---|
documents.resume | application/pdf, application/msword, application/vnd.openxmlformats-officedocument.wordprocessingml.document, application/zip, application/x-ole-storage, application/octet-stream | 5 MB |
documents.cover_letter | Zelfde als cv | 5 MB |
documents.additional (array, max. 5) | Elk MIME-type als string | 20 MB per stuk |
Elk item in documents.additional kan ook een description bevatten (max. 500 tekens).
De types application/zip, application/x-ole-storage en application/octet-stream worden geaccepteerd omdat browsers en oudere Word-bestanden het MIME-type van .doc/.docx vaak verkeerd rapporteren. Geef het type door dat je bestands-API retourneert. Base64-codering vergroot de bestandsgrootte met circa 33%. De totale request body is beperkt tot 30 MB.
Telefoonnummers
mobile_phone en fixed_phone worden gevalideerd als internationale telefoonnummers met soepele parsing: spaties en streepjes zijn toegestaan (+31 6 1234 5678 en +31-6-12345678 worden beide geaccepteerd), maar het nummer moet een landcode bevatten. De voorafgaande + is hierbij essentieel. Een nummer in nationaal formaat zoals 0612345678 geeft de volgende foutmelding:
The mobile phone number must be in valid international format (e.g., +1234567890).Voorbeeld
curl -X POST https://app.recruitsome.com/api/v1/applications \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"vacancy": "maintenance-engineer-amsterdam",
"candidate": {
"given_name": "Emma",
"family_name": "de Vries",
"email": "[email protected]",
"mobile_phone": "+31612345678"
},
"documents": {
"resume": {
"filename": "emma_de_vries_cv.pdf",
"content": "JVBERi0xLjQKJeLj...",
"mime_type": "application/pdf"
}
},
"privacy_policy_accepted": true,
"tracking": {
"ip_address": "84.241.196.34",
"user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)",
"referrer": "https://www.yourcompany.com/vacatures/maintenance-engineer"
}
}'const resumeFile = document.getElementById('resume-input').files[0];
const toBase64 = (file) =>
new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => resolve(reader.result.split(',')[1]);
reader.onerror = reject;
});
const response = await fetch('https://app.recruitsome.com/api/v1/applications', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
vacancy: 'maintenance-engineer-amsterdam',
candidate: {
given_name: 'Emma',
family_name: 'de Vries',
email: '[email protected]',
mobile_phone: '+31612345678',
},
documents: {
resume: {
filename: resumeFile.name,
content: await toBase64(resumeFile),
mime_type: resumeFile.type,
},
},
privacy_policy_accepted: true,
}),
});
if (response.status === 201) {
const result = await response.json();
console.log('Application submitted:', result.data.id);
}Response 201
{
"message": "Application submitted successfully",
"data": {
"id": 456,
"vacancy": {
"id": 123,
"slug": "maintenance-engineer",
"title": "Maintenance Engineer"
},
"applicant": {
"id": null,
"given_name": "Emma",
"family_name": "de Vries",
"email": "[email protected]"
},
"status": "screening",
"source": "api",
"documents": [
{
"id": 789,
"category": "resume",
"filename": "emma_de_vries_cv.pdf",
"size": 245120,
"mime_type": "application/pdf"
}
],
"submitted_at": "2026-06-11T14:30:00+00:00",
"created_at": "2026-06-11T14:30:00+00:00"
}
}Het veld applicant.id bevat het ID van de gekoppelde kandidaat wanneer de sollicitant al als kandidaat bekend is in Recruitsome. Voor een nieuwe sollicitant is de waarde null. Elk item in documents beschrijft een opgeslagen document: id, category (resume, cover_letter of other voor aanvullende documenten), filename, size in bytes en mime_type.
Fouten
Validatiefouten 422
{
"message": "The given data was invalid.",
"errors": {
"candidate.email": [
"The candidate's email address is required."
],
"candidate.mobile_phone": [
"The mobile phone number must be in valid international format (e.g., +1234567890)."
],
"documents.resume": [
"The file size exceeds the maximum allowed limit."
]
}
}Vacature niet gevonden 404
{
"message": "Vacancy not found",
"error": "VACANCY_NOT_FOUND"
}Vacature gesloten 400
De vacature bestaat, maar accepteert geen sollicitaties meer:
{
"message": "This vacancy is no longer accepting applications",
"error": "VACANCY_CLOSED"
}Andere afwijzingen op basis van bedrijfsregels retourneren een 400 met "error": "VALIDATION_ERROR" en de reden in message.
Authenticatie en autorisatie
| Status | Body | Wanneer |
|---|---|---|
401 | {"message": "Unauthenticated."} | Ontbrekende of ongeldige API sleutel |
403 | {"message": "This API key does not have the required permission: applications:write", "error": "INSUFFICIENT_SCOPE", "required_scope": "applications:write"} | De API sleutel mist de applications:write scope |
Rate limiting 429
Het endpoint accepteert 10 verzoeken per minuut per API sleutel. Bij overschrijding ontvang je de standaard Laravel throttle-response met een Retry-After header (het aantal seconden tot het venster wordt gereset):
{
"message": "Too Many Attempts."
}Serverfout 500
{
"message": "An unexpected error occurred while processing your application",
"error": "SUBMISSION_FAILED"
}Een 500 kan optreden vóór of nadat de sollicitatie is opgeslagen. De API dedupliceert geen inzendingen, dus probeer het niet blindelings opnieuw. Doe maximaal één retry. Als je retry een succesvol antwoord retourneert dat op een duplicaat lijkt, neem dan contact op met [email protected] om te dedupliceren.
Je verwerkt persoonsgegevens: verzamel alleen wat de vacature daadwerkelijk nodig heeft en stuur privacy_policy_accepted mee, zodat de toestemming van de kandidaat met een tijdstempel wordt vastgelegd in Recruitsome.