Includes: - API v1/v2 documentation, endpoints, request/response schemas - Complete survey catalog (60 surveys, live-fetched from API) - Series ID decode tables: LAUS, CES, SM, QCEW, OES, JOLTS, CPI, PPI - QCEW quarterly (47 fields) and annual (43 fields) CSV schemas - dc_md_va_unemployment.py: pulls 16 LAUS series for DC/MD/VA + DC MSA - Example API response and 5-year CSV output Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
195 lines
5.0 KiB
Markdown
195 lines
5.0 KiB
Markdown
# BLS Data Reference
|
||
|
||
Bureau of Labor Statistics — API access, dataset catalog, series ID formats, and field schemas.
|
||
|
||
## Quick Start
|
||
|
||
1. Register for an API key: https://data.bls.gov/registrationEngine/
|
||
2. Base API endpoint: `https://api.bls.gov/publicAPI/v2/timeseries/data/`
|
||
3. Content-Type: `application/json` (POST)
|
||
|
||
---
|
||
|
||
## API Versions
|
||
|
||
| Feature | v1 (no key) | v2 (registered) |
|
||
|---------------------------|-------------|-----------------|
|
||
| Daily query limit | 25 | 500 |
|
||
| Series per query | 25 | 50 |
|
||
| Years of history | 10 | 20 |
|
||
| Net/percent changes | No | Yes |
|
||
| Series descriptions | No | Yes |
|
||
| Calculations | No | Yes |
|
||
|
||
---
|
||
|
||
## Registration
|
||
|
||
- URL: https://data.bls.gov/registrationEngine/
|
||
- Free, no approval needed — instant key via email
|
||
- Key goes in the JSON payload as `"registrationkey": "YOUR_KEY"`
|
||
|
||
---
|
||
|
||
## Endpoints
|
||
|
||
### GET: Survey List
|
||
```
|
||
GET https://api.bls.gov/publicAPI/v2/surveys
|
||
GET https://api.bls.gov/publicAPI/v2/surveys/{survey_abbreviation}
|
||
```
|
||
Returns all survey codes and names. See `surveys.json` for full list.
|
||
|
||
### GET: Popular Series
|
||
```
|
||
GET https://api.bls.gov/publicAPI/v2/timeseries/popular
|
||
GET https://api.bls.gov/publicAPI/v2/timeseries/popular?survey={abbreviation}
|
||
```
|
||
Returns the 25 most-requested series IDs for a survey.
|
||
|
||
### POST: Time Series Data
|
||
```
|
||
POST https://api.bls.gov/publicAPI/v2/timeseries/data/
|
||
Content-Type: application/json
|
||
```
|
||
|
||
**Minimal request (unregistered):**
|
||
```json
|
||
{
|
||
"seriesid": ["LAUST110000000000003", "CES0000000001"],
|
||
"startyear": "2023",
|
||
"endyear": "2025"
|
||
}
|
||
```
|
||
|
||
**Full request (registered, v2 features):**
|
||
```json
|
||
{
|
||
"seriesid": ["LAUST110000000000003", "CES0000000001"],
|
||
"startyear": "2020",
|
||
"endyear": "2025",
|
||
"registrationkey": "YOUR_KEY",
|
||
"catalog": true,
|
||
"calculations": true,
|
||
"annualaverage": true,
|
||
"aspects": true
|
||
}
|
||
```
|
||
|
||
**Response schema:**
|
||
```json
|
||
{
|
||
"status": "REQUEST_SUCCEEDED",
|
||
"responseTime": 114,
|
||
"message": [],
|
||
"Results": {
|
||
"series": [
|
||
{
|
||
"seriesID": "LAUST110000000000003",
|
||
"catalog": {
|
||
"series_title": "...",
|
||
"survey_name": "...",
|
||
"measure_data_type": "..."
|
||
},
|
||
"data": [
|
||
{
|
||
"year": "2025",
|
||
"period": "M12",
|
||
"periodName": "December",
|
||
"value": "6.4",
|
||
"footnotes": [
|
||
{ "code": "R", "text": "Data were subject to revision on April 8, 2026." }
|
||
],
|
||
"calculations": {
|
||
"net_changes": { "1": "0.1", "3": "-0.2", "6": "0.5", "12": "-0.3" },
|
||
"pct_changes": { "1": "1.6", "3": "-3.0", "6": "8.3", "12": "-4.5" }
|
||
}
|
||
}
|
||
]
|
||
}
|
||
]
|
||
}
|
||
}
|
||
```
|
||
|
||
**Period codes:**
|
||
- Monthly: `M01`–`M12`, `M13` (annual average)
|
||
- Quarterly: `Q01`–`Q04`, `Q05` (annual average)
|
||
- Annual: `A01`
|
||
|
||
**Status codes:** `REQUEST_SUCCEEDED`, `REQUEST_FAILED`, `REQUEST_NOT_PROCESSED`
|
||
|
||
**Error footnote codes:**
|
||
- `R` — Revised
|
||
- `P` — Preliminary
|
||
- `X` — Data unavailable (e.g., government shutdown gap)
|
||
- `N` — Not available
|
||
|
||
---
|
||
|
||
## Python Example
|
||
|
||
```python
|
||
import requests
|
||
|
||
API_KEY = "YOUR_KEY"
|
||
BASE_URL = "https://api.bls.gov/publicAPI/v2/timeseries/data/"
|
||
|
||
def get_series(series_ids, start_year, end_year):
|
||
payload = {
|
||
"seriesid": series_ids,
|
||
"startyear": str(start_year),
|
||
"endyear": str(end_year),
|
||
"registrationkey": API_KEY,
|
||
"catalog": True,
|
||
"calculations": True,
|
||
"annualaverage": True,
|
||
}
|
||
r = requests.post(BASE_URL, json=payload)
|
||
r.raise_for_status()
|
||
data = r.json()
|
||
if data["status"] != "REQUEST_SUCCEEDED":
|
||
raise ValueError(f"BLS API error: {data['message']}")
|
||
return data["Results"]["series"]
|
||
|
||
# DC unemployment rate (LAUS)
|
||
series = get_series(["LAUST110000000000003"], 2020, 2025)
|
||
for obs in series[0]["data"]:
|
||
print(obs["year"], obs["periodName"], obs["value"])
|
||
```
|
||
|
||
---
|
||
|
||
## Bulk Download (flat files)
|
||
|
||
Base URL: `https://download.bls.gov/pub/time.series/`
|
||
|
||
Each survey folder contains:
|
||
- `{prefix}.series` — master list of all series IDs with metadata
|
||
- `{prefix}.data.{N}.{name}` — actual observations, split by category
|
||
- `{prefix}.{dimension}` — lookup/decode tables (area, industry, measure, etc.)
|
||
|
||
Key folder prefixes:
|
||
```
|
||
la/ — LAUS (local area unemployment)
|
||
ce/ — CES national employment
|
||
sm/ — State & Metro employment (CES state)
|
||
en/ — QCEW
|
||
oe/ — OES (occupational employment)
|
||
jt/ — JOLTS
|
||
cu/ — CPI-U
|
||
wp/ — PPI commodities
|
||
```
|
||
|
||
Files are tab-delimited. Useful for bulk PostgreSQL ingest.
|
||
|
||
---
|
||
|
||
## Files in this folder
|
||
|
||
- `README.md` — this file
|
||
- `surveys.json` — complete survey list from the API
|
||
- `series_id_formats.md` — series ID decode tables for each key dataset
|
||
- `qcew_field_schema.md` — QCEW quarterly and annual CSV field layouts
|
||
- `api_response_example.json` — real API response sample
|