// freehire API
API reference
A read-first, open HTTP API over the freehire job catalogue — query jobs by rich filters, read companies, and (with a key) track applications.
Base URL
All endpoints are served under https://freehire.dev/api/v1. The API is read-first and open: the job, search, facet, and company endpoints need no authentication and may be called cross-origin.
Authenticated endpoints accept either the browser session cookie (set by sign-in, same-origin) or a personal API key sent as a Bearer token — see Authentication and API keys below.
Response envelope
Single items are wrapped as { "data": ... }. Collections add pagination metadata: { "data": [...], "meta": { "total", "limit", "offset" } }. Errors are { "error": "message" } with a matching HTTP status.
{ "data": { "...": "single item" } }
{ "data": [ ... ], "meta": { "total": 4213, "limit": 20, "offset": 0 } }
{ "error": "job not found" }Pagination
List and search endpoints page with limit (default 20, max 100) and offset (default 0). meta.total reports the total matching the current filters, so you can compute the number of pages.
Search pagination is bounded: offset + limit may not exceed 10000 (pagination too deep → 400). This is deep-paging protection, not a cap on the reported total — use filters to narrow rather than paging that far.
Errors
Errors use standard HTTP status codes: 400 (bad request / invalid value), 401 (missing or invalid credentials), 403 (authenticated but not allowed, e.g. a non-moderator), 404 (no such job, company, or owned resource), and 503 (search temporarily unavailable). The body is always { "error": ... }.
Authentication model
Browser clients authenticate with an HttpOnly session cookie set on sign-in (same-origin; the SPA cannot read it). Non-browser clients use a personal API key as Authorization: Bearer <token>.
Endpoints marked “Session or API key” accept either; endpoints marked “Session only” (API-key management, saved searches, subscriptions) accept only the cookie, so a leaked key cannot manage credentials. “Moderator” endpoints additionally require the moderator role.
Filtering jobs
These parameters apply to GET /jobs/search and GET /jobs/facets.
Combine any of them with full-text q.
Modifiers — apply to every facet
- ›Repeat any facet param to OR its values:
skills=go&skills=rustmatches either. - ›Add
<param>_mode=andto require all selected values:skills=go&skills=rust&skills_mode=andmatches both. - ›Add
<param>_exclude=<value>to exclude matches:company_type_exclude=outstaffdrops outstaff jobs. - ›Different facets are ANDed together; numeric and boolean filters are ANDed too.
- ›Use
regions=noneto match jobs with no resolved geography (an empty region set); it ORs with real region values and supports_excludelike any region.
Facets
Every facet below supports repeat-OR, _mode=and, and _exclude as described above.
| Param | Filter | Values |
|---|---|---|
collections | Collection | yc, techstars, european, ai, mag7, bigtech, unicorn, fortune500, eastern-roots, ai-native |
regions | Region | global, north_america, latam, eu, uk, mena, africa, apac, cis, none |
work_mode | Work format | remote, hybrid, onsite |
is_tech | Tech / Non-tech | tech, non_tech |
role | Role | Open vocabulary — call /jobs/facets for live values |
category | Specialization | backend, frontend, fullstack, mobile, devops, sre, network_engineering, data_engineering, data_science, data_analytics, ml_ai, ai_engineering, qa, security, hardware, embedded, blockchain, architecture, design, product, project_management, management, marketing, sales, support, business_analysis, solutions_engineering, developer_relations, technical_writing, recruiting, hr, finance, legal, operations, customer_success, other |
seniority | Seniority | intern, junior, middle, senior, lead, staff, principal, c_level |
skills | Skills | Open vocabulary — call /jobs/facets for live values |
domains | Industry | fintech, crypto, ecommerce, gambling, gamedev, media, travel, healthcare, edtech, govtech, devtools, cybersecurity, ai, hrtech, adtech, proptech, logistics, mobility, climatetech, other |
company_type | Company type | product, startup, outsource, outstaff, agency, inhouse, government |
countries | Countries | Open vocabulary — call /jobs/facets for live values |
cities | City | Open vocabulary — call /jobs/facets for live values |
relocation | Relocation | not_supported, supported, required |
employment_type | Employment | full_time, part_time, contract, internship |
english_level | English | none, a1, a2, b1, b2, c1, c2, native |
posting_language | Job language | Open vocabulary — call /jobs/facets for live values |
reality | Posting reality | fresh, stale, likely-evergreen |
salary_currency | Currency | USD, EUR, GBP, RUB |
company_slug | Company | Open vocabulary — call /jobs/facets for live values |
source | Source | Open vocabulary — call /jobs/facets for live values |
company_size | Company size | 1-10, 11-50, 51-200, 201-500, 501-1000, 1000+ |
education_level | Education level | none, bachelor, master, phd |
salary_period | Salary period | year, month, day, hour |
Numeric & boolean filters
| Param | Filter | Values |
|---|---|---|
visa_sponsorship | Visa sponsorship | true, false |
salary_min | Minimum salary | integer — jobs whose minimum salary is at least this (pair with salary_currency) |
salary_max | Maximum salary | integer — jobs whose maximum salary is at most this (pair with salary_currency) |
experience_years_min | Minimum experience | integer — jobs requiring at least this many years |
posted_within_days | Posted within | integer — jobs whose effective posting date falls in the last N days |
Recipes
Senior Go, remote, in the CIS region
?q=go&seniority=senior&work_mode=remote®ions=cis
Backend roles, freshest first, in Germany
?category=backend&countries=DE&sort=posted_at&order=desc
Must use both Go and Rust
?skills=go&skills=rust&skills_mode=and
Exclude outstaff companies
?company_type_exclude=outstaff
At least $100k, with visa sponsorship
?salary_currency=USD&salary_min=100000&visa_sponsorship=true
Endpoints
Every endpoint has its own page. Pick one below or from the sidebar.
Jobs
- GET /jobs List jobs, newest first, with limit/offset pagination.
- GET /jobs/search Full-text + faceted search over open jobs.
- GET /jobs/facets Count of matching jobs per facet value (and numeric stats).
- GET /jobs/{slug} A single job by its public slug (serves closed jobs too).
- GET /jobs/{slug}/similar Jobs similar to the given one (semantic; may be empty).
- GET /jobs/{slug}/copies Other open postings in the same role cluster (per-city duplicates).
AI analysis
- GET /jobs/{slug}/match Deterministic skill match of the job against your profile (no LLM).
- GET /jobs/{slug}/match-analysis The cached AI fit analysis for the job (never runs the LLM).
- POST /jobs/{slug}/match-analysis Run the three-stage AI fit analysis and cache it.
- GET /jobs/{slug}/match-analysis/stream Run the fit analysis over Server-Sent Events.
- GET /me/recommendations Open jobs ranked by semantic similarity to your CV.
- POST /market/coverage Score a supplied skill list against the filtered job market.
Companies
Authentication
- POST /auth/register Create an account and start a session.
- POST /auth/login Sign in and start a session.
- POST /auth/logout Clear the session cookie.
- GET /auth/me The current user (cookie or API key).
- GET /auth/oauth/providers List the enabled OAuth providers.
- GET /auth/oauth/{provider}/start Begin the OAuth sign-in redirect.
API keys
Job interactions
- POST /jobs/{slug}/view Record that you viewed the job.
- POST /jobs/{slug}/apply Mark the job as applied to.
- POST /jobs/{slug}/save Save (bookmark) the job.
- DELETE /jobs/{slug}/save Unsave the job (no-op if not saved).
- PATCH /jobs/{slug}/track Set the application stage and/or notes.
- DELETE /jobs/{slug}/stage Clear the application stage.
- DELETE /jobs/{slug}/track Remove the interaction record entirely.
- POST /jobs/{slug}/dismiss Dismiss (swipe away) the job.
- DELETE /jobs/{slug}/dismiss Undismiss the job (no-op if not dismissed).
- GET /me/tracking Your tracked jobs joined with the job data.
- GET /me/tracking/viewed Slugs of jobs you have viewed.
- GET /me/tracking/analyses Jobs you have run the AI fit analysis on.
- GET /me/credits Your current AI-credits balance.
- GET /me/tracking/saved Slugs of jobs you have saved.
- GET /me/tracking/pipeline Your application-pipeline snapshot (counts per stage bucket).
- GET /me/tracking/swipe A batch of open jobs for the swipe triage deck.
Job submissions
Job reports
Profile & résumé
- GET /me/profile Your career profile, or null if you have not saved one.
- PUT /me/profile Create or replace your profile.
- DELETE /me/profile Clear your profile (idempotent).
- GET /me/profile/verdict Market-coverage verdict for your profile skills.
- GET /me/profile/ats-report CV ATS-readiness report (deterministic + any cached LLM review).
- POST /me/profile/ats-report Run the optional LLM qualitative ATS review and cache it.
- POST /me/resume/extract Extract a structured profile from an uploaded résumé (no LLM).
- PUT /me/resume Store or replace your résumé.
- GET /me/resume Your résumé status (enabled / present / uploaded_at).
- DELETE /me/resume Delete your stored résumé.
Activity & shared boards
Saved searches & subscriptions
- GET /me/searches List your saved searches.
- POST /me/searches Save a search.
- PATCH /me/searches/{id} Rename or re-query a saved search.
- DELETE /me/searches/{id} Delete a saved search.
- GET /me/subscriptions List your subscriptions.
- POST /me/subscriptions Subscribe a saved search to a digest channel.
- PATCH /me/subscriptions/{id} Pause or resume a subscription.
- DELETE /me/subscriptions/{id} Delete a subscription.
- GET /me/telegram Your Telegram link status (for digests).
- POST /me/telegram/link Start linking your Telegram account.
- DELETE /me/telegram Unlink your Telegram account.