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

# API reference

> Every endpoint of the OnlyX REST API v1: base URL, authentication, versioning, conventions, pagination, errors, rate limits and idempotency, then one page per operation.

This reference describes every endpoint of the OnlyX API, version 1: its parameters, request body, response, scopes, rate limits and errors. Each operation has its own page in the sidebar, grouped by area. For step-by-step tasks, start with the [guides](/developers/quickstart); for AI assistants, see the [MCP server](/developers/mcp/overview), which exposes the same operations as tools.

<Note>
  The pages show request and response examples you can copy. **Interactive testing (a "Send" button on each page) arrives when the API launches.** Until then, call the API from your own code or with `curl`.
</Note>

## Base URL

```text theme={"system"}
https://api.onlyx.ai/v1
```

Every path in this reference starts with `/v1`. Always use HTTPS.

## Authentication

Send a credential in the `Authorization` header:

```http theme={"system"}
GET /v1/me HTTP/1.1
Host: api.onlyx.ai
Authorization: Bearer onx_sk_...
```

| Credential | Format | Where it comes from |
| - | - | - |
| API key | `onx_sk_…` | Created by a workspace owner or admin in OnlyX under **Settings → API & MCP**. Shown once. |
| OAuth access token | `onx_at_…` | Issued to a connected app (for example Claude or ChatGPT through the MCP server). Valid for one hour. |

Tools that cannot set a bearer header may send an API key as `X-API-Key: onx_sk_…` instead. Keys belong to the workspace, not to a person, carry **scopes**, and can be limited to some creators. Every operation page names the scope it needs under **Scope** (the OpenAPI document carries it as `x-required-scope`), and the table below sums it up by area. A credential without the scope gets `403 INSUFFICIENT_SCOPE`, and the error message names the missing scope. One operation needs two: turning review mode off with `PATCH /v1/creators/{creatorId}/ai-settings` releases waiting AI drafts to fans, so it needs `messages:send` as well as `ai:write` (in the OpenAPI document: `x-conditional-scopes`). `GET /v1/me` works with every valid credential and is the quickest way to check one. Details: [Authentication](/developers/authentication) and [Security](/developers/security).

| Area | Read scope | Write scope |
| - | - | - |
| Workspace | `workspace:read` (always granted) | none |
| Creators and connect links | `creators:read` | `creators:write` |
| Conversations, messages, hand-offs | `inbox:read` | `inbox:write`; sending needs `messages:send` |
| Fans and fan lists | `fans:read` | `fans:write` |
| Vault media | `media:read` | none |
| Stats | `stats:read` | none |
| Transactions (`GET /v1/creators/{creatorId}/transactions`) | `money:read` | none |
| AI persona, AI content, AI settings | `ai:read` | `ai:write` |
| Tracking links | `links:read` | `links:write` |

## Versioning

The version is part of the path: `/v1`. Within v1 we only make **additive** changes: new endpoints, new optional parameters, new response fields, new enum values and new error codes. We never remove or rename a field or change its type within v1. Build your integration to ignore fields it does not know and to handle an unknown enum value or error code gracefully. Every change is listed in the [changelog](/developers/changelog).

## Conventions

* **JSON** in and out, UTF-8, with `Content-Type: application/json` on request bodies.
* **camelCase** field names: `displayName`, `priceCents`, `createdAt`.
* **Money** is an integer number of US **cents** in fields ending in `Cents`: `1500` is \$15.00. Where it matters, `netCents` is what the creator earns after OnlyFans' fee and `grossCents` (or `amountCents`) is what the fan paid.
* **Timestamps** are ISO-8601 in UTC with a `Z`, for example `2026-09-26T14:02:31.000Z`. Parse them with a standard ISO-8601 parser and do not assume a fixed number of fractional-second digits. **Dates** are `YYYY-MM-DD` in the workspace time zone (`GET /v1/me` returns it).
* **Null**: a field without a value is present as `null` rather than left out. A few optional fields, such as a fan's `username`, may be missing when OnlyFans does not provide them.
* **Single objects** are returned bare; **lists** are wrapped (see below).
* **Ids** are opaque strings with a prefix that tells you the type. Always take them from a list or get call; never build or guess them.

| Prefix | Object |
| - | - |
| `agc_` | Workspace |
| `cre_` | Creator |
| `cnv_` | Conversation |
| `msg_` | Message |
| `fan_` | Fan |
| `lst_` | Fan list |
| `esc_` | Hand-off |
| `fld_`, `col_`, `set_` | AI content folder, ladder (collection), level |
| `trk_` | Tracking link |
| digits only | Vault media (the creator's own OnlyFans media ids) |

On the wire the AI chatter (Hugo in the OnlyX app) is `ai` and people on your team are `team`.

## Pagination

List endpoints return one page at a time:

```json theme={"system"}
{
  "data": [{ "id": "cre_8f2c1a9b0d7e4c3f2a1b", "displayName": "Mia Rose" }],
  "hasMore": true,
  "nextCursor": "eyJrIjoiY3JlYXRvcnMiLCJwIjp7Im8iOjI1fX0.q7x2YfK9dLw3mN8pR1sT4A"
}
```

Pass `limit` (1 to 100 unless the page says otherwise, default 25) and, for the next page, `cursor` set to the previous `nextCursor`. Stop when `hasMore` is `false`. Cursors are opaque and tamper-evident: an edited cursor is `400 VALIDATION_ERROR`. Message history pages backwards with `before` instead. Details and loops in Python and JavaScript: [Pagination](/developers/pagination).

## Errors

Every error has the same shape, with an HTTP status that matches the kind of problem:

```json theme={"system"}
{
  "error": {
    "code": "CONVERSATION_NOT_FOUND",
    "message": "Conversation not found.",
    "requestId": "req-3f9a1c2b7d4e5f60a1b2c3d4"
  }
}
```

Branch on `code`, never on `message`. An id from another workspace, or one your credential may not see, gets exactly the same `404` as an id that does not exist. Every operation page lists the errors it can return; the full list of codes with fixes is in [Errors](/developers/errors).

| Status | Meaning |
| - | - |
| `200`, `201` | Done. |
| `202` | Accepted: the work continues in the background (sends, the welcome message, tracking-link creation, a report that is being prepared). |
| `204` | Done, no body. |
| `400` | The request is not valid. Fix it; do not retry it unchanged. |
| `401` | No credential, or it is invalid, expired or revoked. |
| `403` | The credential lacks a scope, or the workspace is suspended. |
| `404` | Nothing with that id is visible to this credential. |
| `405` | The path exists but not with this method (`METHOD_NOT_ALLOWED`). |
| `409` | Conflicts with the current state (for example the creator is not connected, or an `Idempotency-Key` was reused). |
| `429` | Over a rate limit. Wait `Retry-After` seconds. |
| `500` | A problem on OnlyX's side (`INTERNAL_ERROR`). Retry with backoff, reusing the `Idempotency-Key` for writes. |
| `503` | Temporarily unavailable. Retry after `Retry-After` (or a few minutes) with the same `Idempotency-Key` — except `SENDING_DISABLED`, which means actions that reach fans are switched off for the API until OnlyX switches them back on. |

## Rate limits

Every credential may make **120 requests per 60 seconds**. Some operations add a tighter limit of their own, counted on top of the general one. Each operation page states its limits under **Rate limit** (the OpenAPI document carries them as `x-rate-limits`); here they are in one place:

| Operation | Extra limit |
| - | - |
| `POST /v1/conversations/{conversationId}/messages` | 30 per 60 seconds per credential, and 300 per hour per creator (all credentials together) |
| `GET /v1/conversations/counts` | 30 per 60 seconds per credential |
| `GET /v1/stats/*` | 20 per 60 seconds per credential, across all four reports |
| `GET /v1/creators/{creatorId}/connection` | 1 per 5 seconds per creator, for each credential |
| `POST /v1/creators` | 10 per 24 hours per workspace |
| `POST /v1/creators/{creatorId}/connect-link` | 20 per hour per workspace |
| `GET /v1/creators/{creatorId}/media/{mediaId}/thumbnail` | 60 per 60 seconds per credential |
| AI content writes (`POST`, `PATCH`, `PUT`, `DELETE` under `/v1/creators/{creatorId}/ai-content`) | 60 per 60 seconds per credential |
| `PATCH /v1/creators/{creatorId}/ai-settings` turning review mode off | 6 per hour per creator |
| `PUT /v1/creators/{creatorId}/welcome-message` | 5 per hour per creator, dry runs included |
| `POST /v1/creators/{creatorId}/tracking-links` | 5 per day per creator, and 10 per hour per workspace |

Every response reports the tightest limit it counted against:

| Header | Meaning |
| - | - |
| `X-RateLimit-Limit` | Requests allowed in the window |
| `X-RateLimit-Remaining` | Requests left in the window |
| `X-RateLimit-Reset` | When the window resets, as Unix epoch seconds |

Over a limit you get `429 RATE_LIMITED` with a `Retry-After` header in seconds. The full table and a backoff example: [Rate limits](/developers/rate-limits).

## Idempotency

Send an `Idempotency-Key` header (8 to 64 letters, digits, `-` or `_`; a UUID is ideal) on any `POST`, `PUT`, `PATCH` or `DELETE`. If the request times out or fails with a `5xx`, retry with the **same** key: OnlyX returns the stored response, marked `Idempotent-Replayed: true`, and does nothing twice. The key is **required** when sending a message (`POST /v1/conversations/{conversationId}/messages`), adding a creator (`POST /v1/creators`) and creating a tracking link (`POST /v1/creators/{creatorId}/tracking-links`); without it they answer `400 IDEMPOTENCY_KEY_REQUIRED`. Keys are kept for 24 hours. Every write's page lists the header (required or optional). Details: [Idempotency](/developers/idempotency).

## Operations that reach fans

Some operations reach a real fan or change the creator's live OnlyFans account: sending a message, releasing a conversation to the AI, switching the AI on for a conversation or a creator, resolving a hand-off, changing AI settings, replacing the welcome message and creating a tracking link. Their pages say so under **Reaches fans**, and the OpenAPI document marks them with `x-reaches-fans: true`. When an automation or an AI assistant is about to call one, show a person exactly what will happen and get a clear yes first.

## Request ids

Every response carries an `X-Request-Id` header, and every error body repeats it as `requestId`. Send your own `X-Request-Id` (8 to 64 letters, digits or `-`) to tie OnlyX's answer to your own logs; otherwise OnlyX creates one. Quote it when you contact support.

## The OpenAPI document

This reference is generated from an OpenAPI 3.1 document. At launch the API serves it, without authentication, at `GET https://api.onlyx.ai/v1/openapi.json`. Use it to generate a client in your language, to import the API into Postman or Insomnia, or to hand an AI agent the exact contract.

## Not in v1 yet

Webhooks, mass messages, vault uploads, posts, disconnecting a creator and more are on the way. See [Coming soon](/developers/coming-soon), and tell us what you need at [developers@onlyx.ai](mailto:developers@onlyx.ai).
