Send the token as a Bearer credential
Put the token in the Authorization header on every request.
curl https://api.jobfront.com/v4/jobs \
-H "Authorization: Bearer YOUR_API_TOKEN"
- The
Bearerscheme is matched case-insensitively. - A bare token with no
Bearerprefix is also accepted, but send the scheme. - All traffic must be over HTTPS. Never put a token in a URL or a query string — it ends up in logs, proxies and browser history.
Tokens are issued as the letter T followed by 32 hex characters. They do not expire
on their own: a token stays valid until you revoke it in the dashboard.
One organization, one plan, one quota
SCOPE MODEL
A token maps to your organization. Every request is automatically limited to your organization's data, so you never pass an organization id — there is no tenant parameter to get wrong.
All of an organization's tokens share one plan and one rate-limit quota. Creating more tokens does not raise your limits, and a plan change applies instantly to every token the organization holds.
Because quota is per organization, the reason to mint several tokens is blast radius, not throughput: one token per integration means you can revoke a leaked or retired credential without disturbing anything else.
See Rate limits & billing for the tier numbers and the two enforcement windows.
Manage tokens in the dashboard
Create, list and revoke tokens in the JobFront dashboard under Settings → API. There is no API for minting tokens — token lifecycle is a dashboard action.
| Action | What it does |
|---|---|
| Create | Issues a new token for your organization. Copy it once and store it in your secret manager. |
| List | Shows your organization's active tokens, each with when it was created and when it was last used. |
| Revoke | Invalidates the token immediately. Requests using it start returning 401 right away. |
Revoke a token the moment it is no longer needed or may have been exposed. There is no automatic rotation and no TTL — rotation is something you do deliberately, as below.
Tip
The last-used timestamp is the quickest way to find tokens nobody is using any more. A token that has not been used in months is a credential you can retire.
Rotate a token with zero downtime
Because the plan lives on the organization, a new token inherits the same plan and quota the instant it exists. Both tokens work until you revoke the old one, so there is no cutover window.
GET /v4/me with the new tokenStep 3 is the one people skip. A 200 from /v4/me with the new token proves three
things at once: the token is valid, it resolves to the organization you expect, and it
carries the rate limits you expect.
curl https://api.jobfront.com/v4/me \
-H "Authorization: Bearer NEW_API_TOKEN"
Before step 4, check that the old token's last-used timestamp has stopped advancing —
that is your signal that every caller has picked up the new credential. Revocation
takes effect immediately, so revoking early means a hard 401 for anything still
holding the old token.
Store tokens safely
A token is a secret with the same weight as a password. It grants full read access to everything your organization is entitled to.
Do
Keep tokens in a secret manager or your platform's env-var store. Inject them at runtime. Use one token per integration. Rotate on a schedule you choose, and immediately on any suspicion of exposure.
Don't
Never ship a token in client-side code — a browser bundle, a mobile app, a public notebook. Never commit one to a repository. Never put one in a URL, a log line, a screenshot or a support ticket.
Anything running in a user's browser should call your backend, and your backend should call JobFront. There is no browser-safe, read-only variant of a JobFront token.
Warning
If a token is exposed, revoke it first and investigate second. Revocation is instantaneous and — because your other tokens are unaffected — cheap.
The Try-it console
The API reference console executes real requests from your own browser. The
token you paste stays in your browser and goes straight to https://api.jobfront.com;
it is not sent to the docs site. Even so, prefer a token you are willing to revoke —
treat any credential you paste into a browser as one with a short life.
What a token can reach
Every token reads the whole JobFront dataset — every company, every posting. There
is no data-access tier to buy and nothing to widen. /v4/jobs with no filters searches
the entire corpus, newest first.
Two things narrow a jobs read, and only two:
| What it does | |
|---|---|
An explicit collections parameter |
Restricts the search to the sources in those collections. You asked for it on the request. |
| Your blocked sources and hidden jobs | Excluded from every jobs read your organization makes — search, ?count=true, cursor pages, single-job fetches by id, the per-source feeds, the /v4/jobs/options facets and the MCP tools. See Data controls. |
Your field tier is a different axis: it decides which keys survive on a record, not which records you can reach. Conventions has the exact rules.
data_access is gone
Tokens used to carry an access mode of organization or global, reported on
GET /v4/me. Both the mode and the response key have been removed — every token
now reads the same index, so there were no longer two different things to
separate. Code branching on data_access should treat its absence as full
access.
How a token resolves to a plan at request time
Every request runs the same four steps. Knowing them makes the error codes obvious.
401X-RateLimit-*The plan lookup is cached for roughly a minute, which is why an upgrade or downgrade shows up within about a minute rather than instantly. Rate-limit windows are keyed to the organization, not to the token — the reason extra tokens buy you nothing.
To see what a token resolves to, call GET /v4/me:
{
"organization_id": "O_abc",
"rate_limit": 600,
"period_seconds": 60,
"remaining": 593,
"rate_limit_5h": 50000,
"period_seconds_5h": 18000,
"remaining_5h": 49821,
"billing_mode": "subscription",
"fields": { "tier": "default", "jobs": ["..."], "sources": ["..."],
"filters": ["..."], "facets": ["..."] }
}
The rate_limit* fields are the two windows described in
Rate limits & billing; billing_mode is
credits on a metered plan or subscription on an unmetered one; fields is your data tier
(min / default / max) and the exact field, filter and facet lists it includes — see
Account types.
Account types reads this response field by field and explains what each
value means.
401 vs 403
These two mean very different things, and they need different responses from your client.
Both arrive in the standard error envelope;
what separates them is error.code.
401 — the credential is the problem. Missing, malformed, invalid, expired or
revoked token. One code, unauthorized:
{
"error": {
"code": "unauthorized",
"message": "Invalid or missing API key.",
"status": 401,
"request_id": "req_9f1ab99688b14ef2bc7ea16daee2bf1e"
}
}
Do not retry with the same credential — it will fail identically. Re-read the token from your secret store (a stale deploy is the usual cause), and if it really has been revoked, issue a new one in the dashboard.
403 — the credential is fine, the access is not. The token authenticated, but
it is not entitled to what was asked for. Three codes produce it:
organization_api_disabled— your organization's API access is switched off. This is an account-level kill-switch, not a token problem, so minting a new token will not help. Talk to your JobFront representative.organization_not_linked— the token is valid but resolves to no organization, so it authenticates and entitles nothing. Also an account-configuration issue.field_not_in_plan— you used a filter your data tier does not include.error.details.fieldsnames the offending query params,error.details.tieryour tier, anderror.details.available_filterswhat you may use. This is the one a working client actually hits: drop the filter or upgrade the plan. Restricted filters are rejected rather than silently dropped — an ignored filter would return records that do not match your request, and on a metered plan you would be charged for them. Which filter needs which tier is on Search & filters;GET /v4/mereports your own lists, so a client can avoid the error entirely.
Note
Retrying is pointless in all four cases. field_not_in_plan is the only 403 a
correctly-configured account sees; the other two mean the account itself needs
attention, not the client.
The full status-code reference, including 400, 402, 404, 405, 413, 429,
500 and 503, is on Errors.
Info
"Not found" is not an error here. Single-object endpoints return 200 {} and list
endpoints return 200 with an empty data array — including when the object exists
but sits outside your scope.
The same token everywhere
- MCP. The remote MCP server authenticates with the same API tokens and draws on the same rate quota and usage counters.
If you have a token and have not made a call yet, Get started is the five-minute path; the API reference has endpoint-level detail.