Updated July 1, 2026
/api/v1/vacancies/{slug}
curl -X GET \
"https://app.recruitsome.com/api/v1/vacancies/{slug}" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Accept: application/json"
const response = await fetch('https://app.recruitsome.com/api/v1/vacancies/{slug}', {
method: 'GET',
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()
->get('https://app.recruitsome.com/api/v1/vacancies/{slug}');
$data = $response->json();
Retrieve full details for a specific vacancy publication — everything your career website needs to render a complete vacancy page: full job texts, media, hiring manager, and (optionally) compensation.
Authentication
Requires an API key with the vacancies:read scope (included in the Career website preset). A key without this scope receives a 403 response.
Path parameters
| Parameter | Type | Description |
|---|---|---|
slug | string | The publication slug (URL-friendly identifier), exactly as returned by the list endpoint |
Query parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
language | string | - | ISO 639-1 language code (e.g., nl, en). Sets the locale for translated fields like education levels, job types, and the work arrangement label. |
include_compensation | boolean | false | Include compensation details |
include_media | boolean | - | Accepted but has no effect on this endpoint: header_image and images are always included in the detail response. (The flag only matters on the list endpoint.) |
include_company_name | boolean | false | Include company name in the company_location object (opt-in for privacy) |
Response fields
| Field | Type | Description |
|---|---|---|
id | integer | Unique vacancy publication ID |
slug | string | URL-friendly identifier |
title | string | Vacancy title |
summary | string | Brief description (HTML) |
language | string | Language code (ISO 639-1) |
published_at | string | ISO 8601 publication date |
ends_at | string|null | ISO 8601 expiration date |
views_count | integer | Number of times viewed (incremented on each request) |
header_image | object|null | Header image URLs in multiple sizes (legacy, mapped to the default crop). Always included on this endpoint. |
images | object | Map of all configured image crops. Always included on this endpoint. |
job_description | string | Full job description (HTML) |
job_requirements | string | Job requirements (HTML) |
job_offer | string | What the company offers (HTML) |
company_description | string|null | Company description in the vacancy's language (falls back to the source description) |
location | object|null | Location details (office/branch location) |
company_location | object|null | Company location details (actual work site, for agency tenants) |
department | object|null | Department details |
hiring_manager | object|null | Hiring manager information |
education_levels | array | Required education levels (may be empty) |
job_types | array | Employment types (may be empty) |
experience_levels | array | Experience/seniority levels (e.g., Junior, Medior, Senior, Lead; may be empty) |
work_arrangement | object | Work model: on-site, hybrid, or remote. Key is absent when the vacancy has no work arrangement set. |
tags | array | Job category tags (main and sub-categories; may be empty) |
classification | object|null | The tenant's classification label for this vacancy. Key is absent unless the tenant has enabled vacancy classification; null when enabled but no label is assigned. |
language_proficiencies | array|null | Required language skills. null when no language requirements are set (not an empty array). |
application_url | string | URL to apply for this position |
metadata | object | Additional vacancy metadata |
compensation | object | Compensation details. Key is absent unless include_compensation=true. |
Object structures
Images object
Returns a map of all configured image crops. The default key corresponds to the legacy header_image URL. Each entry also carries internal variant_settings and photo_library_item_id metadata you can ignore.
{
"default": {
"url": "https://app.recruitsome.com/media/vacancies/412/header-large.jpg",
"width": 1200,
"height": 675,
"mime_type": "image/jpeg"
},
"narrow_casting": {
"url": "https://app.recruitsome.com/media/vacancies/412/narrow-casting.jpg",
"width": 1080,
"height": 1920,
"mime_type": "image/jpeg"
}
}Header image object (legacy)
{
"small": "https://app.recruitsome.com/media/vacancies/412/header-small.jpg",
"medium": "https://app.recruitsome.com/media/vacancies/412/header-medium.jpg",
"large": "https://app.recruitsome.com/media/vacancies/412/header-large.jpg",
"xlarge": "https://app.recruitsome.com/media/vacancies/412/header-xlarge.jpg",
"original": "https://app.recruitsome.com/media/vacancies/412/header.jpg"
}Location object
{
"id": 3,
"name": "Amsterdam Office",
"city": "Amsterdam",
"country_code": "NL",
"country_name": "Netherlands"
}Company location object
The work site location for agency vacancies. Returns null for non-agency tenants or when no company location is assigned.
{
"id": 17,
"name": "Shell Pernis Refinery",
"city": "Rotterdam",
"country_code": "NL",
"country_name": "Netherlands",
"company_name": "Shell Nederland B.V."
}The company_name key is only present when include_company_name=true is passed. This is opt-in to prevent accidentally exposing which client company an agency is recruiting for.
Department object
{
"id": 5,
"name": "Maintenance & Engineering"
}Hiring manager object
The avatar field is a single URL string pointing to the medium-size avatar (256x256), or null when no avatar has been uploaded — it is not an object with multiple sizes.
{
"given_name": "Sanne",
"family_name": "de Vries",
"full_name": "Sanne de Vries",
"job_title": "Recruitment Manager",
"email": "[email protected]",
"avatar": "https://app.recruitsome.com/media/avatars/12/medium.jpg"
}Education level object
{
"id": 1,
"name": "Bachelor"
}Job type object
{
"id": 1,
"name": "Full-time"
}Experience level object
{
"id": 3,
"name": "Senior"
}Possible values: Junior, Medior, Senior, Lead. Returns an empty array when no experience level is assigned.
Work arrangement object
{
"value": "hybrid",
"label": "Hybride"
}The value field contains the canonical identifier: on_site, remote, or hybrid. The label is the localized display name (respects the language query parameter). This key is omitted entirely when the vacancy has no work arrangement set.
Tag object
{
"id": 5,
"name": "Maintenance Engineer",
"type": "sub",
"parent_id": 1
}The type field indicates whether the tag is a main category or a sub category. Main tags have parent_id: null.
Classification object
{
"name": "Priority A",
"key": "priority_a",
"color": "rose"
}key is a stable identifier derived from the label's name at creation. It never changes when the label is renamed, so match on key — not name — when you build logic around a classification. color is one of a fixed palette (rose, amber, emerald, sky, violet, gray) or null.
Language proficiency object
{
"language_code": "en",
"speaking_level": "Professional",
"reading_level": "Professional",
"writing_level": "Professional"
}Metadata object
{
"status": "active"
}Compensation object (when include_compensation=true)
The compensation object can contain salary, hours, holidays, and additional info:
salary: from the vacancy's own fields (min/max in the base currency unit, currency, period)hours: from the vacancy's own fields, falling back to the linked employment conditions (CompanyRemuneration)holidays: from the linked employment conditions (CompanyRemuneration). All day values are floats — partial days like12.5occur.additional_info: free-text notes captured on the vacancy, with optionalspecialty_benefitsandcompensation_noteskeys
{
"salary": {
"min": 3500,
"max": 5000,
"currency": "EUR",
"period": "monthly"
},
"hours": {
"min_per_week": 32,
"max_per_week": 40
},
"holidays": {
"total_days": 38.5,
"breakdown": {
"statutory": 20,
"non_statutory": 5.5,
"adv": 13
}
},
"additional_info": {
"specialty_benefits": "Company van and toolkit provided for on-call shifts.",
"compensation_notes": "Salary depends on relevant certifications (VCA, NEN 3140)."
}
}Each section is omitted when no data is available: a vacancy with no salary set has no salary key, and zero-value entries are dropped from the holidays.breakdown.
Structured employment conditions such as pension, holiday allowance, thirteenth month, travel allowance, and work-from-home allowance are not exposed via the API. Anything beyond salary, hours, and holidays only surfaces as free text in additional_info when it has been captured on the vacancy.
Example
curl -X GET "https://app.recruitsome.com/api/v1/vacancies/maintenance-engineer?include_compensation=true&language=nl" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Accept: application/json"const response = await fetch(
'https://app.recruitsome.com/api/v1/vacancies/maintenance-engineer?include_compensation=true&language=nl',
{
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Accept': 'application/json'
}
}
);
const vacancy = await response.json();Response 200
{
"data": {
"id": 412,
"slug": "maintenance-engineer",
"title": "Maintenance Engineer",
"summary": "<p>Keep our Rotterdam production lines running as part of a five-person technical service team.</p>",
"language": "en",
"published_at": "2026-05-12T09:00:00+00:00",
"ends_at": "2026-07-12T23:59:59+00:00",
"views_count": 42,
"header_image": {
"small": "https://app.recruitsome.com/media/vacancies/412/header-small.jpg",
"medium": "https://app.recruitsome.com/media/vacancies/412/header-medium.jpg",
"large": "https://app.recruitsome.com/media/vacancies/412/header-large.jpg",
"xlarge": "https://app.recruitsome.com/media/vacancies/412/header-xlarge.jpg",
"original": "https://app.recruitsome.com/media/vacancies/412/header.jpg"
},
"images": {
"default": {
"url": "https://app.recruitsome.com/media/vacancies/412/header-large.jpg",
"width": 1200,
"height": 675,
"mime_type": "image/jpeg"
}
},
"job_description": "<h2>About the role</h2><p>As Maintenance Engineer you keep three production lines running...</p>",
"job_requirements": "<h2>Requirements</h2><ul><li>Completed MBO 4 in mechatronics</li><li>VCA certificate</li></ul>",
"job_offer": "<h2>What we offer</h2><ul><li>Salary between €3,500 and €5,000</li><li>38.5 vacation days</li></ul>",
"company_description": "<p>We are a Rotterdam-based production company with 240 employees...</p>",
"location": {
"id": 3,
"name": "Amsterdam Office",
"city": "Amsterdam",
"country_code": "NL",
"country_name": "Netherlands"
},
"company_location": null,
"department": {
"id": 5,
"name": "Maintenance & Engineering"
},
"hiring_manager": {
"given_name": "Sanne",
"family_name": "de Vries",
"full_name": "Sanne de Vries",
"job_title": "Recruitment Manager",
"email": "[email protected]",
"avatar": null
},
"education_levels": [
{
"id": 1,
"name": "Bachelor"
}
],
"job_types": [
{
"id": 1,
"name": "Full-time"
}
],
"experience_levels": [
{
"id": 3,
"name": "Senior"
}
],
"work_arrangement": {
"value": "hybrid",
"label": "Hybride"
},
"tags": [
{
"id": 1,
"name": "Engineering",
"type": "main",
"parent_id": null
},
{
"id": 5,
"name": "Maintenance Engineer",
"type": "sub",
"parent_id": 1
}
],
"classification": {
"name": "Priority A",
"key": "priority_a",
"color": "rose"
},
"language_proficiencies": [
{
"language_code": "en",
"speaking_level": "Professional",
"reading_level": "Professional",
"writing_level": "Professional"
}
],
"compensation": {
"salary": {
"min": 3500,
"max": 5000,
"currency": "EUR",
"period": "monthly"
},
"hours": {
"min_per_week": 32,
"max_per_week": 40
},
"holidays": {
"total_days": 38.5,
"breakdown": {
"statutory": 20,
"non_statutory": 5.5,
"adv": 13
}
}
},
"application_url": "https://www.yourcompany.com/vacatures/maintenance-engineer",
"metadata": {
"status": "active"
}
}
}Error responses
| Status | When | Fix |
|---|---|---|
401 | Missing or invalid API key | Send a valid key as Authorization: Bearer YOUR_API_KEY |
403 | API key lacks the vacancies:read scope | Add the scope to your key or regenerate it with the Career website preset |
404 | No active website publication exists for this slug | Check the slug against the list endpoint — expired or unpublished vacancies also return 404 |
422 | Invalid query parameter (e.g. language not exactly 2 characters) | Correct the parameter per the table above |
Notes
- The
views_countis incremented with each request to this endpoint header_imageandimagesare always included on this endpoint —include_mediahas no effect here- Core relationship fields (
location,company_location,department,hiring_manager) are always present, even whennull;work_arrangementandcompensationkeys are omitted when not applicable classificationis only present for tenants that have enabled vacancy classification (Settings → Vacancies); the key isnullwhen enabled but the vacancy has no label assigned. Match integrations on the stablekey, which survives label renames- Salary amounts are in the base currency unit (e.g., 3500 = €3,500)
Localization
When the language parameter is provided, the following fields are returned in the specified language:
education_levels[].name— translated education level names (e.g., "Middelbaar onderwijs" for Dutch)job_types[].name— translated job type names (e.g., "Voltijd" for Dutch)work_arrangement.label— translated work model label (e.g., "Hybride" for Dutch)
If no language parameter is provided, the API returns values in the application's default locale.