Skip to main content

Error Response Format

Every Fetchin API error returns the same JSON shape: a human-readable error string and a stable, machine-readable code. Branch your integration on code (and the HTTP status) — never on the error text, which may change.
Some errors include an optional details object (or, for the multi-profile endpoint, top-level fields such as creditsNeeded) with extra context.
Authentication errors (401, 403) additionally include legacy message and statusCode fields for backward compatibility. New integrations should rely on error and code.

Error Code Reference

HTTP Status Codes

400 Bad Request

The request itself is malformed — a missing parameter (MISSING_PARAMETER), an invalid value (INVALID_PARAMETER), or an unparseable professional URL/URN (INVALID_URN).
Solution: Fix the request. Retrying without changes will fail again.

401 Unauthorized

The X-API-Key header is missing (UNAUTHENTICATED) or invalid (INVALID_API_KEY).
Solution: Include a valid API key from your dashboard.
A sudden INVALID_API_KEY on a previously working integration usually means the key was revoked from the dashboard. A revoked key never comes back — create a new one, deploy it, and check the Last used column before revoking anything else. See Rotating your API key.

404 Not Found

We reached the service successfully, but the requested profile, post, or company genuinely does not exist.
Solution: Don’t retry — verify the URL/URN you sent.
A 404 consumes 1 credit. It is the one failing response that does, and it is the more expensive answer to produce rather than the cheaper one. A success answers on the first attempt; an absence is only concluded once two independent sessions agree, across up to ten attempts. That verification is what stops a login wall being reported to you as a missing record. It is always 1 credit, even on the 2-credit /post/engagement endpoint.Accounts created from 27 August 2026 onwards are charged from their first request. Accounts that existed before then are not charged for 404s until 1 October 2026. Full breakdown at fetchin.io/pricing/credits.

410 Gone

The path you called was a real endpoint and has been retired (code: "ENDPOINT_REMOVED"). It is deliberately not a 404: a 404 would read as “you mistyped the URL”, when in fact the URL was right and the endpoint is gone.
The error text says what replaced it, when something did. A 410 consumes no credits and never will — it does no work. Solution: Don’t retry; the answer will not change. Move to the replacement named in the message, or contact support. Nothing currently listed in this reference returns a 410; you will only meet it on an integration written against a path we no longer publish.

402 Payment Required

You are out of credits (code: "QUOTA_EXHAUSTED"). Usually this means every balance is empty: your plan allowance for the current period is spent, and no pay-as-you-go credits are left. There is no Retry-After — waiting for the next second does not help. A request that costs more than 1 credit is checked against its full price before it runs, so it also gets a 402 when what is left is positive but below that price. With 1 credit left, for example, /post/engagement and /profile with fullProfile=true are refused while a 1-credit request still goes through.
Solution: Buy pay-as-you-go credits (self-serve at fetchin.io/credits — usable within seconds, no code change), upgrade your plan, or wait for your renewal date. Do not retry blindly.
The error text is unchanged and stays byte-for-byte what it has always been — it says nothing about which balance ran out. That breakdown is in details, which is additive: read it for diagnostics, but branch on code and never require a details field to be present. For live figures at any time, call GET /api/v1/subscription, which keeps answering while you are blocked.

429 Too Many Requests

You exceeded your per-second request rate (code: "RATE_LIMITED"). A Retry-After header tells you how long to wait.
The same status and code also cover a concurrency cap, where one endpoint limits how many of your requests may run at the same moment rather than how fast you start them. Today that is POST /api/v1/posts/search, whose allowance follows your plan’s rate limit and is set so that sending that rate does not reach it. The error text says which one you hit:
Solution: Back off and retry, honoring Retry-After. If the text points at requests in flight, lower your concurrency rather than your rate — see Concurrency limits.

503 Service Unavailable

Our API is temporarily unable to serve your request — we’re at capacity or overloaded. This is on our side. It is not your request’s fault and not an upstream service outage.
Solution: Retry with exponential backoff, honoring the Retry-After header. The same request will typically succeed shortly after.

500 Internal Server Error

An unexpected bug occurred in our API.
Solution: Retry with backoff. If it persists, contact support.

502 / 504 Upstream Errors

UPSTREAM_ERROR (502) and UPSTREAM_TIMEOUT (504) indicate a genuine failure or timeout on the upstream service’s side (as opposed to our capacity, which is 503). Retry with backoff.

Error Handling Examples

JavaScript/TypeScript

Python

Best Practices

The error string is for humans and may change. The code is a stable contract — switch on it to decide how to react.
503, 500, 429, 502, and 504 are transient and safe to retry with exponential backoff. A 400/401/404/410 will keep failing until you change the request.
429 and 503 responses include a Retry-After header (seconds). Wait at least that long before retrying.
They now have different HTTP statuses: QUOTA_EXHAUSTED is 402 (you need more credits — buy pay as you go, upgrade, or wait for renewal), RATE_LIMITED is 429 (slow down and honor Retry-After). The code field carries the same distinction. They require different handling: more credits will never clear a 429, and backing off will never clear a 402.
503 SERVICE_UNAVAILABLE means we couldn’t serve you right now — it does not mean the profile/post is empty or gone. Retry shortly.

Quota & Credits

Failing requests do not consume credits, with one exception: a 404 costs 1 credit, because the lookup ran to completion before it could report the absence. Everything else is free, including 400, 401, 403, 410, 429, 402 itself and every 5xx on our side. What a successful request costs is the endpoint’s own price — one credit on every endpoint documented here except /post/engagement (2 credits) and /profile with fullProfile=true (2 credits, or 1 when its extra page could not be read), unless that endpoint’s reference page states otherwise. Credits come from your monthly plan allowance and from any pay-as-you-go credits you hold; requests spend the plan first, then pay as you go by soonest expiry, and a 402 arrives once both are empty, or once what is left is below the price of the request. See Quotas, Pay as you go and Rate Limits for details, or the full per-endpoint breakdown at fetchin.io/pricing/credits.