NewSearch millions of jobs from your AI agent with MCP
All posts
ReferenceEsco
Reference·Aug 11, 2026·7 min read

ESCO API: the EU's free skills and occupations API, explained for developers

The European Commission serves its entire skills and occupations classification - roughly 3,000 occupations, 14,000 skills, labels in 28 languages - through a free API with no key and no registration. How the search and resource endpoints actually work, the essential-skills graph that powers job matching, the version default that silently serves you an old revision, and an honest map of what reference data can never tell you about the live market.

Dvir Atias

Dvir Atias

Founder, JobsPipe

Every European public employment service, and a growing share of HR tech, describes work in the same vocabulary: ESCO, the European Commission’s classification of Skills, Competences, Qualifications and Occupations. It holds roughly 3,000 occupations and about 14,000 skills, with the same concept labelled in the EU’s 24 official languages plus Arabic, Icelandic, Norwegian and Ukrainian - and all of it is served through a free HTTP API with no key, no registration and no quota paperwork. That combination is rare enough to be worth a guide. What the official portal does not make obvious: which of the scattered endpoints you actually need, the version default that quietly serves an old revision of the classification, and the hard line between what a reference taxonomy can tell you and what only live job postings can.

What ESCO actually is

ESCO has three pillars - occupations, skills and competences, and qualifications - and the first two are what developers use. Every ESCO occupation hangs under an ISCO-08 unit group, so the classification is best read as a fine-grained European extension of the international standard: “data scientist” is ESCO occupation 2511.3, a child of ISCO-08 unit group 2511. The skills pillar is the part nothing else offers at this price: each occupation is linked to the skills it requires, split into essential and optional, and each skill is a first-class resource with its own stable URI. If you are weighing ESCO against O*NET or Lightcast Open Skills, the skills taxonomy comparison covers that choice; the short version is that ESCO wins whenever multilingual matters, because the same skill URI resolves to a label in 28 languages.

Two APIs, no key

The Commission ships the classification two ways. The ESCO web-service API lives at ec.europa.eu/esco/api and is completely open: no authentication, no signup, CORS-friendly JSON. The ESCO local API is the same service as a download you run on your own hardware, which the Commission recommends for production loads - you get the performance and you stop depending on their uptime. There are also plain CSV and RDF downloads on the portal if you want the tables without the service. For prototyping and moderate traffic, the hosted API is fine, and it is the one this guide uses.

Your first request

Search is a GET, and it is the entry point for everything:

curl "https://ec.europa.eu/esco/api/search?text=data%20engineer&type=occupation&language=en&limit=5"

That query returns 452 matches, ranked. Each result carries a title, the ESCO code (2511.3), a preferredLabel object with the title in every supported language, and a broaderIscoGroup link naming the ISCO-08 unit group it belongs to. The field that matters most is uri: something like http://data.europa.eu/esco/occupation/258e46f9-.... ESCO is linked data, and that URI is the primary key you will pass to every other endpoint. Set type=skill to search the skills pillar the same way, and language to any of the 28 to search in that language.

Following the graph

The second endpoint you need is resource, which dereferences a URI into a full profile:

curl "https://ec.europa.eu/esco/api/resource/occupation?uri=http://data.europa.eu/esco/occupation/258e46f9-0075-4a2e-adae-1ff0477e0f30&language=en"

For data scientist that returns a description plus the relations that make ESCO useful: hasEssentialSkill - 23 skills, from data models to build recommender systems - and hasOptionalSkill with 16 more. This graph is the raw material of every ESCO-based product: expand a role into the skills a candidate should have, normalise a messy CV against occupation profiles, or translate a German job title into its English equivalent by round-tripping through the URI. resource/skill works identically in the other direction, listing every occupation a skill is essential for.

The version trap

The one integration mistake almost everyone makes: the hosted API does not default to the current classification. Unless you say otherwise, requests are answered from v1.0.9, an old revision, while the classification itself is at v1.2.1 as of December 2025. Pass selectedVersion=v1.2.0 to query a pinned modern release - the same skill search that returns 249 results on the default version returns 276 on v1.2.0, so the drift is not theoretical. Pin the version explicitly in anything that ships, both so you get current data and so a future default change cannot silently move your results.

What the ESCO API will never tell you

ESCO is reference data, updated on a revision cycle measured in years. Search v1.2.0 for “prompt engineering” and the top skills are prompt performers and manage prompt book - theatre occupations. The skill simply does not exist in the taxonomy yet. Measured against our corpus the day this post published, 9,925 active job postings are tagged with it. That is not a criticism of ESCO - a standard that changed weekly would be useless as a standard - but it draws the line precisely. The API can tell you what a data scientist should know. It cannot tell you how many data scientist roles are open, who is hiring for them, what they pay, or which skills employers started asking for after the last revision shipped. There are no postings, no employers, no counts and no dates anywhere in it.

From ESCO occupation to live postings

The bridge between the two layers is ISCO-08, because every ESCO occupation names its unit group. Take the broaderIscoGroup from any ESCO profile - 2511 for the data scientist above - and query live postings by that code. In our database today there are 2,189,786 active postings; 14,143 of them sit in unit group 2511, and 112,956 across sub-major group 25, ICT professionals. One request:

curl -X POST "https://api.jobspipe.dev/v1/jobs/search" \
  -H "Authorization: Bearer jp_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "occupation_code_or": ["2511"],
    "job_country_code_or": ["DE", "FR", "NL"],
    "posted_at_max_age_days": 14,
    "limit": 25
  }'

Every record comes back with the employer, posting URL, an ISCO-08 occupation code assigned by our classification layer, and extracted skills. One honest note on joining the skill pillars: our skills_or filter matches slugs from a curated lexicon built from what employers actually write - ["python", "kubernetes"], 128,029 active postings on the first of those - not ESCO URIs, so map skill labels rather than identifiers. Occupation codes need no mapping at all; both sides speak ISCO-08. The free tier is 1,000 jobs a month, no card required. For the US-centric counterpart to this post, the O*NET API guide covers the Department of Labor’s equivalent, and the labor market data comparison maps the wider field.

Which layer is yours

  • Multilingual normalisation, matching, interoperability with EU systems. The ESCO API - free, stable, authoritative, and version-pinned if you took the advice above.
  • Demand, employers, salaries, this week’s skills. A postings API. A revision-cycle taxonomy structurally cannot see this layer.
  • Both. The strongest products use ESCO as the vocabulary and live postings as the measurements, joined on ISCO-08 codes.

Live postings with ISCO-08 codes and extracted skills - the demand side of the taxonomy.

Get a free API key