Skip to main content

Tokens & Billing

The Fribl API is metered with tokens. Every billable operation — analyzing a CV, parsing a job, running a match, or sourcing candidates — deducts tokens from your workspace balance. Read-only operations (listing, retrieving, polling status, and the Skills endpoints) are free.

Check balance

GET /tokens/balance — real-time balance for your workspace.

Review usage

GET /tokens/history — a paginated ledger of every charge, refund, and grant.

See pricing

GET /tokens/costs — the live price list for every billable action.

How tokens work

  • Balance is per-workspace. Every API key belongs to a workspace, and all keys in that workspace draw from one shared balance.
  • You’re charged per unit of work. Submitting 5 CVs in one request charges 5 × the CV price. Each unit gets its own ledger entry.
  • You’re not charged for failures. If a task ends in FAILED, or the API returns a server error (5xx), the tokens for that unit are refunded automatically.
  • Retries are safe. Charges are idempotent per task, so re-sending a request that already succeeded never double-charges.
  • The ledger is the source of truth. Every movement — charge, refund, grant, or expiry — is recorded as an immutable entry you can read back via the history endpoint.
Tokens are purchased and managed in the Fribl Console, where you also create API keys and administer your organization. The API itself is read-only with respect to your balance — it reports usage and pricing, but tokens are added in the Console.

Pricing

Each billable endpoint maps to one or more actions, and each action has a price in tokens. The table below shows the standard pricing. Prices can change, so always treat GET /tokens/costs as the authoritative source — don’t hardcode these values.
ActionTokensWhat it covers
cv_processing1Process a single CV
job_processing1Process a single job description
job_matching2Match candidates against a job
sourcing_search_fast3A fast sourcing search
sourcing_search_pro10A deeper “pro” sourcing search
sourcing_ingest2Import one sourced candidate
sourcing_reveal_email2Reveal one candidate’s email
sourcing_reveal_phone2Reveal one candidate’s phone
sourcing_insights1Per-candidate AI insights on a search
sourcing_high_freshness1Per-candidate fresh-profile lookup on a search

What each endpoint charges

EndpointChargedQuantity
POST /cvs/analyzecv_processingOne per CV in inputs
POST /cvs/analyze/filescv_processingOne per uploaded file
POST /jobs/analyzejob_processingOne per job in inputs
POST /jobs/analyze/filesjob_processingOne per uploaded file
POST /matchjob_matchingOne per match request
POST /sourcing/searchsourcing_search_fast / sourcing_search_pro + premiumsBase once, premiums per candidate (see below)
POST /sourcing/ingestsourcing_ingestOne per candidate in selected_ids

Live pricing

Fetch the current price list at any time. This is the canonical pricing source — build your cost estimates against it rather than the static table above.
curl https://api-service.fribl.co/api/v1/tokens/costs \
  -H "x-api-key: your-api-key-here"
Response
{
  "data": [
    { "action": "cv_processing",  "cost_in_tokens": 1, "description": "Process a single CV" },
    { "action": "job_processing", "cost_in_tokens": 1, "description": "Process a job description" },
    { "action": "job_matching",   "cost_in_tokens": 2, "description": "Match candidates to a vacancy" },
    { "action": "sourcing_search_fast", "cost_in_tokens": 3,  "description": "Fast sourcing search" },
    { "action": "sourcing_search_pro",  "cost_in_tokens": 10, "description": "Pro sourcing search" }
  ]
}

Check your balance

Returns the real-time token balance for the workspace the API key belongs to.
curl https://api-service.fribl.co/api/v1/tokens/balance \
  -H "x-api-key: your-api-key-here"
Response
{
  "data": {
    "workspace_id": "ws_a1b2c3d4",
    "balance": 149
  }
}
Call GET /tokens/balance before a large batch (for example, uploading 100 CVs) to confirm you can cover it. A batch that runs out of tokens partway through is rolled back in full — see Insufficient tokens.

Review your usage

Returns a paginated ledger of every token movement for your workspace, newest first.
Query parameterTypeDefaultNotes
limitinteger50Maximum entries to return (max 500).
beforeISO 8601 timestampReturn only entries created before this time. Use the created_at of the last entry you saw to page backward.
curl "https://api-service.fribl.co/api/v1/tokens/history?limit=20" \
  -H "x-api-key: your-api-key-here"
Response
{
  "data": [
    {
      "id": "10473",
      "workspace_id": "ws_a1b2c3d4",
      "action": "job_matching",
      "amount": -2,
      "balance_after": "149",
      "reference_id": "match_9f8e7d6c",
      "created_at": "2026-06-03T10:18:02.114Z"
    },
    {
      "id": "10472",
      "workspace_id": "ws_a1b2c3d4",
      "action": "cv_processing",
      "amount": -1,
      "balance_after": "151",
      "reference_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "created_at": "2026-06-03T10:15:30.000Z"
    }
  ]
}

Reading a ledger entry

FieldMeaning
actionThe billable action, or a balance event such as grant or token_expired.
amountSigned token change: negative for a charge, positive for a refund or grant.
balance_afterYour balance immediately after this entry was applied.
reference_idThe task, match, or session this entry is tied to — useful for reconciling a charge against the request that caused it.
created_atWhen the entry was recorded (ISO 8601, UTC).
The action values you may see in your history:
actionamountMeaning
cv_processing, job_processing, job_matching, sourcing_*negativeA charge for that operation.
any of the abovepositiveA refund of a previous charge (for example, a failed task). The reference_id matches the original charge.
grantpositiveTokens added to your workspace (a purchase or a trial grant).
token_expirednegativeTrial or promotional tokens that reached their expiry date.

Sourcing pricing in detail

Sourcing is the only endpoint with variable, per-candidate pricing. POST /sourcing/search charges:
  1. A base fee, oncesourcing_search_fast (default) or sourcing_search_pro when you set options.search_type: "pro".
  2. Per-candidate premiums for any options you enable, charged once per candidate actually returned:
    • insightssourcing_insights
    • high_freshnesssourcing_high_freshness
  3. Per-reveal fees for contact data, charged once per candidate whose data is actually returned:
    • reveal_emailssourcing_reveal_email
    • reveal_phonessourcing_reveal_phone
Before running the search, the API checks that your balance can cover the worst case (every candidate matching every enabled premium). If it can’t, the request is rejected up front with a 402 and nothing is charged — you never get a half-charged search.
Pagination is free. Each search returns a session_id. Re-requesting a window that’s already cached for that session costs 0 tokens (the response includes "cached": true). You’re only charged again when the search reaches new candidates.
POST /sourcing/ingest charges sourcing_ingest once per candidate in selected_ids. Each candidate is charged independently, so a single failed import is refunded on its own without affecting the others.

Refunds and idempotency

You only pay for work that succeeds.
  • Failed tasks are refunded automatically. When a CV, job, or sourcing task ends in FAILED, its charge is reversed. The refund appears in your history as a positive amount on the original action.
  • Server errors are refunded automatically. If the API returns a 5xx, any tokens charged for that request are reversed.
  • Partial batches roll back. If you submit a batch and the balance runs out partway through, everything already charged in that request is refunded and the whole request returns 402 — you’re never left having paid for half a batch.
  • Retries don’t double-charge. Each unit of work is charged against a stable key, so re-sending an identical request returns the original result without charging again.
Client errors (4xx) are not refunded, because no work was attempted — a 400 for a malformed body, for example, is rejected before anything is charged.

Insufficient tokens

When your balance can’t cover a request, the API responds with 402 Payment Required and a structured body. No work is performed and nothing is charged.
{
  "code": "INSUFFICIENT_TOKENS",
  "message": "Insufficient tokens: have 3, need 10",
  "balance": 3,
  "required": 10
}
FieldMeaning
codeAlways INSUFFICIENT_TOKENS — switch on this rather than parsing message.
balanceYour current balance.
requiredTokens needed for this request (worst case, for sourcing searches).
How to handle it:
1

Detect

Treat any 402 with code: "INSUFFICIENT_TOKENS" as a billing condition, not a transient error — retrying without adding tokens will fail again.
2

Top up

Add tokens in the Fribl Console. You can confirm the new balance with GET /tokens/balance.
3

Retry

Re-send the original request. Because charging is idempotent, it’s safe to retry the exact same payload.

Trial tokens

New workspaces may start with a one-time grant of trial tokens so you can evaluate the API before purchasing. Trial grants can carry an expiry date; when they expire, the unused portion is removed and recorded in your history as a token_expired entry. Check GET /tokens/balance to see what you currently have available.

Next steps

Quickstart

Run your first analyze-and-match flow end to end.

Error Handling

See every status code, including 402 for insufficient tokens.