> ## 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.

# Quickstart

> Create an API key, check it with GET /v1/me, list creators, read the inbox and send a first message.

This quickstart takes about five minutes. You will create an API key, confirm it works, find a creator and a conversation, and send one message with delivery tracking.

**Before you start**

* You are an **owner or admin** of an OnlyX workspace. Other roles cannot create keys.
* At least one creator in the workspace is connected. If none is, follow [Add a creator](/developers/guides/add-a-creator) first.
* You have `curl`, Python 3 with `requests` (`pip install requests`), or Node.js 18 or newer. The JavaScript examples use the built-in `fetch` and top-level `await`: save them in a file ending in `.mjs` and run it with `node file.mjs`.

<Steps>
  <Step title="Create an API key">
    1. Open [app.onlyx.ai](https://app.onlyx.ai/settings?tab=developer) and go to **Settings → API & MCP**.
    2. Under **API keys**, click **Create API key**.
    3. Name it after what will use it, for example `Reporting script`.
    4. Choose an access preset. For this quickstart pick **Full access**, because step 5 sends a message. For a real integration pick the smallest set of scopes it needs (see [Authentication](/developers/authentication#scopes)).
    5. Leave **Creators** on *All creators* and **Expires** on *Never*, or restrict them.
    6. Click **Create** and copy the key. It starts with `onx_sk_` and **is shown only once**. OnlyX stores only a hash of it.

    Store the key in an environment variable, never in code:

    ```bash theme={"system"}
    export ONLYX_API_KEY="onx_sk_..."
    ```
  </Step>

  <Step title="Check the key: GET /v1/me">
    `GET /v1/me` tells you which workspace the key belongs to, which scopes it has, and your rate limit. Every key can call it.

    <CodeGroup>
      ```bash cURL theme={"system"}
      curl https://api.onlyx.ai/v1/me \
        -H "Authorization: Bearer $ONLYX_API_KEY"
      ```

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

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

      me = requests.get(f"{API}/me", headers=HEADERS, timeout=30)
      me.raise_for_status()
      print(me.json())
      ```

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

      const res = await fetch(`${API}/me`, { headers });
      if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
      console.log(await res.json());
      ```
    </CodeGroup>

    ```json Response 200 theme={"system"}
    {
      "workspace": {
        "id": "agc_1a2b3c4d5e6f7a8b9c0d",
        "name": "Northstar Talent",
        "timezone": "Europe/London"
      },
      "credential": {
        "kind": "api_key",
        "id": "apk_0c9d8e7f6a5b4c3d2e1f",
        "name": "Reporting script",
        "scopes": ["workspace:read", "creators:read", "inbox:read", "messages:send"],
        "creatorIds": null
      },
      "rateLimit": { "limit": 120, "windowSeconds": 60 }
    }
    ```

    A `401` with `INVALID_API_KEY` means the key was mistyped, revoked or expired. See [Errors](/developers/errors).
  </Step>

  <Step title="List your creators">
    <CodeGroup>
      ```bash cURL theme={"system"}
      curl https://api.onlyx.ai/v1/creators \
        -H "Authorization: Bearer $ONLYX_API_KEY"
      ```

      ```python Python theme={"system"}
      creators = requests.get(f"{API}/creators", headers=HEADERS, timeout=30).json()["data"]
      for c in creators:
          print(c["id"], c["displayName"], c["connection"]["status"], c["aiEnabled"])
      ```

      ```javascript JavaScript theme={"system"}
      const { data: creators } = await (await fetch(`${API}/creators`, { headers })).json();
      for (const c of creators) console.log(c.id, c.displayName, c.connection.status, c.aiEnabled);
      ```
    </CodeGroup>

    ```json Response 200 theme={"system"}
    {
      "data": [
        {
          "id": "cre_5f2d9a1c7b3e4f60a2d1",
          "displayName": "Mia Rose",
          "handle": "miarose",
          "publicName": "Mia",
          "avatarUrl": "https://...",
          "platform": "onlyfans",
          "aiEnabled": true,
          "connection": { "status": "connected", "connected": true },
          "onlyfans": {
            "userId": "412345678",
            "verified": true,
            "subscribePriceCents": 999,
            "postsCount": 812,
            "photosCount": 1540,
            "videosCount": 230
          },
          "stats": {
            "fans": 2841,
            "conversations": 1912,
            "unreadConversations": 14,
            "openHandoffs": 2,
            "revenueCents": 1284350,
            "pendingCents": 96420,
            "revenueKnown": true
          },
          "contentConsentRequired": false,
          "createdAt": "2026-08-02T09:12:44.000Z"
        }
      ],
      "hasMore": false,
      "nextCursor": null
    }
    ```

    Copy a creator `id` (`cre_...`) whose `connection.status` is `connected`.
  </Step>

  <Step title="Read the inbox">
    List that creator's unread conversations, then read the newest messages of one of them.

    <CodeGroup>
      ```bash cURL theme={"system"}
      curl "https://api.onlyx.ai/v1/conversations?creatorId=cre_5f2d9a1c7b3e4f60a2d1&unread=true&limit=5" \
        -H "Authorization: Bearer $ONLYX_API_KEY"

      curl "https://api.onlyx.ai/v1/conversations/cnv_9f2c41d7a8b35e06c1f4/messages?limit=20" \
        -H "Authorization: Bearer $ONLYX_API_KEY"
      ```

      ```python Python theme={"system"}
      chats = requests.get(
          f"{API}/conversations",
          headers=HEADERS,
          params={"creatorId": "cre_5f2d9a1c7b3e4f60a2d1", "unread": "true", "limit": 5},
          timeout=30,
      ).json()["data"]
      chat = chats[0]

      msgs = requests.get(
          f"{API}/conversations/{chat['id']}/messages",
          headers=HEADERS,
          params={"limit": 20},
          timeout=30,
      ).json()["data"]
      for m in msgs:  # oldest first
          print(m["createdAt"], m["sender"], m["text"])
      ```

      ```javascript JavaScript theme={"system"}
      const q = new URLSearchParams({ creatorId: "cre_5f2d9a1c7b3e4f60a2d1", unread: "true", limit: "5" });
      const { data: chats } = await (await fetch(`${API}/conversations?${q}`, { headers })).json();
      const chat = chats[0];

      const { data: msgs } = await (
        await fetch(`${API}/conversations/${chat.id}/messages?limit=20`, { headers })
      ).json();
      for (const m of msgs) console.log(m.createdAt, m.sender, m.text); // oldest first
      ```
    </CodeGroup>

    ```json Response 200 (messages) theme={"system"}
    {
      "data": [
        {
          "id": "msg_2c8e4a6f1b3d5079e2a4",
          "conversationId": "cnv_9f2c41d7a8b35e06c1f4",
          "direction": "in",
          "sender": "fan",
          "text": "are you online rn?",
          "media": [],
          "paid": null,
          "tipCents": null,
          "createdAt": "2026-09-26T13:58:12.000Z",
          "delivery": null
        }
      ],
      "hasMore": true
    }
    ```

    The conversation's `status` tells you who is answering it: `ai` (the AI chatter), `team` (a human took over), `handoff` (the AI asked for a human) or `ai_off`. See [Conversations](/developers/concepts/conversations).
  </Step>

  <Step title="Send a first message">
    <Warning>
      This reaches a **real fan** on OnlyFans. Try it in a chat with a test subscriber account you own, or skip this step.
    </Warning>

    Sending needs the `messages:send` scope and an `Idempotency-Key` header. Generate a new key (a UUID works) for each new message, and reuse the same key if you retry the same message.

    <CodeGroup>
      ```bash cURL theme={"system"}
      curl -X POST https://api.onlyx.ai/v1/conversations/cnv_9f2c41d7a8b35e06c1f4/messages \
        -H "Authorization: Bearer $ONLYX_API_KEY" \
        -H "Content-Type: application/json" \
        -H "Idempotency-Key: 6f1c2d3e-4b5a-4c7d-8e9f-0a1b2c3d4e5f" \
        -d '{"text": "hey you, I am here now"}'
      ```

      ```python Python theme={"system"}
      import uuid

      sent = requests.post(
          f"{API}/conversations/{chat['id']}/messages",
          headers={**HEADERS, "Idempotency-Key": str(uuid.uuid4())},
          json={"text": "hey you, I am here now"},
          timeout=30,
      )
      sent.raise_for_status()  # 202 Accepted
      message = sent.json()
      print(message["id"], message["delivery"]["status"])  # "queued"
      ```

      ```javascript JavaScript theme={"system"}
      const sendRes = await fetch(`${API}/conversations/${chat.id}/messages`, {
        method: "POST",
        headers: { ...headers, "Content-Type": "application/json", "Idempotency-Key": crypto.randomUUID() },
        body: JSON.stringify({ text: "hey you, I am here now" }),
      });
      if (sendRes.status !== 202) throw new Error(`${sendRes.status} ${await sendRes.text()}`);
      const message = await sendRes.json();
      console.log(message.id, message.delivery.status); // "queued"
      ```
    </CodeGroup>

    ```json Response 202 theme={"system"}
    {
      "id": "msg_7a1d3f9c2e5b40d8a6c3",
      "conversationId": "cnv_9f2c41d7a8b35e06c1f4",
      "direction": "out",
      "sender": "team",
      "text": "hey you, I am here now",
      "media": [],
      "paid": null,
      "tipCents": null,
      "createdAt": "2026-09-26T14:02:31.000Z",
      "delivery": { "status": "queued", "reason": null }
    }
    ```

    `202` means OnlyX accepted the message and queued it for delivery. Poll `GET /v1/conversations/{conversationId}/messages/{messageId}` every 5–10 seconds until `delivery.status` is `sent`, `failed`, `unconfirmed` or `not_sent`. **Never resend on `unconfirmed`**: the fan almost always got it.

    Sending also moves the chat to `team` for 12 hours, so the AI does not talk over you. Details in [Read and send messages](/developers/guides/read-and-send-messages).
  </Step>
</Steps>

## Prefer your AI assistant?

You do not need code to use OnlyX from Claude, ChatGPT, Cursor or VS Code. Connect the OnlyX MCP server in one click, sign in, and ask in plain language: "Which fans are waiting for a reply on Mia's account?"

<CardGroup cols={2}>
  <Card title="Add OnlyX to Claude" icon="plug" href="https://claude.ai/customize/connectors?modal=add-custom-connector&connectorName=OnlyX&connectorUrl=https%3A%2F%2Fmcp.onlyx.ai%2Fmcp">
    Opens Claude with the OnlyX connector filled in. Click **Add**, then sign in.
  </Card>

  <Card title="All AI clients" icon="bot" href="/developers/mcp/overview">
    ChatGPT, Cursor, VS Code, Claude Code and others.
  </Card>
</CardGroup>

## Next steps

* [Authentication](/developers/authentication): scopes, creator restrictions, expiry and OAuth.
* [Add a creator](/developers/guides/add-a-creator): connect a new OnlyFans account, including face verification.
* [Read and send messages](/developers/guides/read-and-send-messages): paid messages, vault media, delivery states, take over and release.
* [Errors](/developers/errors) and [Rate limits](/developers/rate-limits): what to retry and what to fix.
