# Error reference - Veezee docs

Every Veezee error is one of the 16 codes below. REST returns `application/problem+json`; MCP returns the same content as an error result. `message` is written as the next-turn instruction: read it and act on it instead of retrying blind. `is_retriable: true` means retry is safe; `false` means change something first. Every error's `doc_url` points at its entry on this page.

## INVALID_INPUT

HTTP 400, retriable: no.

A parameter failed validation: a malformed identifier or URL, an invalid section name, a limit above the allowed maximum, or a missing required field. `message` names the fix and `param` names the parameter. Fix that parameter and send the call again; retrying unchanged fails the same way.

## NOT_FOUND

HTTP 404, retriable: no.

Nothing matches what you sent: the LinkedIn entity does not exist, the API route is unknown, or an idempotent replay's stored response has expired. Fix or replace the identifier before calling again; retrying it unchanged will not succeed. For an expired replay, send the call again with a fresh Idempotency-Key.

## UNAUTHORIZED

HTTP 401, retriable: no.

The key or link is not usable: unrecognized key format, no matching active account, a suspended account, or a claim or recovery link that is invalid, expired, or already used. Check the key for truncation, or call `provision` for a fresh trial key. For links, get a fresh one: `get_usage` returns `claim_url`, and `POST /v1/recover` sends a new recovery link.

## PROVISION_REQUIRED

HTTP 401, retriable: no.

The call needs a key and none was sent or on file in this session. Call `provision` first (free, instant, no signup). Then over REST send `Authorization: Bearer <key>` on every call; over MCP, later calls in the same session authenticate automatically.

## INSUFFICIENT_CREDITS

HTTP 402, retriable: no.

The account balance cannot cover this call's quote; `credits_required` says how many credits the call needed. Nothing was charged. Give `upgrade_url` to your human to add credits, then retry the same call with the SAME Idempotency-Key.

This error carries `upgrade_url` (give it to your human) and `offer`: see [errors a payment can fix](https://veezee.io/docs/errors#offer).

## QUOTE_EXCEEDS_MAX_CREDITS

HTTP 402, retriable: no.

The call quotes more credits than the `max_credits` you set. Nothing was charged. Raise `max_credits` to at least the quoted amount, or reduce `sections` or `limit` to shrink the quote.

## IDEMPOTENCY_KEY_REQUIRED

HTTP 400, retriable: no.

A metered call (GET included; metered GETs charge credits) arrived without an `Idempotency-Key` header. Send one: any unique string, a UUID is ideal. Reuse the SAME key only when retrying this exact call.

## IDEMPOTENCY_KEY_REUSED

HTTP 409, retriable: no.

This Idempotency-Key was already used with different arguments. Generate a fresh key for a new call; reuse a key only to retry the identical call.

## CONCURRENCY_LIMIT

HTTP 429, retriable: yes.

Another call on this account is still in flight, or the original call with this Idempotency-Key is still running. Wait for it to finish, then retry; `retry_after_seconds` says how long.

On trial accounts, this error carries `upgrade_url` (give it to your human) and `offer`: see [errors a payment can fix](https://veezee.io/docs/errors#offer).

## RATE_LIMITED

HTTP 429, retriable: yes.

Too many calls per minute for this key's plan. Recovery requests have their own per-minute limit. Slow down and retry after `retry_after_seconds`.

On trial accounts, this error carries `upgrade_url` (give it to your human) and `offer`: see [errors a payment can fix](https://veezee.io/docs/errors#offer).

## TRIAL_CAP_EXCEEDED

HTTP 403, retriable: no.

A trial-only cap was hit: a search `limit` above the trial maximum, or the trial's total realtime fetches used up. Stay inside the cap: ask for fewer results, or use `freshness: "recent"` (cached). Or upgrade the account; after upgrading, retry with a fresh Idempotency-Key.

This error carries `upgrade_url` (give it to your human) and `offer`: see [errors a payment can fix](https://veezee.io/docs/errors#offer).

## BUDGET_EXHAUSTED

HTTP 503, retriable: no.

The free anonymous budget is exhausted or closed right now; cached data still serves. Claim or upgrade the account (`get_usage` returns `claim_url` and `upgrade_url`), or retry later. After payment, retry with a fresh Idempotency-Key.

This error carries `upgrade_url` (give it to your human) and `offer`: see [errors a payment can fix](https://veezee.io/docs/errors#offer).

## UPSTREAM_UNAVAILABLE

HTTP 502, retriable: yes.

LinkedIn data wasn't reachable, or live fetching is temporarily paused; cached data still serves. Retry the request; respect `retry_after_seconds` when present.

## PAYLOAD_TOO_LARGE

HTTP 413, retriable: no.

The request or response exceeded the size limit. Reduce the request size and send it again.

## ORIGIN_FORBIDDEN

HTTP 403, retriable: no.

The request came from a browser origin that is not allowed on this endpoint. Call the API from your agent, server, or CLI, not from in-browser JavaScript.

## INTERNAL

HTTP 500, retriable: yes.

Something failed on our side. Retry once; if it persists, report the receipt id to hello@veezee.io.

## Errors a payment can fix

Errors a payment can fix add fields to this shape. INSUFFICIENT_CREDITS, TRIAL_CAP_EXCEEDED, and BUDGET_EXHAUSTED carry `upgrade_url` (give it to your human) and `offer`, its machine-readable twin; RATE_LIMITED and CONCURRENCY_LIMIT carry both on trial accounts only, where a paid plan raises the limit. `offer` holds `offer_version` (1), `reason` (the error code), `currency` ("usd"), `packs` (pack, mode, price_usd_cents, and credits or credits_per_month), `rails` (currently `stripe_checkout`), `checkout_url` (the same account-bound link as `upgrade_url`), `resume`, and `refund_policy`. Follow `offer.resume` after payment: INSUFFICIENT_CREDITS retries the same call with the SAME Idempotency-Key; TRIAL_CAP_EXCEEDED and BUDGET_EXHAUSTED retry with a fresh key; the two limit codes clear on their own with back-off, payment only raises the limit. INSUFFICIENT_CREDITS also sets `credits_required`: the credits the failed call needed. The failed attempt charged nothing.
