JobFront Docs

Authentication & tokens

How JobFront API tokens work — the Bearer header, organization scope, zero-downtime rotation, safe storage, what a token can reach, and 401 vs 403.

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 Bearer scheme is matched case-insensitively.
  • A bare token with no Bearer prefix 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.

Token → org
1:1
a token resolves to exactly one organization
Org → tokens
many
multiple active tokens are supported
Quota
per org
shared across every token
Plan
per org
rate tier + field tier + billing mode

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.

1 · Create a new token in Settings → API — copy it now, this is the only time you see it
2 · Deploy it — update your secret store or config
3 · Verify — call GET /v4/me with the new token
4 · Revoke the old token once traffic has moved

If 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.

Authenticate — the token exists and has not been revoked or expired, or 401
Identify — resolve the token to its organization
Rate limit — look up the organization's tier, check both windows, emit X-RateLimit-*
Scope — subtract the organization's blocked sources and hidden jobs

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.fields names the offending query params, error.details.tier your tier, and error.details.available_filters what 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/me reports 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.