> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.beatapi.io/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.beatapi.io/_mcp/server.

# Social Data API

BeatAPI Social Data is a synchronous, developer-facing API for retrieving public data from supported social platforms. You use a BeatAPI API key and a BeatAPI-owned action ID; accounts, routing, and raw response details stay behind the API.

## Quick start

Choose an action from the [Social Data action catalog](/social-data-catalog), then send its action ID and parameters:

```bash
curl https://api.beatapi.io/v1/social-data/call \
  -H "Authorization: Bearer $BEATAPI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"action":"douyin.web.fetch_one_video","params":{"aweme_id":"7364837462110"}}'
```

The public endpoint is `POST /v1/social-data/call`. The `model` field is not required for this endpoint; the action ID selects the operation. Do not send provider-native URLs or provider-native route names.

## Request

| Field    | Type   | Required | Description                                                                                    |
| -------- | ------ | -------: | ---------------------------------------------------------------------------------------------- |
| `action` | string |      Yes | BeatAPI action ID from the catalog.                                                            |
| `params` | object |       No | Parameters described by the selected catalog entry. Omit it when the action has no parameters. |

`action` must use the catalogued identifier format, such as `douyin.web.fetch_one_video`. The catalog entry's `input_schema` is the source of truth for required fields, types, and allowed values. For actions whose catalog method is `GET`, parameter values are scalar. For `POST` actions, `params` is a JSON object.

The request body is limited to 512 KiB. Authentication uses `Authorization: Bearer <BeatAPI API key>`. You may send `Idempotency-Key` when your client may retry the same request; reusing that key with a different request is rejected.

## Response

Successful calls return the normalized BeatAPI envelope:

```json
{
  "object": "social_data.call",
  "status": "succeeded",
  "request_id": "req_01H...",
  "action": "douyin.web.fetch_one_video",
  "data": {
    "aweme_id": "7364837462110"
  }
}
```

`data` is the public result returned for the selected action. BeatAPI removes provider names, provider request IDs, cache URLs, routing fields, and raw provider error details before returning it. The response is synchronous: a successful HTTP response means the action has completed.

The static action catalog documents inputs, not action-specific output shapes. Use [Capabilities Inspect](/capabilities) to check the current `output_schema` and readiness. `runnable` means the action can run but its output shape is not published; read the fields from the actual response rather than assuming a fixed structure.

## Creator discovery

Two actions answer what the platform catalog cannot: who resembles a creator,
and how to reach them. They use the same endpoint and the same
`action` / `params` contract as every other action.

### `creator.discover`

Given one seed account, returns creators the platform itself considers similar,
each already enriched with the contact details published on their profile.

| Parameter  | Type    | Required | Description                                                                                                                 |
| ---------- | ------- | -------- | --------------------------------------------------------------------------------------------------------------------------- |
| `platform` | string  | Yes      | `instagram`. The related-accounts graph this reads belongs to Instagram; other platforms have no seed-to-similar step here. |
| `seed`     | string  | Yes      | A handle or profile URL, for example `gymshark` or `https://www.instagram.com/gymshark/`.                                   |
| `limit`    | integer | No       | How many similar creators to return, `1`–`6`. Defaults to `6`.                                                              |

```bash
curl https://api.beatapi.io/v1/social-data/call \
  -H "Authorization: Bearer $BEATAPI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"action":"creator.discover","params":{"platform":"instagram","seed":"gymshark","limit":3}}'
```

The seed itself is returned alongside the similar creators, marked
`discovered_via: "input"`, so `limit` counts the similar creators and the
response carries one row more than that.

### `creator.contacts`

Given creators you already know, returns the same record for each — no
discovery step.

| Parameter  | Type      | Required | Description                         |
| ---------- | --------- | -------- | ----------------------------------- |
| `platform` | string    | Yes      | `instagram`, `tiktok` or `youtube`. |
| `handles`  | string\[] | Yes      | 1–8 handles or profile URLs.        |

```bash
curl https://api.beatapi.io/v1/social-data/call \
  -H "Authorization: Bearer $BEATAPI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"action":"creator.contacts","params":{"platform":"youtube","handles":["@mkbhd"]}}'
```

### The creator record

Both actions return the same shape in `data`, one object per creator:

| Field                                                                                   | Description                                                                   |
| --------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------- |
| `platform`, `handle`, `name`, `profile_url`, `user_id`                                  | Identity.                                                                     |
| `followers`, `following`, `posts_count`, `engagement_rate_pct`, `avg_likes`             | Audience and activity. `followers_estimated` says when a count is inferred.   |
| `email`, `extra_emails`, `email_status`, `email_source`                                 | Contact. `email` is `null` when none is published — see below.                |
| `website`, `linkedin_url`, `instagram_url`, `tiktok_url`, `youtube_url`, `facebook_url` | Links found on the profile.                                                   |
| `bio`, `category`, `country`, `verified`, `is_business`, `is_private`                   | Profile attributes.                                                           |
| `lead_score`, `lead_grade`, `lead_tier`                                                 | A rank over the fields above, for triage.                                     |
| `discovered_via`                                                                        | `input` for a creator you named, `instagram_related` for one discovery found. |

> **Warning**
>
> `email_source` tells you where an address came from. An address found on a
> creator's linked website may belong to a brand they promote rather than to them
> — check `email_source` before treating it as a personal contact.

### Credits

Unlike every other action, these two are billed **per creator returned**, not
per request. `GET /v1/social-data/pricing` states this in `billing_unit`:
`"creator"` for these two, `"request"` for the rest.

A request that finds nobody is a successful response with an empty `data`
array, and it still consumes one creator's worth of credit: the discovery work
happened whether or not it found anyone. Cap your spend with `limit` and the
size of `handles`.

## Errors and credits

Errors use the normal BeatAPI error envelope, a stable `code` and `retryable` on every error. See [Errors](/errors) for the retry policy.

| HTTP status | Code                                                    | Meaning                                                                   |
| ----------: | ------------------------------------------------------- | ------------------------------------------------------------------------- |
|         400 | `bad_request`                                           | Invalid JSON, action, or parameters; the message names the field.         |
|         401 | `missing_api_key` / `invalid_api_key`                   | No key was sent, or the key is wrong, expired, disabled, or exhausted.    |
|         402 | `insufficient_credits`                                  | Insufficient balance: the balance is zero or below the price of the call. |
|         403 | `forbidden`                                             | The key or account is not permitted to make this call.                    |
|         404 | `not_found`                                             | The requested action or resource was not found.                           |
|         409 | `idempotency_conflict`                                  | The idempotency key was reused with a different request.                  |
|         429 | `rate_limit_exceeded`                                   | The request limit was reached. Wait `Retry-After` seconds.                |
|         500 | `internal_error`                                        | Unexpected internal error. Retryable.                                     |
|         503 | `processing_unavailable` or another `processing_*` code | The request could not be completed. Retry with backoff.                   |

Failed calls do not consume credits. A successful call consumes credits according to the account's current BeatAPI pricing and the selected action. Supplier costs and supplier URLs are never part of this documentation or public response.

## MCP

The same catalog and contract are available through the `capabilities_search`, `capabilities_inspect`, and `capabilities_run` MCP tools and the [Capabilities API](/capabilities). Search with the platform and the action in the user's words (`小红书 搜索笔记`, `tiktok user profile`); a platform name alone returns an overview grouped by function. Use the `data:<action-id>` reference exactly as Search returns it, and follow each reply's `next`.

MCP returns a preview of large results by default. To retrieve the full result free within one hour, use the same API key and original `reference`, set `operation` to `"result"`, and include the returned `request_id`. No provider credentials or provider-native paths are needed.