# Authentication

Get started

Authenticate every request with your API key in a header. One key works for every endpoint and platform.

Send your API key in the `x-api-key` header of every request:

Shell:

```shell
curl -H "x-api-key: $SOCIALTAP_API_KEY" "https://staging-fly.socialtap.dev/v1/tiktok/profile?..."
```

`authorization: Bearer <key>` works too (what most HTTP and MCP clients send); when both are sent, `x-api-key` wins.

> [!WARNING]
>
> The key is a secret. Call SocialTap from your server or backend jobs, never from code that ships to browsers or apps, and rotate the key if it leaks.

## Keys, scopes and modes

Get a key on the [signup page](https://staging-fly.socialtap.dev/signup/); AI agents can sign up through the API (see [account and API keys](https://staging-fly.socialtap.dev/docs/account/index.md)). Keys starting with `st_live_` are live: real requests, billed. Keys starting with `st_test_` are test keys: every endpoint answers from recorded responses, free (see [test mode](https://staging-fly.socialtap.dev/docs/test-mode/index.md)). Each key has scopes (what it may call) and can have a spend limit, an expiry and an IP allowlist; a key that may not make a request gets [`forbidden`](https://staging-fly.socialtap.dev/docs/errors/index.md#forbidden) (HTTP 403) with the reason. Manage keys in the [dashboard](https://staging-fly.socialtap.dev/dashboard/) or with the API keys routes.

## Request headers

| Header | Type | Description |
| --- | --- | --- |
| `x-api-key` | `string` | Your API key. |
| `authorization` | `string` | Bearer \<your API key>: the same key as x-api-key, in the form most HTTP and MCP clients send (x-api-key wins when both are sent). |
| `x-client-request-id` | `string` | Your own ID for the request (1–128 printable ASCII characters): echoed back and logged with ours, so support can find a request whose response never reached you. |
| `traceparent` | `string` | W3C Trace Context of your trace: recorded with the request (its trace ID) so a trace can be matched to ours; SocialTap starts its own trace. |
| `idempotency-key` | `string` | On any POST: your unique key for the request (1–255 printable ASCII characters; a UUID is ideal), kept 24 hours. Retrying with the same key and body never repeats the work: the answer is the first request's result, in its current state. |
| `prefer` | `string` | RFC 7240. respond-async on any endpoint request runs it as a one-request job: the answer is 202 with the job (Location: its URL) instead of the result. |
| `cache-control` | `string` | max-age=N accepts a cached response up to N seconds old, like the max_age parameter (max_age wins when both are sent). Other directives are ignored. |

## Response headers

| Header | Type | Description |
| --- | --- | --- |
| `x-request-id` | `string` | Unique request ID; include it when contacting support. |
| `x-credits-charged` | `int` | Credits charged for this request (0 for errors and cache hits). |
| `x-credits-remaining` | `int` | Account balance after this request; for a busy account an estimate that may not yet subtract concurrent requests (about a second of usage), never below the real balance. |
| `retry-after` | `int` | Seconds to wait before retrying; sent only with the codes whose retry_after is set in the error codes list (never on credit errors). |
| `allow` | `string` | Methods the endpoint accepts (method_not_allowed only). |
| `age` | `int` | Seconds since the data was fetched (cache hits only). |
| `x-client-request-id` | `string` | Your x-client-request-id, echoed (also meta.client_request_id). |
| `ratelimit-policy` | `string` | The account's runaway-protection ceiling as an IETF RateLimit-Policy field, as enforced: a token bucket of q requests (twice the ceiling in requests per second, at least 10) that refills in w seconds: "account";q=\<requests>;w=\<seconds>. Not a plan limit. |
| `ratelimit` | `string` | What is left of the ceiling (IETF RateLimit field): "account";r=\<requests that may be sent at once now>;t=\<seconds until the bucket is full again>. |
| `deprecation` | `string` | RFC 9745: the endpoint is deprecated, as of this date (@\<unix seconds>; may be in the future). Also in meta.warnings. |
| `sunset` | `string` | RFC 8594: when a deprecated endpoint stops answering (HTTP-date); from then on it answers endpoint_retired. |
| `link` | `string` | RFC 8288 links: rel="next" is the next page of a list (while page.has_more), the same request with cursor set; rel="deprecation" is a deprecated endpoint's notice. |
| `location` | `string` | On 202 answers: the job's URL (GET it, free, for its status). |
| `preference-applied` | `string` | RFC 7240: respond-async when Prefer: respond-async turned the request into a job (202). |
| `idempotent-replayed` | `bool` | true when the answer replays an earlier request with the same Idempotency-Key (it shows the resource's current state). |

`x-credits-charged` and `x-credits-remaining` are on every response to an authenticated request, successful or not: errors show a charge of 0 and your unchanged balance. A request rejected for its key has neither, because there is no account to report on.

## Missing or invalid keys

A request without a key, or with an unknown or revoked one, fails with [`unauthorized`](https://staging-fly.socialtap.dev/docs/errors/index.md#unauthorized) (HTTP 401), carries no credit headers and costs nothing.

## Rate limits

Plans do not limit request rate: you pay for credits (see [Pricing](https://staging-fly.socialtap.dev/pricing/index.md)), and you can send requests as fast and as many in parallel as your balance covers.

Each account has a high safety ceiling on requests per second that only stops runaway clients, such as a retry loop without backoff. Above it, requests fail with [`rate_limited`](https://staging-fly.socialtap.dev/docs/errors/index.md#rate_limited) (HTTP 429) and cost nothing; wait the number of seconds in the `retry-after` header, then retry. If your sustained traffic needs more, ask [support](https://staging-fly.socialtap.dev/docs/index.md) and the ceiling is raised for your account.

---

[HTML version](https://staging-fly.socialtap.dev/docs/authentication/) · [Docs index for AI agents](https://staging-fly.socialtap.dev/llms.txt) · [All docs in one file](https://staging-fly.socialtap.dev/llms-full.txt)
