Bijgewerkt 15 juni 2026
/api/v1/vacancies/facets
curl -X GET \
"https://app.recruitsome.com/api/v1/vacancies/facets" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Accept: application/json"
const response = await fetch('https://app.recruitsome.com/api/v1/vacancies/facets', {
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/facets');
$data = $response->json();
Het facets-endpoint levert geaggregeerde data over beschikbare filteropties voor vacatures. Dit is ideaal voor het bouwen van dynamische zoekinterfaces met facetnavigatie, waarbij gebruikers zien welke filters beschikbaar zijn en hoeveel resultaten elk filter oplevert.
Dit endpoint is efficiënter dan ?include=facets op het hoofdlijst-endpoint wanneer je alleen facetdata nodig hebt zonder de daadwerkelijke vacaturelijst. Denk bijvoorbeeld aan het renderen van de filtersidebar vóór de eerste zoekopdracht.
Authenticatie
Vereist een API sleutel met de vacancies:read-scope (inbegrepen in de Carrièrewebsite-preset). Een sleutel zonder deze scope ontvangt een 403-respons.
Queryparameters
| Parameter | Type | Verplicht | Beschrijving |
|---|---|---|---|
language | string | Nee | Filter op taalcode (exact 2 tekens, bijv. en, nl) |
location_id[] | array | Nee | Filter op locatie-ID. Accepteert arraynotatie, maar alleen het eerste element wordt toegepast. Extra elementen worden genegeerd. |
company_location_id[] | array | Nee | Filter op bedrijfslocatie-ID (werklocatie, voor bureau-tenants). Accepteert arraynotatie, maar alleen het eerste element wordt toegepast op dit endpoint. |
department_id[] | array | Nee | Filter op afdeling-ID. Accepteert arraynotatie, maar alleen het eerste element wordt toegepast. |
search | string | Nee | Zoek in titel en samenvatting |
experience_levels[] | array | Nee | Filter op ervaringsniveau-ID's (meerdere waarden ondersteund) |
job_types[] | array | Nee | Filter op dienstverband-ID's (meerdere waarden ondersteund) |
education_levels[] en tags[] worden niet geaccepteerd op dit endpoint. Ze worden stilzwijgend genegeerd en hebben geen invloed op de tellingen. Wil je facettellingen gefilterd op opleidingsniveau of tag? Gebruik dan GET /vacancies?include=facets op het lijstendpoint, dat deze filters wél toepast.
Voor daadwerkelijk multi-valued filteren op company_location_id[] gebruik je het lijstendpoint (GET /vacancies), dat alle elementen van de array toepast.
Voorbeeld
Haal alle beschikbare facetten op zonder filters:
curl -X GET https://app.recruitsome.com/api/v1/vacancies/facets \
-H "Authorization: Bearer YOUR_API_KEY"const response = await fetch('https://app.recruitsome.com/api/v1/vacancies/facets', {
headers: {
'Authorization': 'Bearer YOUR_API_KEY'
}
});
const facets = await response.json();import requests
response = requests.get(
'https://app.recruitsome.com/api/v1/vacancies/facets',
headers={'Authorization': 'Bearer YOUR_API_KEY'}
)
facets = response.json()Response 200
{
"data": {
"locations": [
{
"id": 1,
"name": "Amsterdam Office",
"city": "Amsterdam",
"country_code": "NL",
"country_name": "Netherlands",
"count": 45,
"selected": false
},
{
"id": 2,
"name": "Rotterdam Office",
"city": "Rotterdam",
"country_code": "NL",
"country_name": "Netherlands",
"count": 23,
"selected": false
}
],
"company_locations": [
{
"id": 10,
"name": "Shell Pernis Refinery",
"city": "Rotterdam",
"country_code": "NL",
"country_name": "Netherlands",
"count": 12,
"selected": false
},
{
"id": 11,
"name": "ASML Veldhoven HQ",
"city": "Veldhoven",
"country_code": "NL",
"country_name": "Netherlands",
"count": 8,
"selected": false
}
],
"departments": [
{
"id": 5,
"name": "Engineering",
"count": 32,
"selected": false
},
{
"id": 6,
"name": "Sales",
"count": 21,
"selected": false
}
],
"experience_levels": [
{
"id": 2,
"name": "Junior",
"count": 20,
"selected": false
},
{
"id": 3,
"name": "Medior",
"count": 35,
"selected": false
},
{
"id": 4,
"name": "Senior",
"count": 28,
"selected": false
}
],
"job_types": [
{
"id": 1,
"name": "Full-time",
"count": 68,
"selected": false
},
{
"id": 2,
"name": "Part-time",
"count": 12,
"selected": false
}
],
"education_levels": [
{
"id": 8,
"name": "Bachelor",
"count": 45,
"selected": false
},
{
"id": 9,
"name": "Master",
"count": 28,
"selected": false
}
],
"tags": [
{
"id": 1,
"name": "Engineering",
"count": 42,
"selected": false,
"sub_tags": [
{
"id": 5,
"name": "Maintenance Engineer",
"count": 25,
"selected": false
},
{
"id": 6,
"name": "Service Technician",
"count": 12,
"selected": false
}
]
},
{
"id": 2,
"name": "Sales",
"count": 28,
"selected": false,
"sub_tags": [
{
"id": 10,
"name": "Account Executive",
"count": 15,
"selected": false
}
]
}
],
"languages": [
{
"code": "en",
"name": "English",
"count": 52,
"selected": false
},
{
"code": "nl",
"name": "Nederlands",
"count": 34,
"selected": false
}
]
},
"meta": {
"generated_at": "2026-05-20T10:30:00+00:00",
"filters_applied": []
}
}Voorbeeld met filters
Haal facetten op met actieve filters om te zien hoe selecties andere opties beïnvloeden:
curl -X GET "https://app.recruitsome.com/api/v1/vacancies/facets?location_id[]=1&language=en" \
-H "Authorization: Bearer YOUR_API_KEY"const params = new URLSearchParams({
'location_id[]': 1,
'language': 'en'
});
const response = await fetch(
`https://app.recruitsome.com/api/v1/vacancies/facets?${params}`,
{
headers: {
'Authorization': 'Bearer YOUR_API_KEY'
}
}
);
const facets = await response.json();import requests
params = {
'location_id[]': 1,
'language': 'en'
}
response = requests.get(
'https://app.recruitsome.com/api/v1/vacancies/facets',
headers={'Authorization': 'Bearer YOUR_API_KEY'},
params=params
)
facets = response.json()Wanneer er filters zijn toegepast:
- Het veld
selectedtoonttruevoor actieve filters - Aantallen in andere facetcategorieën worden bijgewerkt en weerspiegelen alleen de gefilterde resultaten
- De array
filters_appliedinmetalaat zien welke filters actief zijn
Facetaantallen begrijpen
Zonder filters
Wanneer er geen filters zijn toegepast, toont elk facet het totale aantal actieve vacatures met dat kenmerk:
- Locatie "Amsterdam Office" aantal 45 = totaal aantal actieve vacatures in Amsterdam
- Afdeling "Engineering" aantal 32 = totaal aantal actieve vacatures bij Engineering
Met actieve filters
Wanneer er filters zijn toegepast, tonen de aantallen hoeveel resultaten overeenkomen met zowel het facet als de huidige filters:
- Bij filteren op Amsterdam: Afdeling "Engineering" aantal 12 = vacatures in Amsterdam én Engineering
- De locatie Amsterdam zelf toont
"selected": true
Responsstructuur
Structuur van het facet-object
Elk facettype bevat een array van opties met:
| Veld | Type | Beschrijving |
|---|---|---|
id | integer | Unieke identifier voor de optie |
name | string | Leesbare naam (vertaald) |
count | integer | Aantal vacatures met dit kenmerk |
selected | boolean | Of dit filter momenteel actief is |
Locatiefacetten
Locatiefacetten bevatten aanvullende geografische informatie:
| Veld | Type | Beschrijving |
|---|---|---|
id | integer | Unieke locatie-identifier |
name | string | Locatienaam |
city | string|null | Plaatsnaam (uit het locality-veld) |
country_code | string|null | ISO 3166-1 alpha-2 landcode |
country_name | string|null | Volledige landnaam in de huidige taal |
count | integer | Aantal vacatures op deze locatie |
selected | boolean | Of dit filter momenteel actief is |
Bij remote posities of locaties zonder specifieke stad kan het veld city de waarde null hebben.
Bedrijfslocatiefacetten
Bedrijfslocatiefacetten vertegenwoordigen de daadwerkelijke werklocaties (locaties van het klantbedrijf) voor bureau-tenants. Deze array is leeg voor niet-bureau-tenants of wanneer er geen vacatures met een bedrijfslocatie zijn gekoppeld. De velden zijn hetzelfde als bij de locatiefacetten hierboven.
Het facet company_locations bevat niet de bedrijfsnaam, om onbedoelde onthulling van klantrelaties te voorkomen. Gebruik de parameter include_company_name op de vacaturelijst- of detail-endpoints als je bedrijfsnamen nodig hebt.
Tagfacetten (hiërarchisch)
Tagfacetten gebruiken een hiërarchische structuur met hoofdcategorieën die geneste subtags bevatten:
| Veld | Type | Beschrijving |
|---|---|---|
id | integer | Unieke tag-identifier |
name | string | Tagnaam (vertaald) |
count | integer | Totaal aantal vacatures in deze categorie (inclusief subtags) |
selected | boolean | Of dit filter momenteel actief is |
sub_tags | array | Array van subcategorietags |
Elk item in sub_tags bevat: id, name, count en selected.
Items met een telling van nul worden uit het tagfacet verwijderd: subtags zonder overeenkomende vacatures worden weggelaten uit sub_tags, en een hoofdtag waarvan de volledige tak (zichzelf plus alle subtags) nul resultaten heeft, wordt volledig weggelaten uit tags. Verwacht hier dus niet de volledige tagcatalogus, alleen takken met ten minste één actieve vacature.
Taalfacetten
Taalfacetten hebben een iets andere structuur:
| Veld | Type | Beschrijving |
|---|---|---|
code | string | ISO 639-1 taalcode |
name | string | Taalnaam |
count | integer | Aantal vacatures in deze taal |
selected | boolean | Of dit filter momenteel actief is |
Toepassingen
Dynamische filters bouwen
Gebruik facetdata om filterinterfaces te maken die beschikbare opties en aantallen tonen:
// Build location filter dropdown with enhanced geographic info
const locationFilter = facets.data.locations.map(location => ({
value: location.id,
label: `${location.name} (${location.count})`,
description: location.city && location.country_name
? `${location.city}, ${location.country_name}`
: location.country_name || '',
disabled: location.count === 0,
checked: location.selected
}));Slimme filterupdates
Wanneer een gebruiker een filter selecteert, haal je bijgewerkte facetten op om te tonen hoe dit de andere opties beïnvloedt:
async function onFilterChange(filters) {
// Fetch new facets with current filters
const facets = await fetchFacets(filters);
// Update UI to show new counts
updateFilterCounts(facets);
// Disable options with zero results
disableEmptyFilters(facets);
}Filteropties vooraf laden
Laad facetten bij het laden van de pagina om direct de beschikbare filters te tonen:
// On page load
const [vacancies, facets] = await Promise.all([
fetchVacancies({ page: 1 }),
fetchFacets({})
]);
// Initialize filters with facet data
initializeFilters(facets);Prestatieoverwegingen
- Caching: Facetdata verandert minder vaak dan vacatureoverzichten. Dat maakt het ideaal voor caching.
- Parallel laden: Haal facetten parallel op met de initiële vacaturedata voor snellere laadtijden.
- Debouncing: Wanneer je live filterupdates implementeert, gebruik dan debouncing op facetverzoeken om overmatige API-calls te voorkomen.
- Conditionele updates: Haal facetten alleen opnieuw op wanneer filters daadwerkelijk wijzigen.
Foutresponses
401 – ontbrekende of ongeldige API sleutel
{
"message": "Unauthenticated."
}Stuur een geldige sleutel mee als Authorization: Bearer YOUR_API_KEY.
403 – sleutel mist de vereiste scope
{
"message": "This API key does not have the required permission: vacancies:read",
"error": "INSUFFICIENT_SCOPE",
"required_scope": "vacancies:read"
}Voeg de scope vacancies:read toe aan je sleutel, of genereer een nieuwe sleutel met de preset Carrièrewebsite.
422 – ongeldige filterparameter
Dit wordt geretourneerd wanneer een filterwaarde niet door de validatie komt, bijvoorbeeld een location_id[] die niet bestaat:
{
"message": "The selected location_id.0 is invalid.",
"errors": {
"location_id.0": [
"The selected location_id.0 is invalid."
]
}
}