# O\*NET occupations - titles, SOC codes, related jobs, job zones (`retrainmap/onet-occupations`) Actor

Search or look up occupations in the bundled O*NET 30.3 Database (USDOL/ETA, CC BY 4.0): O*NET-SOC code, title, description, job zone, reported titles, related occupations (tiered), task statements, O\*NET OnLine link. Fuzzy title search, code lookup, related-jobs mode; no network calls.

- **URL**: https://apify.com/retrainmap/onet-occupations.md
- **Developed by:** [RetrainMap Team](https://apify.com/retrainmap) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 1,000 records

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## O\*NET occupations — titles, SOC codes, related jobs, job zones

Search or look up occupations in the O*NET 30.3 Database (U.S. Department of Labor,
Employment and Training Administration) and get one flat row per occupation: O*NET-SOC code,
title, description, job zone (preparation level 1–5) with its name, the sample of reported job
titles, the O*NET-related occupations with relatedness tier and rank, optional task
statements, and the O*NET OnLine link — ready for CSV or JSON. Three modes: fuzzy **search**
by job title, **lookup** by O\*NET-SOC / SOC code, and **related** (one row per related
occupation of each given code).

The six O\*NET tables the Actor needs are bundled in the image (3.9 MB), so a run makes **no
network request** and finishes in seconds.

**The default input (search "medical assistant", 25 rows) succeeds within 5
minutes and returns rows** — Apify auto-tests it daily.

### Data source and licence

> This product includes information from the O*NET 30.3 Database by the U.S. Department of
> Labor, Employment and Training Administration (USDOL/ETA). Used under the CC BY 4.0
> license. O*NET® is a trademark of USDOL/ETA. RetrainMap is not affiliated with or endorsed
> by USDOL/ETA.

| | |
|---|---|
| Publisher | USDOL/ETA — the O*NET Program, National Center for O*NET Development (https://www.onetcenter.org/database.html) |
| What is bundled | O*NET 30.3 text distribution files `Occupation Data`, `Related Occupations`, `Job Zones`, `Job Zone Reference`, `Sample of Reported Titles`, `Task Statements` — 1,016 occupations, 923 job-zone assignments, 18,460 related-occupation pairs, 18,796 task statements. `Alternate Titles` is **not** bundled (not available on the build machine); search therefore uses the O*NET title and the sample of reported titles only |
| Refresh cadence | O*NET publishes a database release about **quarterly**; 30.3 is the release bundled here and every row carries `onet_version`. A newer release reaches this Actor only through a rebuild — check the version on the rows against https://www.onetcenter.org/database.html |
| Licence | Creative Commons Attribution 4.0 International (https://www.onetcenter.org/license\_db.html). Keep the attribution line above with any redistribution of the rows. O*NET® is a trademark of USDOL/ETA |
| Known caveats | 93 of the 1,016 occupations (mostly "All Other" aggregates and new/emerging codes) have no job zone, reported titles or related occupations; `job_zone_name` comes from O\*NET's Job Zone Reference, which in 30.3 folds zones 1 and 2 into "Job Zone 1-2"; `tasks` is cut at 3,000 characters (`tasks_truncated` says when); search scores are a simple word-overlap heuristic, not a semantic match — check `match_score` and `matched_on` |

Honesty note: the rows are the O*NET tables joined by O*NET-SOC code and flattened —
nothing is inferred or classified by this Actor; the only computed values are `match_score`
and `matched_on` in search mode (word overlap with light stemming: 100 = the query equals the
O\*NET title, 70–90 = the query's words are all in the title, 65 = equals a reported title,
50 = contained in a reported title, else 40 × word overlap — 10 to 15 means a single shared
word, e.g. "Technicians"; matches below 10 are dropped), and a
run stops with an error rather than guess when a bundled file's layout is not what it
expects.

No requests leave the container, so there is no User-Agent to identify; the operator's
contact is below.

### Input

| Field | Type | Meaning |
|---|---|---|
| `mode` | `search` / `lookup` / `related` | Default `search` |
| `query` | string | For `search`: a job title or a few words |
| `soc_codes` | array | For `lookup` / `related`: O*NET-SOC codes (`43-4051.00`) or 6-digit SOC codes (`43-4051` = every O*NET code under it). An unknown code stops the run |
| `include_tasks` | boolean | Add task statements (default false) |
| `max_records` | integer | Default 100, at most 20,000 |

Example — the related occupations of customer service representatives and heavy-truck drivers,
with tasks:

```json
{ "mode": "related", "soc_codes": ["43-4051.00", "53-3032"], "include_tasks": true, "max_records": 50 }
```

### Output (dataset row)

`onet_soc_code`, `title`, `description`, `job_zone` (1–5), `job_zone_name`,
`reported_titles` (joined with `; `), `related_occupations` (`code Title [tier #index]`,
joined with `; `), `related_count`, `tasks` (joined with `|`, when `include_tasks`),
`tasks_count`, `tasks_truncated`, `match_score` and `matched_on` (search mode),
`related_to_code`, `related_to_title`, `relatedness_tier` (Primary-Short / Primary-Long /
Supplemental) and `relatedness_index` (related mode), `onet_online_url`, `onet_version`,
`fetched_at`, `source` (the attribution line).

A run summary (input, candidate count or resolved codes, rows pushed, licence and
attribution) is stored as `RUN_SUMMARY` in the run's key-value store.

### Pricing (pay per event)

| Event | Price |
|---|---|
| `run-start` — once per run | $0.10 |
| `record` — per row written | $0.005 |

The default search (≤ 25 rows) costs at most $0.225; all 1,016 occupations cost $5.18. Rows
stop when your run's maximum charge is reached; the run summary says so.

### Operator

Steelyard Ventures LLC (RetrainMap) — info@steelyardclinical.com. Not affiliated with or
endorsed by USDOL/ETA or the O\*NET Program. The Actor writes only to its own dataset and
key-value store; it stores no credentials and sends nothing anywhere.

# Actor input Schema

## `mode` (type: `string`):

search = fuzzy match of the query against occupation titles and reported job titles (best matches first, with match\_score). lookup = the given soc\_codes. related = one row per O\*NET-related occupation of each given code, with relatedness tier (Primary-Short, Primary-Long, Supplemental) and index.

## `query` (type: `string`):

For mode=search. A job title or a few words, e.g. 'customer service representative', 'bookkeeper', 'truck driver'. Matching uses word overlap with light stemming on the O\*NET title and its sample of reported titles; rows carry match\_score (100 = exact title) and matched\_on.

## `soc_codes` (type: `array`):

For mode=lookup or related. O*NET-SOC codes such as 43-4051.00, or 6-digit SOC codes such as 43-4051 (= every O*NET code under it). A code that is not in O\*NET 30.3 stops the run. Browse codes at https://www.onetonline.org/find/all.

## `include_tasks` (type: `boolean`):

Add the occupation's O\*NET task statements to each row (joined with ' | ', cut at 3,000 characters; tasks\_count and tasks\_truncated say how many and whether it was cut).

## `max_records` (type: `integer`):

Stop after this many rows. O\*NET 30.3 has 1,016 occupations and 18,460 related-occupation pairs.

## Actor input object example

```json
{
  "mode": "search",
  "query": "medical assistant",
  "include_tasks": false,
  "max_records": 25
}
```

# Actor output Schema

## `results` (type: `string`):

Every matched occupation as one row: O*NET-SOC code, title, description, job zone, reported titles, related occupations, optional task statements, O*NET OnLine link.

## `results_csv` (type: `string`):

The same rows as a CSV file.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "query": "medical assistant",
    "max_records": 25
};

// Run the Actor and wait for it to finish
const run = await client.actor("retrainmap/onet-occupations").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "query": "medical assistant",
    "max_records": 25,
}

# Run the Actor and wait for it to finish
run = client.actor("retrainmap/onet-occupations").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "query": "medical assistant",
  "max_records": 25
}' |
apify call retrainmap/onet-occupations --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,retrainmap/onet-occupations"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/B6DddFblWIr3PQFof/builds/hZ44SdRT7HqEqxrsi/openapi.json
