Every endpoint that spends enrichment credits checks your balance before doing
any work. When that check fails, the API answers with a dedicated status code
and a machine-readable code, so your integration can tell “top up and retry”
apart from “this request will never succeed as-is”.
402 Payment Required — out of credits
The request was valid, but your workspace does not have enough enrichment
credits to pay for it. No credits are spent, and nothing is enqueued or
imported.
402 is retryable: top up (or wait for your plan to renew) and send the same
request again.
You can also receive 402 after the pre-flight check passes, if a concurrent
request drains the balance before this one is charged. Treat it the same way.
403 Forbidden — workspace weekly limit reached
Your workspace has a weekly enrichment credit limit and this request would
exceed it. The balance itself is irrelevant here, so no top_up_url is
returned — buying credits does not lift the limit.
To unblock, a workspace admin has to raise the member’s weekly allowance, or
you wait for the limit to reset.
403 is also returned when an API key does not have access to an endpoint.
Branch on code, not on the status alone: workspace_limit_exceeded is a
spending limit, anything else is a permission problem.
When both conditions apply — the balance is too low and the weekly limit is
reached — the API reports the balance first, with 402.
Endpoints that return these codes
Preview endpoints are free and never return either code.
Every one of them checks credits up-front, so a rejected request never runs a
provider, creates an import, or enqueues an enrichment.
Migrating from the previous behaviour
These conditions used to be reported as:
422 Unprocessable Entity — waterfall enrichment (async, bulk, and
synchronous), WhatsApp validation, POST /accounts/company_hiring, and
POST /accounts/company_stack
401 Unauthorized — POST /intents/accounts/hiring and
POST /intents/accounts/stack
Both now answer 402 (or 403 for a workspace weekly limit). If your
integration detects an empty balance by matching on 422/401, or by
string-matching the message, switch to the status code and code field. 422
still covers validation errors and 401 still covers authentication, so the
old checks will silently stop firing.