# USAJOBS Federal Jobs: Open and Historic Postings, No API Key (`jp-data-lab/usajobs-federal-jobs`) Actor

US federal jobs from the public USAJOBS API, no key needed: open jobs and postings back to 2017 with salary, grade, occupation series, hiring paths and locations. Filter by keyword, location, agency or pay. Commercial reuse allowed by the API terms.

- **URL**: https://apify.com/jp-data-lab/usajobs-federal-jobs.md
- **Developed by:** [JP Data Lab](https://apify.com/jp-data-lab) (community)
- **Categories:** Jobs, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 job postings

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?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## USAJOBS Federal Jobs: Open and Historic Postings, No API Key

Get US federal government jobs from the public USAJOBS Historic JOA API that the Office of Personnel Management (OPM) documents for developers. It needs no API key, no account and no browser. The same Actor returns jobs open right now and about 3.2 million past announcements going back to 2017, including what happened to them: `Candidate selected`, `Job canceled` or `Job closed`.

Use it to feed a job board or an alert, to find federal roles for a client or for veterans and military spouses, to study federal pay and hiring by occupation, agency or state, or to give an AI agent a way to answer "what federal IT jobs are open in Texas?". The API terms allow commercial reuse, so you can build on the results.

### Two ways to use it

**Open jobs.** This is the default. Filter by anything below. Results are newest first:

```json
{ "keywords": ["nurse"], "locations": ["Texas"], "hiringPaths": ["The public"], "maxItems": 50 }
```

For a weekly alert, schedule a run with `openedWithinDays` set to 7 and use `id` to skip jobs you have already seen.

**Past jobs.** Turn off `acceptingOnly` and give a date range. This is what the live USAJOBS search does not offer:

```json
{ "acceptingOnly": false, "openedFrom": "2024-01-01", "openedTo": "2024-12-31", "occupationSeries": ["2210"], "maxItems": 10000 }
```

One run reads up to 100,000 jobs before your filters, which is 2 to 3 months of all federal jobs in a busy year. A wider range stops at once with a message and costs nothing in results. Narrow it with `occupationSeries` or `departmentCodes`, which the API filters for you, or split it into several runs.

The history shows real shifts. USAJOBS has 367,055 announcements opened in 2024 and 168,222 opened in 2025.

### Output

One item per announcement:

```json
{
  "id": "usajobs:861843400",
  "source": "usajobs",
  "controlNumber": "861843400",
  "announcementNumber": "UDB-26-Q2-UDO-ICTAP",
  "title": "Police Officer (Secret Service Police) CTAP, ICTAP",
  "url": "https://www.usajobs.gov/job/861843400",
  "attribution": "Source: USAJOBS, U.S. Office of Personnel Management, https://www.usajobs.gov. Unofficial copy, not endorsed by OPM. Confirm details in the official announcement.",
  "department": "Department of Homeland Security",
  "departmentCode": "HS",
  "agency": "U.S. Secret Service",
  "agencyCode": "HSAD",
  "subAgency": null,
  "status": null,
  "acceptingApplications": true,
  "openDate": "2026-10-31",
  "closeDate": "2026-11-05",
  "hiringPaths": ["Career transition (CTAP, ICTAP, RPL)", "Veterans"],
  "occupationSeries": ["0083"],
  "occupationNames": ["Police"],
  "appointmentType": "Permanent",
  "workSchedule": "Full-time",
  "serviceType": "Competitive",
  "payScale": "LE",
  "minGrade": "1",
  "maxGrade": "1",
  "promotionPotential": "None",
  "minSalary": 77987.0,
  "maxSalary": 134165.0,
  "salaryType": "Per Year",
  "openings": "MANY",
  "location": "Washington, District of Columbia",
  "locationCount": 1,
  "locations": [{ "city": "Washington", "state": "District of Columbia", "country": "United States" }],
  "remote": false,
  "supervisory": false,
  "clearanceRequired": true,
  "securityClearance": "Top Secret",
  "travel": "Occasional travel",
  "drugTestRequired": false,
  "relocationReimbursed": false,
  "scrapedAt": "2026-11-01T00:00:00+00:00"
}
```

| Field | Meaning |
|---|---|
| `id` | Stable key. Use it to remove repeats between runs |
| `source` | Always `usajobs` |
| `controlNumber`, `announcementNumber` | The two numbers on the official announcement |
| `url` | The official announcement. Apply there, and read the duties and requirements there |
| `attribution` | The credit line to keep when you pass the data on |
| `department`, `agency`, `subAgency` | Who is hiring. `departmentCode` and `agencyCode` are the source's codes |
| `status` | The source's wording. Often `null` on a job posted in the last few days |
| `acceptingApplications` | `true` if the close date has not passed and `status` is `Accepting applications` or `null` |
| `openDate`, `closeDate` | When the announcement opens and closes |
| `hiringPaths` | Who can apply. `The public` means anyone |
| `occupationSeries`, `occupationNames` | The federal occupation code and its name from the official code list |
| `appointmentType`, `workSchedule`, `serviceType` | For example `Permanent`, `Full-time`, `Competitive` |
| `payScale`, `minGrade`, `maxGrade`, `promotionPotential` | For example `GS`, `09`, `12` |
| `minSalary`, `maxSalary`, `salaryType` | Pay and its basis, such as `Per Year` or `Per Hour`. `null` if the source gives none |
| `openings` | The source's text: a number, or a word such as `Many` or `Few` |
| `location` | One line for reading. `locations` has every city, state and country |
| `remote` | `true` if a location is `Anywhere in the U.S. (remote job)` |
| `supervisory`, `clearanceRequired`, `drugTestRequired`, `relocationReimbursed` | `true`, `false`, or `null` if not stated |
| `securityClearance`, `travel` | The source's wording |
| `scrapedAt` | When this run produced the item. This is also the retrieval date to cite |

`RUN_SUMMARY` in the key-value store gives the jobs read and matched for each query, and the newest opening date seen.

### Input

| Field | Default | |
|---|---|---|
| `keywords` | none | Title or occupation name contains any of these |
| `locations` | none | City, state or country equals one of these, e.g. `Texas`, `Seattle`, `Japan`. Use full state names |
| `agencies` | none | Department, agency or sub-agency name contains any of these, e.g. `Veterans` |
| `hiringPaths` | all | Who can apply, e.g. `The public`, `Veterans` |
| `remoteOnly` | `false` | Only `Anywhere in the U.S. (remote job)` |
| `minAnnualSalary` | 0 | Top pay reaches this per year. Hourly pay is multiplied by 2,087 hours. Daily and fee-based jobs are left out |
| `acceptingOnly` | `true` | Only jobs still taking applications. Turn off for past jobs |
| `openedWithinDays` | 0 | Opened in the last N days |
| `openedFrom`, `openedTo` | none | Opening date range, such as `2024-01-01`. Required for past jobs |
| `occupationSeries` | none | 4-digit codes, such as `2210` for IT or `0610` for nursing |
| `departmentCodes` | none | 2-letter codes, such as `VA`, `AR`, `AF`, `NV`, `DD` or `HS` |
| `maxItems` | 100 | Total for the run, newest first. You pay per result |

The default run reads all jobs closing today or later, about 8,500, and returns the 100 newest.

### Limitations

- **No job description text.** This API has titles, pay, requirements and locations, but not the duties or qualifications. `keywords` therefore looks at the title and occupation name only. `url` has the full text.
- **Open jobs are close to live, not live.** A status can trail the official site, and `acceptingOnly` leaves out jobs marked `Applications under review` even if their close date is still ahead, because some have stopped taking applications. Turn it off to see them.
- **Past announcements can be removed.** The API keeps a past job's data, but `url` may stop showing the full announcement.
- **No contact details.** This API has no HR contact names, emails or phone numbers.
- **The API has no telework field in use.** `remote` shows only jobs listed as remote. A job that allows telework from a duty station is not marked.
- **Before 2017 is sparse.** Only about 4,000 announcements have earlier opening dates.
- **Pool announcements are broad.** Some list more than 100 locations and stay open for a year, so they match many location filters.
- If a query fails, the run continues with the others and `RUN_SUMMARY` shows `incomplete: true` with the error.
- Not affiliated with or endorsed by USAJOBS, the Office of Personnel Management or any federal agency. This is an unofficial product. Check the official announcement before you apply or rely on a detail.

### Data source and terms

The data comes from the [Historic JOA API](https://developer.usajobs.gov/api-reference/get-api-historicjoa), which OPM documents as open without authentication, and from the public occupation code list. The [USAJOBS API Terms of Service](https://developer.usajobs.gov/guides/terms-of-service) name this endpoint as Public Data, which may be copied, published, redistributed and used for lawful commercial purposes without prior approval. OPM encourages you to name USAJOBS as the source, link to the current announcement, give the retrieval date, and say that your product is unofficial. Each item carries what you need in `attribution`, `url` and `scrapedAt`. The terms also forbid presenting altered data as official, claiming OPM endorsement, and using official seals or logos.

***

### 日本語

米国連邦政府の求人を、人事管理局（OPM）が開発者向けに公開している USAJOBS の Historic JOA API から取得します。API キーもログインも不要です。募集中の求人に加えて、2017 年以降の過去の求人約 320 万件も、採用結果（`Candidate selected` など）とともに取れます。出力は職名・省庁・状態・募集期間・応募資格・職種・給与・勤務地などで、職務内容の本文と人事担当者の連絡先はありません。公式の規約は、この API のデータの商用利用と再配布を事前の承認なしで認めています。

# Actor input Schema

## `keywords` (type: `array`):

Keep jobs whose title or occupation name contains any of these, e.g. nurse, data scientist. Case-insensitive. The source has no job description text, so a word that appears only in the duties will not match.

## `locations` (type: `array`):

Keep jobs with a location whose full city, state or country name equals one of these, e.g. Texas, Seattle, Japan. Virginia does not match West Virginia. Use full state names, not TX.

## `agencies` (type: `array`):

Keep jobs whose department, agency or sub-agency name contains any of these, e.g. Veterans, Secret Service, Navy.

## `hiringPaths` (type: `array`):

Keep jobs open to any of these groups. Choose The public for jobs anyone can apply to. Leave empty for all, including jobs for current federal employees.

## `remoteOnly` (type: `boolean`):

Keep jobs listed as Anywhere in the U.S. (remote job).

## `minAnnualSalary` (type: `integer`):

Keep jobs whose top pay reaches this amount per year. Hourly pay is multiplied by 2,087 hours. Jobs paid per day or by fee are left out when this is set. 0 = no limit.

## `acceptingOnly` (type: `boolean`):

Keep jobs still taking applications. Turn this off for past jobs and set a date below.

## `openedWithinDays` (type: `integer`):

Keep jobs opened in the last N days. Good for a daily or weekly schedule. 0 = no limit.

## `openedFrom` (type: `string`):

Date as 2024-01-01. For past jobs. Do not combine with Opened within (days).

## `openedTo` (type: `string`):

Date as 2024-01-31. A run reads at most 100,000 jobs before these filters, which is 2 to 3 months of all federal jobs in a busy year. Longer ranges need Occupation series or Department codes.

## `occupationSeries` (type: `array`):

4-digit federal occupation codes, e.g. 2210 (IT), 0610 (nursing), 1102 (contracting). Faster than keywords on long date ranges.

## `departmentCodes` (type: `array`):

2-letter codes, e.g. VA (Veterans Affairs), AR (Army), AF (Air Force), NV (Navy), DD (Defense), HS (Homeland Security). Faster than Agencies on long date ranges.

## `maxItems` (type: `integer`):

Total for the run, newest first. You are charged per result.

## Actor input object example

```json
{
  "keywords": [],
  "locations": [],
  "agencies": [],
  "hiringPaths": [],
  "remoteOnly": false,
  "minAnnualSalary": 0,
  "acceptingOnly": true,
  "openedWithinDays": 0,
  "openedFrom": "",
  "openedTo": "",
  "occupationSeries": [],
  "departmentCodes": [],
  "maxItems": 100
}
```

# Actor output Schema

## `jobs` (type: `string`):

One item per announcement: title, department and agency, status, open and close dates, hiring paths, occupation series, pay scale, grades, salary, locations, requirements, official link and attribution.

## `runSummary` (type: `string`):

Jobs read and matched per query in this run, the newest opening date seen, and any query errors.

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("jp-data-lab/usajobs-federal-jobs").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 = {}

# Run the Actor and wait for it to finish
run = client.actor("jp-data-lab/usajobs-federal-jobs").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 '{}' |
apify call jp-data-lab/usajobs-federal-jobs --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,jp-data-lab/usajobs-federal-jobs"
        }
    }
}
```

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/0FXjGujEYMiCZFD9x/builds/dTDgcBrLPJHIBFPm2/openapi.json
