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 treatGET /tokens/costs as the authoritative source — don’t hardcode these values.
| Action | Tokens | What it covers |
|---|---|---|
cv_processing | 1 | Process a single CV |
job_processing | 1 | Process a single job description |
job_matching | 2 | Match candidates against a job |
sourcing_search_fast | 3 | A fast sourcing search |
sourcing_search_pro | 10 | A deeper “pro” sourcing search |
sourcing_ingest | 2 | Import one sourced candidate |
sourcing_reveal_email | 2 | Reveal one candidate’s email |
sourcing_reveal_phone | 2 | Reveal one candidate’s phone |
sourcing_insights | 1 | Per-candidate AI insights on a search |
sourcing_high_freshness | 1 | Per-candidate fresh-profile lookup on a search |
What each endpoint charges
| Endpoint | Charged | Quantity |
|---|---|---|
POST /cvs/analyze | cv_processing | One per CV in inputs |
POST /cvs/analyze/files | cv_processing | One per uploaded file |
POST /jobs/analyze | job_processing | One per job in inputs |
POST /jobs/analyze/files | job_processing | One per uploaded file |
POST /match | job_matching | One per match request |
POST /sourcing/search | sourcing_search_fast / sourcing_search_pro + premiums | Base once, premiums per candidate (see below) |
POST /sourcing/ingest | sourcing_ingest | One 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.Response
Check your balance
Returns the real-time token balance for the workspace the API key belongs to.Response
Review your usage
Returns a paginated ledger of every token movement for your workspace, newest first.| Query parameter | Type | Default | Notes |
|---|---|---|---|
limit | integer | 50 | Maximum entries to return (max 500). |
before | ISO 8601 timestamp | — | Return only entries created before this time. Use the created_at of the last entry you saw to page backward. |
Response
Reading a ledger entry
| Field | Meaning |
|---|---|
action | The billable action, or a balance event such as grant or token_expired. |
amount | Signed token change: negative for a charge, positive for a refund or grant. |
balance_after | Your balance immediately after this entry was applied. |
reference_id | The task, match, or session this entry is tied to — useful for reconciling a charge against the request that caused it. |
created_at | When the entry was recorded (ISO 8601, UTC). |
action values you may see in your history:
action | amount | Meaning |
|---|---|---|
cv_processing, job_processing, job_matching, sourcing_* | negative | A charge for that operation. |
| any of the above | positive | A refund of a previous charge (for example, a failed task). The reference_id matches the original charge. |
grant | positive | Tokens added to your workspace (a purchase or a trial grant). |
token_expired | negative | Trial 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:
- A base fee, once —
sourcing_search_fast(default) orsourcing_search_prowhen you setoptions.search_type: "pro". - Per-candidate premiums for any options you enable, charged once per candidate actually returned:
insights→sourcing_insightshigh_freshness→sourcing_high_freshness
- Per-reveal fees for contact data, charged once per candidate whose data is actually returned:
reveal_emails→sourcing_reveal_emailreveal_phones→sourcing_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.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 positiveamounton 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 with402 Payment Required and a structured body. No work is performed and nothing is charged.
| Field | Meaning |
|---|---|
code | Always INSUFFICIENT_TOKENS — switch on this rather than parsing message. |
balance | Your current balance. |
required | Tokens needed for this request (worst case, for sourcing searches). |
Detect
Treat any
402 with code: "INSUFFICIENT_TOKENS" as a billing condition, not a transient error — retrying without adding tokens will fail again.Top up
Add tokens in the Fribl Console. You can confirm the new balance with
GET /tokens/balance.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 atoken_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.