> **For coding agents and LLMs:** This is one page from the Social Fetch docs (markdown export). The sections below mirror the orientation block in [`/llms.txt`](https://www.socialfetch.dev/llms.txt); use [`/llms.json`](https://www.socialfetch.dev/llms.json) when you need a structured operation inventory. The catalog covers documented operations with on-site reference pages.

## This page

- **On-site (HTML):** [https://www.socialfetch.dev/docs/errors](https://www.socialfetch.dev/docs/errors)
- **Markdown (.mdx) URL:** [https://www.socialfetch.dev/docs/errors.mdx](https://www.socialfetch.dev/docs/errors.mdx)

## API base URL and authentication

- **API origin (from OpenAPI `servers`):** `https://api.socialfetch.dev`
- **Authentication:** send `x-api-key: sfk_...` on `/v1/**` routes unless the operation is explicitly anonymous (check OpenAPI `security`, the [API reference hub](https://www.socialfetch.dev/docs/api.mdx), [`/llms.txt`](https://www.socialfetch.dev/llms.txt), or [`/llms.json`](https://www.socialfetch.dev/llms.json) for each route).
- **OpenAPI JSON:** [https://www.socialfetch.dev/openapi.json](https://www.socialfetch.dev/openapi.json)

## Recommended docs entrypoints (this site)

- [Documentation overview](https://www.socialfetch.dev/docs.mdx) — top-level orientation (markdown).
- [Quickstart](https://www.socialfetch.dev/docs/quickstart.mdx) — authenticate with `x-api-key`, validate auth with `whoami`, and understand the JSON envelope.
- [SDK](https://www.socialfetch.dev/docs/sdk.mdx) — official TypeScript SDK guide, including `SocialFetchClient`, `Result`, and `unwrap()`.
- [SDK reference](https://www.socialfetch.dev/docs/sdk-reference.mdx) — exhaustive SDK method inventory and route mapping for agents, tooling, and power users.
- [Choose the right endpoint](https://www.socialfetch.dev/docs/choose-endpoint.mdx) — task-oriented route selection for smoke tests, profiles, list endpoints, and single-item lookups.
- [Capability matrix](https://www.socialfetch.dev/docs/capability-matrix.mdx) — fast comparison of identifiers, pagination, outcomes, media download, and SDK coverage.
- [`/llms.json`](https://www.socialfetch.dev/llms.json) — structured machine-readable operation inventory with parameter names, pagination, outcomes, credits, and SDK mapping.
- [API reference hub](https://www.socialfetch.dev/docs/api.mdx) — human-friendly index of operations with links into generated pages.
- [Errors](https://www.socialfetch.dev/docs/errors.mdx) — shared error envelope and HTTP status guidance.
- [Credits](https://www.socialfetch.dev/docs/credits.mdx) — metering, `402`, and planning batch jobs.
- Outcome semantics such as `found`, `not_found`, and `private` are documented in [Errors](https://www.socialfetch.dev/docs/errors.mdx) and on operation pages when present in the OpenAPI contract.

## Markdown docs convention

- Every docs page has a markdown twin: append **`.mdx`** to the docs pathname (for example `/docs/quickstart` → `/docs/quickstart.mdx`).
- Agents that send `Accept: text/markdown` on `/docs/**` HTML URLs may receive markdown directly (same URL, `Vary: Accept`).

---
# Errors (https://www.socialfetch.dev/docs/errors)

Success envelope [#success-envelope]

Successful JSON responses are wrapped in a `{ data, meta }` envelope.

* **`data`**: endpoint-specific payload
* **`meta`**: response metadata (including a support-friendly request ID)

Example (200 success):

```json
{
  "data": {
    "lookupStatus": "found",
    "profile": {
      "platform": "tiktok",
      "handle": "charlidamelio",
      "displayName": "charli",
      "bio": "hey",
      "avatarUrl": "https://example.com/avatar-large.jpg",
      "verified": true,
      "profileUrl": "https://www.tiktok.com/@charlidamelio",
      "privateAccount": false
    },
    "metrics": {
      "followers": 150000000,
      "following": 123,
      "likes": 12345678901,
      "posts": 456
    }
  },
  "meta": {
    "requestId": "req_01example",
    "creditsCharged": 1,
    "version": "v1"
  }
}
```

The exact `data` shape varies by endpoint — check the operation’s `200` schema in the **API reference**.

Outcome semantics [#outcome-semantics]

Some endpoints return “domain outcomes” in a **200** response instead of returning a `4xx`. For example, a profile lookup can return `lookupStatus: "not_found"` with HTTP 200:

```json
{
  "data": {
    "lookupStatus": "not_found",
    "profile": null,
    "metrics": null
  },
  "meta": {
    "requestId": "req_01example",
    "creditsCharged": 1,
    "version": "v1"
  }
}
```

Rule of thumb:

* **If HTTP is `200`**: parse the success envelope and check the endpoint’s domain status fields (like `data.lookupStatus`).
* **If HTTP is not `200`**: parse the standard error envelope below.

Common business-level outcomes [#common-business-level-outcomes]

Depending on the endpoint, a successful response may still represent different lookup outcomes:

* **`found`**: the requested entity was resolved and the expected data is present
* **`not_found`**: the requested target does not exist or could not be resolved as an existing entity
* **`private`**: the entity exists but the relevant data is not publicly available

Always confirm the exact response schema on the endpoint page in the [API reference](/docs/api).

Empty result vs not found [#empty-result-vs-not-found]

Do not assume an empty collection always means “not found.”

* a profile can exist while a media list is currently empty
* a target can be valid but private
* a target can truly be missing

Preserve that distinction in your client instead of collapsing all misses into the same case.

Disambiguating list routes [#disambiguating-list-routes]

Some list routes can return HTTP `200` with an empty `data.*` collection for more than one reason, and may not expose `data.lookupStatus`.

If that distinction matters:

1. Call the platform **profile** route for the same handle (`GET /v1/{platform}/profiles/{handle}`).
2. Interpret `data.lookupStatus` (`found`, `private`, `not_found`) from the profile response.
3. Only then call the **list** route if you still need feed items.

If you only need “posts or nothing,” you can skip the profile preflight and accept the ambiguity.

Client logic [#client-logic]

1. check HTTP status
2. if status is `200`, inspect the endpoint-specific outcome fields
3. only enter your HTTP error handling path for non-`200` responses

With the TypeScript SDK, map the same steps to `result.ok` and `result.value.data`.

Credits and outcomes [#credits-and-outcomes]

Some metered endpoints may still charge credits when the lookup attempt completed successfully, even if the business-level result is `not_found` or `private`.

See [Credits](/docs/credits) for the billing side of that behavior.

Error body [#error-body]

Error responses return JSON with a shared `{ error }` envelope:

```json
{
  "error": {
    "code": "unauthorized",
    "message": "Missing API key.",
    "requestId": "req_01example"
  }
}
```

`error.code` [#errorcode]

`error.code` is **machine-readable** and comes from a stable set of values:

* `bad_request`
* `unauthorized`
* `insufficient_credits`
* `lookup_failed`
* `transcript_target_not_video`
* `video_too_long_for_transcription`
* `temporarily_unavailable`
* `internal_error`

Refer to the **API reference** for the exact codes used by each HTTP status on a given route (for example `400`, `401`, `402`, `502`, `503`).

<Callout type="info" title="Correlation">
  Always quote `requestId` when contacting support — it ties your client trace to server logs.
</Callout>

Request ID [#request-id]

You’ll see a request ID in both success and error responses:

* **Success**: `meta.requestId`
* **Error**: `error.requestId`

Include it when contacting support, and consider logging it in your client on failures.

Common cases [#common-cases]

<Callout type="warn" title="Retries">
  Use exponential backoff on &#x2A;*`503`**. Do not blindly retry `4xx` errors without fixing the request.
</Callout>

* **`400`** — invalid request (see `error.code: "bad_request"`) or a known limitation such as `transcript_target_not_video` or `video_too_long_for_transcription`.
* **`401`** — missing or invalid API key (see `error.code: "unauthorized"`).
* **`402`** — insufficient credits (see `error.code: "insufficient_credits"`).
* **`500`** — unexpected error (see `error.code: "internal_error"`).
* **`502`** — lookup could not be completed from the response (see `error.code: "lookup_failed"`).
* **`503`** — service temporarily unavailable; safe to retry with backoff (see `error.code: "temporarily_unavailable"`).

<Cards>
  <Card title="Credits" description="When routes charge and how to handle `402`." href="/docs/credits" icon="<Info className=&#x22;size-5 text-fd-primary&#x22; />" />

  <Card title="API reference" description="Full response schemas per status code." href="/docs/api" icon="<AlertTriangle className=&#x22;size-5 text-fd-primary&#x22; />" />

  <Card title="SDK" description="If you use the TypeScript SDK, the same HTTP and outcome semantics still apply." href="/docs/sdk" icon="<Scale className=&#x22;size-5 text-fd-primary&#x22; />" />
</Cards>