Integrations · Databases and warehouses
Load job postings data into PostgreSQL
Upsert job posts into a PostgreSQL table with the raw JSON in a jsonb column - queryable with SQL and safe to re-run.
Steps
You need: Python 3.9+, pip install requests "psycopg[binary]" and a jobdata API key.
- Copy the fetch helper below and set your API key.
- Point the connection string at your database; the script creates the table on first run.
- Each job is upserted by its
id, so re-runs update rows instead of duplicating them. - Schedule the script daily (cron, a scheduler or your orchestrator).
import requests
API_KEY = "YOUR_API_KEY"
def fetch_jobs(**params):
"""Yield every job for the given filters, following pagination."""
url = "https://jobdataapi.com/api/jobs/"
params = {"page_size": 1000, **params}
headers = {"Authorization": f"Api-Key {API_KEY}"}
while url:
resp = requests.get(url, headers=headers, params=params, timeout=60)
resp.raise_for_status()
data = resp.json()
yield from data["results"]
url, params = data["next"], None # "next" already carries the filters
import psycopg
from psycopg.types.json import Jsonb
UPSERT = """
INSERT INTO jobs (id, title, company, location, published, application_url, data)
VALUES (%s, %s, %s, %s, %s, %s, %s)
ON CONFLICT (id) DO UPDATE SET
title = EXCLUDED.title,
location = EXCLUDED.location,
application_url = EXCLUDED.application_url,
data = EXCLUDED.data
"""
with psycopg.connect("postgresql://user:password@localhost/jobs") as conn:
conn.execute("""
CREATE TABLE IF NOT EXISTS jobs (
id bigint PRIMARY KEY,
title text,
company text,
location text,
published timestamptz,
application_url text,
data jsonb
)
""")
with conn.cursor() as cur:
for job in fetch_jobs(max_age=1):
cur.execute(UPSERT, (
job["id"], job["title"], job["company"]["name"], job["location"],
job["published"], job["application_url"], Jsonb(job),
))
Notes
- Run it daily with
max_age=1to pick up new job posts; on access lite, dropmax_age- the feed covers the past 90 days and upserting byidkeeps it free of duplicates. - Query nested fields straight from the JSON, e.g.
data->'company'->>'website_url', or add columns for the fields you filter on most. - Remove closed listings with the expired jobs endpoint (access pro) or the
expiredfield, so your copy never shows stale posts.
Related docs and tutorials
Jobs API Ingestion Guide: Reliable Historical Backfills and Incremental Syncs
A practical guide to high-volume historical backfills and incremental syncs using bounded windows, multi-pass pagination, ID deduplication, and reconciliation.
Date, ID, and Age Slicing Parameters Documentation
Slice smarter, sync faster: precise dataset windows for the /api/jobs/ endpoint
Jobs Expired API Endpoint Documentation
Tracking the lifecycle of job postings.
Ready to load real data?
All endpoints are public for limited testing - run the script without a key to see the structure, then add your key. Flat monthly plans with unlimited usage.
More integrations
Explore jobdata API with AI tools
Ask an AI assistant how to search and build with live job data.