> **For coding agents and LLMs:** This is one page from the Social Fetch docs (markdown export). For curated orientation and workflow guidance, start with [`/llms.txt`](https://www.socialfetch.dev/llms.txt); for agent onboarding and crawl rules, use [`/agents.txt`](https://www.socialfetch.dev/agents.txt); for the full endpoint list with links to pages like this one, use [`/llms-endpoints.txt`](https://www.socialfetch.dev/llms-endpoints.txt); for one platform's parameters and curls, use [`/llms-{platform}.txt`](https://www.socialfetch.dev/llms-tiktok.txt); use [`/llms.json`](https://www.socialfetch.dev/llms.json) when you need structured JSON for tool registration.

## This page

- **On-site (HTML):** <https://www.socialfetch.dev/docs/credits>
- **Markdown (.mdx) URL:** <https://www.socialfetch.dev/docs/credits.mdx>

## API base URL and authentication

- **API origin (from OpenAPI `servers`):** `https://api.socialfetch.dev`
- **Authentication:** send `x-api-key: sfk_...` on `/v1/**` and `/v2/**` 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>

## 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()`.
- [Capability matrix](https://www.socialfetch.dev/docs/capability-matrix.mdx) — every operation with identifiers, pagination, outcomes, media download, credits, and its SDK method. Generated from OpenAPI, so use it for route selection instead of scanning individual pages.
- [Recipes](https://www.socialfetch.dev/docs/recipes.mdx) — copyable workflows (brand monitoring, transcripts, Ad Library, creator scoring, Reddit research) with credit callouts and SDK examples.
- [Integrations](https://www.socialfetch.dev/docs/integrations.mdx) — MCP for AI clients, n8n verified node, Apify Store Actors, Make custom app, SDK, and REST API connection paths.
- [MCP product page](https://www.socialfetch.dev/mcp) — hosted MCP overview, OAuth, Skills install.
- [MCP integration](https://www.socialfetch.dev/docs/integrations/mcp.mdx) — hosted `/mcp` server, OAuth, Cursor/VS Code/Claude install snippets, 274 endpoint tools, plus docs_search/docs_read for implementation help.
- [n8n integration](https://www.socialfetch.dev/docs/integrations/n8n.mdx) — install `n8n-nodes-socialfetch`, credentials, and workflow examples.
- [Apify integration](https://www.socialfetch.dev/docs/integrations/apify.mdx) — Store Actors under @social-fetch, PPE billing, dataset export, and quick start.
- [Make integration](https://www.socialfetch.dev/docs/integrations/make.mdx) — custom app modules for Make scenarios, API key credentials, and module catalog.
- [`/llms-endpoints.txt`](https://www.socialfetch.dev/llms-endpoints.txt) — every documented operation with a direct link to that route's agent-readable markdown page (prefer this over parsing OpenAPI).
- [`/llms-{platform}.txt`](https://www.socialfetch.dev/llms-tiktok.txt) — per-platform endpoint files generated from OpenAPI (parameters, credits, curls).
- [`/agents.txt`](https://www.socialfetch.dev/agents.txt) — agent crawl/onboarding file with capabilities, auth rules, and allowlist.
- [`/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`).
- Published blog posts use the same convention: `/blog/{slug}` → `/blog/{slug}.mdx`, or `Accept: text/markdown` on the HTML URL (`Vary: Accept`).

---
# Credits (https://www.socialfetch.dev/docs/credits)

{/* Figures on this page come from code: grace buffers, refill thresholds and pack sizes from packages/auth/src/billing/catalog.ts, the card bonus from CARD_BONUS_CREDITS in task-rewards-catalog.ts, the workspace limit from DEFAULT_MAX_OWNED_WORKSPACES in packages/auth/src/workspace/entitlements.ts, add-on prices from packages/auth/src/billing/add-ons.ts and the in-flight limit from DEFAULT_MAX_IN_FLIGHT_PER_ACCOUNT in apps/api/src/middleware/account-in-flight-limit.ts. Update them here when those change. */}

Social Fetch charges in credits. Each lookup costs a set number of credits, listed on its page in the [API reference](/docs/api); many cost 1. Each response's `meta.creditsCharged` says what that request cost. The [app's tools](/docs/tools/ad-tracker), such as the Ad Tracker, spend the same credits. When a workspace runs out, metered requests return `402 insufficient_credits`.

You pay as you go by default: buy a credit pack and spend it whenever you like. Pay-as-you-go credits never expire. A plan adds included credits each month on top. Plan names, pack sizes and prices are on the [Pricing](/pricing) page.

## What costs credits

* **A completed lookup is charged**, even when it finds nothing. A private or not-found profile, or a `restricted` post, comes back as a `200` with `data.lookupStatus` saying what happened, and costs the normal price. See [Errors and outcomes](/docs/errors#outcome-semantics).
* **Service failures and requests rejected before a lookup aren't charged.** `502 lookup_failed` and `503 temporarily_unavailable` cost no credits. Neither do validation failures (`400 bad_request`), invalid, revoked or expired keys (`401 unauthorized`), or an insufficient-credit rejection (`402 insufficient_credits`). Some endpoint-specific outcomes, such as a TikTok photo post sent to the transcript endpoint, can still be billed; check that endpoint's API reference.
* **A screenshot of a bot challenge isn't charged.** When a page answers `GET /v1/web/screenshot` with a challenge or block page, the response is `lookupStatus: "restricted"` with no image and `meta.creditsCharged: 0`.
* **A missing key has different responses on paid and free routes.** Without an API key or x402 payment, a paid route returns `402 payment_required`. Include a valid `x-api-key` header to spend workspace credits. Free routes that require a key, such as `GET /v1/balance`, return `401 unauthorized` when the key is missing. These authentication and unpaid-payment rejections don't spend workspace credits.
* **Some endpoints charge for extras.** Options such as Instagram's `include=recentMedia` add credits only when the extra is returned, so `meta.creditsCharged` can be lower than the most a request could cost. Each endpoint's page in the API reference says how it's priced.
* **`GET /v1/whoami` and `GET /v1/balance` are free.** Use them to check a key and read your balance.

## Pay-as-you-go and plans

Without a plan, requests spend your pay-as-you-go balance. When it's empty, metered requests return `402 insufficient_credits`.

With an active plan, requests use credits in this order:

1. The plan's included credits for the current month.
2. Your pay-as-you-go balance: credit packs, free credits and earlier refill packs.
3. Refill packs, bought automatically when your balance drops below your refill threshold (see [Auto top-up and auto-refill](#auto-top-up-and-auto-refill)).

Included credits reset at the start of each monthly period, even on an annual plan. On a monthly plan, unused included credits don't roll over. On an annual plan, they carry into the next month, up to one month's allowance, so you can hold at most two months' worth. Pay-as-you-go credits, including refill packs, are separate and never expire. Cancelling a plan never removes them.

You can buy credit packs while on a plan. They're used after the plan's credits and before any refill.

## Where to see your credits

### Your balance

Your balance shows in the top bar of every page in the app, and on the **Billing** page as **Available balance**. Hover the **i** beside it to see what it's made of: plan credits (used first, and reset each month), pay-as-you-go credits (which never expire) and any grace credits (see [Grace buffer](#grace-buffer-when-a-refill-charge-fails)).

### What one request cost

Every successful response says what it cost in `meta.creditsCharged`. In the [Playground](https://app.socialfetch.dev/playground), the same figure shows beside the status code once you click **Send**.

```json
{
  "data": { "lookupStatus": "found", "profile": { "handle": "charlidamelio" } },
  "meta": {
    "requestId": "req_…",
    "creditsCharged": 1,
    "version": "v1"
  }
}
```

### Every request

**Request history** (linked from **Usage** and **Billing**) lists each metered request with its status and the credits it used. Filter by path, request ID, status code or date, or tick **Errors only**. Click a row to see its parameters and response.

### Spending over time

The [Usage](https://app.socialfetch.dev/usage) page shows requests and credits for the last 7 and 30 days, a daily chart, and your top endpoints with the credits each used. When more than one API key, or more than one teammate, has spent credits, it also breaks spending down by key and by teammate. **Export CSV** downloads it.

## Plan for it in your integration

* Check your balance with `GET /v1/balance` before a large job.
* For `402 insufficient_credits`, read the message: a low workspace balance needs more credits, while an API key's monthly limit needs a workspace owner or admin to raise or remove it, or you must wait for the next calendar month. Buying credits doesn't raise a key's limit.
* Add up `meta.creditsCharged` if you need your own records to match what you were charged.
* Owners and admins can cap what one API key spends in a calendar month: on **API Keys**, click **Limit** on the key's row. A key at its limit gets `402 insufficient_credits` with a message saying so; the workspace balance isn't touched. See [API keys and spending](/docs/teams#api-keys-and-spending).

## Free credits for adding a card

If you haven't bought anything yet, save a card on the **Billing** page (**Add a card, get 250 free credits**) and we add 250 credits. Nothing is charged until you buy. There's one bonus per person and per card, and prepaid cards don't qualify.

## Auto top-up and auto-refill

Auto top-up buys credits for you when your balance runs low, so requests don't stop. It's on the **Billing** page under **Credit top-ups**. It's called **Auto top-up** on pay-as-you-go and **Auto-refill** on a plan.

* **Pay-as-you-go:** auto top-up switches on after your first credit pack purchase. When your balance drops to 100 credits or below, we charge your saved card for the same pack. You can change the pack and the trigger threshold, or switch it off.
* **On a plan:** auto-refill is on by default when you subscribe. Once the plan's credits and your pay-as-you-go balance run low, it buys a refill pack (your plan's refill pack by default, or a credit pack you choose) when your spendable balance drops to 100 credits or below. You can raise the **Trigger threshold**, and set a **Per-period spend cap (optional)**: once refills reach it, they stop and metered requests return `402` until the next period or until you raise the cap.

Refill credits go into your pay-as-you-go balance and never expire. Switch auto top-up off if you'd rather requests stop at zero.

## Grace buffer when a refill charge fails

If an automatic refill charge fails (a declined card or insufficient funds), we add a one-time grace buffer so your app keeps running while you fix the payment. You get it only if auto top-up is on with a saved card and you're a paying customer (you've bought credits or subscribed). Free credits alone don't qualify.

| Account       | Grace buffer   |
| ------------- | -------------- |
| Pay-as-you-go | 500 credits    |
| Starter plan  | 2,000 credits  |
| Growth plan   | 5,000 credits  |
| Scale plan    | 10,000 credits |

You get the buffer once per unpaid episode. When your next charge succeeds (a refill or a credit pack), the grace credits you received are taken back from it and the rest stays in your balance. If the buffer runs out while payment is still failing, requests return `402` and **Billing** shows a banner asking you to update your payment method.

This is separate from your plan's renewal. If the renewal payment fails at the start of a period, that month's included credits aren't added until the invoice is paid. You keep your pay-as-you-go balance. Update your card through **Billing → Manage payment** to restore it.

## Credits belong to a workspace

Credits, plans and payment methods belong to a workspace, and requests made with that workspace's API keys spend its credits. You can own up to 5 shared workspaces as well as your personal one. Credits can't be moved between workspaces yourself; if you bought credits in the wrong one, [contact us](/contact) and we can move them. When a workspace is closed, its remaining credits are lost once its 30-day restoration window ends. See [Teams and workspaces](/docs/teams).

## Add-ons

Add-ons are extras on a paid plan. Most are a flat monthly price per workspace; Extra seats is priced per seat. Annual billing is 10% cheaper than twelve monthly payments.

| Add-on                                                    | Price                 | Sold on                               | Included with                 |
| --------------------------------------------------------- | --------------------- | ------------------------------------- | ----------------------------- |
| [Single sign-on and directory sync](/docs/single-sign-on) | $149 / month          | Scale                                 | Enterprise                    |
| [Custom roles](/docs/teams#custom-roles)                  | $49 / month           | Scale                                 | Enterprise                    |
| Priority support                                          | $19 / month           | Any paid plan that doesn't include it | Growth and above              |
| Shared Slack channel                                      | $49 / month           | Any paid plan that doesn't include it | Scale                         |
| [Extra seats](/docs/teams#seats)                          | $5 per seat per month | Growth and Scale                      | Enterprise sets its own limit |

* You don't need an add-on to build Social Fetch data into your own product and sell it. Every plan allows it under our [Terms](/terms).
* Workspace owners and people with the Billing role can buy add-ons, under **Billing → Add-ons**. An add-on starts straight away.
* An add-on is billed with your plan: same invoice, same renewal date. Adding one mid-period charges a prorated amount for the rest of the period. Removing one gives a prorated credit, and add-ons stop when the plan ends.
* Extra seats are added on top of the seats your plan includes, up to 100 extra. Adding seats is charged now, prorated. Removing seats is credited on your next invoice, and you can't go below the seats in use. See [Teams and workspaces](/docs/teams#seats).
* Remove an add-on before moving to a plan it isn't sold on. Upgrading doesn't affect it.
* Add-ons need a paid plan (Starter or higher), so they aren't available on pay-as-you-go alone.

## Cancelling or changing plans

* **Cancel** from **Billing**. It takes effect at the end of the period: your included credits last until then, and after that you're on pay-as-you-go.
* **Upgrade** takes effect straight away, with a prorated charge and the extra included credits added.
* **Downgrade** takes effect at the end of the period.

Payment methods and invoices are managed in the billing portal, which opens from the **Billing** page.

## Checking your balance from code

[`GET /v1/balance`](/docs/api/v1/balance) is free. Call it before large jobs or on a schedule.

* `data.balance` is the credits you can spend right now, the same number that decides when requests return `402`. During a grace episode, grace credits aren't counted in `balance` until your included and pay-as-you-go credits are used up; after that, `balance` counts down what's left of the grace buffer.
* `data.billingAlert` is `none`, `payment_action_required` or `suspended`. Check it even when `balance` looks healthy: a refill may have failed while the grace buffer still has credits left.

The other fields (`payg`, `paygSpendable`, `graceDebtCredits`, `refillState`) break down the same state; the [Balance API reference](/docs/api/v1/balance) describes each one.

With an SDK `client` already configured (see [TypeScript SDK](/docs/sdk)), check `result.ok` before reading the response. Here `notifyOps` is your own alert function. A failed balance check needs attention too; it doesn't tell you that your balance is zero.

```typescript
const result = await client.billing.getBalance();
const MIN_CREDITS = 1_000;

if (!result.ok) {
  console.error(result.error.code, result.error.message);
  notifyOps(); // investigate the failed balance check
} else {
  const { data } = result.value;
  if (data.billingAlert !== "none" || data.balance < MIN_CREDITS) {
    notifyOps(); // check Billing for low credits or a payment problem
  }
}
```

During a grace episode, after a failed payment, `balance` is what's left of the buffer and `billingAlert` is the warning:

```json
{
  "data": {
    "balance": 1998,
    "billingAlert": "payment_action_required",
    "paygSpendable": 0,
    "refillState": "grace",
    "graceDebtCredits": 2000
  }
}
```

## Throughput and concurrency

Credits are the only limit on paid metered `/v1/*` requests. There's no request quota and no requests-per-second cap; run requests in parallel as your product needs, up to 200 in flight per workspace.

Under heavy load, requests may be queued. Under extreme concurrency, or above the in-flight limit (`reason` `concurrency_limit`), the API returns `503 temporarily_unavailable` with a `Retry-After` header. That means we're busy, not that you hit a rate limit: we don't use `429` for paid metered requests. These `503` responses aren't charged. Wait for `Retry-After` (or back off gradually) and retry.

The free routes (`GET /v1/whoami`, `GET /v1/balance`) have a per-key rate limit and can return `429`. See [Errors](/docs/errors).

- [Pricing](/pricing) — Credit packs and plans, with current prices.

- [Balance endpoint](/docs/api/v1/balance) — GET /v1/balance: read your balance for free.

- [API reference](/docs/api) — What each endpoint costs, on its own page.

- [Errors and outcomes](/docs/errors#outcome-semantics) — Why not-found and private results come back as 200, and still cost credits.