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 and shows you its value once. Give it a name while you are there. |
| List | Shows your organization's tokens — masked, as T…9f3c — each with its name, 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.
A token is shown once
The full value appears exactly once: in the dashboard, at the moment you create it. Copy it then. Every view afterwards shows only the last four characters, and the full value cannot be recovered — not by you, and not by JobFront support. A lost token is replaced, not retrieved.
When replacing a lost token, order matters: create the replacement first, then revoke the lost one. Creating a token requires holding at least one (see the limits below), so revoking your only token first would leave you unable to create its replacement. Two exceptions:
- At the five-token limit, creation is refused, so revoke the lost token first — your remaining tokens keep creation available.
- If a token was exposed rather than merely lost, revoke it immediately, whatever else is true. If it was your only token, your JobFront representative can issue a replacement.
Because the list is masked, the name is what tells your tokens apart. Set one when you create a token — "Production ETL", "staging", whatever matches where it runs.
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.
Two limits on creating tokens
CREATION POLICY
- You need a token to make a token. Your organization's first token is issued when your API access is set up — talk to your JobFront representative if you do not have one yet. Creating tokens in the dashboard is for rotating and fanning out from there.
- Five live tokens per organization. Revoking one frees its slot immediately.
Both are enforced server-side and refuse with a 403 naming the reason. Neither affects
tokens you already hold: the limits apply when a token is created, never when one is
used. An organization already holding more than five keeps every one of them working and
is simply blocked from creating another until it is back under the limit.
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 tokenIf you are already at five tokens
Step 1 is refused — the limit is checked before the new token is created, so there is nothing to clean up. Free a slot first by revoking one you no longer use, then rotate as above with no cutover window.
If all five are genuinely in use, rotate one integration at a time: revoke that integration's token, create its replacement, deploy. Only that integration sees a gap, and the other four are untouched.
Step 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.