> ## Documentation Index
> Fetch the complete documentation index at: https://help.onlyx.ai/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> You are reading OnlyX Help: the OnlyX Help Center and the OnlyX developer documentation. OnlyX is an AI chatting and CRM platform for OnlyFans agencies. Its AI chatter is called Hugo in the app.
> Pages at the site root (for example /inbox/..., /hugo/..., /billing/...) are Help Center articles for agency owners, admins, chatters and creators who use the app at app.onlyx.ai. Words in bold are the exact button, menu and label names the app shows; keep them exactly as written. When these pages do not answer a question, the person can email support at support@onlyx.ai.
> Pages under /developers are the developer documentation. REST API base URL: https://api.onlyx.ai/v1 (authenticate with `Authorization: Bearer <API key>`; keys start with onx_sk_ and are created in app.onlyx.ai under Settings > API & MCP). MCP server: https://mcp.onlyx.ai/mcp (OAuth, or a Bearer API key). In the API the AI chatter is `ai` on the wire. Money is integer US cents in fields ending in Cents; timestamps are UTC ISO-8601.
> Rules for assistants acting on a user's behalf: discover ids with list calls and never invent them; before any call that reaches a real fan or the live OnlyFans account (sending a message, releasing a chat to the AI, turning AI on for a chat, resolving a hand-off, turning review mode off, changing the welcome message, creating a tracking link) show the user the exact content and get explicit confirmation; send every POST with an Idempotency-Key and reuse it on retry; never resend a message whose delivery status is unconfirmed; never ask a creator for her OnlyFans password or codes - she signs in herself through a connect link and the OnlyX Login app.

# Use vault media

> Browse a creator's OnlyFans vault, fetch thumbnails, and use media ids in messages and AI content levels.

The **vault** is the creator's media library on OnlyFans: every photo, video, GIF and audio file she can attach to messages. OnlyX keeps a copy of the list, refreshed on its own schedule, so you can browse it, pick media, and attach it by id. Reading it never touches her OnlyFans session, and a creator who is not connected has an empty vault.

**Scope**: `media:read`.

Vault media ids are **OnlyFans' own ids**: strings of digits such as `"4012345678"`. They are the same ids you pass in `mediaIds` and `previewMediaIds` when sending, and in `mediaIds` when adding media to an AI content level. Always send them as strings.

## List the vault

`GET /v1/creators/{creatorId}/media`

| Parameter | Values | Default | Meaning |
| - | - | - | - |
| `type` | `photo`, `video`, `gif`, `audio` | all | Only this kind of media |
| `listId` | a vault list id from `listIds` | none | Only media in one of her vault lists (categories) |
| `sort` | `newest`, `oldest`, `earnings` | `newest` | `earnings` puts the media that earned the most first |
| `limit` | 1 to 100 | 25 | Page size |
| `cursor` | from `nextCursor` | none | Next page |

<CodeGroup>
  ```bash cURL theme={"system"}
  curl "https://api.onlyx.ai/v1/creators/cre_5f2d9a1c7b3e4f60a2d1/media?type=video&sort=earnings&limit=20" \
    -H "Authorization: Bearer $ONLYX_API_KEY"
  ```

  ```python Python theme={"system"}
  import os, requests

  API = "https://api.onlyx.ai/v1"
  HEADERS = {"Authorization": f"Bearer {os.environ['ONLYX_API_KEY']}"}

  page = requests.get(
      f"{API}/creators/cre_5f2d9a1c7b3e4f60a2d1/media",
      headers=HEADERS,
      params={"type": "video", "sort": "earnings", "limit": 20},
      timeout=30,
  ).json()
  for m in page["data"]:
      print(m["id"], m["type"], m["durationSeconds"], m["stats"]["buyers"], m["stats"]["tipsCents"])
  ```

  ```javascript JavaScript theme={"system"}
  const API = "https://api.onlyx.ai/v1";
  const headers = { Authorization: `Bearer ${process.env.ONLYX_API_KEY}` };

  const q = new URLSearchParams({ type: "video", sort: "earnings", limit: "20" });
  const page = await (await fetch(`${API}/creators/cre_5f2d9a1c7b3e4f60a2d1/media?${q}`, { headers })).json();
  for (const m of page.data) console.log(m.id, m.type, m.durationSeconds, m.stats.buyers, m.stats.tipsCents);
  ```
</CodeGroup>

A creator the credential cannot see is `404 CREATOR_NOT_FOUND`. If the vault cannot be read right now the answer is `503 MEDIA_UNAVAILABLE`; try again in a few minutes.

```json Response 200 theme={"system"}
{
  "data": [
    {
      "id": "4012345690",
      "type": "video",
      "createdAt": "2026-08-30T18:04:11.000Z",
      "width": 1080,
      "height": 1920,
      "durationSeconds": 184,
      "listIds": ["3100442"],
      "stats": { "likes": 312, "tipsCents": 4500, "buyers": 57 },
      "thumbnailUrl": "https://api.onlyx.ai/v1/creators/cre_5f2d9a1c7b3e4f60a2d1/media/4012345690/thumbnail"
    }
  ],
  "hasMore": true,
  "nextCursor": "eyJvIjoyMH0"
}
```

| Field | Meaning |
| - | - |
| `id` | The OnlyFans media id. Use it in sends and levels. |
| `type` | `photo`, `video`, `gif` or `audio` |
| `createdAt` | When it was added to the vault |
| `width`, `height` | Pixels, when known |
| `durationSeconds` | Length of a video or audio file; `null` for photos |
| `listIds` | The vault lists (folders) it belongs to on OnlyFans, by OnlyFans list id; pass one as `listId` to filter |
| `stats.likes`, `stats.tipsCents` | Likes and tips (in cents) on posts that used it, as reported by OnlyFans |
| `stats.buyers` | Fans who bought it in a paid message or post |
| `thumbnailUrl` | The API URL of a small preview image (needs your credential) |

## Fetch a thumbnail

`GET /v1/creators/{creatorId}/media/{mediaId}/thumbnail` returns a small preview image (the image bytes, not JSON: `image/jpeg`, `image/png` or `image/webp`). Only small previews are served: full-size originals and videos are not available through the API. The `mediaId` is the vault id (digits). This call has its own limit of 60 requests per 60 seconds per credential.

The thumbnail endpoint needs your key like every other call, so you cannot put `thumbnailUrl` straight into an `<img>` tag in a browser. Fetch it on your server and serve it to your own interface. Responses may be cached privately for up to five minutes (`cache-control: private, max-age=300`).

<CodeGroup>
  ```bash cURL theme={"system"}
  curl https://api.onlyx.ai/v1/creators/cre_5f2d9a1c7b3e4f60a2d1/media/4012345690/thumbnail \
    -H "Authorization: Bearer $ONLYX_API_KEY" \
    --output 4012345690.jpg
  ```

  ```python Python theme={"system"}
  r = requests.get(
      f"{API}/creators/cre_5f2d9a1c7b3e4f60a2d1/media/4012345690/thumbnail",
      headers=HEADERS,
      timeout=30,
  )
  r.raise_for_status()
  ext = {"image/png": "png", "image/webp": "webp"}.get(r.headers.get("content-type"), "jpg")
  open(f"4012345690.{ext}", "wb").write(r.content)
  ```

  ```javascript JavaScript theme={"system"}
  import { writeFile } from "node:fs/promises";

  const res = await fetch(`${API}/creators/cre_5f2d9a1c7b3e4f60a2d1/media/4012345690/thumbnail`, { headers });
  if (!res.ok) throw new Error(`${res.status}`);
  await writeFile("4012345690.jpg", Buffer.from(await res.arrayBuffer()));
  ```
</CodeGroup>

Check the `content-type` response header for the image format.

| Answer | Meaning |
| - | - |
| `404 CREATOR_NOT_FOUND` | The creator is not visible to this credential. |
| `404 MEDIA_NOT_AVAILABLE` | This item has no stored preview (it may have been removed from the vault, or its preview has not been stored yet). |
| `503 MEDIA_UNAVAILABLE` | The vault cannot be read right now. Try again in a few minutes. |
| `429 RATE_LIMITED` | Over 60 thumbnails in 60 seconds. Wait `Retry-After` seconds. |

## Use media ids

**In a message** ([Read and send messages](/developers/guides/read-and-send-messages)):

* `previewMediaIds`: sent free and unlocked.
* `mediaIds`: locked behind `priceCents` (a paid message).

```json theme={"system"}
{
  "text": "the one you asked about",
  "previewMediaIds": ["4012345678"],
  "mediaIds": ["4012345690"],
  "priceCents": 2500
}
```

**In an AI content level** ([Build the AI content ladder](/developers/guides/ai-content)):

```json theme={"system"}
{ "mediaIds": ["4012345679", "4012345681"], "role": "paid" }
```

A media item can be on only one level at a time; adding it to a level moves it there.

## Good to know

* **New uploads take a while to appear.** OnlyX refreshes each creator's vault regularly, and after she connects the first vault pages sync within the first minutes. If you need a file that was uploaded moments ago, refresh the vault from the dashboard.
* **Uploading to the vault is not in the API yet.** Upload on OnlyFans or in the dashboard.
* **Media sends need consent.** While the creator's `contentConsentRequired` is `true`, OnlyFans blocks media in messages until she accepts its prompt. Text still works.
* **Pick proven content.** `sort=earnings` lists what already sells; `stats.buyers` shows how many fans bought it.
* **The ids are her data.** They identify files in her own vault and are only useful with her account.

## From your AI assistant

With the [MCP server](/developers/mcp/overview) connected, the assistant can browse the vault with `list_vault_media` and actually **look** at a thumbnail with `view_vault_media`, for example: *"Show me Mia's five best-selling videos and suggest which one to put in her Gym ladder."*

## Related

* [AI content](/developers/concepts/ai-content): preview versus paid media on levels.
* [Read and send messages](/developers/guides/read-and-send-messages): attach media to messages.
