Live job listings data
Hiring data you can actually compare.
Point /extract at a careers page or job board and get back title, compensation, location, and remote policy, matched to your schema and normalized across every source. Build a jobs aggregator or a hiring-signals feed from the live web with no scraper to maintain. The extraction happens inside the call.
import Tabstack, { APIError } from '@tabstack/sdk'
const client = new Tabstack()
// Any job posting in, a structured row out.
try {
const job = await client.extract.json({
url: 'https://careers.example.com/jobs/eng',
json_schema: {
type: 'object',
properties: {
title: { type: 'string' },
company: { type: 'string' },
location: { type: 'string' },
remote: { type: 'boolean' },
employment_type: { type: 'string' },
salary_min: { type: 'number' },
salary_max: { type: 'number' },
currency: { type: 'string' },
skills: { type: 'array' },
posted_at: { type: 'string' },
},
},
effort: 'standard',
})
console.log(job) // normalized
} catch (err) {
if (!(err instanceof APIError)) throw err
console.error(err.status, err.message)
}The old way
Every job board is a different shape.
Postings live on hundreds of boards and bespoke career sites, each with its own layout and its own way of writing salary and location. A DIY scraper needs a parser per source and normalization glue on top, and it breaks every time a board ships a redesign or an anti-bot wall.
A parser per board
- Hundreds of layouts, each with its own structure
- Comp and location written a different way every time
Constant normalization
- Glue code to reconcile fields across sources
- Breaks on every redesign or anti-bot wall
/extract/json
One schema across every board and careers page.
Define the job shape once (title, comp range, location, remote, skills, posted date) and point /extract at any board or company careers page. The same call normalizes fields across sources with no per-site parser, so a salary range or a remote flag comes back the same shape everywhere. Run it across a URL list to build an aggregator.
Features
- ✓One schema across every board and layout
- ✓Normalized comp, location, and remote fields
- ✓Skills and posted-date parsing built in
- ✓Run across a URL list to build a feed
import Tabstack, { APIError } from '@tabstack/sdk'
const client = new Tabstack()
// Any job posting in, a structured row out.
try {
const job = await client.extract.json({
url: 'https://careers.example.com/jobs/eng',
json_schema: {
type: 'object',
properties: {
title: { type: 'string' },
company: { type: 'string' },
location: { type: 'string' },
remote: { type: 'boolean' },
employment_type: { type: 'string' },
salary_min: { type: 'number' },
salary_max: { type: 'number' },
currency: { type: 'string' },
skills: { type: 'array' },
posted_at: { type: 'string' },
},
},
effort: 'standard',
})
console.log(job) // normalized
} catch (err) {
if (!(err instanceof APIError)) throw err
console.error(err.status, err.message)
}import Tabstack, { APIError } from '@tabstack/sdk'
const client = new Tabstack()
// store and notify are your own storage and alerting.
try {
// Snapshot a careers page and diff to catch new roles.
const page = await client.extract.markdown({
url: 'https://careers.example.com',
effort: 'standard',
})
const prev = await store.get('careers-example')
if (page.content !== prev) {
await store.set('careers-example', page.content)
await notify('New activity on Example careers page')
}
} catch (err) {
if (!(err instanceof APIError)) throw err
console.error(err.status, err.message)
}/extract/markdown
Snapshot careers pages to catch new roles.
Structured rows capture each posting; a full-page snapshot captures the change. Grab a company careers page as clean markdown on a schedule, diff it against the last snapshot, and surface a new opening the day it goes live, a hiring signal for sales, recruiting, or market research.
Features
- ✓Clean full-page markdown for change tracking
- ✓Diff over time to catch new roles
- ✓Run on a schedule and alert on change
- ✓A hiring signal for sales and recruiting
Try it live
Normalize a live job posting.
Paste a job posting URL and get a schema-matched record back from a real /extract/json call. The result is cached in your browser.
Runs a live /extract/json call and normalizes the posting to one schema.
Own it vs. buy it
Own the pipeline instead of licensing a jobs feed.
A licensed jobs feed covers the boards the vendor indexes and lags the postings on the actual pages. Build the extraction step on a handful of calls, pull exactly the sources you care about, refresh whenever you want, and own the pipeline.
Jobs feed vendor
- Only the boards the vendor indexes
- Postings that lag the live careers page
- A pipeline you cannot inspect or extend
Licensed feed
Build on Tabstack
owned- Usage-based credits across five endpoints
- Pull exactly the sources you need, refresh anytime
- Open every source and verify the posting yourself
Who builds on this
Teams that build hiring data without a jobs feed.
Job board & aggregator engineers
One schema across every board, no parser per source.
Sales & recruiting teams
A hiring signal the day a role goes live.
Market researchers
Labor-market data straight to the warehouse.
Agents
A live job lookup inside a workflow.
Mozilla-backed
Privacy, Transparency, and Control
When you build on /research, your users' questions and the data behind every answer stay yours. Tabstack is a Mozilla-backed platform, and we handle live-web research responsibly, so you can ship features your users actually trust.
Private by default.Queries and retrieved pages are used to build your answer and support you, then purged. Never sold, never used to train models.
Verifiable by design.Every answer returns source URLs and inline citations, so you and your users can confirm exactly where each claim came from.
Yours to control.You set the mode, scope, and depth of every call. No retained corpus, no lock-in, just clean, cited data you own.
See exactly how we source and handle data in the documentation.
Mozilla ManifestoPricing & Plans
All prices in USD.
Starter
100,000 credits included
For tinkerers & hobbyists who want to simply connect their systems to the internet.
Get StartedTeam
500,000 credits included
Low-latency, predictable cost automation so you can focus on your core product.
Get StartedPro
3,000,000 credits included
For teams deploying and managing production workloads efficiently at scale.
Get StartedEnterprise Plan
Need Custom Pricing?
Custom API quotas, dedicated support, and SLAs for high-volume teams.
Cost per action
Every endpoint bills in credits. Extract and Generate are a single action per call. Automate and Research run a variable number of actions per task, so cost scales with the work they do.
- Extract (Markdown)10 credits
- Extract (JSON)50 credits
- Generate100 credits
- Automate100 credits
- Research (Fast)250 credits
- Research (Balanced)350 credits
Add a board without writing a parser.
Start with 10,000 free credits, no card.