Skip to main content

Get Vacancy Facets

NL EN

Updated April 22, 2026

GET /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();

Get Vacancy Facets

The facets endpoint provides aggregated data about available filter options for vacancies. This is ideal for building dynamic search interfaces with faceted navigation, showing users what filters are available and how many results each filter would return.

Overview

This endpoint returns counts for all available filter options while respecting any currently applied filters. It's more efficient than using ?include=facets on the main listing endpoint when you only need facet data without the actual vacancy listings.

Simple Example

Get all available facets without any filters:

``bash cURL

curl -X GET https://app\.recruitsome\.com/api/v1/vacancies/facets \

-H "Authorization: Bearer YOUR_API_KEY"


javascript JavaScript

const response = await fetch('https://app\.recruitsome\.com/api/v1/vacancies/facets', {

headers: {

'Authorization': 'Bearer YOUR_API_KEY'

}

});

const facets = await response.json();


python Python

import requests

response = requests.get(

'https://app\.recruitsome\.com/api/v1/vacancies/facets',

headers={'Authorization': 'Bearer YOUR_API_KEY'}

)

facets = response.json()



Response Example

json

{

"data": {

"locations": [

{

"id": 1,

"name": "Amsterdam",

"city": "Amsterdam",

"country_code": "NL",

"country_name": "Netherlands",

"count": 45,

"selected": false

},

{

"id": 2,

"name": "Rotterdam",

"city": "Rotterdam",

"country_code": "NL",

"country_name": "Netherlands",

"count": 23,

"selected": false

},

{

"id": 3,

"name": "Utrecht",

"city": "Utrecht",

"country_code": "NL",

"country_name": "Netherlands",

"count": 18,

"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

},

{

"id": 7,

"name": "Marketing",

"count": 15,

"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

},

{

"id": 3,

"name": "Contract",

"count": 8,

"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": "Software Engineer",

"count": 25,

"selected": false

},

{

"id": 6,

"name": "DevOps Engineer",

"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": "2024-01-20T10:30:00Z",

"filters_applied": []

}

}


Filtered Example

Get facets with active filters to see how selections affect other options:

bash cURL

curl -X GET "https://app\.recruitsome\.com/api/v1/vacancies/facets?\

location_id[]=1&\

language=en" \

-H "Authorization: Bearer YOUR_API_KEY"


javascript JavaScript

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();


python Python

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()



When filters are applied:

  • The selected field shows true for active filters
  • Counts in other facet categories are updated to reflect only the filtered results
  • The filters_applied array in meta shows which filters are active

Query Parameters

ParameterTypeRequiredDescription
languagestringNoFilter by language code (e.g., 'en', 'nl', 'de')
location_id[]arrayNoFilter by location IDs (supports multiple)
company_location_id[]arrayNoFilter by company location IDs (work site, for agency tenants)
department_id[]arrayNoFilter by department IDs (supports multiple)
searchstringNoSearch in title and summary
experience_levels[]arrayNoFilter by experience level IDs
education_levels[]arrayNoFilter by education level IDs
job_types[]arrayNoFilter by job type IDs
tags[]arrayNoFilter by tag IDs (main tags cascade to include sub-tags)

<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 company_location_id parameter supports array notation on both this endpoint and the main vacancies endpoint. location_id and department_id support array notation only on this facets endpoint.</p></div>

Understanding Facet Counts

Without Filters

When no filters are applied, each facet shows the total count of active vacancies with that attribute:

  • Location "Amsterdam" count: 45 = Total active vacancies in Amsterdam
  • Department "Engineering" count: 32 = Total active vacancies in Engineering

With Active Filters

When filters are applied, counts show how many results match both the facet AND the current filters:

  • If filtering by Amsterdam: Department "Engineering" count: 12 = Vacancies in Amsterdam AND Engineering
  • The Amsterdam location itself will show "selected": true

Response Structure

Facet Object Structure

Each facet type contains an array of options with:

FieldTypeDescription
idintegerUnique identifier for the option
namestringHuman-readable name (translated)
countintegerNumber of vacancies with this attribute
selectedbooleanWhether this filter is currently active

Location Facets

Location facets include additional geographic information:

FieldTypeDescription
idintegerUnique location identifier
namestringLocation name
citystring\nullCity name (from locality field)
country_codestring\nullISO 3166-1 alpha-2 country code
country_namestring\nullFull country name in current locale
countintegerNumber of vacancies at this location
selectedbooleanWhether this filter is currently active

<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">For remote positions or locations without a specific city, the city field may be null.</p></div>

Company Location Facets

Company location facets represent the actual work sites (client company locations) for agency tenants. This array will be empty for non-agency tenants or when no vacancies have a company location assigned.

FieldTypeDescription
idintegerUnique company location identifier
namestringCompany location name
citystring\nullCity name (from locality field)
country_codestring\nullISO 3166-1 alpha-2 country code
country_namestring\nullFull country name in current locale
countintegerNumber of vacancies at this work site
selectedbooleanWhether this filter is currently active

<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 company_locations facet does not include the company name to prevent accidental disclosure of client relationships. Use the include_company_name parameter on the vacancy list/detail endpoints if you need company names.</p></div>

Tags Facets (Hierarchical)

Tags facets use a hierarchical structure with main categories containing nested sub-tags:

FieldTypeDescription
idintegerUnique tag identifier
namestringTag name (translated)
countintegerTotal vacancies in this category (including sub-tags)
selectedbooleanWhether this filter is currently active
sub_tagsarrayArray of sub-category tags

Each sub_tags item contains: id, name, count, and selected.

<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">When filtering by a main tag (e.g., "Engineering"), all vacancies tagged with any of its sub-tags are automatically included in the results.</p></div>

Language Facets

Language facets have a slightly different structure:

FieldTypeDescription
codestringISO 639-1 language code
namestringLanguage name
countintegerNumber of vacancies in this language
selectedbooleanWhether this filter is currently active

Use Cases

Building Dynamic Filters

Use facet data to create filter interfaces that show available options and counts:

javascript

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

}));

// Example output:

// {

// value: 1,

// label: "Amsterdam Office (45)",

// description: "Amsterdam, Netherlands",

// disabled: false,

// checked: false

// }


Smart Filter Updates

When a user selects a filter, fetch updated facets to show how it affects other options:

javascript

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);

}


Pre-loading Filter Options

Load facets on page load to immediately show available filters:

javascript

// On page load

const [vacancies, facets] = await Promise.all([

fetchVacancies({ page: 1 }),

fetchFacets({})

]);

// Initialize filters with facet data

initializeFilters(facets);


Performance Considerations

  1. Caching: Facet data changes less frequently than vacancy listings, making it ideal for caching
  2. Parallel Loading: Fetch facets in parallel with initial vacancy data for faster page loads
  3. Debouncing: When implementing live filter updates, debounce facet requests to avoid excessive API calls
  4. Conditional Updates: Only refetch facets when filters actually change

Error Responses

Invalid Filter Parameter

json

{

"message": "The given data was invalid.",

"errors": {

"location_id.0": ["The location_id.0 must be a valid location."]

}

}


API Access Disabled

json

{

"message": "API access is not enabled for this tenant."

}

``

Best Practices

  1. Cache Facet Results: Implement client-side caching with appropriate TTL
  2. Handle Empty States: Design UI to gracefully handle facets with zero counts
  3. Progressive Enhancement: Load initial page with basic filters, enhance with facet data
  4. Batch Updates: When multiple filters change, update them together in a single request
  5. Loading States: Show loading indicators while fetching updated facets