- API reference
- Endpoints
API reference
Ten read-only endpoints over the job index, and the conventions that apply to all of them.
The API is read-only. Every endpoint is a GET against
https://api.hyperjobs.io, returns JSON, and takes its input entirely from the
query string. There are no webhooks, no writes, and no batch endpoint.
Endpoints#
| Endpoint | Returns | |
|---|---|---|
/v1/jobs | GET | Search the index with filters, paging, and collapsing. |
/v1/jobs/count | GET | Count matches for any /v1/jobs filter set, without fetching. |
/v1/jobs/feed | GET | Newly indexed postings, ascending — for syncing. |
/v1/jobs/expired | GET | Ids that expired since a cutoff — the purge feed. |
/v1/jobs/modified | GET | Jobs whose tracked fields changed — the update feed. |
/v1/jobs/{id} | GET | One job by id. |
/v1/companies | GET | Search companies. |
/v1/companies/{slug} | GET | One company by slug. |
/v1/meta | GET | Live dataset counts, source vocabulary, per-field coverage. |
/v1/health | GET | Liveness. No key needed. |
/openapi.json | GET | The generated OpenAPI 3.1 spec, served live. No key needed. |
Authentication#
Send your key as a bearer token:
curl -H "Authorization: Bearer $HYPERJOBS_KEY" https://api.hyperjobs.io/v1/metaThe Bearer prefix is optional — a bare key in the header works. The key can
also go in the query string as ?api_key=. If both are present, the header
wins.
/v1/health and
/openapi.json are the exceptions:
no key, and no rate limiting. Everything else returns
401 without a valid key. See
authentication.
Validation is strict
Every parameter is validated on every endpoint. An unknown parameter, a bad
or empty value, or a malformed cursor is a 400 that names the parameter
and says what's allowed — ?limit=abc, ?seniority=senior, and
?time_frame=1week are all rejected, not silently coerced or dropped.
The upside: bad input can no longer masquerade as an empty result set. If
you got a 200, every filter you sent was applied.
Errors has the shapes.
Status codes#
| Status | Meaning | Retry? |
|---|---|---|
200 | Success. | — |
400 | Unknown parameter, bad value, or malformed search syntax. | No — fix the request |
401 | Missing, unknown, or revoked key. | No — fix the key |
404 | Unknown job id, company slug, or endpoint path. | No |
405 | Non-GET method — the API is read-only. | No |
429 | Per-minute rate limit exceeded (retry after Retry-After) or monthly quota exhausted (no retry until reset). | Depends — check for Retry-After |
500 | Unhandled server error. | Yes, with backoff |
That's the complete list. Full shapes in errors.
Response headers#
Every response carries these headers worth knowing about:
| Header | Value |
|---|---|
Content-Type | application/json; charset=utf-8 |
X-Content-Type-Options | nosniff |
Access-Control-Allow-Origin | * |
X-RateLimit-Limit | Your per-minute limit (authenticated responses). |
X-RateLimit-Remaining | Requests left in the sliding 60s window. |
X-RateLimit-Reset | Seconds until the window frees up. |
A per-minute 429 adds a standard Retry-After header (seconds); the
monthly-quota 429 doesn't. See
rate limits.
There is no Cache-Control and no ETag — conditional requests aren't
supported. CORS preflight (OPTIONS) is handled, so the Authorization
header works from browsers; whether a browser should hold your key at all is
another matter — see
authentication.
Conventions#
- Versioning.
/v1is the only version. There's no version header and no dated pinning; additive changes ship in place and are noted in the changelog. - Trailing slashes are stripped —
/v1/jobs/and/v1/jobsare the same route. - Sorting isn't configurable. See pagination.
- Unknown paths return
404with{"error": "unknown endpoint", "see": "…"}.
Reference pages#
The flagship endpoint. Every filter, with exact semantics.
Count jobsThe same filters as the search, returning just the number.
Get the feedNewly indexed postings, ascending. Excludes expired and duplicates.
Expired jobsThe purge feed — ids to delete from your mirror.
Modified jobsJobs whose tracked fields changed, with what changed.
Retrieve a jobOne job by id, returned bare rather than wrapped.
List companiesSearch the company dataset.
Retrieve a companyOne company by slug.
Dataset metadataLive counts and the exact ?source= vocabulary.