# The Only API β€” complete documentation > Everything: guides plus all 529 endpoints. Large; consider llms-guides.txt, llms-crm.txt or llms-of.txt instead. --- # Introduction (/docs) The Only API gives you programmatic access to OnlyFans and Fansly through a single REST API and a single API key. OnlyFans has no public API. Its private endpoints require **signed headers** (`sign`, `time`, `app-token`) that rotate constantly, a live session cookie, and a residential or datacenter proxy that matches the IP the session logged in from. We do all of that server-side. You send one header. Every connected account has a `platform` of either `onlyfans` or `fansly`. The CRM routes work for both and return the same normalized shapes. The `/api2/v2/*` passthrough is OnlyFans-only. See [OnlyFans & Fansly](/docs/platforms). ## The shape of the API [#the-shape-of-the-api] Your **CRM panel** is the tenant boundary. A panel has an ID (`crm_…`), an API key, and a set of connected creator accounts β€” one slot per account, each with its own persisted session and proxy. Almost every path is scoped to a panel: ``` https://theonlyapi.com/api/crm/{crm_id}/… ``` There are two very different surfaces underneath that prefix, and knowing which one you are on explains most surprising responses: 95 endpoints. OnlyFans and Fansly rows projected to the same shape, plus server-side aggregations, cached reads, async jobs, webhooks, automations and events that have no platform equivalent. 434 endpoints under `/api2/v2/*`. OnlyFans' own response body, unchanged, wrapped in a small `{ success, status_code, data }` envelope. Read [The two surfaces](/docs/two-surfaces) for how to choose between them. ## Start here [#start-here] Panel β†’ connected account β†’ first authenticated call, in about five minutes. Where keys live, and the difference between primary and secondary keys. Session paste (recommended) or credentials with automatic 2FA handling. The two envelopes, the real error shapes, and one wrapper that will confuse you if you test without a key. ## Using these docs with an AI [#using-these-docs-with-an-ai] Every page here has a Markdown twin: append `.md` to any URL, or use the **Copy page** button in the page header to copy it, view it as Markdown, or open it directly in ChatGPT or Claude. There is also an [`llms.txt`](/llms.txt) index, per-section full-text bundles, and an MCP server for the docs themselves. See [Use these docs with an AI](/docs/ai-agents). --- # Use these docs with an AI (/docs/ai-agents) This documentation is built to be read by machines as well as people. Every page has a plain-Markdown twin, the whole corpus is available as text bundles, and there are two MCP servers β€” one for the docs, one for the API itself. ## Copy any page [#copy-any-page] Every page header carries a **Copy Markdown** button and an **Open β–Ύ** menu: | Action | What it does | | ------------------------------------------------ | ------------------------------------------------------------------------------------------------- | | **Copy Markdown** (button) | Puts the page's raw Markdown on your clipboard | | **View as Markdown** | Opens the `.md` twin | | **Open in ChatGPT / Claude / Cursor / Scira AI** | Opens that assistant pre-filled with *"Read \, I want to ask questions about it."* | Those links carry a prompt asking the assistant to **fetch the page itself**, so they only work if it has web access β€” and it will fetch the HTML, not the smaller `.md` twin. For a guaranteed clean paste, use **Copy Markdown**. ## Markdown twins [#markdown-twins] Append `.md` to any documentation URL: ```bash curl https://docs.theonlyapi.com/docs/webhooks.md curl https://docs.theonlyapi.com/docs/crm/messaging/send-a-dm-or-ppv.md ``` Content negotiation works too β€” request the normal URL with `Accept: text/markdown` and you get Markdown back: ```bash curl -H 'Accept: text/markdown' https://docs.theonlyapi.com/docs/pagination ``` The 529 endpoint pages have no prose body of their own β€” they are rendered from the OpenAPI document. Their Markdown twins are generated from the same spec, so each one arrives as a complete, self-contained brief: signature, description, auth, parameters, request body, response shapes and a runnable `curl` example. An agent can make a correct call from one page. ## Text bundles [#text-bundles] | File | Contents | | -------------------------------------- | ----------------------------------------------------- | | [`/llms.txt`](/llms.txt) | Index of every page, with descriptions. Start here. | | [`/llms-guides.txt`](/llms-guides.txt) | Every guide, full text. The one to paste into a chat. | | [`/llms-crm.txt`](/llms-crm.txt) | All 95 CRM endpoints, full text. | | [`/llms-of.txt`](/llms-of.txt) | All 434 OnlyFans passthrough endpoints, full text. | | [`/llms-full.txt`](/llms-full.txt) | Everything. Large β€” for crawlers and indexers. | | [`/agents.md`](/agents.md) | A short operating brief for coding agents. | The split exists for a practical reason: `llms-full.txt` is over a megabyte, which is more than most models want in one paste. `llms-guides.txt` is the file a human should actually hand to an assistant. ```bash # Give an assistant everything it needs to write an integration curl https://docs.theonlyapi.com/llms-guides.txt ``` ## MCP servers [#mcp-servers] There are two, and they do different jobs. Connecting the wrong one is the usual confusion. `https://docs.theonlyapi.com/mcp` Β· public, no auth Β· search and read these pages. `https://theonlyapi.com/mcp` Β· OAuth 2.1 or a bearer API key Β· 59 tools that act on your real panel. ### Docs MCP [#docs-mcp] Read-only access to this documentation. No account, no key. ```bash claude mcp add --transport http theonlyapi-docs https://docs.theonlyapi.com/mcp ``` ```json { "mcpServers": { "theonlyapi-docs": { "type": "http", "url": "https://docs.theonlyapi.com/mcp" } } } ``` Tools: | Tool | Purpose | | ---------------- | ----------------------------------------------------------------------------------------- | | `search_docs` | Full-text search across every page | | `get_page` | Fetch one page as Markdown by path | | `list_endpoints` | List API endpoints, filtered by surface, tag or method | | `get_endpoint` | Full reference for one endpoint by method and path | | `list_tags` | Every tag with its surface and endpoint count β€” cheap orientation before `list_endpoints` | Use this when you want an agent to *learn* the API β€” answer questions, write integration code, look up a parameter. ### API MCP [#api-mcp] The product's own MCP server, which actually calls the API on your behalf: 59 tools across accounts, fans, messaging, earnings, subscribers, campaigns, webhooks, automations and events. ```bash claude mcp add --transport http theonlyapi https://theonlyapi.com/mcp ``` It supports OAuth 2.1 with PKCE, and clients that cannot do OAuth may send a CRM API key as `Authorization: Bearer `. Notable behaviours: * **The destructive and money-moving tools require** `confirm=true` β€” sending a DM, requesting a payout, changing subscription price, deleting an account, webhook or automation, and any non-GET through the escape hatches. Lower-risk writes (tagging a fan, creating a webhook or automation) apply immediately. * **Non-GET proxying is off by default.** Enable `mcp_unsafe_proxy` in the dashboard danger zone, or via `PATCH /api/crm/{crm_id}/mcp/unsafe-proxy`, if you need the escape-hatch tools. Note the toggle applies to static bearer-key clients only β€” OAuth sessions (ChatGPT, Claude.ai) never get non-GET proxying. * No *dedicated* vault, media-upload, mass-DM or scheduling tools exist β€” `of_send_message` sends one text DM to one fan, with no price, media or recipient list. Those surfaces are reachable only through the `of_crm_request` escape hatch, which needs `confirm=true` for any non-GET. Full setup instructions for ChatGPT, Claude, Cursor and Claude Code are on the [MCP integration page](https://theonlyapi.com/integrations/chatgpt). ## The OpenAPI spec [#the-openapi-spec] If your tooling speaks OpenAPI, skip the prose entirely: ```bash curl https://theonlyapi.com/api/openapi.json ``` OpenAPI 3.1, 450 paths, 529 operations, every operation with a summary. This reference is generated from it. ## Prompting suggestions [#prompting-suggestions] * **Give it the guides, not the full bundle.** `llms-guides.txt` plus the two or three endpoint pages you care about beats a megabyte of everything. * **Name the surface.** "Use the CRM layer, not the `/api2/v2` passthrough" removes most wrong answers, because the two have different response envelopes. * **Warn it about the money rule.** Agents will happily write `SUM(amount)` for earnings, which is wrong β€” see [the chargeback trap](/docs/earnings). * **Warn it about pagination.** The `/chats` and `/messages` quirks in [Pagination](/docs/pagination) are not guessable; an agent will write a walker that loses data unless it has read that page. --- # Async jobs (/docs/async-jobs) Anything that has to walk a platform API takes longer than a request should. Those operations return `202 Accepted` immediately and run in the background. ## The pattern [#the-pattern] ### Start the job [#start-the-job] ```bash curl -X POST "$BASE/api/crm/$CRM/accounts/$OFUID/subscribers/refresh" \ -H "X-API-Key: $KEY" ``` Returns `202` with the job or state payload. ### Watch it β€” poll or stream [#watch-it--poll-or-stream] Poll the matching status route: ```bash curl "$BASE/api/crm/$CRM/accounts/$OFUID/subscribers/refresh/status" \ -H "X-API-Key: $KEY" ``` The `/refresh/status` routes report **cache freshness**, not job progress β€” they return `{success, cache: {…}}` with no `status` or `phase`. To see whether a job is still running, use `GET /refresh/active`, or subscribe to [server-sent events](/docs/streaming) and watch `refresh.progress` / `refresh.complete`. The dashboard uses SSE. ### Read the result [#read-the-result] The job writes into the cache, so the result is just the corresponding `/cached` read β€” see [Cached reads](/docs/cached-reads). Exports instead produce a downloadable ZIP. ## The jobs [#the-jobs] | Start | Freshness check | What it does | | -------------------------------------------------- | ------------------------------- | ----------------------------------------------------------- | | `POST /accounts/{of_user_id}/subscribers/refresh` | `…/subscribers/refresh/status` | Delta-sync the subscriber cache | | `POST /accounts/{of_user_id}/transactions/refresh` | `…/transactions/refresh/status` | Delta-sync the transaction cache | | `POST /accounts/{of_user_id}/campaigns/refresh` | `…/campaigns/refresh/status` | Delta-sync campaigns and claimers | | `POST /accounts/{of_user_id}/backfill` | via `/refresh/active` | Backfill historical data | | `POST /accounts/{of_user_id}/exports` | `…/exports/{job_id}` | Build a data export ZIP β€” see [Data exports](/docs/exports) | Two panel-wide helpers: ``` GET /refresh/active # every running refresh job in the panel POST /accounts/{of_user_id}/refresh/{kind}/clear # clear a stuck job's state ``` ## One at a time, per account per kind [#one-at-a-time-per-account-per-kind] Starting a job while one of the same kind is already running is **not an error**. You get `202` with `already_running: true` and the in-flight job β€” `state` for refresh and backfill, `job` for exports. ```json { "success": true, "already_running": true, "state": { "…": "…" } } ``` Treat it as success. Retrying on it just spins. A **stale** job is superseded. The two clocks differ, and it matters: a refresh is abandoned after **10 minutes with no recorded progress** β€” a healthy long job keeps resetting that clock, so it never looks stale β€” while an export is abandoned **30 minutes after it started**, regardless of progress. The stale job is marked failed and yours starts fresh, so a crashed worker never blocks you permanently. Exports behave the same way; only the payload key differs: ```json { "success": true, "already_running": true, "job": { "job_id": "f01152d3…", "status": "running" } } ``` Treat `already_running: true` as success β€” something is already doing the work you wanted. No refresh or export route returns `409` for this; the `409`s that exist are for a different class of mistake, like downloading an export before it has finished. ## Don't poll tightly [#dont-poll-tightly] Refresh jobs finish in seconds to minutes depending on account size; exports with messages and media can take many minutes. Poll every few seconds at most, or use SSE and stop polling entirely. Status polls are **free** β€” they never touch the platform and carry no monthly quota cost. They do count against the per-minute rate limit, so do not spin on them. --- # Authentication (/docs/authentication) Send your key on every request: ```http X-API-Key: YOUR_API_KEY ``` That is the whole scheme for API clients. There are no bearer tokens and no request signing. Two other schemes exist but are not available to you: OAuth 2.1, used only by the [MCP server](/docs/ai-agents), and an internal `X-Service-Token` used by our own services calling each other. The API does not accept a key as a query parameter, even though one old error message mentions it. Keys in URLs end up in access logs, proxy logs and browser history. ## Keys are scoped to one panel [#keys-are-scoped-to-one-panel] A key authenticates you as a specific CRM panel. Passing a key that is valid but belongs to a **different** panel than the `{crm_id}` in the path is rejected the same way an invalid key is β€” there is no cross-panel access. Likewise, `{of_user_id}` must be an account connected to *your* panel: ```json { "error": "Account not found or does not belong to this CRM panel" } ``` Most routes answer that with a `403`, and it means the same thing whether the account does not exist or simply is not yours. A handful answer the same condition with `404 {"error": "Account not found"}` instead β€” `DELETE /accounts/{of_user_id}`, the `/proxy` read and update, the `/polling` read, and `/fansly-credentials`. Treat `403` and `404` on an account path as the same thing: not yours. ## Unscoped routes [#unscoped-routes] These seven carry no `{crm_id}` and are served by `https://api.theonlyapi.com` β€” not `theonlyapi.com`, which does not route them. "Unscoped" is not the same as "open": most still require something. | Route | What it needs | | ----------------------------------------- | ----------------------------------------------------------------------------- | | `GET /health` | nothing | | `POST /api/auth/login` | nothing (the credentials *are* the auth) | | `POST /api/auth/start-email-verification` | nothing | | `POST /api/auth/verify-email` | nothing | | `GET /api/whoami` | **an API key** β€” it resolves a key to its panel, it is just not scoped by one | | `POST /api/auth/register` | **a captcha** β€” see below | | `POST /api/crm/register` | **a captcha** β€” see below | See [Base URL & panels](/docs/base-url) for why the host differs. The two registration routes require either a Cloudflare Turnstile token (`captcha_token` in the body, or an `X-Captcha-Token` header) or an internal service token. Without one they return: ```json { "success": false, "code": "CAPTCHA_REQUIRED", "error": "Captcha verification is required to create an account.", "reason": "missing_token" } ``` Sign up through [the website](https://theonlyapi.com/pricing), which solves the captcha for you β€” see [Get an API key](/docs/get-an-api-key). There is no need to call either route yourself. ## Failure codes [#failure-codes] | Code | Body | What it means | | ----- | ---------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | | `403` | `{"error": "Invalid API key"}` | Key is unknown, revoked, or belongs to another panel | | `401` | `{"error": "Missing X-API-Key header…"}` | No key sent β€” note **401**, while an *invalid* key is 403 | | `403` | `{"error": "Account not found or does not belong to this CRM panel"}` | `of_user_id` is not connected to your panel | | `403` | `{"error": "…"}` | A secondary key attempted a primary-key-only operation | | `429` | `{"error": "Rate limit exceeded", "retry_after": "1000 per 1 minute"}` | Per-minute limit. `retry_after` echoes the limit that fired, **not** a number of seconds β€” use the `Retry-After` header for the delay | | `429` | `{"error": "API call limit reached", "plan": …, "limit": N}` | Monthly quota exhausted | | `403` | `{"code": "WRITES_DISABLED"}` | The account has `allow_of_write_actions` off β€” see [Connect an account](/docs/connect-an-account) | | `403` | `{"code": "SLOT_LIMIT"}` | Connecting an account beyond your plan's slots | | `403` | `{"code": "CAPTCHA_REQUIRED"}` | A registration route called without a captcha | | `404` | `{"error": "Account not found"}` | Same as the `403` above, on the few routes noted earlier | | `501` | `{"code": "platform_not_supported", "platform": …, "feature": …}` | The operation does not exist for that account's platform β€” see [OnlyFans & Fansly](/docs/platforms) | Invalid, revoked and wrong-panel keys all return the same `403`. Key comparison is constant-time, and unknown keys still run a dummy comparison, so response timing does not reveal whether a key exists. --- # Automations (/docs/automations) An automation is a rule stored on your panel: when an event of a given type arrives and every condition matches, run an action. No infrastructure needed on your side. ```bash curl -X POST "$BASE/api/crm/$CRM/automations" \ -H "X-API-Key: $KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "Thank big tippers on Discord", "trigger_event": "new_tip", "conditions": [ { "field": "payload.amount", "op": "gt", "value": 20 } ], "action_type": "discord", "action_params": { "url": "https://discord.com/api/webhooks/…", "message": "πŸ’Έ {payload.fan.username} tipped ${payload.amount}" }, "is_active": true }' ``` ## Conditions [#conditions] A list, joined with **AND**. Every condition must match for the action to run. An empty list matches every event of that type. ```json { "conditions": [ { "field": "payload.amount", "op": "gt", "value": 5 }, { "field": "payload.fan.username", "op": "neq", "value": "banned_user" } ] } ``` `field` is a dotted path into the [event envelope](/docs/events), so `event_type`, `of_user_id`, `occurred_at` and anything under `payload.` are all addressable. ### Operators [#operators] | `op` | Meaning | | ------------ | ------------------------------------------------ | | `eq` | equal | | `neq` | not equal | | `gt` / `gte` | greater than / or equal | | `lt` / `lte` | less than / or equal | | `contains` | substring | | `startswith` | prefix | | `in` | the field's value appears in the list you supply | ## Actions [#actions] | `action_type` | `action_params` | | ------------- | ------------------------------------------------------------------------------------------------------------------------- | | `webhook` | `{ "url", "method"?, "headers"?, "body"? }` β€” **unsigned and un-retried**, unlike a [first-party webhook](/docs/webhooks) | | `discord` | `{ "url", "message", "username"? }` | | `slack` | `{ "url", "message" }` | | `telegram` | `{ "bot_token", "chat_id", "message" }` | | `send_dm` | `{ "message", "to_fan_id"? }` β€” defaults to `payload.fan.id` | | `tag_fan` | `{ "tag": "vip" }` | ### Templating [#templating] Any `message` supports `{dotted.path}` interpolation against the event, resolved at dispatch: ``` "πŸ’Έ {payload.fan.username} tipped ${payload.amount} on {occurred_at}" ``` Templating applies to **every string** in `action_params` β€” `url`, `tag`, `to_fan_id`, nested objects and arrays β€” not just `message`. Credential keys (`bot_token`, `secret`, `token`, `api_key`, `password`) are deliberately excluded and passed through byte-for-byte. An unresolvable path renders as an **empty string**, not as literal `{…}`. A typo silently leaves a hole in the message (`"πŸ’Έ tipped $"`) rather than announcing itself β€” check the first delivery. `send_dm` is an OnlyFans write and is gated per account by `allow_of_write_actions`. Enable it via `PATCH /accounts/{of_user_id}/polling`. Otherwise the action is logged as a `failed` run in `GET /automations/{id}/runs` with `error_snippet: "send_dm blocked: account has allow_of_write_actions=false"`. There is no HTTP error to observe β€” automations run in the event fan-out, not in a request. See [Connect an account](/docs/connect-an-account). ## Managing automations [#managing-automations] ``` GET /automations # list POST /automations # create GET /automations/{id} # read one PATCH /automations/{id} # update (send {"is_active": false} to pause) DELETE /automations/{id} POST /automations/{id}/run-now # fire the action immediately, for testing GET /automations/{id}/runs # run history ``` `run-now` validates an action without waiting for a real event β€” but it builds a synthetic event from the `sample_payload` you supply, so **send one**. Without it the payload is empty, every `payload.*` condition fails, and the run is recorded as `skipped`. ```bash curl -X POST "$BASE/api/crm/$CRM/automations/$ID/run-now" \ -H "X-API-Key: $KEY" -H "Content-Type: application/json" \ -d '{"sample_payload": {"amount": 25, "fan": {"id": "987", "username": "somefan"}}}' ``` The response is `{"status": "success" | "skipped" | "failed"}`. `GET /runs` (default 50, max 200) has the history. `POST /automations` also accepts `of_user_id` to scope a rule to one connected account β€” the per-account routing that [webhooks](/docs/webhooks) cannot do. An unknown or misspelled `op` is accepted, then fails every comparison at dispatch, so the automation silently never fires. Check `/runs` after creating a rule. ## Worked examples [#worked-examples] ```json { "name": "VIP tagging", "trigger_event": "new_purchase", "conditions": [{ "field": "payload.amount", "op": "gte", "value": 100 }], "action_type": "tag_fan", "action_params": { "tag": "vip" } } ``` The tag then shows up in `GET /fans`, so you can segment on it later β€” including as a mass-DM audience filter. See [Messaging](/docs/messaging). ```json { "name": "Account needs reconnecting", "trigger_event": "polling_paused", "conditions": [], "action_type": "telegram", "action_params": { "bot_token": "123456:ABC…", "chat_id": "-1001234567890", "message": "⚠️ Polling paused for {of_user_id} β€” {payload.reason} ({payload.failures} failures)" } } ``` This is the single most useful automation to set up first. It is the earliest reliable signal that a session has died β€” see [Sessions](/docs/sessions). ```json { "name": "Welcome DM", "trigger_event": "new_subscriber", "conditions": [], "action_type": "send_dm", "action_params": { "message": "Hey {payload.fan.display_name}, thanks for subscribing πŸ’•", "to_fan_id": "{payload.fan.id}" } } ``` Note `to_fan_id` is templated from the event, so one rule covers every new subscriber. ## Automations, webhooks, or your own code? [#automations-webhooks-or-your-own-code] Automations are the right tool when the reaction is a notification or a simple one-step side effect. Once you need branching logic, external data, or state, use a [webhook](/docs/webhooks) and do the work in your own service. Both run from the same event emission, so you can use them together β€” an automation for the Discord ping, a webhook for your database. --- # Base URL & panels (/docs/base-url) ``` https://theonlyapi.com/api/crm/{crm_id} ``` `{crm_id}` is your panel ID β€” a string like `crm_0123456789abcdef`, shown in **Dashboard β†’ Settings**. If you only have an API key, resolve it: ```bash curl "https://api.theonlyapi.com/api/whoami" -H "X-API-Key: $KEY" ``` ## The panel is the tenant boundary [#the-panel-is-the-tenant-boundary] A panel owns: * its API keys (one primary, any number of secondary) * its connected creator accounts β€” one **slot** per account, each with its own persisted session and proxy * its events, webhooks, automations, exports and cached data Nothing crosses panels. A key for panel A cannot read panel B, and `{of_user_id}` must belong to the panel in the path. ## Unscoped routes use a different host [#unscoped-routes-use-a-different-host] Seven routes are not panel-scoped. They live on the **API host**, not the marketing host: ``` https://api.theonlyapi.com/health https://api.theonlyapi.com/api/whoami https://api.theonlyapi.com/api/auth/register https://api.theonlyapi.com/api/auth/login https://api.theonlyapi.com/api/auth/start-email-verification https://api.theonlyapi.com/api/auth/verify-email https://api.theonlyapi.com/api/crm/register ``` `theonlyapi.com` is a Next.js app that proxies `/api/crm/{crm_id}/…` through to the API. It does **not** route the unscoped paths, and two of them collide with its own routes: | Route on `theonlyapi.com` | What you actually get | | ------------------------- | --------------------------------------------------------------------------------------------------------------- | | `GET /health` | `404` | | `GET /api/whoami` | `404` | | `POST /api/crm/register` | `{"error": "Unauthorized"}` | | `POST /api/auth/*` | `Error: This action with HTTP POST is not supported by NextAuth.js` β€” the site's own auth handler answers first | Use `api.theonlyapi.com` for all seven. In this reference those endpoints are documented with their full path, and their "Test it" server is `api.theonlyapi.com` rather than the panel-scoped base URL. ## Path anatomy [#path-anatomy] ``` https://theonlyapi.com/api/crm/crm_abc123/accounts/482687148/chats └──────── origin β”€β”€β”€β”€β”˜β””β”€ panel scope β”€β”€β”˜β””β”€β”€β”€β”€ resource β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` Most resources hang off a connected account: ``` /accounts/{of_user_id}/balances /accounts/{of_user_id}/subscribers/cached /accounts/{of_user_id}/chats/{with_user_id}/messages ``` A few are panel-wide, aggregating across every connected account: ``` /fans /balances/summary /earnings/summary /events /webhooks /automations ``` And the passthrough mirrors OnlyFans' own paths verbatim after the prefix: ``` /api2/v2/users/me /api2/v2/subscriptions/subscribers?limit=10&type=active ``` Despite the name, `of_user_id` identifies a connected account on **either** platform. A Fansly account's ID is returned and used as `of_user_id` too. Get the list from `GET /accounts`. ## Which host to use [#which-host-to-use] | Routes | Host | | ----------------------------------------------- | ---------------------------- | | Everything panel-scoped β€” `/api/crm/{crm_id}/…` | `https://theonlyapi.com` | | The seven unscoped routes above | `https://api.theonlyapi.com` | `api.theonlyapi.com` reaches the API directly and serves the panel-scoped routes too, so it works for both if you would rather use one host everywhere. The panel-scoped examples in these docs use `theonlyapi.com` because that is the documented product base URL. --- # Bulk account import (/docs/bulk-import) Connecting accounts one at a time is fine for a handful. For an agency onboarding dozens, paste them all at once: the importer parses the paste, tells you exactly what will happen before touching anything, then works through the rows in the background β€” parking any that need a 2FA code until you supply one. All eight routes are panel-scoped and authenticated like every other CRM route β€” see the [Bulk Import reference](/docs/crm/bulk-import) for full request and response schemas. ## The flow [#the-flow] ### Preview β€” no side effects [#preview--no-side-effects] ```bash curl -X POST "$BASE/api/crm/$CRM/import/preview" \ -H "X-API-Key: $KEY" \ -H "Content-Type: application/json" \ -d '{ "text": "creator1@example.com,hunter2,http://user:pass@host:port\ncreator2@example.com,hunter3", "default_platform": "onlyfans" }' ``` Nothing is written and no login is attempted. You get back what the importer *would* do: the detected format, which rows are valid, which lane each takes, and precisely why row 47 is bad. ```json { "success": true, "format": "bare", "delimiter": ",", "has_header": false, "columns": ["email", "password", "proxy"], "total": 2, "valid_count": 2, "invalid_count": 0, "rows": [ { "row_index": 0, "email": "creator1@example.com", "platform": "onlyfans", "lane": "password", "proxy": "host:port", "has_password": true, "has_totp_secret": false, "cookie_fields": [], "valid": true, "errors": [] } ] } ``` Passwords and TOTP secrets come back as booleans (`has_password`, `has_totp_secret`), cookies as a list of field *names*, and the proxy as `host:port` only β€” the credentials are stripped. The paste already crossed the network once; reflecting it back would double the exposure for no benefit. Always preview first. It is free, it costs no platform requests, and it is the only chance to catch a malformed paste before logins start. ### Create the job [#create-the-job] Same body, plus an optional `source`: ```bash curl -X POST "$BASE/api/crm/$CRM/import/jobs" \ -H "X-API-Key: $KEY" \ -H "Content-Type: application/json" \ -d '{"text": "…", "default_platform": "onlyfans", "source": "paste"}' ``` Returns `202` with the job, and dispatches a background worker. Up to **1,000 rows** per job by default. ### Watch it [#watch-it] Progress arrives on the [event stream](/docs/streaming) as `import.progress` (coalesced to at most one per second) and finishes with `import.complete`: ```bash curl -N "$BASE/api/crm/$CRM/events/stream" -H "X-API-Key: $KEY" ``` Or poll: ```bash curl "$BASE/api/crm/$CRM/import/jobs/$JOB_ID" -H "X-API-Key: $KEY" # one job curl "$BASE/api/crm/$CRM/import/jobs" -H "X-API-Key: $KEY" # history ``` ### Answer the 2FA prompts [#answer-the-2fa-prompts] Rows whose platform demands a code **park** rather than fail, with status `needs_2fa`. Supply the code and that row finishes: ```bash curl -X POST "$BASE/api/crm/$CRM/import/jobs/$JOB_ID/rows/$ROW_ID/otp" \ -H "X-API-Key: $KEY" \ -H "Content-Type: application/json" \ -d '{"code": "123456"}' ``` This call is **synchronous** β€” one platform call, and the response carries the real outcome rather than "queued", because someone is waiting on it. ## Parked rows outlive the job [#parked-rows-outlive-the-job] ```bash curl "$BASE/api/crm/$CRM/import/pending-2fa?limit=200" -H "X-API-Key: $KEY" ``` Panel-wide, across every job. This is what lets a dashboard say "3 accounts need a 2FA code" long after whoever started the import has closed the tab β€” a per-job query could not answer that. ## Retry and cancel [#retry-and-cancel] ```bash # Retry one failed row curl -X POST "$BASE/api/crm/$CRM/import/jobs/$JOB_ID/rows/$ROW_ID/retry" \ -H "X-API-Key: $KEY" # Stop the whole job curl -X POST "$BASE/api/crm/$CRM/import/jobs/$JOB_ID/cancel" -H "X-API-Key: $KEY" ``` ## Lanes [#lanes] Every valid row is routed down one of two lanes, decided by what you supplied: | Lane | Triggered by | Behaviour | | ---------- | -------------------------------------- | ----------------------------------------------- | | `cookie` | Session cookies or a Fansly auth token | Session paste β€” no login attempt, most reliable | | `password` | An email/username and password | Full login flow, may park on 2FA | Prefer `cookie` rows where you have them, for the same reasons given in [Connect an account](/docs/connect-an-account). ## Row statuses [#row-statuses] | Status | Meaning | | ------------------- | ---------------------------------------------------------------------------------- | | `pending` | Parsed and accepted, not yet claimed | | `running` | Login in flight | | `needs_2fa` | Parked β€” waiting for you to post a code | | `needs_2fa_expired` | The 2FA window closed and the credential was destroyed; `retry` restarts the login | | `success` | Account connected | | `failed` | Gave up; see the row's error | | `invalid` | Failed parse validation β€” never attempted | | `skipped` | That email is already connected to this panel | | `slot_exhausted` | Plan account limit reached | | `canceled` | Job canceled before this row ran | There is no `queued` and no `complete` β€” success is `success`. The authoritative list comes back as `row_states` on `GET /import/jobs/{job_id}`. ## Endpoints [#endpoints] | Endpoint | What it does | | ----------------------------------------------------------------------------------------------------------- | --------------------------------- | | [`POST /import/preview`](/docs/crm/bulk-import/preview-an-import-paste) | Parse + validate, no side effects | | [`POST /import/jobs`](/docs/crm/bulk-import/start-a-bulk-import) | Create a job β†’ `202` | | [`GET /import/jobs`](/docs/crm/bulk-import/list-import-jobs) | Job history | | [`GET /import/jobs/{job_id}`](/docs/crm/bulk-import/get-an-import-job) | One job, with rows | | [`POST /import/jobs/{job_id}/cancel`](/docs/crm/bulk-import/cancel-an-import-job) | Stop a running job | | [`POST /import/jobs/{job_id}/rows/{row_id}/otp`](/docs/crm/bulk-import/supply-a-2fa-code-for-an-import-row) | Supply a 2FA code (synchronous) | | [`POST /import/jobs/{job_id}/rows/{row_id}/retry`](/docs/crm/bulk-import/retry-an-import-row) | Retry one row | | [`GET /import/pending-2fa`](/docs/crm/bulk-import/list-rows-waiting-on-a-2fa-code) | Panel-wide parked rows | All writes are on the 100/minute sensitive-route limit. Each connected account consumes a slot. A row that hits the cap ends as `slot_exhausted` (not `failed`) with `Account limit reached (N). Buy a slot to add another account.` and `code: "SLOT_LIMIT"`. The check is a read, not a reservation, so up to the lane concurrency (10 cookie / 6 password) rows can all observe the same last free slot and proceed β€” a panel can end up slightly over its cap. Check `GET /api/crm/{crm_id}/usage` first. --- # Cached reads (/docs/cached-reads) Every live read reaches OnlyFans or Fansly and counts against **their** per-account rate limits β€” the ones that get accounts flagged. The `/cached` routes serve from our own store instead and cost **zero** platform requests. For anything you read repeatedly β€” dashboards, reports, reconciliation, any loop β€” use the cached route. ## The cached routes [#the-cached-routes] | Route | Returns | | -------------------------------------------------------------------- | ---------------------------------------------------------------- | | `GET /accounts/{of_user_id}/subscribers/cached` | Subscriber snapshot, paginated | | `GET /accounts/{of_user_id}/subscribers/new` | Newly seen subscribers | | `GET /accounts/{of_user_id}/subscribers/stats` | Aggregated counts by `granularity` (`hour`/`day`/`week`/`month`) | | `GET /accounts/{of_user_id}/transactions/cached` | Transaction rows, paginated | | `GET /accounts/{of_user_id}/fans/{fan_id}/transactions/cached` | One fan's transactions | | `GET /accounts/{of_user_id}/campaigns/{campaign_id}/claimers/cached` | Campaign claimers | All of them except `/subscribers/stats` use offset pagination with a trustworthy `total` β€” convention 1 in [Pagination](/docs/pagination). Note the rows come back under a generic `list` key, not one named after the resource. `/subscribers/stats` is not paginated at all: it returns a zero-filled `buckets` array plus `total_in_window`. ```bash curl "$BASE/api/crm/$CRM/accounts/$OFUID/subscribers/cached?limit=100&offset=0" \ -H "X-API-Key: $KEY" ``` ## Keeping the cache fresh [#keeping-the-cache-fresh] Two things update it. **Background polling.** Connected accounts are polled on a schedule. This is what generates [events](/docs/events) β€” new tips, subscribers, messages, balance changes β€” and it keeps the caches moving without you asking. **Explicit refresh.** When you need current data right now, kick off an [async refresh job](/docs/async-jobs): ```bash curl -X POST "$BASE/api/crm/$CRM/accounts/$OFUID/subscribers/refresh" \ -H "X-API-Key: $KEY" # 202 β†’ poll .../subscribers/refresh/status ``` Refreshes are **delta syncs** β€” they fetch what changed rather than re-walking everything, so they are cheap enough to run on a schedule. For history that predates the account being connected, use `POST /accounts/{of_user_id}/backfill`. ## A sensible read pattern [#a-sensible-read-pattern] ```python # 1. Trigger a refresh only when your data is older than you can tolerate. if cache_age_seconds > 300: session.post(f"{BASE}/api/crm/{CRM}/accounts/{OFUID}/subscribers/refresh", headers={"X-API-Key": KEY}) # 2. Read from the cache regardless β€” it always answers, and costs nothing # against the platform. The refresh will land shortly. rows = list(walk(session, f"{BASE}/api/crm/{CRM}/accounts/{OFUID}/subscribers/cached", KEY, item_key="list")) ``` Do not block on the refresh finishing before reading. Read the cache, and let either the next refresh or the background poller catch you up. If you need to know the moment new data lands, subscribe to [events](/docs/streaming) instead of polling status. `GET` and `PATCH /accounts/{of_user_id}/polling` control what we poll for an account, and how often. The same object holds `allow_of_write_actions`, the gate on OnlyFans write operations β€” see [Connect an account](/docs/connect-an-account). ## When to read live instead [#when-to-read-live-instead] Reach for the live route when staleness is genuinely unacceptable β€” confirming a balance right before a payout, or checking whether a specific message landed. Live routes are `GET /accounts/{of_user_id}/subscribers`, `/balances`, `/earnings`, `/purchases`, `/chats`, and the whole `/api2/v2/*` passthrough. Even then, do it once, not in a loop. --- # Connect an account (/docs/connect-an-account) Before you can read or write anything for a creator, that account has to be connected to your panel. Each connected account occupies one **slot**. There are two ways in. Session paste is more reliable and is what we recommend. ## Option A β€” session paste (recommended) [#option-a--session-paste-recommended] Open a browser logged into OnlyFans, then **DevTools β†’ Application β†’ Cookies β†’ onlyfans.com** and copy `sess` and `auth_id` (and `fp` if present). ```bash curl -X POST "$BASE/api/crm/$CRM/accounts/login/cookies" \ -H "X-API-Key: $KEY" \ -H "X-Proxy: http://user:pass@host:port" \ -H "Content-Type: application/json" \ -d '{ "platform": "onlyfans", "sess": "", "auth_id": "", "fp": "" }' ``` Omitting `X-Proxy` does **not** return an error. The login proceeds and egresses on our shared server IP, and the saved session records **no** proxy β€” so every later request for that account also goes out direct. The failure surfaces later, as a session that keeps breaking. A malformed proxy is silently downgraded to none rather than rejected, so a typo degrades to direct egress with no signal. OnlyFans ties sessions to the IP that created them. See [Proxies](/docs/proxies). Paste an auth token rather than cookies. `X-Proxy` is optional. ```bash curl -X POST "$BASE/api/crm/$CRM/accounts/login/cookies" \ -H "X-API-Key: $KEY" \ -H "Content-Type: application/json" \ -d '{ "platform": "fansly", "auth_token": "", "fansly_session_id": "", "fansly_client_id": "" }' ``` The session is stored server-side. You never pass cookies or tokens again β€” from here on, the `of_user_id` is enough. ## Option B β€” credentials [#option-b--credentials] We run the whole login flow for you: Cloudflare init, Turnstile solve, signed login request, and a 2FA prompt if the platform asks for one. ```bash curl -X POST "$BASE/api/crm/$CRM/accounts/login" \ -H "X-API-Key: $KEY" \ -H "X-Proxy: http://user:pass@host:port" \ -H "Content-Type: application/json" \ -d '{ "platform": "onlyfans", "email": "creator@example.com", "password": "…", "use_captcha": true }' ``` For `platform: "fansly"` the `email` field accepts a **username or an email**, `X-Proxy` is optional, and `use_captcha` is ignored β€” Fansly's login has no captcha step. ### Two-factor authentication [#two-factor-authentication] If the platform demands 2FA, the response includes `requires_2fa: true` (Fansly additionally returns `twofa_type`). Submit the code to `POST /accounts/login/verify-otp`, passing the **same** `platform`, the **same** identifier you logged in with. You do **not** need to resend `X-Proxy` β€” the proxy stored with the parked 2FA challenge is reused, and the header is ignored here: ```bash curl -X POST "$BASE/api/crm/$CRM/accounts/login/verify-otp" \ -H "X-API-Key: $KEY" \ -H "X-Proxy: http://user:pass@host:port" \ -H "Content-Type: application/json" \ -d '{"platform": "onlyfans", "email": "creator@example.com", "otp_code": "123456"}' ``` This route reads `otp_code` only β€” sending `code` returns `400 OTP code required`. (The unrelated [bulk-import](/docs/bulk-import) OTP route accepts either spelling, which makes the inconsistency easy to trip over.) Each of the three connection routes gets its own allowance of **20 requests per minute**. They are counted separately, so in one minute you could paste 20 sessions *and* attempt 20 credential logins *and* submit 20 OTP codes. The count is per API key, so it is your panel's budget alone β€” other customers cannot use it up. Going over returns `429` until the minute rolls over. The practical consequence: do not retry a failed login in a loop. Twenty quick retries and you have spent the allowance and locked yourself out of connecting anything for the rest of that minute. ## Connecting many at once [#connecting-many-at-once] For more than a handful of accounts, paste them all and let the importer work through them β€” including parking rows that need a 2FA code until you supply one. See [Bulk account import](/docs/bulk-import). ## After connecting [#after-connecting] `GET /accounts` lists connected accounts and their IDs: ```bash curl "$BASE/api/crm/$CRM/accounts" -H "X-API-Key: $KEY" ``` Add `?include_session=true` and each **OnlyFans** entry also carries a `session` block with `sess`, `auth_id` and `proxy` β€” present only when a stored session file exists; a read failure yields `session_error` instead. Fansly accounts never get one; use `GET /accounts/{of_user_id}/fansly-credentials` for those. You rarely need either β€” passing `of_user_id` and letting us resolve the session is the point. ## Disconnecting [#disconnecting] ```bash curl -X DELETE "$BASE/api/crm/$CRM/accounts/$OFUID" -H "X-API-Key: $KEY" ``` This frees the slot. Add `?purge=true` to also delete the account's retained data rather than keeping it. ## Write actions are off until you enable them [#write-actions-are-off-until-you-enable-them] Connecting an account does not by itself allow us to *act* as it. Every write performed as the account is gated by the `allow_of_write_actions` polling setting: ```bash curl -X PATCH "$BASE/api/crm/$CRM/accounts/$OFUID/polling" \ -H "X-API-Key: $KEY" \ -H "Content-Type: application/json" \ -d '{"allow_of_write_actions": true}' ``` Without it, writes return `403` with `code: "WRITES_DISABLED"`. Match on the code, not the message. The gate now covers **every OnlyFans or Fansly write performed as the account**: single DM/PPV sends (both platforms), the mass-DM real send, the `send_dm` automation action, payout requests, subscription-price changes, creating a campaign, the raw `POST /accounts/{of_user_id}/request` proxy when its body `method` is not `GET`, and **any non-GET request through the `/api2/v2/*` passthrough**. Reads are never gated. --- # CRM API (/docs/crm) {/* Generated by scripts/gen-api.ts β€” edit that script, not this file. */} Endpoints on this surface return **normalized** data: OnlyFans and Fansly rows are projected to the same shape, and several routes are server-side aggregations with no platform equivalent at all. Base URL `https://theonlyapi.com/api/crm/{crm_id}`, authenticated with an `X-API-Key` header. Responses put data in a sibling key alongside `success` rather than nesting it β€” see [Responses & errors](/docs/responses). This is the surface to build on. Reach for the [OnlyFans passthrough](/docs/of-api) only when you need something here does not cover. Connect a creator account (OnlyFans or Fansly) and complete 2FA. All three routes accept `platform: "onlyfans" | "fansly"` and are rate limited to 10 requests/minute. Manage connected creator accounts (OnlyFans and Fansly), their polling settings, proxies, and slots. Panel signup, health, keyβ†’panel resolution, and plan/usage counters. Works for OnlyFans and Fansly panels alike. Primary + secondary API key management. `POST /api-keys` and `DELETE /api-keys/{key_id}` are PRIMARY-KEY ONLY (a secondary key gets 403). The primary `Default` key cannot be revoked β€” rotate it via `POST /rotate-key`. Revenue & earnings data, including the cross-account `GET /earnings/summary` aggregation. Fansly-aware. Payout & purchase transactions, live and cached. Withdrawal requests and payout account details. Creating a withdrawal is OnlyFans only. OnlyFans referral programme β€” who the account referred, what it earned, and referral payout history. **OnlyFans only**: Fansly accounts get `501 platform_not_supported` (`feature: "referrals"`). Live reads, no cache; one quota call per request. OnlyFans' referral response bodies are passed through with minimal normalization β€” only the `list`/`hasMore`/`marker` envelope keys are read, and the raw body is echoed under `data`. Fields *inside* a referral row are unverified: do not depend on them without checking against a live account. Subscriber reads. Live routes hit the platform; `/subscribers/cached`, `/subscribers/new`, and `/subscribers/stats` cost zero platform requests and normalize OnlyFans + Fansly rows to the same shape. Fan CRM across all accounts in the panel β€” tags, notes, per-fan cached transactions, profile refresh. Fansly-aware. Chats, single DMs/PPVs, mass DMs, and PPV performance stats. Fansly-aware. Media upload. Runs OnlyFans' four-stage signed-S3 pipeline server-side and returns a reference you attach to a post, message or story via `mediaFiles`. OnlyFans only. Tracking link campaigns, claimers, campaign tags, and the tracked-campaign allowlist. Account notifications. Fansly-aware. Async refresh, backfill, and job-status routes that populate the local cache. Refresh routes return 202 β€” poll the matching `/refresh/status` route or listen on `GET /events/stream`. Real-time event feed β€” `GET /events` for polling, `GET /events/stream` for Server-Sent Events (rate-limit exempt). Outbound webhook subscriptions, test fires, and delivery history. Event-triggered automations, manual runs, and run history. Async data export jobs producing a downloadable ZIP. Progress streams over `GET /events/stream`. Third-party integrations. One Telegram channel per panel: pair it once, then matching events are delivered to that chat. The bot token is encrypted at rest and is never returned by any route. Account settings, subscription price & proxy management Generic authenticated OnlyFans API proxy (`POST /accounts/{of_user_id}/request`). OnlyFans only. Hosted MCP server support. `GET /api/whoami` turns a bearer token into a tenant; `PATCH /mcp/unsafe-proxy` toggles non-GET tool access (off by default). Connect many creator accounts from one pasted list. `POST /import/preview` validates without side effects; `POST /import/jobs` runs the import in the background and streams `import.progress` / `import.complete` over `GET /events/stream`. Rows that hit a 2FA prompt park as `needs_2fa` until you supply a code. *116 endpoints, generated from the [OpenAPI 3.1 spec](https://theonlyapi.com/api/openapi.json).* --- # Accounts (/docs/crm/accounts) {/* Generated by scripts/gen-api.ts β€” edit that script, not this file. */} Manage connected creator accounts (OnlyFans and Fansly), their polling settings, proxies, and slots. | Method | Endpoint | Path | | -------- | --------------------------------------------------------------------------------------------------- | ------------------------------------------- | | `GET` | [List connected accounts](/docs/crm/accounts/list-connected-accounts) | `/accounts` | | `DELETE` | [Disconnect an account](/docs/crm/accounts/disconnect-an-account) | `/accounts/{of_user_id}` | | `GET` | [Read a Fansly account's stored session](/docs/crm/accounts/read-a-fansly-account-s-stored-session) | `/accounts/{of_user_id}/fansly-credentials` | | `GET` | [Get polling settings](/docs/crm/accounts/get-polling-settings) | `/accounts/{of_user_id}/polling` | | `PATCH` | [Update polling settings](/docs/crm/accounts/update-polling-settings) | `/accounts/{of_user_id}/polling` | | `POST` | [Tag a connected account](/docs/crm/accounts/tag-a-connected-account) | `/accounts/{of_user_id}/tags` | | `DELETE` | [Remove an account tag](/docs/crm/accounts/remove-an-account-tag) | `/accounts/{of_user_id}/tags/{tag}` | --- # Disconnect an account (/docs/crm/accounts/disconnect-an-account) `DELETE https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}` Delete/disconnect a creator account from this CRM panel, freeing its slot. Works for OnlyFans and Fansly accounts. This is the only way to release a paid slot. **Guide:** [Connect an account](/docs/connect-an-account) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `of_user_id` (string, required) β€” Creator account ID of the connected account (OnlyFans or Fansly). Use `GET /accounts` to list connected accounts and their IDs. ## Responses ### 200 β€” Account disconnected and its slot released - `success` (boolean) β€” e.g. `true`. ### 404 β€” Account not found in this panel ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}" \ -H "X-API-Key: " ``` --- # Get polling settings (/docs/crm/accounts/get-polling-settings) `GET https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/polling` Read the background polling configuration for an account β€” whether polling is enabled, the interval, and whether write actions are allowed. **Guide:** [Connect an account](/docs/connect-an-account) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `of_user_id` (string, required) β€” Creator account ID of the connected account (OnlyFans or Fansly). Use `GET /accounts` to list connected accounts and their IDs. ## Responses ### 200 β€” Polling settings - `success` (boolean) - `polling` (object) - `enabled` (boolean) - `interval_seconds` (integer) - `allow_of_write_actions` (boolean) ### 404 β€” Account not found ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/polling" \ -H "X-API-Key: " ``` --- # List connected accounts (/docs/crm/accounts/list-connected-accounts) `GET https://theonlyapi.com/api/crm/your-crm-id/accounts` Returns every creator account connected to this CRM panel β€” OnlyFans and Fansly. Each entry carries `of_user_id`, `username`, and `platform` (`"onlyfans"` or `"fansly"`). Use `of_user_id` as the `{of_user_id}` path parameter and as the `user-id` header elsewhere in this API. **Guide:** [Connect an account](/docs/connect-an-account) ## Authentication - `X-API-Key` header (apiKey) ## Query parameters - `include_session` (boolean) β€” Include the per-account session block (`sess`, `auth_id`, `proxy`) in each entry. Default `false`. ## Responses ### 200 β€” Account list - `success` (boolean) - `count` (integer) - `accounts` (object[]) - `of_user_id` (string) - `username` (string) - `platform` ("onlyfans" | "fansly") - `session` (object) β€” Only present when `include_session=true`. - `sess` (string) - `auth_id` (string) - `proxy` (string) Example response: ```json { "success": true, "count": 2, "accounts": [ { "of_user_id": "482687148", "username": "creator_one", "platform": "onlyfans" }, { "of_user_id": "739104882", "username": "creator_two", "platform": "fansly" } ] } ``` ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/accounts" \ -H "X-API-Key: " ``` --- # Read a Fansly account's stored session (/docs/crm/accounts/read-a-fansly-account-s-stored-session) `GET https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/fansly-credentials` Return the **current** Fansly session for one account you own, so an external worker can pick up refreshed tokens instead of holding a stale copy. We stay the credential authority: we are the thing that re-logs in and rewrites these tokens, so a caller that re-reads here each run is always current. Read-only β€” it mutates nothing, and is gated by the same API key and ownership checks as every other account route. **Fansly only**; an OnlyFans account returns `400`. **Guide:** [Connect an account](/docs/connect-an-account) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `of_user_id` (string, required) β€” Creator account ID of the connected account (OnlyFans or Fansly). Use `GET /accounts` to list connected accounts and their IDs. ## Responses ### 200 Current session material: `auth_token`, `session_id`, `client_id`, and the account's `proxy`. - `auth_token` (any, required) - `client_id` (any, required) - `of_user_id` (string, required) - `platform` (string, required) - `proxy` (string, required) - `session_id` (any, required) - `success` (boolean, required) - `username` (string, required) ### 400 β€” Not a Fansly account. ### 403 β€” Account does not belong to this panel. ### 404 Account not found, or no Fansly session is stored yet β€” connect it first. ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/fansly-credentials" \ -H "X-API-Key: " ``` --- # Remove an account tag (/docs/crm/accounts/remove-an-account-tag) `DELETE https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/tags/{tag}` Remove a tag from a connected account. Pass the tag exactly as the API returned it β€” the stored form is escaped once on the way in, so re-escaping it here would look for a different string and silently delete nothing. `success: false` means there was no such tag. **Guide:** [Connect an account](/docs/connect-an-account) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `of_user_id` (string, required) β€” Creator account ID of the connected account (OnlyFans or Fansly). Use `GET /accounts` to list connected accounts and their IDs. - `tag` (string, required) β€” The tag, exactly as returned by the API. ## Responses ### 200 β€” `success` reports whether a tag was actually removed. - `success` (boolean, required) ### 400 β€” Missing tag, or longer than 40 characters. ### 403 β€” Account does not belong to this panel. ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/tags/{tag}" \ -H "X-API-Key: " ``` --- # Tag a connected account (/docs/crm/accounts/tag-a-connected-account) `POST https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/tags` Add a tag to a connected account, for grouping creators inside the panel. Tags are panel-local β€” they are never sent to the platform. Max 40 characters; re-adding an existing tag is a no-op. **Guide:** [Connect an account](/docs/connect-an-account) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `of_user_id` (string, required) β€” Creator account ID of the connected account (OnlyFans or Fansly). Use `GET /accounts` to list connected accounts and their IDs. ## Request body Content type: `application/json` (required) - `tag` (string, required) β€” e.g. `"vip"`. ## Responses ### 200 β€” The stored tag Send this exact string back when deleting it. - `success` (boolean, required) - `tag` (any, required) ### 400 β€” Missing tag, or longer than 40 characters. ### 403 β€” Account does not belong to this panel. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/tags" \ -H "X-API-Key: " \ -H "Content-Type: application/json" \ -d '{"tag":"vip"}' ``` --- # Update polling settings (/docs/crm/accounts/update-polling-settings) `PATCH https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/polling` Enable/disable background polling for an account, set the interval, and control whether automations may perform write actions on the platform. **Guide:** [Connect an account](/docs/connect-an-account) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `of_user_id` (string, required) β€” Creator account ID of the connected account (OnlyFans or Fansly). Use `GET /accounts` to list connected accounts and their IDs. ## Request body Content type: `application/json` (required) - `enabled` (boolean) - `interval_seconds` (integer) β€” Polling interval in seconds (60–3600). - `allow_of_write_actions` (boolean) β€” Allow automations to send DMs and other writes for this account. ## Responses ### 200 β€” Polling settings updated - `polling` (object, required) - `allow_of_write_actions` (integer) - `last_polled_at` (string) - `of_user_id` (string) - `polling_enabled` (integer) - `polling_failure_count` (integer) - `polling_interval_seconds` (integer) - `success` (boolean, required) - `warning` (string) ### 400 β€” interval_seconds out of range (60–3600) ## Example ```bash curl -X PATCH "https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/polling" \ -H "X-API-Key: " \ -H "Content-Type: application/json" \ -d '{}' ``` --- # API Keys (/docs/crm/api-keys) {/* Generated by scripts/gen-api.ts β€” edit that script, not this file. */} Primary + secondary API key management. `POST /api-keys` and `DELETE /api-keys/{key_id}` are PRIMARY-KEY ONLY (a secondary key gets 403). The primary `Default` key cannot be revoked β€” rotate it via `POST /rotate-key`. | Method | Endpoint | Path | | -------- | --------------------------------------------------------------------------- | -------------------------- | | `GET` | [List API keys](/docs/crm/api-keys/list-api-keys) | `/api-keys` | | `POST` | [Create a secondary API key](/docs/crm/api-keys/create-a-secondary-api-key) | `/api-keys` | | `DELETE` | [Revoke a secondary API key](/docs/crm/api-keys/revoke-a-secondary-api-key) | `/api-keys/{key_id}` | | `GET` | [Per-key usage detail](/docs/crm/api-keys/per-key-usage-detail) | `/api-keys/{key_id}/usage` | | `POST` | [Rotate your API key](/docs/crm/api-keys/rotate-your-api-key) | `/rotate-key` | --- # Create a secondary API key (/docs/crm/api-keys/create-a-secondary-api-key) `POST https://theonlyapi.com/api/crm/your-crm-id/api-keys` Mint a new secondary API key. **PRIMARY-KEY ONLY** β€” calling this with a secondary key returns `403`. The full key is returned **exactly once**, in this response, and is never retrievable again. **Guide:** [Get an API key](/docs/get-an-api-key) ## Authentication - `X-API-Key` header (apiKey) ## Request body Content type: `application/json` - `name` (string) β€” Default `"Untitled key"`. e.g. `"CI pipeline"`. ## Responses ### 201 β€” Key created β€” `api_key` is shown only here - `success` (boolean) - `id` (integer) - `name` (string) - `prefix` (string) - `api_key` (string) - `created_at` (string) ### 403 β€” Not the primary key ### 404 β€” CRM panel not found ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api-keys" \ -H "X-API-Key: " \ -H "Content-Type: application/json" \ -d '{"name":"CI pipeline"}' ``` --- # List API keys (/docs/crm/api-keys/list-api-keys) `GET https://theonlyapi.com/api/crm/your-crm-id/api-keys` List all API keys for the panel (active + revoked), each with this-month request count and a 30-day series. Full key bodies are never returned β€” only a prefix. **Guide:** [Get an API key](/docs/get-an-api-key) ## Authentication - `X-API-Key` header (apiKey) ## Responses ### 200 β€” Key list - `success` (boolean) - `keys` (object[]) - `id` (integer) - `name` (string) - `prefix` (string) - `is_primary` (boolean) - `created_at` (string) - `last_used_at` (string) - `revoked_at` (string) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api-keys" \ -H "X-API-Key: " ``` --- # Per-key usage detail (/docs/crm/api-keys/per-key-usage-detail) `GET https://theonlyapi.com/api/crm/your-crm-id/api-keys/{key_id}/usage` 30/90-day usage series, month and all-time totals, last-used timestamp, and this month's endpoint breakdown for one key. **Guide:** [Get an API key](/docs/get-an-api-key) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `key_id` (integer, required) ## Query parameters - `days` (integer) β€” Default `30`. ## Responses ### 200 β€” Usage detail - `success` (boolean) - `key` (object) - `totals` (object) - `series` (object[]) - `breakdown` (object[]) ### 404 β€” Key not found ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api-keys/{key_id}/usage" \ -H "X-API-Key: " ``` --- # Revoke a secondary API key (/docs/crm/api-keys/revoke-a-secondary-api-key) `DELETE https://theonlyapi.com/api/crm/your-crm-id/api-keys/{key_id}` Revoke a secondary key. **PRIMARY-KEY ONLY** β€” calling this with a secondary key returns `403`. The primary `Default` key is non-revocable; rotate it via `POST /rotate-key` instead. **Guide:** [Get an API key](/docs/get-an-api-key) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `key_id` (integer, required) ## Responses ### 200 β€” Key revoked - `success` (boolean, required) ### 403 β€” Not the primary key ### 404 β€” Key not found, already revoked, or non-revocable (primary) ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/api-keys/{key_id}" \ -H "X-API-Key: " ``` --- # Rotate your API key (/docs/crm/api-keys/rotate-your-api-key) `POST https://theonlyapi.com/api/crm/your-crm-id/rotate-key` Rotate (regenerate) the caller's own API key. Authenticate with your **current** key. The old key dies immediately and the new key is returned once in the response body β€” store it before discarding the response. **Guide:** [Get an API key](/docs/get-an-api-key) ## Authentication - `X-API-Key` header (apiKey) ## Responses ### 200 β€” Key rotated - `success` (boolean) - `api_key` (string) β€” The new key. Returned only here. ### 404 β€” CRM panel not found ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/rotate-key" \ -H "X-API-Key: " ``` --- # Auth (/docs/crm/auth) {/* Generated by scripts/gen-api.ts β€” edit that script, not this file. */} Connect a creator account (OnlyFans or Fansly) and complete 2FA. All three routes accept `platform: "onlyfans" | "fansly"` and are rate limited to 10 requests/minute. | Method | Endpoint | Path | | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | | `POST` | [Connect an account with credentials (OnlyFans or Fansly)](/docs/crm/auth/connect-an-account-with-credentials-onlyfans-or-fansly) | `/accounts/login` | | `POST` | [Connect an account with an existing session (OnlyFans or Fansly)](/docs/crm/auth/connect-an-account-with-an-existing-session-onlyfans-or-fansly) | `/accounts/login/cookies` | | `POST` | [Verify 2FA OTP code (OnlyFans or Fansly)](/docs/crm/auth/verify-2fa-otp-code-onlyfans-or-fansly) | `/accounts/login/verify-otp` | --- # Connect an account with an existing session (OnlyFans or Fansly) (/docs/crm/auth/connect-an-account-with-an-existing-session-onlyfans-or-fansly) `POST https://theonlyapi.com/api/crm/your-crm-id/accounts/login/cookies` Connect a creator account using credentials you already hold, rather than a password login. - **OnlyFans** β€” session cookie paste. Body: `{ sess, auth_id, fp? }`. `sess` and `auth_id` are **required for OnlyFans only**. **`X-Proxy` is REQUIRED.** - **Fansly** β€” auth-token paste. Body: `{ platform: "fansly", auth_token, fansly_session_id, fansly_client_id? }`. `auth_token` and `fansly_session_id` are **required for Fansly**. `X-Proxy` is optional. Where to find the OnlyFans cookies: open onlyfans.com while logged in β†’ **DevTools β†’ Application β†’ Cookies β†’ onlyfans.com** and copy `sess` and `auth_id`. Consumes one account slot. Rate limited to 10 requests/minute. **Guide:** [Connect an account](/docs/connect-an-account) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` (required) - `platform` ("onlyfans" | "fansly") β€” Which platform to connect. Defaults to `onlyfans` when omitted. Default `"onlyfans"`. - `sess` (string) β€” The `sess` cookie value. **Required for OnlyFans**, unused for Fansly. - `auth_id` (string) β€” The `auth_id` cookie value (OnlyFans user ID). **Required for OnlyFans**, unused for Fansly. - `fp` (string) β€” The `fp` fingerprint cookie (OnlyFans, optional β€” used as `x-bc`). - `auth_token` (string) β€” Fansly bearer/auth token. **Required for Fansly**, unused for OnlyFans. - `fansly_session_id` (string) β€” Fansly session ID. **Required for Fansly**, unused for OnlyFans. - `fansly_client_id` (string) β€” Fansly device/client ID (optional, Fansly only). ## Responses ### 200 β€” Account connected - `success` (boolean) - `of_user_id` (string) - `username` (string) - `platform` ("onlyfans" | "fansly") - `login_method` (string) β€” e.g. `"cookies"`. ### 401 β€” Invalid or expired session credentials ## Example **OnlyFans β€” cookie paste (X-Proxy required)** ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/accounts/login/cookies" \ -H "X-API-Key: " \ -H "X-Proxy: http://user:pass@host:port" \ -H "Content-Type: application/json" \ -d '{"platform":"onlyfans","sess":"","auth_id":"482687148","fp":""}' ``` **Fansly β€” auth-token paste (X-Proxy optional)** ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/accounts/login/cookies" \ -H "X-API-Key: " \ -H "X-Proxy: http://user:pass@host:port" \ -H "Content-Type: application/json" \ -d '{"platform":"fansly","auth_token":"","fansly_session_id":"","fansly_client_id":""}' ``` --- # Connect an account with credentials (OnlyFans or Fansly) (/docs/crm/auth/connect-an-account-with-credentials-onlyfans-or-fansly) `POST https://theonlyapi.com/api/crm/your-crm-id/accounts/login` Connect a new creator account via email/username + password. Set `platform` to `"onlyfans"` (default) or `"fansly"`. - **X-Proxy header is REQUIRED for OnlyFans**, optional for Fansly. You may pass `proxy` in the body as an alternative. - For `platform: "fansly"` the `email` field accepts a **username or an email**. - Supports 2FA: if the account has 2FA enabled the response includes `requires_2fa: true` (Fansly also returns `twofa_type`), and you must call `POST /accounts/login/verify-otp` next with the same `platform` and identifier. Consumes one account slot. Rate limited to 10 requests/minute. **Guide:** [Connect an account](/docs/connect-an-account) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` (required) - `platform` ("onlyfans" | "fansly") β€” Which platform to connect. Defaults to `onlyfans` when omitted. Default `"onlyfans"`. - `email` (string, required) β€” Account identifier. An email for OnlyFans; a **username or an email** for Fansly. e.g. `"user@example.com"`. - `password` (string, required) β€” e.g. `"your_password"`. - `use_captcha` (boolean) β€” Use captcha solver for login. Default `true`. - `proxy` (string) β€” Proxy for this account β€” alternative to the `X-Proxy` header. Required for OnlyFans (via header or here), optional for Fansly. e.g. `"http://user:pass@host:port"`. ## Responses ### 200 β€” Login successful or 2FA required - `about` (string) - `avatar` (string) - `email` (string, required) - `expires_in_seconds` (integer) - `of_user_id` (string) - `otp_methods` (any[]) - `otp_state` (string) - `platform` (string) - `proxy` (string) - `requires_2fa` (boolean) - `success` (boolean, required) - `twofa_type` (string) - `username` (string) - `x_bc` (string) Successful login: ```json { "success": true, "of_user_id": "123456789", "username": "example_user", "email": "user@example.com", "avatar": "https://..." } ``` 2FA required: ```json { "success": false, "requires_2fa": true, "otp_state": "...", "email": "user@example.com" } ``` ### 500 β€” Login failed ## Example **OnlyFans (X-Proxy header required)** ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/accounts/login" \ -H "X-API-Key: " \ -H "X-Proxy: http://user:pass@host:port" \ -H "Content-Type: application/json" \ -d '{"platform":"onlyfans","email":"user@example.com","password":"your_password","use_captcha":true}' ``` **Fansly (username accepted, proxy optional)** ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/accounts/login" \ -H "X-API-Key: " \ -H "X-Proxy: http://user:pass@host:port" \ -H "Content-Type: application/json" \ -d '{"platform":"fansly","email":"creator_username","password":"your_password"}' ``` --- # Verify 2FA OTP code (OnlyFans or Fansly) (/docs/crm/auth/verify-2fa-otp-code-onlyfans-or-fansly) `POST https://theonlyapi.com/api/crm/your-crm-id/accounts/login/verify-otp` Complete a 2FA login started by `POST /accounts/login`. - Pass the same `platform` and the same identifier you logged in with. For `platform: "fansly"` the `email` field may be a **username**. - The Fansly 2FA challenge returned by `POST /accounts/login` carries a `twofa_type` field indicating the delivery channel. - **The `X-Proxy` header is required.** Rate limited to 10 requests/minute. **Guide:** [Connect an account](/docs/connect-an-account) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `X-Proxy` (string, required) β€” Proxy URL β€” **required** on this route. Use the same proxy the login attempt was made through. ## Request body Content type: `application/json` (required) - `platform` ("onlyfans" | "fansly") β€” Must match the `platform` used on `POST /accounts/login`. Default `"onlyfans"`. - `email` (string, required) β€” The same identifier used on `POST /accounts/login`. An email for OnlyFans; a **username or an email** for Fansly. e.g. `"user@example.com"`. - `otp_code` (string, required) β€” 6-digit OTP code. e.g. `"123456"`. ## Responses ### 200 β€” OTP verified, account connected - `about` (string, required) - `avatar` (string, required) - `email` (string, required) - `of_user_id` (string, required) - `proxy` (string, required) - `success` (boolean, required) - `username` (string, required) - `x_bc` (string, required) ### 404 β€” 2FA session not found or expired β€” start the login again ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/accounts/login/verify-otp" \ -H "X-API-Key: " \ -H "X-Proxy: http://user:pass@host:port" \ -H "Content-Type: application/json" \ -d '{"platform":"onlyfans","email":"user@example.com","otp_code":"123456"}' ``` --- # Automations (/docs/crm/automations) {/* Generated by scripts/gen-api.ts β€” edit that script, not this file. */} Event-triggered automations, manual runs, and run history. | Method | Endpoint | Path | | -------- | ------------------------------------------------------------------------------------ | -------------------------------------- | | `GET` | [List automations](/docs/crm/automations/list-automations) | `/automations` | | `POST` | [Create an automation](/docs/crm/automations/create-an-automation) | `/automations` | | `GET` | [Get an automation](/docs/crm/automations/get-an-automation) | `/automations/{automation_id}` | | `PATCH` | [Update an automation](/docs/crm/automations/update-an-automation) | `/automations/{automation_id}` | | `DELETE` | [Delete an automation](/docs/crm/automations/delete-an-automation) | `/automations/{automation_id}` | | `POST` | [Run an automation immediately](/docs/crm/automations/run-an-automation-immediately) | `/automations/{automation_id}/run-now` | | `GET` | [List automation runs](/docs/crm/automations/list-automation-runs) | `/automations/{automation_id}/runs` | --- # Create an automation (/docs/crm/automations/create-an-automation) `POST https://theonlyapi.com/api/crm/your-crm-id/automations` Run an action whenever a panel event fires. `trigger_event` must be a known event type (not `*`) and `action_type` must be a supported action. Rate limited to 120 requests/minute. **Guide:** [Automations](/docs/automations) ## Authentication - `X-API-Key` header (apiKey) ## Request body Content type: `application/json` (required) - `name` (string, required) β€” e.g. `"Welcome DM"`. - `trigger_event` (string, required) β€” A known event type. `*` is not allowed. e.g. `"new_subscriber"`. - `action_type` (string, required) β€” A supported action type. e.g. `"send_dm"`. - `conditions` (object[]) β€” Default `[]`. - `action_params` (object) β€” Default `{}`. - `of_user_id` (string) β€” Restrict to one connected account. Omit to apply panel-wide. ## Responses ### 200 β€” Automation created - `automation` (any, required) - `success` (boolean, required) ### 400 β€” Invalid trigger_event or action_type ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/automations" \ -H "X-API-Key: " \ -H "Content-Type: application/json" \ -d '{"name":"Welcome DM","trigger_event":"new_subscriber","action_type":"send_dm","conditions":[],"action_params":{}}' ``` --- # Delete an automation (/docs/crm/automations/delete-an-automation) `DELETE https://theonlyapi.com/api/crm/your-crm-id/automations/{automation_id}` **Guide:** [Automations](/docs/automations) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `automation_id` (integer, required) ## Responses ### 200 β€” Automation deleted - `success` (boolean, required) ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/automations/{automation_id}" \ -H "X-API-Key: " ``` --- # Get an automation (/docs/crm/automations/get-an-automation) `GET https://theonlyapi.com/api/crm/your-crm-id/automations/{automation_id}` **Guide:** [Automations](/docs/automations) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `automation_id` (integer, required) ## Responses ### 200 β€” Automation - `automation` (any, required) - `success` (boolean, required) ### 404 β€” Not found ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/automations/{automation_id}" \ -H "X-API-Key: " ``` --- # List automation runs (/docs/crm/automations/list-automation-runs) `GET https://theonlyapi.com/api/crm/your-crm-id/automations/{automation_id}/runs` Execution history for one automation. **Guide:** [Automations](/docs/automations) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `automation_id` (integer, required) ## Query parameters - `limit` (integer) β€” Maximum number of rows to return. Default `100`. ## Responses ### 200 β€” Run history - `runs` (object[], required) - `automation_id` (integer) - `created_at` (string) - `error_snippet` (string) - `event_id` (integer) - `id` (integer) - `status` (string) - `success` (boolean, required) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/automations/{automation_id}/runs" \ -H "X-API-Key: " ``` --- # List automations (/docs/crm/automations/list-automations) `GET https://theonlyapi.com/api/crm/your-crm-id/automations` **Guide:** [Automations](/docs/automations) ## Authentication - `X-API-Key` header (apiKey) ## Responses ### 200 β€” Automation list - `automations` (object[], required) - `action_params` (object) - `action_type` (string) - `conditions` (any[]) - `created_at` (string) - `crm_id` (string) - `id` (integer) - `is_active` (integer) - `last_run_at` (string) - `name` (string) - `of_user_id` (string) - `run_count` (integer) - `trigger_event` (string) - `success` (boolean, required) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/automations" \ -H "X-API-Key: " ``` --- # Run an automation immediately (/docs/crm/automations/run-an-automation-immediately) `POST https://theonlyapi.com/api/crm/your-crm-id/automations/{automation_id}/run-now` **Guide:** [Automations](/docs/automations) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `automation_id` (integer, required) ## Responses ### 200 β€” Run triggered - `result` (any, required) - `success` (boolean, required) ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/automations/{automation_id}/run-now" \ -H "X-API-Key: " ``` --- # Update an automation (/docs/crm/automations/update-an-automation) `PATCH https://theonlyapi.com/api/crm/your-crm-id/automations/{automation_id}` **Guide:** [Automations](/docs/automations) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `automation_id` (integer, required) ## Request body Content type: `application/json` (required) - `name` (string) - `enabled` (boolean) - `conditions` (object[]) - `action_params` (object) ## Responses ### 200 β€” Automation updated - `automation` (any, required) - `success` (boolean, required) ## Example ```bash curl -X PATCH "https://theonlyapi.com/api/crm/your-crm-id/automations/{automation_id}" \ -H "X-API-Key: " \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Bulk Import (/docs/crm/bulk-import) {/* Generated by scripts/gen-api.ts β€” edit that script, not this file. */} Connect many creator accounts from one pasted list. `POST /import/preview` validates without side effects; `POST /import/jobs` runs the import in the background and streams `import.progress` / `import.complete` over `GET /events/stream`. Rows that hit a 2FA prompt park as `needs_2fa` until you supply a code. | Method | Endpoint | Path | | ------ | ------------------------------------------------------------------------------------------------ | ------------------------------------------- | | `GET` | [List import jobs](/docs/crm/bulk-import/list-import-jobs) | `/import/jobs` | | `POST` | [Start a bulk import](/docs/crm/bulk-import/start-a-bulk-import) | `/import/jobs` | | `GET` | [Get an import job](/docs/crm/bulk-import/get-an-import-job) | `/import/jobs/{job_id}` | | `POST` | [Cancel an import job](/docs/crm/bulk-import/cancel-an-import-job) | `/import/jobs/{job_id}/cancel` | | `POST` | [Supply a 2FA code for an import row](/docs/crm/bulk-import/supply-a-2fa-code-for-an-import-row) | `/import/jobs/{job_id}/rows/{row_id}/otp` | | `POST` | [Retry an import row](/docs/crm/bulk-import/retry-an-import-row) | `/import/jobs/{job_id}/rows/{row_id}/retry` | | `GET` | [List rows waiting on a 2FA code](/docs/crm/bulk-import/list-rows-waiting-on-a-2fa-code) | `/import/pending-2fa` | | `POST` | [Preview an import paste](/docs/crm/bulk-import/preview-an-import-paste) | `/import/preview` | --- # Cancel an import job (/docs/crm/bulk-import/cancel-an-import-job) `POST https://theonlyapi.com/api/crm/your-crm-id/import/jobs/{job_id}/cancel` Stop an import. Cancellation is cooperative: `pending` rows are canceled at once and nothing further is claimed, but a row already mid-login runs to completion β€” we cannot un-send a login attempt β€” and records its real outcome. Expect a few more successes after cancelling. Only a `queued` or `running` job can be canceled. ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `job_id` (string, required) β€” Import job ID (32-character hex) returned by `POST /import/jobs`. ## Responses ### 200 Canceled. `canceled_rows` is how many pending rows were dropped. - `canceled_rows` (any, required) - `counts` (any, required) - `job` (any, required) - `success` (boolean, required) ### 404 β€” No such job in this panel. ### 409 Job is already finished β€” the body reports its actual status. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/import/jobs/{job_id}/cancel" \ -H "X-API-Key: " ``` --- # Get an import job (/docs/crm/bulk-import/get-an-import-job) `GET https://theonlyapi.com/api/crm/your-crm-id/import/jobs/{job_id}` One job with its rows and counts. This is the fallback whenever an SSE event is missed β€” the stored row is authoritative, the events are only a live nudge. `counts` is zero-filled across every state, so a missing key never has to be read as "unknown". `row_states` echoes the full state vocabulary: `pending`, `running`, `success`, `needs_2fa`, `needs_2fa_expired`, `failed`, `canceled`, `invalid`, `skipped`, `slot_exhausted`. Rows never carry credentials β€” each has `has_password` / `has_totp_secret` flags instead, and a row parked on 2FA also reports `two_fa_remaining_seconds`. ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `job_id` (string, required) β€” Import job ID (32-character hex) returned by `POST /import/jobs`. ## Query parameters - `limit` (integer) β€” Rows per page (1–1000). Default `1000`. - `offset` (integer) β€” Row offset for pagination. Default `0`. - `status` ("pending" | "running" | "success" | "needs_2fa" | "needs_2fa_expired" | "failed" | "canceled" | "invalid" | "skipped" | "slot_exhausted") β€” Return only rows in this state. An unrecognised value is a `400`, not an empty page. ## Responses ### 200 β€” Job, counts, and one page of rows. - `counts` (any, required) - `job` (any, required) - `row_states` (any[], required) - `rows` (any[], required) - `success` (boolean, required) - `total` (integer, required) ### 400 β€” Unknown `status` filter. ### 404 β€” No such job in this panel. ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/import/jobs/{job_id}" \ -H "X-API-Key: " ``` --- # List import jobs (/docs/crm/bulk-import/list-import-jobs) `GET https://theonlyapi.com/api/crm/your-crm-id/import/jobs` Import history for the panel, newest first, each job carrying its per-status row counts. ## Authentication - `X-API-Key` header (apiKey) ## Query parameters - `limit` (integer) β€” Jobs per page (1–200). Default `50`. - `offset` (integer) β€” Row offset for pagination. Default `0`. ## Responses ### 200 β€” Job history with `total` for pagination. - `jobs` (any[], required) - `success` (boolean, required) - `total` (integer, required) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/import/jobs" \ -H "X-API-Key: " ``` --- # List rows waiting on a 2FA code (/docs/crm/bulk-import/list-rows-waiting-on-a-2fa-code) `GET https://theonlyapi.com/api/crm/your-crm-id/import/pending-2fa` Every parked 2FA row on the panel, across **all** jobs β€” `needs_2fa` first, soonest to expire first. This is deliberately panel-wide rather than per-job: an operator closes the importer and the dashboard still has to be able to say "9 accounts need a 2FA code". `count` is how many are still answerable, `expired_count` how many need a retry instead, and `expiry_seconds` is the window length each one gets. ## Authentication - `X-API-Key` header (apiKey) ## Query parameters - `limit` (integer) β€” Maximum rows to return (1–1000). Default `200`. ## Responses ### 200 β€” Parked rows across every job in the panel. - `count` (integer, required) - `expired_count` (integer, required) - `expiry_seconds` (any, required) - `rows` (any[], required) - `success` (boolean, required) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/import/pending-2fa" \ -H "X-API-Key: " ``` --- # Preview an import paste (/docs/crm/bulk-import/preview-an-import-paste) `POST https://theonlyapi.com/api/crm/your-crm-id/import/preview` Parse and validate a pasted account list **without side effects** β€” nothing is written, no login is attempted, and no slot is consumed. Use it to show which rows are valid, which lane each one will take (`cookie` or `password`), and exactly why a bad row is bad, before committing to an import. Secrets are never echoed back: passwords and TOTP secrets are reduced to `has_password` / `has_totp_secret`, cookies to a `cookie_fields` name list, and a proxy URL to `host:port` with its credentials stripped. Accepted formats are auto-detected β€” CSV, TSV, colon- or pipe-separated, with or without a header row. Limits are 1,000 rows and 2 MiB per paste; exceeding either is a rejection, never a silent truncation. ## Authentication - `X-API-Key` header (apiKey) ## Request body Content type: `application/json` (required) - `text` (string, required) β€” The pasted account list, one account per line. e.g. `"email,password,proxy\ncreator1@example.com,pw1,http://user:pass@host:1080\ncreator2@example.com,pw2,"`. - `default_platform` ("onlyfans" | "fansly") β€” Platform for rows that do not name one themselves. Also accepted as `platform`. Default `"onlyfans"`. ## Responses ### 200 β€” Parse result `rows[]` is redacted; `lanes` and `platforms` count the valid rows by lane and platform. - `columns` (any[], required) - `delimiter` (string, required) - `format` (string, required) - `has_header` (boolean, required) - `invalid_count` (integer, required) - `lanes` (any, required) - `limits` (object, required) - `platforms` (any, required) - `rows` (any[]) - `success` (boolean, required) - `total` (integer, required) - `valid_count` (integer, required) ### 400 `text` missing, `default_platform` not one of `onlyfans`/`fansly`, or the paste could not be parsed (`code: "IMPORT_PARSE"`). ### 413 β€” Paste exceeds `max_rows` (1,000) or `max_bytes` (2 MiB) Returns `code: "IMPORT_LIMIT"` with a `limits` object. Nothing is imported β€” split the paste and retry. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/import/preview" \ -H "X-API-Key: " \ -H "Content-Type: application/json" \ -d '{"text":"email,password,proxy\ncreator1@example.com,pw1,http://user:pass@host:1080\ncreator2@example.com,pw2,","default_platform":"onlyfans"}' ``` --- # Retry an import row (/docs/crm/bulk-import/retry-an-import-row) `POST https://theonlyapi.com/api/crm/your-crm-id/import/jobs/{job_id}/rows/{row_id}/retry` Re-queue one row and restart the job's worker. A `needs_2fa_expired` row re-runs the login **from scratch** β€” the parked challenge is dead, so replaying it would only earn another rejection. A row cannot be retried once its stored credential has been destroyed (which happens when a password-lane row reaches a terminal state or ages out after 24 hours); re-import it instead. ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `job_id` (string, required) β€” Import job ID (32-character hex) returned by `POST /import/jobs`. - `row_id` (integer, required) β€” Row ID within the import job β€” the `id` field of a row from `GET /import/jobs/{job_id}`, not its `row_index`. ## Responses ### 202 β€” Row re-queued; the job is running again. - `success` (boolean, required) - `row` (object, required) - `id` (integer) β€” Row ID β€” this is the `{row_id}` for the OTP and retry routes. - `job_id` (string) - `row_index` (integer) β€” Zero-based position within the paste. - `source_line` (integer) β€” Line number in the original paste, for error display. - `lane` ("cookie" | "password") β€” How this row connects: pasted session (`cookie`) or credentials (`password`). - `platform` ("onlyfans" | "fansly") - `email` (string) - `label` (string) β€” Optional per-row label from the paste. - `proxy` (string) - `status` ("pending" | "running" | "success" | "needs_2fa" | "needs_2fa_expired" | "failed" | "canceled" | "invalid" | "skipped" | "slot_exhausted") - `has_password` (boolean) - `has_totp_secret` (boolean) - `two_fa_expires_at` (string) β€” When a parked 2FA challenge stops being answerable. - `two_fa_remaining_seconds` (integer) β€” Seconds left on the 2FA window; `null` unless the row is parked. - `of_user_id` (string) β€” Set once the account connects. - `username` (string) - `error` (string) - `error_reason` (string) β€” Machine-readable failure cause; match on this, not `error`. - `permanent` (boolean) β€” True when retrying cannot help. - `attempts` (integer) - `started_at` (string) - `finished_at` (string) - `created_at` (string) - `updated_at` (string) ### 404 β€” No such row in this job. ### 409 Not retryable: already queued or running, already connected, never parsed (`invalid`), or its credential is gone. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/import/jobs/{job_id}/rows/{row_id}/retry" \ -H "X-API-Key: " ``` --- # Start a bulk import (/docs/crm/bulk-import/start-a-bulk-import) `POST https://theonlyapi.com/api/crm/your-crm-id/import/jobs` Create an import job and start working through the rows in the background. Returns `202` immediately with the job and its per-status counts. Progress streams over [`GET /events/stream`](#tag/events-and-streaming) as `import.progress` (coalesced to at most one per second) and finishes with `import.complete`. The job row is the source of truth β€” if you miss an event, `GET /import/jobs/{job_id}` still has the current state. Rows that hit a 2FA prompt do not fail: they park as `needs_2fa` holding the challenge, and wait for a code via `POST /import/jobs/{job_id}/rows/{row_id}/otp`. Parked rows expire after 10 minutes (retry them for a fresh login) and their stored credential is destroyed after 24 hours regardless. Invalid rows are reported but never attempted. If *no* row is valid the request fails with `400` and the per-row reasons rather than creating a job that is 100% failures. ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `X-User-Email` (string) β€” Optional label recorded as the job's `requested_by`, for panels where several operators share a key. ## Request body Content type: `application/json` (required) - `text` (string, required) β€” The pasted account list, one account per line. - `default_platform` ("onlyfans" | "fansly") β€” Platform for rows that do not name one themselves. Also accepted as `platform`. Default `"onlyfans"`. - `source` (string) β€” Free-text label for where the list came from, stored on the job. Default `"paste"`. ## Responses ### 202 β€” Job created and running `warning` is present only when some rows failed validation and will not be attempted. - `columns` (any[], required) - `counts` (any, required) - `delimiter` (string, required) - `format` (string, required) - `has_header` (boolean, required) - `invalid_count` (integer, required) - `job` (any, required) - `lanes` (any, required) - `limits` (object, required) - `platforms` (any, required) - `success` (boolean, required) - `total` (integer, required) - `valid_count` (integer, required) - `warning` (string) ### 400 β€” No valid rows The body carries the same `rows[]` and counts as `POST /import/preview` so you can show what to fix. ### 413 Paste exceeds `max_rows` or `max_bytes` (`code: "IMPORT_LIMIT"`). ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/import/jobs" \ -H "X-API-Key: " \ -H "Content-Type: application/json" \ -d '{"text":"string","default_platform":"onlyfans","source":"paste"}' ``` --- # Supply a 2FA code for an import row (/docs/crm/bulk-import/supply-a-2fa-code-for-an-import-row) `POST https://theonlyapi.com/api/crm/your-crm-id/import/jobs/{job_id}/rows/{row_id}/otp` Complete one row parked on `needs_2fa` by submitting the code the creator received. Synchronous by design: it is a single platform call and an operator is watching, so the response carries the real outcome rather than "queued". `success: true` means the account is connected. The field is `code` (`otp_code` is also accepted here), 4–12 characters, letters, digits and hyphens. This route is on the standard sensitive tier (100/minute), not the login tier β€” clearing a queue of parked rows back to back is the expected workflow, and the code is verified by the platform rather than by us. ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `job_id` (string, required) β€” Import job ID (32-character hex) returned by `POST /import/jobs`. - `row_id` (integer, required) β€” Row ID within the import job β€” the `id` field of a row from `GET /import/jobs/{job_id}`, not its `row_index`. ## Request body Content type: `application/json` (required) - `code` (string, required) β€” The 2FA code. Also accepted as `otp_code`. e.g. `"123456"`. ## Responses ### 200 β€” Connected. - `success` (boolean, required) - `row` (object, required) - `id` (integer) β€” Row ID β€” this is the `{row_id}` for the OTP and retry routes. - `job_id` (string) - `row_index` (integer) β€” Zero-based position within the paste. - `source_line` (integer) β€” Line number in the original paste, for error display. - `lane` ("cookie" | "password") β€” How this row connects: pasted session (`cookie`) or credentials (`password`). - `platform` ("onlyfans" | "fansly") - `email` (string) - `label` (string) β€” Optional per-row label from the paste. - `proxy` (string) - `status` ("pending" | "running" | "success" | "needs_2fa" | "needs_2fa_expired" | "failed" | "canceled" | "invalid" | "skipped" | "slot_exhausted") - `has_password` (boolean) - `has_totp_secret` (boolean) - `two_fa_expires_at` (string) β€” When a parked 2FA challenge stops being answerable. - `two_fa_remaining_seconds` (integer) β€” Seconds left on the 2FA window; `null` unless the row is parked. - `of_user_id` (string) β€” Set once the account connects. - `username` (string) - `error` (string) - `error_reason` (string) β€” Machine-readable failure cause; match on this, not `error`. - `permanent` (boolean) β€” True when retrying cannot help. - `attempts` (integer) - `started_at` (string) - `finished_at` (string) - `created_at` (string) - `updated_at` (string) ### 400 β€” Malformed code, or the platform rejected it The row stays parked when the window is still open, so a mistyped code can be resubmitted. ### 404 β€” No such row in this job. ### 409 Row is not waiting for a code β€” either it never was, or its 10-minute window closed (`status: "needs_2fa_expired"`). Retry the row to start a fresh login. ### 503 β€” The platform's OTP verification is temporarily unavailable The row stays parked; try again. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/import/jobs/{job_id}/rows/{row_id}/otp" \ -H "X-API-Key: " \ -H "Content-Type: application/json" \ -d '{"code":"123456"}' ``` --- # Cache & Sync (/docs/crm/cache-and-sync) {/* Generated by scripts/gen-api.ts β€” edit that script, not this file. */} Async refresh, backfill, and job-status routes that populate the local cache. Refresh routes return 202 β€” poll the matching `/refresh/status` route or listen on `GET /events/stream`. | Method | Endpoint | Path | | ------ | ------------------------------------------------------------------------------------------- | --------------------------------------------- | | `POST` | [Backfill historical data (async)](/docs/crm/cache-and-sync/backfill-historical-data-async) | `/accounts/{of_user_id}/backfill` | | `POST` | [Clear a stuck refresh job](/docs/crm/cache-and-sync/clear-a-stuck-refresh-job) | `/accounts/{of_user_id}/refresh/{kind}/clear` | | `GET` | [List active refresh jobs](/docs/crm/cache-and-sync/list-active-refresh-jobs) | `/refresh/active` | --- # Backfill historical data (async) (/docs/crm/cache-and-sync/backfill-historical-data-async) `POST https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/backfill` Kick off a historical backfill for this account, walking further back than the routine refresh. Returns **202** β€” track progress via the refresh-status routes or `GET /events/stream`. **Guide:** [Cached reads](/docs/cached-reads) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `of_user_id` (string, required) β€” Creator account ID of the connected account (OnlyFans or Fansly). Use `GET /accounts` to list connected accounts and their IDs. ## Header parameters - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 202 β€” Backfill job accepted and running - `already_running` (boolean) - `days` (integer) - `platform` (string) - `state` (any) - `success` (boolean, required) ### 409 β€” A job is already in progress ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/backfill" \ -H "X-API-Key: " ``` --- # Clear a stuck refresh job (/docs/crm/cache-and-sync/clear-a-stuck-refresh-job) `POST https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/refresh/{kind}/clear` Force a wedged refresh job to a terminal state so a new one can start. The refresh routes already supersede a stale job automatically, but that is a timer β€” you have to wait it out, and it cannot help at all with a job that keeps re-stamping its progress while making none. This is the escape hatch for that case. Makes no platform calls, so it costs no quota. Always returns `200`; `cleared` says whether there was in fact something to clear, and `state` is the job's final state (or `null`). **Guide:** [Cached reads](/docs/cached-reads) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `of_user_id` (string, required) β€” Creator account ID of the connected account (OnlyFans or Fansly). Use `GET /accounts` to list connected accounts and their IDs. - `kind` ("subs" | "tx" | "campaigns", required) β€” Which refresh job to act on: `subs` (subscribers), `tx` (transactions), or `campaigns` (campaign claimers). ## Responses ### 200 `cleared: true` when a job was terminated, `false` when none was running. - `cleared` (boolean, required) - `state` (any, required) - `success` (boolean, required) ### 400 β€” `kind` is not one of `subs`, `tx`, `campaigns`. ### 403 β€” Account does not belong to this panel. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/refresh/{kind}/clear" \ -H "X-API-Key: " ``` --- # List active refresh jobs (/docs/crm/cache-and-sync/list-active-refresh-jobs) `GET https://theonlyapi.com/api/crm/your-crm-id/refresh/active` All refresh/backfill jobs currently running across the panel. **Zero platform requests.** **Guide:** [Cached reads](/docs/cached-reads) ## Authentication - `X-API-Key` header (apiKey) ## Responses ### 200 β€” Active job list - `jobs` (any[], required) - `success` (boolean, required) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/refresh/active" \ -H "X-API-Key: " ``` --- # Campaigns (/docs/crm/campaigns) {/* Generated by scripts/gen-api.ts β€” edit that script, not this file. */} Tracking link campaigns, claimers, campaign tags, and the tracked-campaign allowlist. | Method | Endpoint | Path | | -------- | -------------------------------------------------------------------------------------------- | ---------------------------------------------------------------- | | `GET` | [List campaign tags](/docs/crm/campaigns/list-campaign-tags) | `/accounts/{of_user_id}/campaign-tags` | | `GET` | [List campaigns](/docs/crm/campaigns/list-campaigns) | `/accounts/{of_user_id}/campaigns` | | `POST` | [Create campaign](/docs/crm/campaigns/create-campaign) | `/accounts/{of_user_id}/campaigns` | | `GET` | [Get campaign claimers (live)](/docs/crm/campaigns/get-campaign-claimers-live) | `/accounts/{of_user_id}/campaigns/{campaign_id}/claimers` | | `GET` | [Get cached campaign claimers](/docs/crm/campaigns/get-cached-campaign-claimers) | `/accounts/{of_user_id}/campaigns/{campaign_id}/claimers/cached` | | `POST` | [Add a tag to a campaign](/docs/crm/campaigns/add-a-tag-to-a-campaign) | `/accounts/{of_user_id}/campaigns/{campaign_id}/tags` | | `DELETE` | [Remove a tag from a campaign](/docs/crm/campaigns/remove-a-tag-from-a-campaign) | `/accounts/{of_user_id}/campaigns/{campaign_id}/tags/{tag}` | | `GET` | [Campaign earnings breakdown](/docs/crm/campaigns/campaign-earnings-breakdown) | `/accounts/{of_user_id}/campaigns/earnings` | | `POST` | [Refresh the campaign cache (async)](/docs/crm/campaigns/refresh-the-campaign-cache-async) | `/accounts/{of_user_id}/campaigns/refresh` | | `GET` | [Campaign refresh status](/docs/crm/campaigns/campaign-refresh-status) | `/accounts/{of_user_id}/campaigns/refresh/status` | | `GET` | [Get the tracked-campaign allowlist](/docs/crm/campaigns/get-the-tracked-campaign-allowlist) | `/accounts/{of_user_id}/tracked-campaigns` | | `PUT` | [Set the tracked-campaign allowlist](/docs/crm/campaigns/set-the-tracked-campaign-allowlist) | `/accounts/{of_user_id}/tracked-campaigns` | --- # Add a tag to a campaign (/docs/crm/campaigns/add-a-tag-to-a-campaign) `POST https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/campaigns/{campaign_id}/tags` **Guide:** [Subscribers & fans](/docs/subscribers) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `of_user_id` (string, required) β€” Creator account ID of the connected account (OnlyFans or Fansly). Use `GET /accounts` to list connected accounts and their IDs. - `campaign_id` (string, required) β€” Tracking-link campaign ID. ## Request body Content type: `application/json` (required) - `tag` (string, required) β€” e.g. `"reddit"`. ## Responses ### 200 β€” Tag added - `success` (boolean, required) ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/campaigns/{campaign_id}/tags" \ -H "X-API-Key: " \ -H "Content-Type: application/json" \ -d '{"tag":"reddit"}' ``` --- # Campaign earnings breakdown (/docs/crm/campaigns/campaign-earnings-breakdown) `GET https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/campaigns/earnings` Earnings attributed to each tracking-link campaign, computed from cached claimers joined with cached transactions. **Zero platform requests.** **Guide:** [Subscribers & fans](/docs/subscribers) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `of_user_id` (string, required) β€” Creator account ID of the connected account (OnlyFans or Fansly). Use `GET /accounts` to list connected accounts and their IDs. ## Responses ### 200 β€” Per-campaign earnings - `cache` (object, required) - `campaigns` (integer) - `claimers` (integer) - `consecutive_failures` (integer) - `last_refreshed_at` (any) - `last_row_synced_at` (any) - `last_spend_refreshed_at` (any) - `earnings` (object[], required) - `campaign_id` (string) - `canon_messages` (any) - `canon_posts` (any) - `canon_streams` (any) - `canon_subs` (any) - `canon_tips` (any) - `canonical_spent` (any) - `fan_of_user_id` (string) - `messages` (any) - `posts` (any) - `spent_messages` (any) - `spent_posts` (any) - `spent_streams` (any) - `spent_subscriptions` (any) - `spent_tips` (any) - `streams` (any) - `subs` (any) - `tips` (any) - `tx_messages` (any) - `tx_posts` (any) - `tx_spent` (any) - `tx_streams` (any) - `tx_subs` (any) - `tx_tips` (any) - `success` (boolean, required) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/campaigns/earnings" \ -H "X-API-Key: " ``` --- # Campaign refresh status (/docs/crm/campaigns/campaign-refresh-status) `GET https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/campaigns/refresh/status` Progress/state of the current or last campaign refresh job. **Zero platform requests.** **Guide:** [Subscribers & fans](/docs/subscribers) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `of_user_id` (string, required) β€” Creator account ID of the connected account (OnlyFans or Fansly). Use `GET /accounts` to list connected accounts and their IDs. ## Responses ### 200 β€” Refresh job status - `cache` (object, required) - `campaigns` (integer) - `claimers` (integer) - `consecutive_failures` (integer) - `last_refreshed_at` (any) - `last_row_synced_at` (any) - `last_spend_refreshed_at` (any) - `live` (boolean) - `success` (boolean, required) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/campaigns/refresh/status" \ -H "X-API-Key: " ``` --- # Create campaign (/docs/crm/campaigns/create-campaign) `POST https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/campaigns` Create a new tracking link campaign. **Guide:** [Subscribers & fans](/docs/subscribers) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `of_user_id` (string, required) β€” Creator account ID of the connected account (OnlyFans or Fansly). Use `GET /accounts` to list connected accounts and their IDs. ## Header parameters - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` (required) - `name` (string, required) β€” e.g. `"My Campaign"`. ## Responses ### 200 β€” Campaign created - `campaigns` (any[]) - `hasMore` (boolean) - `name` (string) - `success` (boolean) ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/campaigns" \ -H "X-API-Key: " \ -H "Content-Type: application/json" \ -d '{"name":"My Campaign"}' ``` --- # Get cached campaign claimers (/docs/crm/campaigns/get-cached-campaign-claimers) `GET https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/campaigns/{campaign_id}/claimers/cached` Cached claimers for one campaign, already joined with the subscriber cache so each row carries `total_spent`, its breakdown, and `mapped_spent`. **Zero platform requests.** **Guide:** [Subscribers & fans](/docs/subscribers) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `of_user_id` (string, required) β€” Creator account ID of the connected account (OnlyFans or Fansly). Use `GET /accounts` to list connected accounts and their IDs. - `campaign_id` (string, required) β€” Tracking-link campaign ID. ## Query parameters - `limit` (integer) β€” Maximum number of rows to return. Default `100`. - `offset` (integer) β€” Row offset for pagination. Default `0`. ## Responses ### 200 β€” Cached claimer list - `count` (integer, required) - `hasMore` (boolean, required) - `limit` (integer, required) - `list` (any[], required) - `offset` (integer, required) - `success` (boolean, required) - `total` (integer, required) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/campaigns/{campaign_id}/claimers/cached" \ -H "X-API-Key: " ``` --- # Get campaign claimers (live) (/docs/crm/campaigns/get-campaign-claimers-live) `GET https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/campaigns/{campaign_id}/claimers` Fetch subscribers who converted through a specific campaign. **OnlyFans only** β€” rejected for Fansly accounts. Fetched live from the platform, so it consumes platform requests. For a zero-platform-request read, use `GET /accounts/{of_user_id}/campaigns/{campaign_id}/claimers/cached`. **Guide:** [Subscribers & fans](/docs/subscribers) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `of_user_id` (string, required) β€” Creator account ID of the connected account (OnlyFans or Fansly). Use `GET /accounts` to list connected accounts and their IDs. - `campaign_id` (string, required) ## Query parameters - `limit` (integer) β€” Default `10`. - `offset` (integer) β€” Default `0`. ## Header parameters - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Claimer list - `success` (boolean) - `claimers` (object[]) - `hasMore` (boolean) - `count` (integer) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/campaigns/{campaign_id}/claimers" \ -H "X-API-Key: " ``` --- # Get the tracked-campaign allowlist (/docs/crm/campaigns/get-the-tracked-campaign-allowlist) `GET https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/tracked-campaigns` The allowlist of tracking-link campaigns (names/codes) kept synced for this account. When set, scheduled and backfill claimer syncs walk only these β€” so a huge link (20k+ subscribers) is never walked on a timer. **Guide:** [Subscribers & fans](/docs/subscribers) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `of_user_id` (string, required) β€” Creator account ID of the connected account (OnlyFans or Fansly). Use `GET /accounts` to list connected accounts and their IDs. ## Responses ### 200 β€” Tracked campaign allowlist - `success` (boolean, required) - `tracked_campaigns` (any, required) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/tracked-campaigns" \ -H "X-API-Key: " ``` --- # List campaign tags (/docs/crm/campaigns/list-campaign-tags) `GET https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/campaign-tags` All campaign tags in use for this account. **Guide:** [Subscribers & fans](/docs/subscribers) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `of_user_id` (string, required) β€” Creator account ID of the connected account (OnlyFans or Fansly). Use `GET /accounts` to list connected accounts and their IDs. ## Responses ### 200 β€” Campaign tag list - `all_tags` (any[], required) - `success` (boolean, required) - `tags` (object[], required) - `campaign_id` (string) - `tag` (string) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/campaign-tags" \ -H "X-API-Key: " ``` --- # List campaigns (/docs/crm/campaigns/list-campaigns) `GET https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/campaigns` Get tracking link campaigns with statistics and pagination. **Guide:** [Subscribers & fans](/docs/subscribers) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `of_user_id` (string, required) β€” Creator account ID of the connected account (OnlyFans or Fansly). Use `GET /accounts` to list connected accounts and their IDs. ## Query parameters - `limit` (integer) β€” Default `10`. - `offset` (integer) β€” Default `0`. ## Header parameters - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Campaign list - `success` (boolean) - `campaigns` (object[]) - `hasMore` (boolean) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/campaigns" \ -H "X-API-Key: " ``` --- # Refresh the campaign cache (async) (/docs/crm/campaigns/refresh-the-campaign-cache-async) `POST https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/campaigns/refresh` Start an async campaign + claimer sync. Returns **202** β€” poll `GET /accounts/{of_user_id}/campaigns/refresh/status` or listen on `GET /events/stream`. Honours the `/tracked-campaigns` allowlist when one is set. **Guide:** [Subscribers & fans](/docs/subscribers) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `of_user_id` (string, required) β€” Creator account ID of the connected account (OnlyFans or Fansly). Use `GET /accounts` to list connected accounts and their IDs. ## Header parameters - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 202 β€” Refresh job accepted and running - `already_running` (boolean) - `message` (string) - `not_needed` (boolean) - `state` (any) - `success` (boolean, required) ### 409 β€” A refresh is already in progress ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/campaigns/refresh" \ -H "X-API-Key: " ``` --- # Remove a tag from a campaign (/docs/crm/campaigns/remove-a-tag-from-a-campaign) `DELETE https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/campaigns/{campaign_id}/tags/{tag}` **Guide:** [Subscribers & fans](/docs/subscribers) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `of_user_id` (string, required) β€” Creator account ID of the connected account (OnlyFans or Fansly). Use `GET /accounts` to list connected accounts and their IDs. - `campaign_id` (string, required) β€” Tracking-link campaign ID. - `tag` (string, required) ## Responses ### 200 β€” Tag removed - `success` (boolean, required) ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/campaigns/{campaign_id}/tags/{tag}" \ -H "X-API-Key: " ``` --- # Set the tracked-campaign allowlist (/docs/crm/campaigns/set-the-tracked-campaign-allowlist) `PUT https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/tracked-campaigns` **Guide:** [Subscribers & fans](/docs/subscribers) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `of_user_id` (string, required) β€” Creator account ID of the connected account (OnlyFans or Fansly). Use `GET /accounts` to list connected accounts and their IDs. ## Request body Content type: `application/json` (required) - `campaigns` (string[]) β€” Campaign names or codes to keep synced. ## Responses ### 200 β€” Allowlist updated - `success` (boolean, required) - `tracked_campaigns` (any, required) ## Example ```bash curl -X PUT "https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/tracked-campaigns" \ -H "X-API-Key: " \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Content (/docs/crm/content) {/* Generated by scripts/gen-api.ts β€” edit that script, not this file. */} Media upload. Runs OnlyFans' four-stage signed-S3 pipeline server-side and returns a reference you attach to a post, message or story via `mediaFiles`. OnlyFans only. | Method | Endpoint | Path | | ------ | ------------------------------------------------------------------------ | ------------------------------ | | `POST` | [Upload media to the vault](/docs/crm/content/upload-media-to-the-vault) | `/accounts/{of_user_id}/media` | --- # Upload media to the vault (/docs/crm/content/upload-media-to-the-vault) `POST https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/media` Upload a photo, video, gif or audio file to the account's vault, and get back a reference you can attach to a post, message or story. **Two ways to call it:** 1. `multipart/form-data` with a `file` part β€” raw bytes. 2. `application/json` with `{"source_url": "https://…"}` β€” we fetch the file server-side. Use this when your media already lives somewhere public (Drive, S3, a CDN); it saves you building a multipart request at all. **What happens under the hood.** OnlyFans has no single upload endpoint. The web client runs a four-stage pipeline and so do we: `POST /api2/v2/upload/signed/create` β†’ `PUT` the bytes straight to the returned pre-signed S3 URL (5 MiB parts for files β‰₯ 5 MiB) β†’ `POST /api2/v2/upload/signed/finish` β†’ hand the S3 descriptor to OnlyFans' converter host. You do not have to orchestrate any of that. **Using the result.** Put the returned `media` object into the post/message's **`mediaFiles`** array β€” not `media`, which OnlyFans silently ignores for freshly uploaded files. Pass the object through whole; trimming it to just `processId` also silently attaches nothing: ```json { "text": "new set πŸ”₯", "mediaFiles": [ { "processId": "0ifuov…", "host": "convert4.onlyfans.com", "thumbId": 1, "name": "IMG_2676.HEIC", "extra": "…" } ], "isScheduled": 1, "scheduledDate": "2026-08-20T12:00:00+00:00" } ``` ⚠️ Two things that fail *silently*, both confirmed on a live account: * Using `media` instead of `mediaFiles`, or trimming the object down to `{processId}`, returns `200` with **no media attached**. * **`postedAt` does not schedule anything.** In either format (`…Z` or `…+00:00`) OnlyFans ignores it and publishes immediately β€” verified live. Scheduling requires **two** fields instead: ```json { "isScheduled": 1, "scheduledDate": "2026-08-20T12:00:00+00:00" } ``` Always confirm the post actually queued by checking `GET /api2/v2/schedules` for its id β€” a post that published instead of queueing looks identical in the create response apart from `postedAt`. Media already in the vault is still referenced by plain integer id β€” list those with `GET /api2/v2/vault/media`. **An upload does not by itself create a vault item, and that matches OnlyFans exactly.** OnlyFans has no upload-to-vault endpoint: its own vault page is browse/organise only (list, hide, folders, attach), and the uploader is wired solely into the post/message composer. The vault entry is created when a post, message or story consumes the `processId`. So immediately after this call the file will *not* appear in `GET /api2/v2/vault/media`, nor in `GET /api2/v2/vault/media/processing`, nor under `GET /api2/v2/vault/media/hash?h={md5}&size={bytes}` β€” that last one is the lookup OnlyFans' own client uses to decide whether a file is already in the vault, and it answers `404 Media Not Found`. Publish or schedule with the `processId` and the vault row appears. This is the same behaviour you get clicking upload in the OnlyFans web app. **Working example:** a runnable Python client covering upload, immediate posting and scheduling β€” including every silent-failure case above β€” is at [theonlyapi-posting-example.zip](https://docs.theonlyapi.com/theonlyapi-posting-example.zip). **Requires writes to be enabled** for the account (`PATCH /accounts/{of_user_id}/polling {"allow_of_write_actions": true}`), because uploading acts as the creator. **OnlyFans only.** The Fansly upload pipeline is not wired yet; a Fansly account returns 501. *(This replaces the long-documented `POST /api2/v2/media`, which never existed.)* ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `of_user_id` (string, required) β€” Creator account ID of the connected account (OnlyFans or Fansly). Use `GET /accounts` to list connected accounts and their IDs. ## Header parameters - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `multipart/form-data` (required) - `file` (string, required) β€” The media file to upload. - `secure` (boolean) β€” Upload to the secure (DRM) path instead of the standard one. Default `false`. ## Responses ### 200 β€” Upload complete - `success` (boolean) - `media` (object) β€” Ready to drop into a post/message `media` array. - `processId` (string) - `host` (string) - `name` (string) - `extra` (string) - `data` (object) β€” Full converter response β€” thumbs, sourceUrl, duration, plus the echoed key/etag/contentType/size. ### 400 No file and no source_url, an unsafe source_url, or OnlyFans rejected the upload descriptor. ### 403 Writes are disabled for this account (`code: WRITES_DISABLED`). ### 413 β€” File exceeds MEDIA_UPLOAD_MAX_BYTES. ### 501 β€” Fansly account β€” not supported yet. ### 502 A stage failed upstream (S3 PUT, the converter, or fetching source_url). The `stage` field says which. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/media" \ -H "X-API-Key: " ``` --- # Earnings (/docs/crm/earnings) {/* Generated by scripts/gen-api.ts β€” edit that script, not this file. */} Revenue & earnings data, including the cross-account `GET /earnings/summary` aggregation. Fansly-aware. | Method | Endpoint | Path | | ------ | ------------------------------------------------------------------------------------------------------------- | ---------------------------------------- | | `GET` | [Get account balances](/docs/crm/earnings/get-account-balances) | `/accounts/{of_user_id}/balances` | | `GET` | [Get earnings chart data](/docs/crm/earnings/get-earnings-chart-data) | `/accounts/{of_user_id}/earnings` | | `GET` | [Verify cached earnings against the platform](/docs/crm/earnings/verify-cached-earnings-against-the-platform) | `/accounts/{of_user_id}/earnings/verify` | | `GET` | [Get panel-wide payout totals](/docs/crm/earnings/get-panel-wide-payout-totals) | `/balances/summary` | | `GET` | [Aggregated earnings across all accounts](/docs/crm/earnings/aggregated-earnings-across-all-accounts) | `/earnings/summary` | --- # Aggregated earnings across all accounts (/docs/crm/earnings/aggregated-earnings-across-all-accounts) `GET https://theonlyapi.com/api/crm/your-crm-id/earnings/summary` Server-side earnings aggregation across every account in the panel β€” OnlyFans and Fansly combined into one normalized response. The response is cached in memory per (panel, period) with a 2–15 minute TTL depending on the period, and auto-invalidates when an earnings-changing event (`new_tip`, `new_purchase`, `balance_increased`) fires for any account in the panel. **Guide:** [Earnings & transactions](/docs/earnings) ## Authentication - `X-API-Key` header (apiKey) ## Query parameters - `period` ("today" | "week" | "month") β€” Default `week`. ## Responses ### 200 β€” Aggregated earnings - `total` (number) - `prev_total` (number) - `by_category` (object) - `subscriptions` (number) - `posts` (number) - `messages` (number) - `tips` (number) - `streams` (number) - `referrals` (number) - `chart` (number[]) β€” Daily net values. - `accounts_count` (integer) - `transactions_counted` (integer) - `transactions_capped` (boolean) - `period` (string) - `cached` (boolean) - `cached_age_seconds` (integer) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/earnings/summary" \ -H "X-API-Key: " ``` --- # Get account balances (/docs/crm/earnings/get-account-balances) `GET https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/balances` Fetch current payout balance for a connected account. **Guide:** [Earnings & transactions](/docs/earnings) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `of_user_id` (string, required) β€” Creator account ID of the connected account (OnlyFans or Fansly). Use `GET /accounts` to list connected accounts and their IDs. ## Header parameters - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Balance data - `success` (boolean) - `balances` (object) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/balances" \ -H "X-API-Key: " ``` --- # Get earnings chart data (/docs/crm/earnings/get-earnings-chart-data) `GET https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/earnings` Fetch earnings data for a date range with chart-ready breakdown. **Guide:** [Earnings & transactions](/docs/earnings) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `of_user_id` (string, required) β€” Creator account ID of the connected account (OnlyFans or Fansly). Use `GET /accounts` to list connected accounts and their IDs. ## Query parameters - `startDate` (string, required) β€” Start date (ISO format). - `endDate` (string) β€” End date (ISO format). - `withTotal` (string) β€” Default `true`. ## Header parameters - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Earnings data with chart arrays - `success` (boolean) - `earnings` (object) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/earnings" \ -H "X-API-Key: " ``` --- # Get panel-wide payout totals (/docs/crm/earnings/get-panel-wide-payout-totals) `GET https://theonlyapi.com/api/crm/your-crm-id/balances/summary` Available and pending payout totals across every connected account, in **one** query and **zero** platform calls. These are last-known values, not live ones. `payoutAvailable` is only knowable by asking the platform, so a live panel-wide total would cost one round trip per account β€” the honest trade is to serve the last sample and say how old it is. `GET /accounts/{of_user_id}/balances` stamps a fresh sample each time it runs, so normal dashboard use keeps the figures warm at no extra cost. Label the number with `oldest_sample_at` / `newest_sample_at`, and treat `accounts_never_sampled` as "not counted yet" rather than zero. `currency` is the panel's most common currency. **Guide:** [Earnings & transactions](/docs/earnings) ## Authentication - `X-API-Key` header (apiKey) ## Responses ### 200 β€” Panel totals with sample-freshness metadata Amounts are rounded to 2 decimal places. - `accounts` (integer, required) - `accounts_never_sampled` (any, required) - `accounts_with_balance` (any, required) - `currency` (any, required) - `newest_sample_at` (any, required) - `oldest_sample_at` (any, required) - `success` (boolean, required) - `total_available` (number, required) - `total_pending` (number, required) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/balances/summary" \ -H "X-API-Key: " ``` --- # Verify cached earnings against the platform (/docs/crm/earnings/verify-cached-earnings-against-the-platform) `GET https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/earnings/verify` Cross-check one account's cached earnings against OnlyFans' own chart for the same window, and report both numbers plus the difference. `GET /earnings/summary` sums the local transaction cache rather than asking the platform, because the live path cannot converge at panel scale. The cost of that choice is a trust question, and this is the answer to it: same period, both sources, side by side. **Per-account on purpose.** It makes real upstream calls and sits on the sensitive rate-limit tier so it can never become something a dashboard fans out over hundreds of accounts. If the platform is unreachable, `live_available` is `false` and `live_total`/`difference` are `null` β€” that is "could not check", not "matches". **Guide:** [Earnings & transactions](/docs/earnings) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `of_user_id` (string, required) β€” Creator account ID of the connected account (OnlyFans or Fansly). Use `GET /accounts` to list connected accounts and their IDs. ## Query parameters - `period` ("today" | "week" | "month") β€” Window to compare. Ignored when `startDate` and `endDate` are both supplied. Default `week`. - `startDate` (string) β€” Custom range start. Requires `endDate`. - `endDate` (string) β€” Custom range end. Requires `startDate`. ## Responses ### 200 β€” Both totals and their difference `matches` is the verdict for this window. - `cached_total` (number, required) - `cached_transactions` (any, required) - `difference` (number, required) - `end` (any, required) - `last_synced_at` (string, required) - `live_available` (boolean, required) - `live_total` (any, required) - `matches` (boolean, required) - `of_user_id` (string, required) - `period` (any, required) - `start` (any, required) - `success` (boolean, required) ### 400 `period` not one of `today`/`week`/`month`, or an unparseable `startDate`/`endDate`. ### 404 β€” Account not found in this panel. ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/earnings/verify" \ -H "X-API-Key: " ``` --- # Events & Streaming (/docs/crm/events-and-streaming) {/* Generated by scripts/gen-api.ts β€” edit that script, not this file. */} Real-time event feed β€” `GET /events` for polling, `GET /events/stream` for Server-Sent Events (rate-limit exempt). | Method | Endpoint | Path | | ------ | ----------------------------------------------------------------------- | ---------------- | | `GET` | [List events](/docs/crm/events-and-streaming/list-events) | `/events` | | `GET` | [Stream events (SSE)](/docs/crm/events-and-streaming/stream-events-sse) | `/events/stream` | --- # List events (/docs/crm/events-and-streaming/list-events) `GET https://theonlyapi.com/api/crm/your-crm-id/events` Poll the panel's event feed. **Zero platform requests.** Covers OnlyFans and Fansly accounts alike. **Guide:** [Events](/docs/events) ## Authentication - `X-API-Key` header (apiKey) ## Query parameters - `types` (string) β€” Comma-separated event types, e.g. `new_subscriber,new_tip`. An unknown type returns 400. - `of_user_id` (string) β€” Restrict to one connected account. - `since` (string) β€” ISO timestamp lower bound. - `until` (string) β€” ISO timestamp upper bound. - `limit` (integer) β€” Default `100`. ## Responses ### 200 β€” Event list - `success` (boolean) - `events` (object[]) ### 400 β€” Unknown event type ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/events" \ -H "X-API-Key: " ``` --- # Stream events (SSE) (/docs/crm/events-and-streaming/stream-events-sse) `GET https://theonlyapi.com/api/crm/your-crm-id/events/stream` Long-lived **Server-Sent Events** stream of panel events. **Rate-limit exempt.** Use this instead of polling to observe refresh-job completion and `export.progress` / `export.complete`. Optional server-side filtering: `?types=new_subscriber,new_tip` (`*` or absent = everything). An unknown type returns 400. **Guide:** [Events](/docs/events) ## Authentication - `X-API-Key` header (apiKey) ## Query parameters - `types` (string) β€” Comma-separated event types, or `*` for everything. ## Responses ### 200 β€” SSE stream ### 400 β€” Unknown event type ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/events/stream" \ -H "X-API-Key: " ``` --- # Exports (/docs/crm/exports) {/* Generated by scripts/gen-api.ts β€” edit that script, not this file. */} Async data export jobs producing a downloadable ZIP. Progress streams over `GET /events/stream`. | Method | Endpoint | Path | | -------- | ---------------------------------------------------------------------------- | -------------------------------------------------- | | `GET` | [List export jobs](/docs/crm/exports/list-export-jobs) | `/accounts/{of_user_id}/exports` | | `POST` | [Create an export job](/docs/crm/exports/create-an-export-job) | `/accounts/{of_user_id}/exports` | | `GET` | [Get export job status](/docs/crm/exports/get-export-job-status) | `/accounts/{of_user_id}/exports/{job_id}` | | `DELETE` | [Delete an export job](/docs/crm/exports/delete-an-export-job) | `/accounts/{of_user_id}/exports/{job_id}` | | `POST` | [Cancel a running export job](/docs/crm/exports/cancel-a-running-export-job) | `/accounts/{of_user_id}/exports/{job_id}/cancel` | | `GET` | [Download an export ZIP](/docs/crm/exports/download-an-export-zip) | `/accounts/{of_user_id}/exports/{job_id}/download` | --- # Cancel a running export job (/docs/crm/exports/cancel-a-running-export-job) `POST https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/exports/{job_id}/cancel` **Guide:** [Data exports](/docs/exports) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `of_user_id` (string, required) β€” Creator account ID of the connected account (OnlyFans or Fansly). Use `GET /accounts` to list connected accounts and their IDs. - `job_id` (string, required) ## Responses ### 200 β€” Job cancelled - `job` (any, required) - `success` (boolean, required) ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/exports/{job_id}/cancel" \ -H "X-API-Key: " ``` --- # Create an export job (/docs/crm/exports/create-an-export-job) `POST https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/exports` Kick off an async data export for one account. Returns **202** with the created job. Progress streams over `GET /events/stream` as `export.progress`; completion fires `export.complete`. The generated ZIP is downloadable from `GET /accounts/{of_user_id}/exports/{job_id}/download` for the configured retention window. Fansly-aware. **Guide:** [Data exports](/docs/exports) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `of_user_id` (string, required) β€” Creator account ID of the connected account (OnlyFans or Fansly). Use `GET /accounts` to list connected accounts and their IDs. ## Request body Content type: `application/json` (required) - `data_types` ("subscribers" | "transactions" | "fans" | "earnings" | "messages" | "account"[]) β€” e.g. `["subscribers","transactions"]`. - `since` (string) β€” YYYY-MM-DD lower bound. e.g. `"2026-01-01"`. - `until` (string) β€” YYYY-MM-DD upper bound. e.g. `"2026-06-30"`. - `include_media` (boolean) β€” OnlyFans only in v1. Default `false`. ## Responses ### 202 β€” Export job created - `already_running` (boolean) - `job` (any, required) - `success` (boolean, required) - `warning` (string) ### 400 β€” Invalid data_types or date range ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/exports" \ -H "X-API-Key: " \ -H "Content-Type: application/json" \ -d '{"data_types":["subscribers","transactions"],"since":"2026-01-01","until":"2026-06-30","include_media":false}' ``` --- # Delete an export job (/docs/crm/exports/delete-an-export-job) `DELETE https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/exports/{job_id}` Delete the job and its generated ZIP. **Guide:** [Data exports](/docs/exports) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `of_user_id` (string, required) β€” Creator account ID of the connected account (OnlyFans or Fansly). Use `GET /accounts` to list connected accounts and their IDs. - `job_id` (string, required) ## Responses ### 200 β€” Job deleted - `success` (boolean, required) ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/exports/{job_id}" \ -H "X-API-Key: " ``` --- # Download an export ZIP (/docs/crm/exports/download-an-export-zip) `GET https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/exports/{job_id}/download` Download the generated archive. Available until the retention window expires. **Guide:** [Data exports](/docs/exports) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `of_user_id` (string, required) β€” Creator account ID of the connected account (OnlyFans or Fansly). Use `GET /accounts` to list connected accounts and their IDs. - `job_id` (string, required) ## Responses ### 200 β€” ZIP archive ### 404 β€” Job not found, not finished, or expired ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/exports/{job_id}/download" \ -H "X-API-Key: " ``` --- # Get export job status (/docs/crm/exports/get-export-job-status) `GET https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/exports/{job_id}` **Guide:** [Data exports](/docs/exports) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `of_user_id` (string, required) β€” Creator account ID of the connected account (OnlyFans or Fansly). Use `GET /accounts` to list connected accounts and their IDs. - `job_id` (string, required) ## Responses ### 200 β€” Export job - `job` (any, required) - `success` (boolean, required) ### 404 β€” Job not found ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/exports/{job_id}" \ -H "X-API-Key: " ``` --- # List export jobs (/docs/crm/exports/list-export-jobs) `GET https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/exports` **Guide:** [Data exports](/docs/exports) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `of_user_id` (string, required) β€” Creator account ID of the connected account (OnlyFans or Fansly). Use `GET /accounts` to list connected accounts and their IDs. ## Responses ### 200 β€” Export job list - `jobs` (any[], required) - `success` (boolean, required) - `total` (integer, required) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/exports" \ -H "X-API-Key: " ``` --- # Fans (/docs/crm/fans) {/* Generated by scripts/gen-api.ts β€” edit that script, not this file. */} Fan CRM across all accounts in the panel β€” tags, notes, per-fan cached transactions, profile refresh. Fansly-aware. | Method | Endpoint | Path | | -------- | ------------------------------------------------------------------------------------------------- | ---------------------------------------------------------- | | `POST` | [Refresh a fan profile from the platform](/docs/crm/fans/refresh-a-fan-profile-from-the-platform) | `/accounts/{of_user_id}/fans/{fan_id}/refresh-profile` | | `GET` | [Get a fan's cached transactions](/docs/crm/fans/get-a-fan-s-cached-transactions) | `/accounts/{of_user_id}/fans/{fan_id}/transactions/cached` | | `GET` | [List fans](/docs/crm/fans/list-fans) | `/fans` | | `PUT` | [Set a fan note](/docs/crm/fans/set-a-fan-note) | `/fans/{fan_of_user_id}/note` | | `POST` | [Add a tag to a fan](/docs/crm/fans/add-a-tag-to-a-fan) | `/fans/{fan_of_user_id}/tags` | | `DELETE` | [Remove a tag from a fan](/docs/crm/fans/remove-a-tag-from-a-fan) | `/fans/{fan_of_user_id}/tags/{tag}` | --- # Add a tag to a fan (/docs/crm/fans/add-a-tag-to-a-fan) `POST https://theonlyapi.com/api/crm/your-crm-id/fans/{fan_of_user_id}/tags` **Guide:** [Subscribers & fans](/docs/subscribers) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `fan_of_user_id` (string, required) β€” Fan's platform user ID β€” the same value returned as `of_user_id` on a row from `GET /fans`, not an internal database id. ## Request body Content type: `application/json` (required) - `tag` (string, required) β€” e.g. `"whale"`. ## Responses ### 200 β€” Tag added - `success` (boolean, required) ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/fans/{fan_of_user_id}/tags" \ -H "X-API-Key: " \ -H "Content-Type: application/json" \ -d '{"tag":"whale"}' ``` --- # Get a fan's cached transactions (/docs/crm/fans/get-a-fan-s-cached-transactions) `GET https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/fans/{fan_id}/transactions/cached` Every cached transaction attributed to one fan on this account. **Zero platform requests.** Fansly-aware. **Guide:** [Subscribers & fans](/docs/subscribers) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `of_user_id` (string, required) β€” Creator account ID of the connected account (OnlyFans or Fansly). Use `GET /accounts` to list connected accounts and their IDs. - `fan_id` (string, required) β€” Fan's platform user ID. ## Query parameters - `limit` (integer) β€” Maximum number of rows to return. Default `100`. - `offset` (integer) β€” Row offset for pagination. Default `0`. ## Responses ### 200 β€” Cached transaction list - `count` (integer, required) - `hasMore` (boolean, required) - `limit` (integer, required) - `list` (any[], required) - `mapped_spent` (number, required) - `offset` (integer, required) - `success` (boolean, required) - `total` (integer, required) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/fans/{fan_id}/transactions/cached" \ -H "X-API-Key: " ``` --- # List fans (/docs/crm/fans/list-fans) `GET https://theonlyapi.com/api/crm/your-crm-id/fans` Fan CRM across the whole panel β€” every fan seen on any connected account, OnlyFans or Fansly, with tags, notes, spend, and activity counters. **Zero platform requests.** **Guide:** [Subscribers & fans](/docs/subscribers) ## Authentication - `X-API-Key` header (apiKey) ## Query parameters - `of_user_id` (string) β€” Restrict to fans of one connected account. - `limit` (integer) β€” Default `100`. - `offset` (integer) β€” Row offset for pagination. Default `0`. - `sort` ("last_seen" | "first_seen" | "tips" | "spend" | "events") β€” Default `last_seen`. - `search` (string) β€” Free-text search over fan name/username. - `tag` (string) β€” Filter to fans carrying this tag. ## Responses ### 200 β€” Fan list - `success` (boolean) - `fans` (object[]) - `count` (integer) ### 400 β€” Invalid sort value ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/fans" \ -H "X-API-Key: " ``` --- # Refresh a fan profile from the platform (/docs/crm/fans/refresh-a-fan-profile-from-the-platform) `POST https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/fans/{fan_id}/refresh-profile` Re-fetch one fan's profile from the platform and update the cache. Consumes a platform request. **Guide:** [Subscribers & fans](/docs/subscribers) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `of_user_id` (string, required) β€” Creator account ID of the connected account (OnlyFans or Fansly). Use `GET /accounts` to list connected accounts and their IDs. - `fan_id` (string, required) β€” Fan's platform user ID. ## Header parameters - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Fan profile refreshed - `fan` (any, required) - `success` (boolean, required) - `updated_cache` (boolean, required) ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/fans/{fan_id}/refresh-profile" \ -H "X-API-Key: " ``` --- # Remove a tag from a fan (/docs/crm/fans/remove-a-tag-from-a-fan) `DELETE https://theonlyapi.com/api/crm/your-crm-id/fans/{fan_of_user_id}/tags/{tag}` **Guide:** [Subscribers & fans](/docs/subscribers) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `fan_of_user_id` (string, required) β€” Fan's platform user ID β€” the same value returned as `of_user_id` on a row from `GET /fans`, not an internal database id. - `tag` (string, required) ## Responses ### 200 β€” Tag removed - `success` (boolean, required) ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/fans/{fan_of_user_id}/tags/{tag}" \ -H "X-API-Key: " ``` --- # Set a fan note (/docs/crm/fans/set-a-fan-note) `PUT https://theonlyapi.com/api/crm/your-crm-id/fans/{fan_of_user_id}/note` Replace the free-text CRM note stored against a fan. Send an empty string to clear it. **Guide:** [Subscribers & fans](/docs/subscribers) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `fan_of_user_id` (string, required) β€” Fan's platform user ID β€” the same value returned as `of_user_id` on a row from `GET /fans`, not an internal database id. ## Request body Content type: `application/json` (required) - `note` (string) β€” e.g. `"Prefers PPV over tips."`. ## Responses ### 200 β€” Note saved - `success` (boolean, required) ## Example ```bash curl -X PUT "https://theonlyapi.com/api/crm/your-crm-id/fans/{fan_of_user_id}/note" \ -H "X-API-Key: " \ -H "Content-Type: application/json" \ -d '{"note":"Prefers PPV over tips."}' ``` --- # Integrations (/docs/crm/integrations) {/* Generated by scripts/gen-api.ts β€” edit that script, not this file. */} Third-party integrations. One Telegram channel per panel: pair it once, then matching events are delivered to that chat. The bot token is encrypted at rest and is never returned by any route. | Method | Endpoint | Path | | -------- | ----------------------------------------------------------------------------------------- | ------------------------------- | | `GET` | [Get the Telegram integration](/docs/crm/integrations/get-the-telegram-integration) | `/integrations/telegram` | | `PATCH` | [Update the Telegram integration](/docs/crm/integrations/update-the-telegram-integration) | `/integrations/telegram` | | `DELETE` | [Remove the Telegram integration](/docs/crm/integrations/remove-the-telegram-integration) | `/integrations/telegram` | | `POST` | [Register Telegram groups](/docs/crm/integrations/register-telegram-groups) | `/integrations/telegram/groups` | | `POST` | [Start Telegram pairing](/docs/crm/integrations/start-telegram-pairing) | `/integrations/telegram/pair` | | `POST` | [Send a Telegram test message](/docs/crm/integrations/send-a-telegram-test-message) | `/integrations/telegram/test` | --- # Get the Telegram integration (/docs/crm/integrations/get-the-telegram-integration) `GET https://theonlyapi.com/api/crm/your-crm-id/integrations/telegram` The panel's Telegram channel, or `integration: null` if none is configured. `shared_bot_available` says whether this deployment has our shared bot configured β€” check it before offering "use the Xcelerate bot", so you never present a button that cannot work. `event_types` lists every event type you may subscribe to. The bot token is never returned by this or any other route; `has_custom_token` only reports whether one is stored. **Guide:** [Integrations](/docs/integrations) ## Authentication - `X-API-Key` header (apiKey) ## Responses ### 200 Integration state, plus the deployment's shared-bot availability and the allowed event types. - `event_types` (any[], required) - `integration` (object, required) - `bot_mode` (any) - `bot_username` (any) - `chat_id` (any) - `chat_title` (any) - `chat_type` (any) - `consecutive_failures` (any) - `created_at` (string) - `event_types` (any) - `has_custom_token` (boolean) - `is_active` (boolean) - `is_paired` (boolean) - `last_delivery_at` (any) - `last_error` (any) - `paired_at` (any) - `updated_at` (string) - `shared_bot_available` (boolean, required) - `shared_bot_username` (any, required) - `success` (boolean, required) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/integrations/telegram" \ -H "X-API-Key: " ``` --- # Register Telegram groups (/docs/crm/integrations/register-telegram-groups) `POST https://theonlyapi.com/api/crm/your-crm-id/integrations/telegram/groups` Register Telegram group targets so automations and webhooks can deliver notifications there. **Guide:** [Integrations](/docs/integrations) ## Authentication - `X-API-Key` header (apiKey) ## Request body Content type: `application/json` (required) - `groups` (object[]) β€” Telegram group identifiers to register. ## Responses ### 200 β€” Groups registered - `groups` (any[], required) - `success` (boolean, required) ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/integrations/telegram/groups" \ -H "X-API-Key: " \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Remove the Telegram integration (/docs/crm/integrations/remove-the-telegram-integration) `DELETE https://theonlyapi.com/api/crm/your-crm-id/integrations/telegram` Unpair the channel and delete the stored configuration, including any custom bot token. **Guide:** [Integrations](/docs/integrations) ## Authentication - `X-API-Key` header (apiKey) ## Responses ### 200 β€” Removed. - `success` (boolean, required) ### 404 β€” No Telegram integration configured. ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/integrations/telegram" \ -H "X-API-Key: " ``` --- # Send a Telegram test message (/docs/crm/integrations/send-a-telegram-test-message) `POST https://theonlyapi.com/api/crm/your-crm-id/integrations/telegram/test` Post a test message to the paired chat, so you can confirm the whole path end to end. Returns `400` with the failure reason β€” and the current integration state, including `last_error` β€” if Telegram refuses it. **Guide:** [Integrations](/docs/integrations) ## Authentication - `X-API-Key` header (apiKey) ## Responses ### 200 β€” Test message delivered. - `integration` (object, required) - `bot_mode` (any) - `bot_username` (any) - `chat_id` (any) - `chat_title` (any) - `chat_type` (any) - `consecutive_failures` (any) - `created_at` (string) - `event_types` (any) - `has_custom_token` (boolean) - `is_active` (boolean) - `is_paired` (boolean) - `last_delivery_at` (any) - `last_error` (any) - `paired_at` (any) - `updated_at` (string) ### 400 β€” Not paired, inactive, or Telegram rejected the send The body carries the reason. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/integrations/telegram/test" \ -H "X-API-Key: " ``` --- # Start Telegram pairing (/docs/crm/integrations/start-telegram-pairing) `POST https://theonlyapi.com/api/crm/your-crm-id/integrations/telegram/pair` Begin (or restart) pairing and get a `t.me` deep link. Open the link, and the chat that the bot lands in becomes the panel's channel. Two modes: - `bot_mode: "shared"` β€” use our bot. Nothing else to supply. Returns `409` if this deployment has no shared bot configured, rather than handing back a link that can never resolve. - `bot_mode: "custom"` β€” use your own bot, passing its `bot_token`. We verify the token with Telegram before storing it, encrypt it at rest, and clear any existing webhook on that bot (otherwise our polling would conflict with it and the deep link would silently never resolve). The response carries the deep link and its expiry, never a token. Calling this again replaces any pending code. **Guide:** [Integrations](/docs/integrations) ## Authentication - `X-API-Key` header (apiKey) ## Request body Content type: `application/json` (required) - `bot_mode` ("shared" | "custom") β€” Default `"shared"`. - `bot_token` (string) β€” Required when `bot_mode` is `custom`. Stored encrypted and never returned. e.g. `"123456789:AA…"`. - `event_types` (string[]) β€” Which events to deliver. Defaults to every type. ## Responses ### 200 β€” Pairing started Open `deep_link` before `expires_at` (`ttl_seconds` from now). - `bot_username` (any, required) - `deep_link` (any, required) - `expires_at` (any, required) - `integration` (object, required) - `bot_mode` (any) - `bot_username` (any) - `chat_id` (any) - `chat_title` (any) - `chat_type` (any) - `consecutive_failures` (any) - `created_at` (string) - `event_types` (any) - `has_custom_token` (boolean) - `is_active` (boolean) - `is_paired` (boolean) - `last_delivery_at` (any) - `last_error` (any) - `paired_at` (any) - `updated_at` (string) - `success` (boolean, required) - `ttl_seconds` (any, required) ### 400 `bot_mode` invalid, an event type is not recognised, the token is malformed, Telegram rejected it, or it is the shared token (use `bot_mode: "shared"`). ### 409 `bot_mode: "shared"` requested but this deployment has no shared bot. Connect your own bot instead. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/integrations/telegram/pair" \ -H "X-API-Key: " \ -H "Content-Type: application/json" \ -d '{"bot_mode":"shared","bot_token":"123456789:AA…"}' ``` --- # Update the Telegram integration (/docs/crm/integrations/update-the-telegram-integration) `PATCH https://theonlyapi.com/api/crm/your-crm-id/integrations/telegram` Change which events are delivered, or pause delivery without unpairing. Send only the fields you want to change. **Guide:** [Integrations](/docs/integrations) ## Authentication - `X-API-Key` header (apiKey) ## Request body Content type: `application/json` (required) - `event_types` (string[]) β€” Event types to deliver. `["*"]` means every type. e.g. `["new_subscriber","new_tip"]`. - `is_active` (boolean) β€” Set `false` to stop delivery while keeping the pairing. ## Responses ### 200 β€” Updated integration. - `integration` (object, required) - `bot_mode` (any) - `bot_username` (any) - `chat_id` (any) - `chat_title` (any) - `chat_type` (any) - `consecutive_failures` (any) - `created_at` (string) - `event_types` (any) - `has_custom_token` (boolean) - `is_active` (boolean) - `is_paired` (boolean) - `last_delivery_at` (any) - `last_error` (any) - `paired_at` (any) - `updated_at` (string) - `success` (boolean, required) ### 400 β€” An event type is not recognised. ### 404 β€” No Telegram integration configured. ## Example ```bash curl -X PATCH "https://theonlyapi.com/api/crm/your-crm-id/integrations/telegram" \ -H "X-API-Key: " \ -H "Content-Type: application/json" \ -d '{"event_types":["new_subscriber","new_tip"]}' ``` --- # MCP (/docs/crm/mcp) {/* Generated by scripts/gen-api.ts β€” edit that script, not this file. */} Hosted MCP server support. `GET /api/whoami` turns a bearer token into a tenant; `PATCH /mcp/unsafe-proxy` toggles non-GET tool access (off by default). | Method | Endpoint | Path | | ------- | -------------------------------------------------------------------------------- | ------------------- | | `PATCH` | [Toggle MCP non-GET proxy access](/docs/crm/mcp/toggle-mcp-non-get-proxy-access) | `/mcp/unsafe-proxy` | --- # Toggle MCP non-GET proxy access (/docs/crm/mcp/toggle-mcp-non-get-proxy-access) `PATCH https://theonlyapi.com/api/crm/your-crm-id/mcp/unsafe-proxy` Toggle whether the hosted MCP server may issue non-GET requests through the generic OF proxy tool. **Off by default.** Use with care: enabling it lets a model POST/PATCH/DELETE arbitrary OnlyFans endpoints on your behalf. **Guide:** [Use these docs with an AI](/docs/ai-agents) ## Authentication - `X-API-Key` header (apiKey) ## Request body Content type: `application/json` (required) - `enabled` (boolean) β€” Default `false`. ## Responses ### 200 β€” Toggle updated - `success` (boolean) - `mcp_unsafe_proxy` (boolean) ## Example ```bash curl -X PATCH "https://theonlyapi.com/api/crm/your-crm-id/mcp/unsafe-proxy" \ -H "X-API-Key: " \ -H "Content-Type: application/json" \ -d '{"enabled":false}' ``` --- # Messaging (/docs/crm/messaging) {/* Generated by scripts/gen-api.ts β€” edit that script, not this file. */} Chats, single DMs/PPVs, mass DMs, and PPV performance stats. Fansly-aware. | Method | Endpoint | Path | | ------ | ------------------------------------------------------------------ | ------------------------------------------------------ | | `GET` | [List chats](/docs/crm/messaging/list-chats) | `/accounts/{of_user_id}/chats` | | `GET` | [Get message history](/docs/crm/messaging/get-message-history) | `/accounts/{of_user_id}/chats/{with_user_id}/messages` | | `POST` | [Send a DM or PPV](/docs/crm/messaging/send-a-dm-or-ppv) | `/accounts/{of_user_id}/chats/{with_user_id}/messages` | | `POST` | [Send a mass DM](/docs/crm/messaging/send-a-mass-dm) | `/accounts/{of_user_id}/messages/mass` | | `GET` | [PPV performance stats](/docs/crm/messaging/ppv-performance-stats) | `/accounts/{of_user_id}/ppv-stats` | --- # Get message history (/docs/crm/messaging/get-message-history) `GET https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/chats/{with_user_id}/messages` Message history for one conversation, newest-first by default. Fansly-aware. **Guide:** [Messaging & mass DM](/docs/messaging) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `of_user_id` (string, required) β€” Creator account ID of the connected account (OnlyFans or Fansly). Use `GET /accounts` to list connected accounts and their IDs. - `with_user_id` (string, required) β€” The fan's user ID. ## Query parameters - `limit` (integer) β€” Default `100`. ## Header parameters - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Message list - `hasMore` (boolean, required) - `messages` (any[], required) - `success` (boolean, required) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/chats/{with_user_id}/messages" \ -H "X-API-Key: " ``` --- # List chats (/docs/crm/messaging/list-chats) `GET https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/chats` Conversation list for a connected account. Fansly-aware. **Guide:** [Messaging & mass DM](/docs/messaging) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `of_user_id` (string, required) β€” Creator account ID of the connected account (OnlyFans or Fansly). Use `GET /accounts` to list connected accounts and their IDs. ## Query parameters - `limit` (integer) β€” Default `100`. - `offset` (integer) β€” Row offset for pagination. Default `0`. ## Header parameters - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Chat list - `chats` (any[], required) - `hasMore` (boolean, required) - `success` (boolean, required) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/chats" \ -H "X-API-Key: " ``` --- # PPV performance stats (/docs/crm/messaging/ppv-performance-stats) `GET https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/ppv-stats` Purchase/unlock statistics for PPV messages sent from this account, computed from cached transactions. **Zero platform requests.** Fansly-aware. **Guide:** [Messaging & mass DM](/docs/messaging) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `of_user_id` (string, required) β€” Creator account ID of the connected account (OnlyFans or Fansly). Use `GET /accounts` to list connected accounts and their IDs. ## Query parameters - `since` (string) β€” ISO date lower bound. - `until` (string) β€” ISO date upper bound. ## Responses ### 200 β€” PPV statistics - `stats` (object, required) - `success` (boolean, required) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/ppv-stats" \ -H "X-API-Key: " ``` --- # Send a DM or PPV (/docs/crm/messaging/send-a-dm-or-ppv) `POST https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/chats/{with_user_id}/messages` Send a single DM (or PPV) to one fan. Works for OnlyFans and Fansly. - `price > 0` makes the message a **PPV**. - `mediaFiles` locks vault media behind the price. - OnlyFans sends are gated per account by the `allow_of_write_actions` polling setting (`PATCH /accounts/{of_user_id}/polling`). Rate limited to 120 requests/minute. **Guide:** [Messaging & mass DM](/docs/messaging) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `of_user_id` (string, required) β€” Creator account ID of the connected account (OnlyFans or Fansly). Use `GET /accounts` to list connected accounts and their IDs. - `with_user_id` (string, required) β€” The fan's user ID. ## Header parameters - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` (required) - `text` (string, required) β€” e.g. `"Hey! New drop is up πŸ’•"`. - `price` (number) β€” Above 0 makes this a PPV message. Default `0`. - `mediaFiles` (string[]) β€” Vault media IDs to attach. ## Responses ### 200 β€” Message sent - `message` (string, required) - `success` (boolean, required) ### 403 β€” Write actions disabled for this account ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/chats/{with_user_id}/messages" \ -H "X-API-Key: " \ -H "Content-Type: application/json" \ -d '{"text":"Hey! New drop is up πŸ’•","price":0}' ``` --- # Send a mass DM (/docs/crm/messaging/send-a-mass-dm) `POST https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/messages/mass` Send one message to many fans at once. Supports PPV pricing and vault media, and can target a subscriber segment. Rate limited to 120 requests/minute. Fansly-aware. **Guide:** [Messaging & mass DM](/docs/messaging) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `of_user_id` (string, required) β€” Creator account ID of the connected account (OnlyFans or Fansly). Use `GET /accounts` to list connected accounts and their IDs. ## Header parameters - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` (required) - `text` (string, required) β€” e.g. `"New set just dropped!"`. - `price` (number) β€” Above 0 makes this a mass PPV. Default `0`. - `mediaFiles` (string[]) β€” Vault media IDs to attach. - `userLists` (string[]) β€” Target segment(s), e.g. `["active"]` or specific list IDs. - `excludedLists` (string[]) β€” Segment(s) to exclude. ## Responses ### 200 β€” Mass DM queued/sent - `dry_run` (boolean) - `failed` (integer) - `note` (string) - `recipients` (integer, required) - `results` (any[]) - `sample` (any[]) - `sent` (integer, required) - `success` (boolean, required) ### 403 β€” Write actions disabled for this account ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/messages/mass" \ -H "X-API-Key: " \ -H "Content-Type: application/json" \ -d '{"text":"New set just dropped!","price":0}' ``` --- # Notifications (/docs/crm/notifications) {/* Generated by scripts/gen-api.ts β€” edit that script, not this file. */} Account notifications. Fansly-aware. | Method | Endpoint | Path | | ------ | -------------------------------------------------------------- | -------------------------------------- | | `GET` | [Get notifications](/docs/crm/notifications/get-notifications) | `/accounts/{of_user_id}/notifications` | --- # Get notifications (/docs/crm/notifications/get-notifications) `GET https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/notifications` Fetch notifications for a connected account. **Guide:** [Events](/docs/events) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `of_user_id` (string, required) β€” Creator account ID of the connected account (OnlyFans or Fansly). Use `GET /accounts` to list connected accounts and their IDs. ## Query parameters - `limit` (integer) β€” Default `20`. ## Header parameters - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Notification list - `success` (boolean) - `count` (integer) - `notifications` (object[]) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/notifications" \ -H "X-API-Key: " ``` --- # Panel & Usage (/docs/crm/panel-and-usage) {/* Generated by scripts/gen-api.ts β€” edit that script, not this file. */} Panel signup, health, keyβ†’panel resolution, and plan/usage counters. Works for OnlyFans and Fansly panels alike. | Method | Endpoint | Path | | ------ | -------------------------------------------------------------------------------------------------- | ------------------------------------ | | `POST` | [Dashboard user login](/docs/crm/panel-and-usage/dashboard-user-login) | `/api/auth/login` | | `POST` | [Register a dashboard user](/docs/crm/panel-and-usage/register-a-dashboard-user) | `/api/auth/register` | | `POST` | [Send an email verification code](/docs/crm/panel-and-usage/send-an-email-verification-code) | `/api/auth/start-email-verification` | | `POST` | [Verify an email code](/docs/crm/panel-and-usage/verify-an-email-code) | `/api/auth/verify-email` | | `POST` | [Create a CRM panel](/docs/crm/panel-and-usage/create-a-crm-panel) | `/api/crm/register` | | `GET` | [Resolve an API key to a panel](/docs/crm/panel-and-usage/resolve-an-api-key-to-a-panel) | `/api/whoami` | | `GET` | [Service health check](/docs/crm/panel-and-usage/service-health-check) | `/health` | | `GET` | [Get request metrics for your panel](/docs/crm/panel-and-usage/get-request-metrics-for-your-panel) | `/metrics/requests` | | `GET` | [Get plan usage](/docs/crm/panel-and-usage/get-plan-usage) | `/usage` | --- # Create a CRM panel (/docs/crm/panel-and-usage/create-a-crm-panel) `POST https://api.theonlyapi.com/api/crm/register` Create a CRM panel and receive its `crm_id` plus the primary `Default` API key. The key is returned once β€” store it. **Guide:** [Base URL & panels](/docs/base-url) ## Authentication None β€” this endpoint is public. ## Responses ### 200 β€” Panel created - `success` (boolean) - `crm_id` (string) - `api_key` (string) ## Example ```bash curl -X POST "https://api.theonlyapi.com/api/crm/register" ``` --- # Dashboard user login (/docs/crm/panel-and-usage/dashboard-user-login) `POST https://api.theonlyapi.com/api/auth/login` Authenticate a dashboard user. Rate limited to **6 requests/minute** β€” the strictest limit in the API. **Guide:** [Base URL & panels](/docs/base-url) ## Authentication None β€” this endpoint is public. ## Request body Content type: `application/json` (required) - `email` (string, required) - `password` (string, required) ## Responses ### 200 β€” Authenticated - `crm_id` (string, required) - `email` (string, required) - `is_admin` (any, required) - `name` (string, required) - `success` (boolean, required) - `user_id` (any, required) ### 401 β€” Invalid credentials ### 429 β€” Rate limit exceeded (6/minute) ## Example ```bash curl -X POST "https://api.theonlyapi.com/api/auth/login" \ -H "Content-Type: application/json" \ -d '{"email":"string","password":"string"}' ``` --- # Get plan usage (/docs/crm/panel-and-usage/get-plan-usage) `GET https://theonlyapi.com/api/crm/your-crm-id/usage` Current plan and consumption for this panel. Plans: **Free** β€” $0/mo, 1 connected account, 1,000 API calls/month. **Slots** β€” $20 per slot per month ($15 per slot at 15+ slots), 1 slot = 1 connected account, unlimited API calls. **Enterprise** β€” custom pricing and limits. An `api_calls_limit` of `-1` means unlimited. **Guide:** [Base URL & panels](/docs/base-url) ## Authentication - `X-API-Key` header (apiKey) ## Responses ### 200 β€” Usage statistics - `crm_id` (string) - `plan` (string) β€” e.g. `"only-api-free"`. - `api_calls_used` (integer) - `api_calls_limit` (integer) β€” `1000` on Free, `-1` (unlimited) on paid plans. - `accounts_used` (integer) - `accounts_limit` (integer) - `month` (string) β€” e.g. `"2026-07"`. Example response: ```json { "crm_id": "crm_abc123", "plan": "only-api-free", "api_calls_used": 214, "api_calls_limit": 1000, "accounts_used": 1, "accounts_limit": 1, "month": "2026-07" } ``` ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/usage" \ -H "X-API-Key: " ``` --- # Get request metrics for your panel (/docs/crm/panel-and-usage/get-request-metrics-for-your-panel) `GET https://theonlyapi.com/api/crm/your-crm-id/metrics/requests` Request outcomes for your own panel over a time window: volume, status classes, error rate, latency, and the slowest and most error-prone routes. This is what the dashboard Overview charts. The current partial bucket is included, so the numbers are current rather than up to a minute stale. `top_tenants` is always empty here β€” it exists only so one component can render this and the platform-wide admin view interchangeably. **Guide:** [Base URL & panels](/docs/base-url) ## Authentication - `X-API-Key` header (apiKey) ## Query parameters - `hours` (integer) β€” Window to report, in hours (1–2160, i.e. up to 90 days). Default `24`. - `granularity` ("5m" | "15m" | "1h" | "6h" | "1d") β€” Bucket size for `series`. Defaults to a sensible size for `hours`. Also accepted as `bucket`. - `limit` (integer) β€” How many rows in each top-N breakdown (1–50). Default `10`. ## Responses ### 200 `metrics` carries `range`, `totals`, `series`, `status_codes`, `top_routes`, `slowest_routes`, `top_error_routes`, `top_tenants` (empty) and `collector`. - `metrics` (any, required) - `success` (boolean, required) ### 400 `hours` or `limit` out of range, or an unknown `granularity`. ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/metrics/requests" \ -H "X-API-Key: " ``` --- # Register a dashboard user (/docs/crm/panel-and-usage/register-a-dashboard-user) `POST https://api.theonlyapi.com/api/auth/register` Create a dashboard account. This **also creates your CRM panel** and returns its `crm_id` and primary `api_key` in the same response β€” there is no second step. Do *not* follow it with `POST /api/crm/register`: that creates a separate panel with no dashboard user attached, which you cannot log into or manage. **Guide:** [Base URL & panels](/docs/base-url) ## Authentication None β€” this endpoint is public. ## Request body Content type: `application/json` (required) - `email` (string, required) - `password` (string, required) ## Responses ### 200 β€” User registered - `crm_id` (string, required) - `email` (string, required) - `email_verified` (boolean, required) - `name` (string, required) - `success` (boolean, required) - `user_id` (any, required) ### 400 β€” Invalid payload or email already in use ## Example ```bash curl -X POST "https://api.theonlyapi.com/api/auth/register" \ -H "Content-Type: application/json" \ -d '{"email":"string","password":"string"}' ``` --- # Resolve an API key to a panel (/docs/crm/panel-and-usage/resolve-an-api-key-to-a-panel) `GET https://api.theonlyapi.com/api/whoami` Resolves the API key sent in `X-API-Key` to its `crm_id`. This is how the hosted MCP server turns a bearer token into a tenant. Returns only public-safe fields (panel id, plan info). **Guide:** [Base URL & panels](/docs/base-url) ## Authentication - `X-API-Key` header (apiKey) ## Responses ### 200 β€” Panel resolved - `crm_id` (string) - `plan` (string) β€” e.g. `"only-api-free"`. ### 401 β€” Missing or invalid API key ## Example ```bash curl -X GET "https://api.theonlyapi.com/api/whoami" \ -H "X-API-Key: " ``` --- # Send an email verification code (/docs/crm/panel-and-usage/send-an-email-verification-code) `POST https://api.theonlyapi.com/api/auth/start-email-verification` **Guide:** [Base URL & panels](/docs/base-url) ## Authentication None β€” this endpoint is public. ## Request body Content type: `application/json` (required) - `email` (string, required) ## Responses ### 200 β€” Verification email sent - `expires_at` (any, required) - `success` (boolean, required) - `token` (any, required) ## Example ```bash curl -X POST "https://api.theonlyapi.com/api/auth/start-email-verification" \ -H "Content-Type: application/json" \ -d '{"email":"string"}' ``` --- # Service health check (/docs/crm/panel-and-usage/service-health-check) `GET https://api.theonlyapi.com/health` Liveness probe. Exempt from rate limiting and requires no API key. **Guide:** [Base URL & panels](/docs/base-url) ## Authentication None β€” this endpoint is public. ## Responses ### 200 β€” Service is healthy - `service` (string, required) - `status` (string, required) ## Example ```bash curl -X GET "https://api.theonlyapi.com/health" ``` --- # Verify an email code (/docs/crm/panel-and-usage/verify-an-email-code) `POST https://api.theonlyapi.com/api/auth/verify-email` **Guide:** [Base URL & panels](/docs/base-url) ## Authentication None β€” this endpoint is public. ## Request body Content type: `application/json` (required) - `email` (string, required) - `code` (string, required) β€” e.g. `"123456"`. ## Responses ### 200 β€” Email verified - `api_key` (string, required) - `crm_id` (string, required) - `email` (string, required) - `name` (string, required) - `success` (boolean, required) - `user_id` (any, required) ### 400 β€” Invalid or expired code ## Example ```bash curl -X POST "https://api.theonlyapi.com/api/auth/verify-email" \ -H "Content-Type: application/json" \ -d '{"email":"string","code":"123456"}' ``` --- # Payouts (/docs/crm/payouts) {/* Generated by scripts/gen-api.ts β€” edit that script, not this file. */} Withdrawal requests and payout account details. Creating a withdrawal is OnlyFans only. | Method | Endpoint | Path | | ------ | ---------------------------------------------------------------------- | ---------------------------------------- | | `GET` | [Get payout account](/docs/crm/payouts/get-payout-account) | `/accounts/{of_user_id}/payout-account` | | `GET` | [List withdrawal requests](/docs/crm/payouts/list-withdrawal-requests) | `/accounts/{of_user_id}/payout-requests` | | `POST` | [Create payout request](/docs/crm/payouts/create-payout-request) | `/accounts/{of_user_id}/payout-requests` | --- # Create payout request (/docs/crm/payouts/create-payout-request) `POST https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/payout-requests` Create a withdrawal request for a connected account. **OnlyFans only** β€” rejected for Fansly accounts. Requires an `X-Proxy` header (or a proxy saved on the account). **Guide:** [Earnings & transactions](/docs/earnings) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `of_user_id` (string, required) β€” Creator account ID of the connected account (OnlyFans or Fansly). Use `GET /accounts` to list connected accounts and their IDs. ## Header parameters - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` (required) - `withdrawal_amount` (number, required) β€” Amount to withdraw in USD. e.g. `100`. ## Responses ### 200 β€” Payout request created - `data` (any, required) - `request` (any, required) - `success` (boolean, required) ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/payout-requests" \ -H "X-API-Key: " \ -H "Content-Type: application/json" \ -d '{"withdrawal_amount":100}' ``` --- # Get payout account (/docs/crm/payouts/get-payout-account) `GET https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/payout-account` Payout/withdrawal account details for a connected account. **Guide:** [Earnings & transactions](/docs/earnings) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `of_user_id` (string, required) β€” Creator account ID of the connected account (OnlyFans or Fansly). Use `GET /accounts` to list connected accounts and their IDs. ## Header parameters - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Payout account details - `account` (any, required) - `balances` (any[], required) - `blockers` (any[], required) - `can_withdraw` (any, required) - `check_receive` (any, required) - `success` (boolean, required) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/payout-account" \ -H "X-API-Key: " ``` --- # List withdrawal requests (/docs/crm/payouts/list-withdrawal-requests) `GET https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/payout-requests` Withdrawal request history for the account. For OnlyFans this is read live from the platform; for Fansly it is served from the synced wallet ledger. **Guide:** [Earnings & transactions](/docs/earnings) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `of_user_id` (string, required) β€” Creator account ID of the connected account (OnlyFans or Fansly). Use `GET /accounts` to list connected accounts and their IDs. ## Query parameters - `limit` (integer) β€” Maximum number of rows to return. Default `100`. - `offset` (integer) β€” Row offset for pagination. Default `0`. ## Header parameters - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Withdrawal request history - `success` (boolean) - `payout_requests` (object[]) - `hasMore` (boolean) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/payout-requests" \ -H "X-API-Key: " ``` --- # Proxy (/docs/crm/proxy) {/* Generated by scripts/gen-api.ts β€” edit that script, not this file. */} Generic authenticated OnlyFans API proxy (`POST /accounts/{of_user_id}/request`). OnlyFans only. | Method | Endpoint | Path | | ------ | ------------------------------------------------------------ | -------------------------------- | | `POST` | [Generic OF API proxy](/docs/crm/proxy/generic-of-api-proxy) | `/accounts/{of_user_id}/request` | --- # Generic OF API proxy (/docs/crm/proxy/generic-of-api-proxy) `POST https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/request` Send any authenticated request to the OnlyFans API. Use this to access any OF endpoint not covered by the dedicated CRM routes. Auto-relogins on session expiry. **OnlyFans only** β€” rejected for Fansly accounts. For Fansly, use the platform-neutral CRM data routes. **Guide:** [Proxies](/docs/proxies) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `of_user_id` (string, required) β€” Creator account ID of the connected account (OnlyFans or Fansly). Use `GET /accounts` to list connected accounts and their IDs. ## Header parameters - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` (required) - `path` (string, required) β€” OnlyFans API path. e.g. `"/api2/v2/users/me"`. - `method` ("GET" | "POST" | "PUT" | "PATCH" | "DELETE") β€” Default `"GET"`. - `body` (object) β€” Request body (for POST/PUT/PATCH). ## Responses ### 200 β€” Proxied response - `success` (boolean) - `status_code` (integer) - `data` (object) ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/request" \ -H "X-API-Key: " \ -H "Content-Type: application/json" \ -d '{"path":"/api2/v2/users/me","method":"GET"}' ``` --- # Referrals (/docs/crm/referrals) {/* Generated by scripts/gen-api.ts β€” edit that script, not this file. */} OnlyFans referral programme β€” who the account referred, what it earned, and referral payout history. **OnlyFans only**: Fansly accounts get `501 platform_not_supported` (`feature: "referrals"`). Live reads, no cache; one quota call per request. OnlyFans' referral response bodies are passed through with minimal normalization β€” only the `list`/`hasMore`/`marker` envelope keys are read, and the raw body is echoed under `data`. Fields *inside* a referral row are unverified: do not depend on them without checking against a live account. | Method | Endpoint | Path | | ------ | ---------------------------------------------------------------------------------- | -------------------------------------------------- | | `GET` | [List referred users](/docs/crm/referrals/list-referred-users) | `/accounts/{of_user_id}/referrals` | | `GET` | [Referral balance + chart](/docs/crm/referrals/referral-balance-chart) | `/accounts/{of_user_id}/referrals/earnings` | | `GET` | [List referral payout requests](/docs/crm/referrals/list-referral-payout-requests) | `/accounts/{of_user_id}/referrals/payout-requests` | --- # List referral payout requests (/docs/crm/referrals/list-referral-payout-requests) `GET https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/referrals/payout-requests` Referral payout history β€” the referral twin of `GET /accounts/{of_user_id}/payout-requests`, shaped identically. The row shape inside `requests` is **unverified**; rows pass through untouched and the raw upstream body is echoed under `data`. **OnlyFans only** β€” Fansly returns `501`. **Guide:** [Earnings & transactions](/docs/earnings) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `of_user_id` (string, required) β€” Creator account ID of the connected account (OnlyFans or Fansly). Use `GET /accounts` to list connected accounts and their IDs. ## Query parameters - `startDate` (string) β€” Range start, `YYYY-MM-DD` or `YYYY-MM-DD HH:MM:SS`. - `endDate` (string) β€” Range end, same format as startDate. - `offset` (integer) - `marker` (string) β€” Pagination cursor returned by OnlyFans. - `limit` (integer) ## Header parameters - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Referral payout requests - `success` (boolean) - `requests` (object[]) β€” Rows exactly as OnlyFans returned them β€” item fields unverified. - `count` (integer) - `marker` (any) β€” Upstream pagination cursor; pass back as `marker` for the next page. - `data` (any) β€” Raw upstream body, verbatim. ### 400 β€” Invalid startDate/endDate format ### 403 β€” Account does not belong to this panel ### 501 Fansly account β€” referrals are not available on this platform ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/referrals/payout-requests" \ -H "X-API-Key: " ``` --- # List referred users (/docs/crm/referrals/list-referred-users) `GET https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/referrals` The creators/users this account referred, read live from OnlyFans. **OnlyFans only** β€” a Fansly account returns `501` with `code: "platform_not_supported"` and `feature: "referrals"`. Query params are forwarded upstream **only when supplied** β€” no default date window is invented, because a wrong default silently truncates money figures. The row shape inside `referrals` is **unverified** (OnlyFans' item fields were never captured); rows pass through untouched and the raw upstream body is echoed under `data`. **Guide:** [Earnings & transactions](/docs/earnings) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `of_user_id` (string, required) β€” Creator account ID of the connected account (OnlyFans or Fansly). Use `GET /accounts` to list connected accounts and their IDs. ## Query parameters - `startDate` (string) β€” Range start, `YYYY-MM-DD` or `YYYY-MM-DD HH:MM:SS`. - `endDate` (string) β€” Range end, same format as startDate. - `offset` (integer) - `marker` (string) β€” Pagination cursor returned by OnlyFans. - `onlyPerformers` (string) β€” Restrict to referred creators/performers. - `limit` (integer) ## Header parameters - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Referred users - `success` (boolean) - `referrals` (object[]) β€” Rows exactly as OnlyFans returned them β€” item fields unverified. - `count` (integer) - `hasMore` (boolean) - `data` (any) β€” Raw upstream body, verbatim. ### 400 β€” Invalid startDate/endDate format ### 403 β€” Account does not belong to this panel ### 501 Fansly account β€” referrals are not available on this platform ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/referrals" \ -H "X-API-Key: " ``` --- # Referral balance + chart (/docs/crm/referrals/referral-balance-chart) `GET https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/referrals/earnings` Referral money summary in one response, fanned out to two OnlyFans endpoints (still one quota call). `balance` and `chart` hold the **raw** upstream bodies β€” no field mapping. The two documentation sources disagree about the chart body, and the balance endpoint appears in no capture at all, so mapping fields would fabricate a contract. Partial failure is tolerated: a source that fails comes back `null` and `sources` records its status. If **both** fail, the route returns the upstream status with `success: false` β€” an expired session must not be indistinguishable from "no referral earnings". **OnlyFans only** β€” Fansly returns `501`. **Guide:** [Earnings & transactions](/docs/earnings) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `of_user_id` (string, required) β€” Creator account ID of the connected account (OnlyFans or Fansly). Use `GET /accounts` to list connected accounts and their IDs. ## Query parameters - `startDate` (string) β€” Chart range start (forwarded to the chart call). - `endDate` (string) β€” Chart range end. - `withTotal` (string) β€” Include totals. Defaults to the value the OnlyFans web client sends. Default `1`. - `withChart` (string) β€” Include the chart series. Defaults to the value the OnlyFans web client sends. Default `true`. - `filter` (string) β€” Chart filter; forwarded verbatim when supplied. ## Header parameters - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Referral earnings (one source may be null) - `success` (boolean) - `balance` (any) β€” Raw body of the OnlyFans referral balance endpoint, or null if it failed. Shape unverified. - `chart` (any) β€” Raw body of the OnlyFans referral chart endpoint, or null if it failed. Shape unverified. - `sources` (object) β€” Per-source outcome, so a null above is explainable. - `balance` (object) - `ok` (boolean) - `status` (integer) - `chart` (object) - `ok` (boolean) - `status` (integer) ### 400 β€” Invalid startDate/endDate format ### 403 β€” Account does not belong to this panel ### 501 Fansly account β€” referrals are not available on this platform ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/referrals/earnings" \ -H "X-API-Key: " ``` --- # Settings (/docs/crm/settings) {/* Generated by scripts/gen-api.ts β€” edit that script, not this file. */} Account settings, subscription price & proxy management | Method | Endpoint | Path | | ------- | ------------------------------------------------------------------------- | ------------------------------------------- | | `GET` | [Get account proxy](/docs/crm/settings/get-account-proxy) | `/accounts/{of_user_id}/proxy` | | `PATCH` | [Update account proxy](/docs/crm/settings/update-account-proxy) | `/accounts/{of_user_id}/proxy` | | `GET` | [Get subscription price](/docs/crm/settings/get-subscription-price) | `/accounts/{of_user_id}/subscription-price` | | `PATCH` | [Update subscription price](/docs/crm/settings/update-subscription-price) | `/accounts/{of_user_id}/subscription-price` | | `POST` | [Test a proxy](/docs/crm/settings/test-a-proxy) | `/proxy/test` | --- # Get account proxy (/docs/crm/settings/get-account-proxy) `GET https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/proxy` Get the current proxy configured for an account. **Guide:** [Cached reads](/docs/cached-reads) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `of_user_id` (string, required) β€” Creator account ID of the connected account (OnlyFans or Fansly). Use `GET /accounts` to list connected accounts and their IDs. ## Responses ### 200 β€” Proxy info - `success` (boolean) - `proxy` (string) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/proxy" \ -H "X-API-Key: " ``` --- # Get subscription price (/docs/crm/settings/get-subscription-price) `GET https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/subscription-price` Read the account's current subscription price live from `/users/me`. Consumes a platform request. **Guide:** [Cached reads](/docs/cached-reads) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `of_user_id` (string, required) β€” Creator account ID of the connected account (OnlyFans or Fansly). Use `GET /accounts` to list connected accounts and their IDs. ## Header parameters - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Current subscription price - `success` (boolean) - `subscribePrice` (number) β€” e.g. `9.99`. ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/subscription-price" \ -H "X-API-Key: " ``` --- # Test a proxy (/docs/crm/settings/test-a-proxy) `POST https://theonlyapi.com/api/crm/your-crm-id/proxy/test` Check that a proxy URL is reachable and usable before connecting an account with it. HTTP and SOCKS5 are both accepted. **Guide:** [Cached reads](/docs/cached-reads) ## Authentication - `X-API-Key` header (apiKey) ## Request body Content type: `application/json` (required) - `proxy` (string, required) β€” e.g. `"http://user:pass@host:port"`. ## Responses ### 200 β€” Proxy test result - `geo` (any, required) - `ip` (any, required) - `latency_ms` (integer, required) - `ok` (boolean, required) ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/proxy/test" \ -H "X-API-Key: " \ -H "Content-Type: application/json" \ -d '{"proxy":"http://user:pass@host:port"}' ``` --- # Update account proxy (/docs/crm/settings/update-account-proxy) `PATCH https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/proxy` Update or remove the proxy for an account. Set to `null` to remove. **Guide:** [Cached reads](/docs/cached-reads) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `of_user_id` (string, required) β€” Creator account ID of the connected account (OnlyFans or Fansly). Use `GET /accounts` to list connected accounts and their IDs. ## Request body Content type: `application/json` (required) - `proxy` (string) β€” e.g. `"http://user:pass@host:port"`. ## Responses ### 200 β€” Proxy updated - `message` (string) - `proxy` (string, required) - `success` (boolean, required) ## Example ```bash curl -X PATCH "https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/proxy" \ -H "X-API-Key: " \ -H "Content-Type: application/json" \ -d '{"proxy":"http://user:pass@host:port"}' ``` --- # Update subscription price (/docs/crm/settings/update-subscription-price) `PATCH https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/subscription-price` Change the subscription price for a connected OnlyFans account. **Guide:** [Cached reads](/docs/cached-reads) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `of_user_id` (string, required) β€” Creator account ID of the connected account (OnlyFans or Fansly). Use `GET /accounts` to list connected accounts and their IDs. ## Header parameters - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` (required) - `subscribePrice` (number, required) β€” New subscription price in USD. e.g. `9.99`. ## Responses ### 200 β€” Price updated - `data` (any) - `isFree` (boolean) - `subscribePrice` (number, required) - `success` (boolean, required) ## Example ```bash curl -X PATCH "https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/subscription-price" \ -H "X-API-Key: " \ -H "Content-Type: application/json" \ -d '{"subscribePrice":9.99}' ``` --- # Subscribers (/docs/crm/subscribers) {/* Generated by scripts/gen-api.ts β€” edit that script, not this file. */} Subscriber reads. Live routes hit the platform; `/subscribers/cached`, `/subscribers/new`, and `/subscribers/stats` cost zero platform requests and normalize OnlyFans + Fansly rows to the same shape. | Method | Endpoint | Path | | ------ | ------------------------------------------------------------------------------------------------ | --------------------------------------------------- | | `GET` | [List subscribers](/docs/crm/subscribers/list-subscribers) | `/accounts/{of_user_id}/subscribers` | | `GET` | [List cached subscribers](/docs/crm/subscribers/list-cached-subscribers) | `/accounts/{of_user_id}/subscribers/cached` | | `GET` | [List newly-seen subscribers](/docs/crm/subscribers/list-newly-seen-subscribers) | `/accounts/{of_user_id}/subscribers/new` | | `POST` | [Refresh the subscriber cache (async)](/docs/crm/subscribers/refresh-the-subscriber-cache-async) | `/accounts/{of_user_id}/subscribers/refresh` | | `GET` | [Subscriber refresh status](/docs/crm/subscribers/subscriber-refresh-status) | `/accounts/{of_user_id}/subscribers/refresh/status` | | `GET` | [Subscriber statistics](/docs/crm/subscribers/subscriber-statistics) | `/accounts/{of_user_id}/subscribers/stats` | --- # List cached subscribers (/docs/crm/subscribers/list-cached-subscribers) `GET https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/subscribers/cached` Read subscribers from the local cache, populated by the background refresh job. **Zero platform requests.** Platform-neutral: OnlyFans and Fansly rows are normalized to the same shape. Each row carries the raw platform payload merged with the flat spend/lifecycle projection (total spent, breakdown), which for Fansly is backfilled from the wallet ledger. **Guide:** [Subscribers & fans](/docs/subscribers) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `of_user_id` (string, required) β€” Creator account ID of the connected account (OnlyFans or Fansly). Use `GET /accounts` to list connected accounts and their IDs. ## Query parameters - `limit` (integer) β€” Default `100`. - `offset` (integer) β€” Row offset for pagination. Default `0`. - `type` ("all" | "active" | "expired") β€” Default `all`. ## Responses ### 200 β€” Cached subscriber list - `success` (boolean) - `subscribers` (object[]) - `count` (integer) - `hasMore` (boolean) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/subscribers/cached" \ -H "X-API-Key: " ``` --- # List newly-seen subscribers (/docs/crm/subscribers/list-newly-seen-subscribers) `GET https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/subscribers/new` Subscribers first seen within a recent window, read from the cache. **Zero platform requests.** Fansly-aware. **Guide:** [Subscribers & fans](/docs/subscribers) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `of_user_id` (string, required) β€” Creator account ID of the connected account (OnlyFans or Fansly). Use `GET /accounts` to list connected accounts and their IDs. ## Query parameters - `since` (string) β€” ISO timestamp or date lower bound. - `limit` (integer) β€” Maximum number of rows to return. Default `100`. ## Responses ### 200 β€” New subscriber list - `count` (integer, required) - `hasMore` (boolean, required) - `limit` (integer, required) - `offset` (integer, required) - `subscribers` (any[], required) - `success` (boolean, required) - `total` (integer, required) - `window` (object, required) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/subscribers/new" \ -H "X-API-Key: " ``` --- # List subscribers (/docs/crm/subscribers/list-subscribers) `GET https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/subscribers` Get subscribers with pagination and type filtering. Includes total spent data. **Paging:** advance with the `nextOffset` from the response, and stop when `hasMore` is `false` β€” not when `list` is empty. `offset` does not mean the same thing on both platforms: OnlyFans filters by type server-side so its offset counts rows *returned*, while Fansly filters client-side so its offset counts rows *consumed*, which can exceed `count`. Computing `offset + list.length` yourself silently skips subscribers on Fansly, and a page whose rows were all filtered out comes back with an empty `list` and more still behind it. `nextOffset` + `hasMore` are correct on both. **Guide:** [Subscribers & fans](/docs/subscribers) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `of_user_id` (string, required) β€” Creator account ID of the connected account (OnlyFans or Fansly). Use `GET /accounts` to list connected accounts and their IDs. ## Query parameters - `limit` (integer) β€” Default `10`. - `offset` (integer) β€” Default `0`. - `type` ("all" | "active" | "expired") β€” Default `all`. ## Header parameters - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Subscriber list - `success` (boolean) - `list` (object[]) - `hasMore` (boolean) β€” The stop signal. An empty `list` is not β€” a page can filter to zero rows and still have more behind it. - `count` (integer) β€” Length of `list` after type filtering. A page-size readout, not a cursor. - `offset` (integer) - `nextOffset` (integer) β€” The offset to pass for the next page. Always follow this rather than computing offset + list.length. - `limit` (integer) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/subscribers" \ -H "X-API-Key: " ``` --- # Refresh the subscriber cache (async) (/docs/crm/subscribers/refresh-the-subscriber-cache-async) `POST https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/subscribers/refresh` Start an async subscriber sync for this account. Returns **202** immediately β€” poll `GET /accounts/{of_user_id}/subscribers/refresh/status` or listen on `GET /events/stream` for completion. Works for OnlyFans and Fansly. **Guide:** [Subscribers & fans](/docs/subscribers) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `of_user_id` (string, required) β€” Creator account ID of the connected account (OnlyFans or Fansly). Use `GET /accounts` to list connected accounts and their IDs. ## Header parameters - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 202 β€” Refresh job accepted and running - `already_running` (boolean) - `state` (any, required) - `success` (boolean, required) ### 409 β€” A refresh is already in progress ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/subscribers/refresh" \ -H "X-API-Key: " ``` --- # Subscriber refresh status (/docs/crm/subscribers/subscriber-refresh-status) `GET https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/subscribers/refresh/status` Progress/state of the current or last subscriber refresh job. **Zero platform requests.** **Guide:** [Subscribers & fans](/docs/subscribers) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `of_user_id` (string, required) β€” Creator account ID of the connected account (OnlyFans or Fansly). Use `GET /accounts` to list connected accounts and their IDs. ## Responses ### 200 β€” Refresh job status - `cache` (object, required) - `active` (integer) - `breakdown` (object) - `consecutive_failures` (integer) - `expired` (integer) - `last_refreshed_at` (any) - `last_row_synced_at` (any) - `spenders` (integer) - `total` (integer) - `total_spent_sum` (number) - `success` (boolean, required) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/subscribers/refresh/status" \ -H "X-API-Key: " ``` --- # Subscriber statistics (/docs/crm/subscribers/subscriber-statistics) `GET https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/subscribers/stats` Time-bucketed counts of incoming subscriptions, plus the cache summary. **Zero platform requests.** Fansly-aware. Query: `granularity` = `hour|day|week|month` (default `day`), `since`/`until` = inclusive ISO-8601 bounds on `subscribed_at`. Buckets are ascending, contiguous and **zero-filled server-side** β€” a quiet day comes back as `count: 0`, not as a missing key, so the array plots directly. With both `since` and `until` the axis spans exactly that window even if it holds no subscriptions; otherwise it spans the first to the last bucket with data. Week buckets are Monday-start ISO dates. `zero_filled` is `false` when the requested span exceeded the server's bucket ceiling (e.g. `granularity=hour` over an unbounded window): the series is then sparse and you must fill the gaps yourself. Narrow the window or coarsen the granularity. **Guide:** [Subscribers & fans](/docs/subscribers) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `of_user_id` (string, required) β€” Creator account ID of the connected account (OnlyFans or Fansly). Use `GET /accounts` to list connected accounts and their IDs. ## Responses ### 200 β€” Subscriber statistics - `buckets` (any, required) - `cache` (object, required) - `active` (integer) - `breakdown` (object) - `consecutive_failures` (integer) - `expired` (integer) - `last_refreshed_at` (any) - `last_row_synced_at` (any) - `spenders` (integer) - `total` (integer) - `total_spent_sum` (number) - `granularity` (string, required) - `success` (boolean, required) - `total_in_window` (any, required) - `window` (object, required) - `zero_filled` (any, required) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/subscribers/stats" \ -H "X-API-Key: " ``` --- # Transactions (/docs/crm/transactions) {/* Generated by scripts/gen-api.ts β€” edit that script, not this file. */} Payout & purchase transactions, live and cached. | Method | Endpoint | Path | | ------ | --------------------------------------------------------------------------------------------------- | ---------------------------------------------------- | | `GET` | [Get purchase transactions](/docs/crm/transactions/get-purchase-transactions) | `/accounts/{of_user_id}/purchases` | | `GET` | [List cached transactions](/docs/crm/transactions/list-cached-transactions) | `/accounts/{of_user_id}/transactions/cached` | | `POST` | [Refresh the transaction cache (async)](/docs/crm/transactions/refresh-the-transaction-cache-async) | `/accounts/{of_user_id}/transactions/refresh` | | `GET` | [Transaction refresh status](/docs/crm/transactions/transaction-refresh-status) | `/accounts/{of_user_id}/transactions/refresh/status` | --- # Get purchase transactions (/docs/crm/transactions/get-purchase-transactions) `GET https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/purchases` Fetch payout transactions with marker-based pagination. **Guide:** [Earnings & transactions](/docs/earnings) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `of_user_id` (string, required) β€” Creator account ID of the connected account (OnlyFans or Fansly). Use `GET /accounts` to list connected accounts and their IDs. ## Query parameters - `startDate` (string) - `marker` (string) β€” Pagination marker (use nextMarker from response). - `limit` (integer) β€” Default `100`. ## Header parameters - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Transaction list - `success` (boolean) - `purchases` (object[]) - `hasMore` (boolean) - `nextMarker` (string) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/purchases" \ -H "X-API-Key: " ``` --- # List cached transactions (/docs/crm/transactions/list-cached-transactions) `GET https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/transactions/cached` Read transactions from the local cache. **Zero platform requests.** OnlyFans and Fansly rows are normalized to the same shape. **Guide:** [Earnings & transactions](/docs/earnings) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `of_user_id` (string, required) β€” Creator account ID of the connected account (OnlyFans or Fansly). Use `GET /accounts` to list connected accounts and their IDs. ## Query parameters - `limit` (integer) β€” Maximum number of rows to return. Default `100`. - `offset` (integer) β€” Row offset for pagination. Default `0`. - `since` (string) β€” ISO date lower bound. - `until` (string) β€” ISO date upper bound. ## Responses ### 200 β€” Cached transaction list - `cache` (object, required) - `by_type` (any) - `consecutive_failures` (integer) - `last_refreshed_at` (any) - `last_tx_marker` (any) - `newest` (any) - `oldest` (any) - `total` (integer) - `total_amount` (number) - `total_net` (number) - `count` (integer, required) - `hasMore` (boolean, required) - `limit` (integer, required) - `list` (any[], required) - `offset` (integer, required) - `success` (boolean, required) - `total` (integer, required) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/transactions/cached" \ -H "X-API-Key: " ``` --- # Refresh the transaction cache (async) (/docs/crm/transactions/refresh-the-transaction-cache-async) `POST https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/transactions/refresh` Start an async transaction sync. Returns **202** β€” poll `GET /accounts/{of_user_id}/transactions/refresh/status` or listen on `GET /events/stream`. Works for OnlyFans and Fansly. **Guide:** [Earnings & transactions](/docs/earnings) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `of_user_id` (string, required) β€” Creator account ID of the connected account (OnlyFans or Fansly). Use `GET /accounts` to list connected accounts and their IDs. ## Header parameters - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 202 β€” Refresh job accepted and running - `already_running` (boolean) - `state` (any, required) - `success` (boolean, required) ### 409 β€” A refresh is already in progress ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/transactions/refresh" \ -H "X-API-Key: " ``` --- # Transaction refresh status (/docs/crm/transactions/transaction-refresh-status) `GET https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/transactions/refresh/status` Progress/state of the current or last transaction refresh job. **Zero platform requests.** **Guide:** [Earnings & transactions](/docs/earnings) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `of_user_id` (string, required) β€” Creator account ID of the connected account (OnlyFans or Fansly). Use `GET /accounts` to list connected accounts and their IDs. ## Responses ### 200 β€” Refresh job status - `cache` (object, required) - `by_type` (any) - `consecutive_failures` (integer) - `last_refreshed_at` (any) - `last_tx_marker` (any) - `newest` (any) - `oldest` (any) - `total` (integer) - `total_amount` (number) - `total_net` (number) - `success` (boolean, required) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/accounts/{of_user_id}/transactions/refresh/status" \ -H "X-API-Key: " ``` --- # Webhooks (/docs/crm/webhooks) {/* Generated by scripts/gen-api.ts β€” edit that script, not this file. */} Outbound webhook subscriptions, test fires, and delivery history. | Method | Endpoint | Path | | -------- | --------------------------------------------------------------------- | ----------------------------------- | | `GET` | [List webhooks](/docs/crm/webhooks/list-webhooks) | `/webhooks` | | `POST` | [Create a webhook](/docs/crm/webhooks/create-a-webhook) | `/webhooks` | | `GET` | [Get a webhook](/docs/crm/webhooks/get-a-webhook) | `/webhooks/{webhook_id}` | | `PATCH` | [Update a webhook](/docs/crm/webhooks/update-a-webhook) | `/webhooks/{webhook_id}` | | `DELETE` | [Delete a webhook](/docs/crm/webhooks/delete-a-webhook) | `/webhooks/{webhook_id}` | | `GET` | [List webhook deliveries](/docs/crm/webhooks/list-webhook-deliveries) | `/webhooks/{webhook_id}/deliveries` | | `POST` | [Send a test delivery](/docs/crm/webhooks/send-a-test-delivery) | `/webhooks/{webhook_id}/test` | --- # Create a webhook (/docs/crm/webhooks/create-a-webhook) `POST https://theonlyapi.com/api/crm/your-crm-id/webhooks` Subscribe an HTTPS endpoint to panel events. Rate limited to 120 requests/minute. **Guide:** [Webhooks](/docs/webhooks) ## Authentication - `X-API-Key` header (apiKey) ## Request body Content type: `application/json` (required) - `url` (string, required) β€” e.g. `"https://example.com/hooks/theonlyapi"`. - `event_types` (string[], required) β€” Event types to deliver. **Required and non-empty** β€” omitting it returns `400 event_types must be a non-empty list`. Use `["*"]` for every type. e.g. `["new_subscriber","new_tip"]`. - `description` (string) β€” Optional label for your own reference. ## Responses ### 200 β€” Webhook created - `success` (boolean, required) - `webhook` (any, required) ### 400 β€” Invalid URL or event type ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/webhooks" \ -H "X-API-Key: " \ -H "Content-Type: application/json" \ -d '{"url":"https://example.com/hooks/theonlyapi","event_types":["new_subscriber","new_tip"]}' ``` --- # Delete a webhook (/docs/crm/webhooks/delete-a-webhook) `DELETE https://theonlyapi.com/api/crm/your-crm-id/webhooks/{webhook_id}` **Guide:** [Webhooks](/docs/webhooks) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `webhook_id` (integer, required) ## Responses ### 200 β€” Webhook deleted - `success` (boolean, required) ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/webhooks/{webhook_id}" \ -H "X-API-Key: " ``` --- # Get a webhook (/docs/crm/webhooks/get-a-webhook) `GET https://theonlyapi.com/api/crm/your-crm-id/webhooks/{webhook_id}` **Guide:** [Webhooks](/docs/webhooks) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `webhook_id` (integer, required) ## Responses ### 200 β€” Webhook - `success` (boolean, required) - `webhook` (any, required) ### 404 β€” Not found ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/webhooks/{webhook_id}" \ -H "X-API-Key: " ``` --- # List webhook deliveries (/docs/crm/webhooks/list-webhook-deliveries) `GET https://theonlyapi.com/api/crm/your-crm-id/webhooks/{webhook_id}/deliveries` Delivery history with response status codes, for debugging failures. **Guide:** [Webhooks](/docs/webhooks) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `webhook_id` (integer, required) ## Query parameters - `limit` (integer) β€” Maximum number of rows to return. Default `100`. ## Responses ### 200 β€” Delivery history - `deliveries` (object[], required) - `attempt` (integer) - `completed_at` (string) - `created_at` (string) - `event_id` (integer) - `id` (integer) - `next_retry_at` (string) - `response_code` (integer) - `response_snippet` (string) - `status` (string) - `webhook_id` (integer) - `success` (boolean, required) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/webhooks/{webhook_id}/deliveries" \ -H "X-API-Key: " ``` --- # List webhooks (/docs/crm/webhooks/list-webhooks) `GET https://theonlyapi.com/api/crm/your-crm-id/webhooks` **Guide:** [Webhooks](/docs/webhooks) ## Authentication - `X-API-Key` header (apiKey) ## Responses ### 200 β€” Webhook list - `success` (boolean, required) - `webhooks` (object[], required) - `consecutive_failures` (integer) - `created_at` (string) - `crm_id` (string) - `description` (string) - `event_types` (any[]) - `id` (integer) - `is_active` (integer) - `last_delivery_at` (string) - `last_status_code` (integer) - `reject_reason` (string) - `reviewed_at` (string) - `status` (string) - `url` (string) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/webhooks" \ -H "X-API-Key: " ``` --- # Send a test delivery (/docs/crm/webhooks/send-a-test-delivery) `POST https://theonlyapi.com/api/crm/your-crm-id/webhooks/{webhook_id}/test` Fire a synthetic event at the webhook so you can verify the endpoint and signature handling. The delivery carries X-OnlyAPI-Signature (sha256=), X-OnlyAPI-Timestamp, X-OnlyAPI-Event and X-OnlyAPI-Delivery-Id; the digest is HMAC-SHA256 over "{X-OnlyAPI-Timestamp}." + the raw body. **Guide:** [Webhooks](/docs/webhooks) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `webhook_id` (integer, required) ## Responses ### 200 β€” Test delivery result - `success` (boolean, required) ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/webhooks/{webhook_id}/test" \ -H "X-API-Key: " ``` --- # Update a webhook (/docs/crm/webhooks/update-a-webhook) `PATCH https://theonlyapi.com/api/crm/your-crm-id/webhooks/{webhook_id}` **Guide:** [Webhooks](/docs/webhooks) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `webhook_id` (integer, required) ## Request body Content type: `application/json` (required) - `url` (string) - `event_types` (string[]) β€” Event types to deliver. **Required and non-empty** β€” omitting it returns `400 event_types must be a non-empty list`. Use `["*"]` for every type. e.g. `["new_subscriber","new_tip"]`. - `description` (string) β€” Optional label for your own reference. - `is_active` (boolean) β€” Enable or disable the webhook. Setting it true also resets the consecutive-failure counter, which is how you revive a webhook that was auto-deactivated. ## Responses ### 200 β€” Webhook updated - `success` (boolean, required) - `webhook` (any, required) ## Example ```bash curl -X PATCH "https://theonlyapi.com/api/crm/your-crm-id/webhooks/{webhook_id}" \ -H "X-API-Key: " \ -H "Content-Type: application/json" \ -d '{"event_types":["new_subscriber","new_tip"]}' ``` --- # Earnings & transactions (/docs/earnings) ## Balances and earnings [#balances-and-earnings] ```bash # One account, live curl "$BASE/api/crm/$CRM/accounts/$OFUID/balances" -H "X-API-Key: $KEY" curl "$BASE/api/crm/$CRM/accounts/$OFUID/earnings" -H "X-API-Key: $KEY" # Whole panel, aggregated server-side across every connected account curl "$BASE/api/crm/$CRM/balances/summary" -H "X-API-Key: $KEY" curl "$BASE/api/crm/$CRM/earnings/summary" -H "X-API-Key: $KEY" ``` The two `/summary` routes are the ones to reach for when building a dashboard β€” they aggregate in one request instead of N live calls, and they work across both platforms. See [`GET /balances/summary`](/docs/crm/earnings/get-panel-wide-payout-totals) and [`GET /earnings/summary`](/docs/crm/earnings/aggregated-earnings-across-all-accounts) for the full field lists. `/balances/summary` serves last-known samples rather than live values β€” a live panel-wide payout total would cost one platform round trip per account. Label it with the `oldest_sample_at` / `newest_sample_at` it returns, and treat `accounts_never_sampled` as "not counted yet" rather than zero. Each call to `GET /accounts/{of_user_id}/balances` refreshes that account's sample. ## Transactions [#transactions] ```bash # Cached β€” zero platform requests, trustworthy total curl "$BASE/api/crm/$CRM/accounts/$OFUID/transactions/cached?limit=100&offset=0" \ -H "X-API-Key: $KEY" # One fan's history curl "$BASE/api/crm/$CRM/accounts/$OFUID/fans/$FANID/transactions/cached" \ -H "X-API-Key: $KEY" # Live walk (cursor-paginated β€” carry the marker forward) curl "$BASE/api/crm/$CRM/accounts/$OFUID/purchases?limit=100" -H "X-API-Key: $KEY" ``` Keep the cache current with `POST /accounts/{of_user_id}/transactions/refresh` (see [Async jobs](/docs/async-jobs)), and use `POST /accounts/{of_user_id}/backfill` for history predating the connection. ## The chargeback trap [#the-chargeback-trap] This is the single most important thing on this page. **Do not compute earnings with a plain sum over transaction amounts.** A chargeback is the **original row relabelled** β€” `status` flips to `undo`, `tx_type` becomes `chargeback`, and `amount`/`net` stay positive. There is no reversing entry. That means the correct treatment differs by what you are computing: | Computing | Treatment | | ---------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | | **Period revenue** (`/earnings/summary`) | **Exclude** `chargeback` rows. A naive sum overstates by one chargeback; subtracting would double-count the reversal | | **Per-fan lifetime spend** | **Subtract** them β€” the platform's canonical lifetime total still contains the original sale, so the delta has to reverse it out | For per-fan spend, sign each row by status: | `status` | Meaning | Contribution | | ------------- | ---------------------------------------------------- | --------------- | | `done` | Cleared; withdrawable | `+net` | | `loading` | Within the payout pending window (7 days by default) | `+net` | | `undo` | Chargeback or refund | `βˆ’net` | | anything else | Unknown | `0` β€” ignore it | ```python def signed_total(rows): total = 0.0 for row in rows: status = row.get("status") # `net` is what the creator received (gross minus the platform fee). # `amount` is what the fan paid. The canonical lifetime total is net, so # summing `amount` here inflates the result by roughly 1.25x. if status in ("done", "loading"): total += row["net"] elif status == "undo": total -= row["net"] # Unknown statuses contribute nothing. Deliberately not treated as # positive β€” if the platform adds a status, you want a visible # discrepancy rather than a silently wrong number. return total ``` Treating an unrecognised status as income hides the problem. Contributing zero makes a new status show up as a divergence you can notice and fix. Deleted fans still count. The money was real. ## Per-fan lifetime spend [#per-fan-lifetime-spend] `GET /fans` reports `total_spend` as `MAX(platform lifetime total, sum of captured tip/purchase events)` β€” a hybrid that favours whichever source is higher. No signed delta, no chargeback correction. It also returns `spend_known`: when that is `0`, the spend is **unknown**, not zero. `total` appears only if you pass `?with_total=true`. For the chargeback-corrected per-fan figure, read `mapped_spent` from `GET /accounts/{of_user_id}/fans/{fan_id}/transactions/cached`. The canonical model below is how per-fan spend is defined: ``` current_spent(fan) = canonical(fan) + signed_delta(fan, since = last subscriber sync) ``` * **canonical** is the platform's own lifetime total for that fan, as of the last subscriber-cache sync. * **signed\_delta** is the status-signed sum of that fan's transactions *after* that sync timestamp. The cutoff is strictly greater-than, so a transaction landing in the same second as the sync stays inside `canonical` and is not double-counted. A fan with transactions but no subscriber row yet gets `canonical = 0` and is flagged `source: "tx-only"` in the result, so you can tell a genuinely small spender from one we have not fully synced. ## Money scale differs by platform [#money-scale-differs-by-platform] OnlyFans reports money as decimal dollars, and the CRM routes pass those through untouched β€” `/api2/v2/*` and the CRM money routes agree, so mixing them is safe. **Fansly reports integer tenths of a cent.** `497496` is `$497.50`. The CRM routes divide by 1000 on read and multiply by 1000 on write. Fansly amounts are not cents β€” they are tenths of a cent. Sending a raw dollar value to a Fansly write produces a PPV priced 1000x too low. The `/api2/v2/*` passthrough rejects Fansly accounts outright, so raw Fansly integers are not reachable there. ## Why two caches [#why-two-caches] Subscriber rows carry the platform's **lifetime** total per fan but are only as fresh as the last sync. Transactions are fresh and attributable per event but only cover a recent window, not all history. Combining them gives both lifetime accuracy and up-to-the-minute freshness β€” which is exactly what the formula above does. If a figure looks wrong, refresh both caches before investigating anything else: ```bash curl -X POST "$BASE/api/crm/$CRM/accounts/$OFUID/subscribers/refresh" -H "X-API-Key: $KEY" curl -X POST "$BASE/api/crm/$CRM/accounts/$OFUID/transactions/refresh" -H "X-API-Key: $KEY" ``` ## Payouts [#payouts] ``` GET /accounts/{of_user_id}/payout-account # payout destination GET /accounts/{of_user_id}/payout-requests # history POST /accounts/{of_user_id}/payout-requests # request a payout β€” OnlyFans only ``` Requesting a payout is OnlyFans-only (`501` on Fansly) and sits on the sensitive rate tier. It **is** behind `allow_of_write_actions`, like every other write performed as the account. Body: `{"withdrawal_amount": 20}`. The route pre-flights the platform's own payout eligibility, so a blocked account gets a `400` with a `blockers[]` array rather than an opaque platform error. ## Referrals are separate money [#referrals-are-separate-money] `GET /earnings/summary` sums the transaction cache, and referral payouts never land there β€” so `by_category.referrals` is reported but is always `0`. Add referral money explicitly if you need a true total β€” see [CRM API β†’ Referrals](/docs/crm/referrals): ``` GET /accounts/{of_user_id}/referrals GET /accounts/{of_user_id}/referrals/earnings GET /accounts/{of_user_id}/referrals/payout-requests ``` ## Verifying a figure [#verifying-a-figure] [`GET /accounts/{of_user_id}/earnings/verify`](/docs/crm/earnings/verify-cached-earnings-against-the-platform) cross-checks the computed total against the platform's own chart for the same window, and returns both numbers plus the difference. That tells you whether a discrepancy is in the cache or in your aggregation. It makes real upstream calls, so it is per-account and on the 100/minute sensitive tier β€” do not fan it out across a panel. If the platform is unreachable, `live_available` is `false` and `live_total` is `null`: that is "could not check", not "matches". --- # Events (/docs/events) Polling is **opt-in per account**. Once you enable it β€” `PATCH /accounts/{of_user_id}/polling` with `{"enabled": true}` β€” we poll that account in the background, diff the results, and emit typed events. Those events are stored, broadcast over [SSE](/docs/streaming), delivered to your [webhooks](/docs/webhooks), and evaluated by your [automations](/docs/automations) β€” all from the same emission. ## Event types [#event-types] | `event_type` | Emitted when | Key payload fields | | -------------------- | -------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- | | `new_subscriber` | A new subscription appears | `fan`, `price`, `subscribed_at`, `expire_at` | | `renewed_subscriber` | An existing subscription renews | `fan`, `price`, `subscribed_at`, `expire_at` | | `expired_subscriber` | The subscriber count drops (sampled every 10th poll) | `previous_total`, `new_total`, `delta` β€” **negative** | | `new_tip` | A `tip` row appears in the transactions ledger | `fan`, `amount`, `net`, `currency`, `tx_type`, `status`, `description` | | `new_message` | A new-message notification arrives | `fan`, `text` β€” the only type with a `text` field | | `new_purchase` | A paid-content row appears β€” `tx_type` is `message`, `post`, `stream` or `chargeback` | `fan`, `amount`, `net`, `currency`, `tx_type`, `status`, `description` | | `balance_increased` | **Fansly only** β€” the wallet balance rises. Never emitted for OnlyFans; the money signal there is `new_tip`/`new_purchase` | `delta`, `available`, `previous_balance`, `new_balance`, `currency` | | `polling_paused` | Polling auto-pauses after 5 consecutive failures | `reason`, `failures` | | `payout_completed` | Reserved β€” **not currently emitted** | β€” | Background jobs additionally emit progress events on the SSE stream, which are not stored or delivered to webhooks: | Event | Emitted by | | --------------------------------------- | --------------------------------------------------------------------------------------------- | | `export.progress` / `export.complete` | [Data exports](/docs/exports) | | `refresh.progress` / `refresh.complete` | Cache refreshes and backfills, including the automatic backfill when you first enable polling | | `import.progress` / `import.complete` | [Bulk account import](/docs/bulk-import) β€” progress is coalesced to at most one per second | Webhook subscriptions also accept `*` as a wildcard for every type. `*` is a subscription filter only β€” it is never the `event_type` of a delivered event. ## Envelope [#envelope] ```json { "id": 12345, "event_type": "new_tip", "crm_id": "crm_0123456789abcdef", "of_user_id": "1234567", "occurred_at": "2026-04-18T12:34:56.789", "payload": { "fan": { "id": "987", "username": "somefan", "display_name": "Some Fan", "avatar": "https://…" }, "amount": 10.0, "net": 8.0, "currency": "USD", "tx_type": "tip", "status": "done", "description": "Tip from somefan", "created_at": "2026-04-18T12:34:50+00:00" } } ``` ## Reading past events [#reading-past-events] ```bash curl "$BASE/api/crm/$CRM/events?types=new_tip,new_subscriber&limit=100" \ -H "X-API-Key: $KEY" ``` | Parameter | Purpose | | ----------------- | ------------------------------------------------------------------------------------------------------------ | | `types` | Comma-separated event types | | `of_user_id` | Restrict to one connected account | | `since` / `until` | ISO bounds on `created_at` (when we recorded it), not `occurred_at`. `since` is exclusive, `until` inclusive | | `limit` | Default 100, max 500 | This route is panel-wide and takes no `offset` β€” narrow with `since`/`until` rather than paging. ## Behaviours worth knowing [#behaviours-worth-knowing] `new_subscriber` and `renewed_subscriber` are derived exclusively from the platform's subscriber feed, distinguished by whether the entry is a subscribe or a renewal. Notifications are not used for this β€” they carry no reliable renewal indicator, so using them would double-count renewals as new subscribers. `new_tip` and `new_purchase` take `amount` and `net` **directly from the transactions ledger** β€” real numbers. The exception is `new_message`, whose `amount` is best-effort-parsed out of a formatted display string (`"$25.00"`) and is often `null`. Reconcile money against [cached transactions](/docs/earnings) regardless. This event is derived from a drop in the total subscriber count, sampled only on every 10th poll β€” roughly every 20 minutes at the default interval, so several expiries collapse into one event. `delta` is `new_total - previous_total`, so it is **negative** (`-3` means three expired), and it carries no fan identity. To recover *who*, read `GET /subscribers/cached?type=expired`, which names them with each row's `expired_at`. Events are unique on `(crm_id, of_user_id, event_type, source_event_id)`. `source_event_id` is a key we derive per source β€” the transaction id, the fan id plus subscribe timestamp, and so on β€” not always the platform's own id. A poll that re-walks the same record does not emit twice. Your handler should still be idempotent β€” webhook *delivery* retries on failure, so the same event can arrive more than once. ## Choosing a delivery mechanism [#choosing-a-delivery-mechanism] Best for servers. Signed, retried, with a delivery log. Survives your process restarting. Best for dashboards and live UI. No retry β€” if you disconnect, you miss what happened while you were gone. No infrastructure at all. Match a condition, fire a Discord/Slack/Telegram message, a DM, or a fan tag. Simplest, and the right fallback for batch reconciliation. --- # Data exports (/docs/exports) An async, per-account export. You start a job, it walks the selected data β€” cheap cached tables first, expensive live platform walks last β€” packages **CSV + JSON into a ZIP**, and reports progress live over [SSE](/docs/streaming). The ZIP stays downloadable for **7 days**. ## Endpoints [#endpoints] | Method | Path | Purpose | | -------- | -------------------------------------------------- | -------------------------- | | `POST` | `/accounts/{of_user_id}/exports` | Start a job β†’ `202` | | `GET` | `/accounts/{of_user_id}/exports` | History, paginated | | `GET` | `/accounts/{of_user_id}/exports/{job_id}` | One job's status | | `GET` | `/accounts/{of_user_id}/exports/{job_id}/download` | Download the ZIP | | `POST` | `/accounts/{of_user_id}/exports/{job_id}/cancel` | Stop a running job | | `DELETE` | `/accounts/{of_user_id}/exports/{job_id}` | Delete the job and its ZIP | ## Start an export [#start-an-export] ```bash curl -X POST "$BASE/api/crm/$CRM/accounts/$OFUID/exports" \ -H "X-API-Key: $KEY" \ -H "Content-Type: application/json" \ -d '{ "data_types": ["account","subscribers","transactions","fans","earnings","messages"], "since": "2026-06-01", "until": null, "include_media": false }' ``` | Field | Type | Notes | | --------------- | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `data_types` | `string[]` | Non-empty subset of `account`, `subscribers`, `transactions`, `fans`, `earnings`, `messages` | | `since` | `"YYYY-MM-DD"` \| `null` | Lower bound | | `until` | `"YYYY-MM-DD"` \| `null` | Upper bound. Both null means all-time | | `include_media` | `boolean` | Download message media. **Required:** `messages` must be in `data_types`, or this is silently ignored. OnlyFans only β€” a Fansly export records a warning and lists attachment URLs in the message JSON instead | The `202` response includes a warning worth heeding: ```json { "success": true, "job": { "job_id": "f01152d3…", "status": "queued", … }, "warning": "Messages and media are fetched live from the platform β€” this can take several minutes and counts against your API quota." } ``` `account`, `subscribers`, `fans` and (on OnlyFans) `transactions` are cached reads and nearly free. **`earnings` costs 1–2 live calls.** Fansly `transactions` falls back to a live wallet walk of up to 20 pages when its cache is cold. `messages` β€” and especially `include_media` β€” is the expensive one. Export messages when you need them, not by default. ## One export at a time [#one-export-at-a-time] A second request while one is in flight returns the **existing** job rather than an error: ```json { "already_running": true, "job": { … } } ``` Unless that job is stale β€” no terminal status for over **30 minutes** β€” in which case it is marked failed and yours starts fresh. ## Track progress [#track-progress] Poll: ```bash curl "$BASE/api/crm/$CRM/accounts/$OFUID/exports/$JOB_ID" -H "X-API-Key: $KEY" ``` Or stream, which is what the dashboard does: ```bash curl -N "$BASE/api/crm/$CRM/events/stream" -H "X-API-Key: $KEY" ``` ``` event: export.progress data: {"job_id":"…","status":"running","phase":"messages","phase_index":6, "phase_total":7,"counts":{…},"updated_at":"…"} event: export.complete data: {"job_id":"…","status":"complete",…} ``` `phase_index` / `phase_total` give you a real progress bar; `phase` names what is running. Because messages come last, a job can sit at high progress for a long time β€” that is the live walk, not a stall. ## Download [#download] ```bash curl -L -o export.zip \ "$BASE/api/crm/$CRM/accounts/$OFUID/exports/$JOB_ID/download" \ -H "X-API-Key: $KEY" ``` Responds `application/zip`. What each type produces differs: | Type | Files | | ------------------------------------- | --------------------------------------------------------------- | | `subscribers`, `transactions`, `fans` | `.json` **and** `.csv` | | `account`, `earnings` | `.json` only | | `messages` | one JSON per conversation, plus `messages.csv` and `index.json` | Available for 7 days, then cleaned up. `DELETE` the job to remove it sooner. Statuses are `queued`, `running`, `complete`, `failed`, `canceled`, `expired` β€” the terminal success value is `complete`, not `completed`. A poll loop waiting for `"completed"` never fires. ## Cancelling [#cancelling] ```bash curl -X POST "$BASE/api/crm/$CRM/accounts/$OFUID/exports/$JOB_ID/cancel" \ -H "X-API-Key: $KEY" ``` Worth doing if you started a media export by accident β€” it will otherwise keep consuming quota until it finishes. ## There is a UI for this [#there-is-a-ui-for-this] `Dashboard β†’ Export` drives exactly these endpoints. If a human needs a one-off download rather than an integration, send them there. --- # FAQ (/docs/faq) The risk is real and it comes almost entirely from **request pacing**, not from the API itself. We keep sessions stable, sign requests with the current algorithm, and route each account through the proxy you supplied β€” the things that get accounts flagged when done wrong. (If you supply no proxy, traffic egresses on our server IP; see below.) What is left to you: pace your live calls. As a reference point, our own background poller runs at roughly 3–5 requests per *two minutes* per account, and internal sweeps self-throttle to about 1 req/s β€” that is the shape of traffic the platforms are comfortable with. The [cached routes](/docs/cached-reads) cost zero platform requests, so read from those and refresh them on a schedule rather than polling live endpoints in a loop. See [Rate limits & quotas](/docs/rate-limits). For OnlyFans, in practice yes β€” but it is **not enforced**. Omit it and the session is created from our server's IP and pinned there, which is what gets accounts flagged later. A malformed `X-Proxy` is silently ignored rather than rejected, so a typo degrades to direct egress without any error. Use one sticky residential or ISP proxy per account, and keep the exit location stable. Rotating proxies defeat the purpose. See [Proxies](/docs/proxies). Only requests that actually reach the platform: live reads, refreshes, backfills, payout calls and every `/api2/v2/*` call β€” about 30 of \~145 routes. **Cached reads, async-job status polls and background polling are free**, in quota as well as in platform requests. `GET /health` and `GET /events/stream` are also exempt from the per-minute limit. Check consumption at `GET /api/crm/{crm_id}/usage`; `api_calls_limit: -1` means unlimited. The normalized CRM routes are Fansly-aware and return the same shapes for both platforms. Not supported for Fansly: the `/api2/v2/*` passthrough (OnlyFans-only by definition), payout requests, campaign claimers, mass DM, campaign *creation*, subscription-price *updates*, PPV stats, the three referrals routes, and real-time WebSocket (Fansly is polling-only). Most return `501` with `code: "platform_not_supported"` plus `platform` and `feature`. Full matrix in [OnlyFans & Fansly](/docs/platforms). You are not talking to the API. `_notice` comes from our honeypot layer on **decoy paths** β€” most commonly `https://theonlyapi.com/api/health`, which is bait and returns fabricated data. The selection is by path, not by whether you authenticated. Real API paths are panel-scoped: `https://theonlyapi.com/api/crm/{crm_id}/…`. A missing or wrong key there returns a plain `401`/`403` JSON error with no `_notice`. Details in [Responses & errors](/docs/responses). It does not. There is no User-Agent check anywhere on the API β€” a `curl` request and a browser-UA request get byte-identical responses, and `-A "Mozilla/5.0"` changes nothing. If you are seeing decoy data, you are on a decoy **path** (see the previous answer). OnlyFans write operations are gated per account, off by default: ```bash curl -X PATCH "$BASE/api/crm/$CRM/accounts/$OFUID/polling" \ -H "X-API-Key: $KEY" -H "Content-Type: application/json" \ -d '{"allow_of_write_actions": true}' ``` The gate now covers **every OnlyFans or Fansly write performed as the account**: single DM/PPV sends (both platforms), the mass-DM real send, the `send_dm` automation action, payout requests, subscription-price changes, the raw `POST /accounts/{of_user_id}/request` proxy, and **any non-GET request through the `/api2/v2/*` passthrough**. Reads are never gated. Match on `code: "WRITES_DISABLED"` rather than the message text. Almost certainly the pagination quirks. `/chats` ignores `limit` and returns 10–14 conversations regardless, and a short page from `/messages` does **not** mean the end of the conversation. Note the CRM `/messages` route is **offset**-paged; the `id=` cursor works only on the `/api2/v2/chats/{fan_id}/messages` passthrough, which is the reliable way to walk a full history. See [Pagination](/docs/pagination). Two likely causes. You are summing `amount` (the gross the fan paid) instead of `net` (what the creator received) β€” that inflates the total by roughly 1.25x. And you are counting chargebacks: a reversal is the **original row relabelled** to `status: "undo"` / `tx_type: "chargeback"` with the amount still positive. For period revenue, **exclude** chargeback rows β€” a naive sum overstates by one chargeback, and subtracting double-counts the reversal. For per-fan lifetime spend, subtract them. See [the chargeback trap](/docs/earnings). First check `status` β€” a webhook on an unapproved domain is `pending` and delivers nothing at all. Otherwise: five consecutive failed deliveries (each an exhausted retry ladder) deactivates it until you re-enable it with `PATCH /webhooks/{id}` and `{"is_active": true}`. Check `GET /webhooks/{id}/deliveries` for the failures, fix the endpoint, re-enable, then backfill the gap from `GET /events?since=…`. See [Webhooks](/docs/webhooks). The session probably died. After five consecutive failures, polling for that account is paused and a `polling_paused` event is emitted. Reconnecting clears the session block but **not** the pause β€” re-enable polling explicitly with `PATCH /accounts/{of_user_id}/polling` and `{"enabled": true}`. Set up a `polling_paused` [automation](/docs/automations) so you hear about this before your users do. See [Sessions & re-login](/docs/sessions). Not with your API key. A key grants full access to the panel, so it must never reach client-side JavaScript β€” a browser cannot keep a secret. Cross-origin requests to `/api/*` are restricted to an allowlist, so a page on another domain cannot read your panel even if it has a key. Proxy through your own backend and attach the key server-side. For live events this is required regardless, because the browser `EventSource` API cannot set headers β€” there is a worked example in [Server-sent events](/docs/streaming). Not yet. The API is plain REST with a single header, and there is an [OpenAPI 3.1 spec](https://theonlyapi.com/api/openapi.json) you can point a generator at. For AI-assisted work, the [MCP server](/docs/ai-agents) is usually faster than generating a client. Three differences to plan for: 1. **Panel-scoped paths.** Every route carries your `crm_id`: `https://theonlyapi.com/api/crm/{crm_id}/…`. Seven unscoped routes are the exception, and they live on `api.theonlyapi.com` β€” see [Base URL & panels](/docs/base-url). 2. **Two surfaces.** Providers that only proxy OnlyFans map onto our `/api2/v2/*` passthrough. The normalized CRM layer β€” cached reads, aggregations, events, exports β€” has no equivalent and is where the value is. See [The two surfaces](/docs/two-surfaces). 3. **Slot pricing, not per-call metering.** Paid plans have unlimited API calls; you pay per connected account. So caching is about protecting the *platform's* limits, not your bill. Sessions do not transfer. Reconnect each account with [session paste](/docs/connect-an-account) β€” it takes about a minute per account. [Contact us](https://theonlyapi.com/contact). For a `500`, include the `correlation_id` from the response body β€” it maps to the full server-side traceback, which is deliberately not returned to callers. --- # Get an API key (/docs/get-an-api-key) Every request needs an `X-API-Key` header. Keys are scoped to a single CRM panel. ## Get your first key [#get-your-first-key] Sign up on the website. Your key already exists by the time you land in the dashboard. Registration happens through the website form. Creating the account also creates your CRM panel and mints its first API key, in the same step. Your `crm_id` and key are here, alongside per-key usage and the controls to mint or revoke additional keys. There is no separate "create a panel" step and no API call to make. A panel is the tenant your key belongs to, and one is provisioned for you at signup β€” `crm_id`, primary key, and the user record linking them are all written together. The rest of this page assumes you are signed in and looking at **Dashboard β†’ API Keys**. ## Primary and secondary keys [#primary-and-secondary-keys] A panel has exactly one **primary** key (named `Default`) plus any number of **secondary** keys. | | Primary | Secondary | | ---------------------------------------------------- | ---------------------- | --------- | | Read and write panel data | yes | yes | | Create a secondary key (`POST /api-keys`) | yes | **403** | | Revoke a secondary key (`DELETE /api-keys/{key_id}`) | yes | **403** | | Can be revoked | no β€” rotate it instead | yes | Use secondary keys to give each service, environment or teammate its own credential, so you can revoke one without disrupting everything else. Per-key usage is tracked separately. `POST /api-keys` returns the full key in that response and never again. List endpoints only ever return a `prefix`. If you lose a secondary key, revoke it and mint a new one. ```bash curl -X POST "$BASE/api/crm/$CRM/api-keys" \ -H "X-API-Key: $PRIMARY_KEY" \ -H "Content-Type: application/json" \ -d '{"name": "production-worker"}' ``` ## Rotate a key [#rotate-a-key] Rotation replaces the key you are calling with. The old key dies **immediately** and the new one is returned once in the response body. ```bash curl -X POST "$BASE/api/crm/$CRM/rotate-key" \ -H "X-API-Key: $KEY" ``` The primary `Default` key cannot be revoked β€” rotate it. ## Resolve a key to a panel [#resolve-a-key-to-a-panel] If you have a key but not its `crm_id`: ```bash curl "https://api.theonlyapi.com/api/whoami" \ -H "X-API-Key: $KEY" ``` This is also how the hosted MCP server turns a bearer token into a tenant. ## Check your usage [#check-your-usage] ```bash curl "$BASE/api/crm/$CRM/usage" -H "X-API-Key: $KEY" ``` Returns `plan`, `api_calls_used`, `api_calls_limit`, `accounts_used` and `accounts_limit`. An `api_calls_limit` of `-1` means unlimited. Per-key detail β€” 30/90-day series, month and all-time totals, endpoint breakdown β€” is at `GET /api-keys/{key_id}/usage`. ## Keeping keys safe [#keeping-keys-safe] * Send keys in the `X-API-Key` **header** only. The API deliberately does not read a key from a query parameter, so keys never land in access logs. * Some keys in circulation are **canary tokens**. Using a key you found rather than one you were issued raises an alert while still failing as `Invalid API key`. [Authentication](/docs/authentication) covers what each failure code means. --- # Integrations (/docs/integrations) Panel-scoped and authenticated exactly like every other CRM route. Each endpoint below links to its full reference page. ## Telegram notifications [#telegram-notifications] A first-class Telegram integration, separate from the `telegram` action available in [automations](/docs/automations). Pairing is done through a deep link, so a bot token never has to be sent to a chat. | Endpoint | What it does | | ----------------------------------------------------------------------------------------- | ------------------------------------------------------------- | | [`GET /integrations/telegram`](/docs/crm/integrations/get-the-telegram-integration) | Current integration + whether a shared bot is available | | [`POST /integrations/telegram/pair`](/docs/crm/integrations/start-telegram-pairing) | Start or restart pairing β†’ returns a `t.me` deep link | | [`PATCH /integrations/telegram`](/docs/crm/integrations/update-the-telegram-integration) | Update event types or pause delivery (404 if none configured) | | [`POST /integrations/telegram/test`](/docs/crm/integrations/send-a-telegram-test-message) | Send a test notification | | [`DELETE /integrations/telegram`](/docs/crm/integrations/remove-the-telegram-integration) | Remove the integration | | [`POST /integrations/telegram/groups`](/docs/crm/integrations/register-telegram-groups) | **List** the groups your own bot can see | ### Pairing [#pairing] ```bash curl -X POST "$BASE/api/crm/$CRM/integrations/telegram/pair" \ -H "X-API-Key: $KEY" \ -H "Content-Type: application/json" \ -d '{ "bot_mode": "shared", "event_types": ["new_tip", "new_subscriber"] }' ``` | Field | Notes | | ------------- | -------------------------------------------------------------------- | | `bot_mode` | `"shared"` to use the platform's own bot, or `"custom"` for your own | | `bot_token` | Required for `"custom"` only | | `event_types` | Optional filter; omit for everything | The response is a `t.me` deep link β€” **never a token**. Open it and start the bot to complete pairing. `GET /integrations/telegram` reports `shared_bot_available`, so a UI can hide the shared-bot option on a deployment where no shared bot is configured rather than offering a button that fails. ### Read, test, remove [#read-test-remove] ```bash curl "$BASE/api/crm/$CRM/integrations/telegram" -H "X-API-Key: $KEY" curl -X POST "$BASE/api/crm/$CRM/integrations/telegram/test" -H "X-API-Key: $KEY" curl -X DELETE "$BASE/api/crm/$CRM/integrations/telegram" -H "X-API-Key: $KEY" ``` `PATCH` returns `404 No Telegram integration configured` if you have not paired yet β€” pair first, then update. `POST /integrations/telegram/groups` **lists** the group chats your bot can see so a UI can offer a picker β€” it registers nothing. It requires `{"bot_token": "…"}` and is custom-bot only; passing the shared platform token is refused with `400`, because that token is a single-consumer stream. Writes here are on the 100/minute sensitive-route limit; the `GET` is on the default 100/minute. ## Account tags [#account-tags] Tag connected accounts (distinct from [fan tags](/docs/subscribers)) β€” useful for grouping creators by manager, niche or status. | Endpoint | What it does | | -------------------------------------------------------------------------------------- | ----------------------------------------- | | [`POST /accounts/{of_user_id}/tags`](/docs/crm/accounts/tag-a-connected-account) | Add a tag β€” body `{"tag": "vip-creator"}` | | [`DELETE /accounts/{of_user_id}/tags/{tag}`](/docs/crm/accounts/remove-an-account-tag) | Remove a tag | ```bash curl -X POST "$BASE/api/crm/$CRM/accounts/$OFUID/tags" \ -H "X-API-Key: $KEY" -H "Content-Type: application/json" \ -d '{"tag": "managed-by-alex"}' ``` Tags are capped at 40 characters. The full set for the panel comes back as `all_tags` on `GET /accounts`. Tag values are HTML-escaped once when stored. The `DELETE` path segment is deliberately **not** re-escaped, so pass the tag exactly as it was stored β€” a double-escaped value silently matches nothing and deletes nothing. ## Referrals [#referrals] Full reference: [CRM API β†’ Referrals](/docs/crm/referrals). Referral money is separate from subscription and tip revenue, so it is not included in `GET /earnings/summary` β€” add it explicitly if your reporting needs a true total. See [Earnings & transactions](/docs/earnings). ## Earnings verification [#earnings-verification] ``` GET /accounts/{of_user_id}/earnings/verify ``` Cross-checks the computed earnings figures against the platform's own totals. Useful when a number looks wrong and you want to know whether the discrepancy is in the cache or in your own aggregation β€” see [the chargeback trap](/docs/earnings) for the most common cause. ## Request metrics [#request-metrics] [`GET /metrics/requests`](/docs/crm/panel-and-usage/get-request-metrics-for-your-panel) returns your panel's own request outcomes over a window β€” volume, status classes, error rate, latency, and the slowest and most error-prone routes. It is what the dashboard Overview charts, and it includes the current partial bucket so the numbers are not up to a minute stale. ## Related guides [#related-guides] | Endpoint | Guide | | ------------------------------------------------------------------------------------------------------------ | ----------------------------------------- | | The eight [`/import/*`](/docs/crm/bulk-import) routes | [Bulk account import](/docs/bulk-import) | | [`GET /balances/summary`](/docs/crm/earnings/get-panel-wide-payout-totals) | [Earnings & transactions](/docs/earnings) | | [`GET /accounts/{of_user_id}/fansly-credentials`](/docs/crm/accounts/read-a-fansly-account-s-stored-session) | [OnlyFans & Fansly](/docs/platforms) | | [`POST /accounts/{of_user_id}/refresh/{kind}/clear`](/docs/crm/cache-and-sync/clear-a-stuck-refresh-job) | [Async jobs](/docs/async-jobs) | Discord, Slack and OnlyFans DM notifications are delivered through [automation actions](/docs/automations) β€” you configure them as part of a rule rather than as a standalone integration. Only Telegram has dedicated endpoints, because of the pairing handshake. --- # Messaging & mass DM (/docs/messaging) ## Read a conversation [#read-a-conversation] ```bash # List conversations curl "$BASE/api/crm/$CRM/accounts/$OFUID/chats" -H "X-API-Key: $KEY" # Message history with one fan curl "$BASE/api/crm/$CRM/accounts/$OFUID/chats/$FANID/messages" -H "X-API-Key: $KEY" ``` `/chats` largely ignores `limit` and returns 10–14 conversations regardless, and `/messages` uses an `id=` cursor where a short page does **not** mean the end. A walker that gets this wrong loses most of a message history. Read [Pagination](/docs/pagination) before writing one. ## Send a DM or PPV [#send-a-dm-or-ppv] ```bash curl -X POST "$BASE/api/crm/$CRM/accounts/$OFUID/chats/$FANID/messages" \ -H "X-API-Key: $KEY" \ -H "Content-Type: application/json" \ -d '{ "text": "Hey! New drop is up πŸ’•", "price": 0, "mediaFiles": [] }' ``` * `price > 0` makes the message a **PPV**. * `mediaFiles` takes vault media IDs, locked behind the price. * Works for OnlyFans and Fansly. Rate limited to 100 requests/minute. OnlyFans sends are gated per account by `allow_of_write_actions`. Without it you get a `403` with `code: "WRITES_DISABLED"` (match on the code, not the message). This applies to Fansly sends too: ```bash curl -X PATCH "$BASE/api/crm/$CRM/accounts/$OFUID/polling" \ -H "X-API-Key: $KEY" -H "Content-Type: application/json" \ -d '{"allow_of_write_actions": true}' ``` ## Mass DM [#mass-dm] **OnlyFans only** β€” Fansly returns `501` with `{"code": "PLATFORM_NOT_SUPPORTED"}`. ```bash curl -X POST "$BASE/api/crm/$CRM/accounts/$OFUID/messages/mass" \ -H "X-API-Key: $KEY" \ -H "Content-Type: application/json" \ -d '{ "text": "New set just dropped πŸ”₯", "price": 12, "mediaFiles": ["1234567"], "previews": ["1234567"], "audience": { "min_spent": 20, "since": "2026-01-01T00:00:00Z" }, "dry_run": true }' ``` A message needs `text`, `mediaFiles`, or both β€” an empty send is rejected with `400 message requires text or mediaFiles`. ### `dry_run` defaults to true [#dry_run-defaults-to-true] This is the important detail. `dry_run` is **`true` unless you explicitly set it to `false`**. In dry-run mode the API resolves the audience, counts the recipients and returns a sample β€” **without sending anything**. ```json { "success": true, "dry_run": true, "recipients": 418, "sent": 0, "sample": [ { "fan_of_user_id": "987", "username": "somefan" } ], "note": "Preview only β€” no messages were sent." } ``` `recipients` is the resolved count; `sample` is the first **10** only. This is the "who will this actually reach?" preview, and it costs nothing. Check the count and the sample, then re-send the identical body with `"dry_run": false`. A mass DM cannot be recalled once sent. ### Audience filters [#audience-filters] | Field | Effect | | ----------------- | --------------------------------------------------------------------------- | | `type` | `all` \| `active` \| `expired` β€” **defaults to** `active` | | `fan_ids` | Explicit id list. **Overrides every other filter.** Truncated at 5,000 | | `min_spent` | Only fans who have spent at least this much | | `since` / `until` | Inclusive bounds on the fan's `subscribed_at` | Omitting `type` reaches only **current** subscribers, not everyone. There is no `tag` field β€” the audience is resolved from the subscriber cache, which carries no tags, so a `tag` key is silently ignored. To target a segment, resolve it yourself with `GET /fans`, then pass the ids as `audience.fan_ids`. ## PPV performance [#ppv-performance] ```bash curl "$BASE/api/crm/$CRM/accounts/$OFUID/ppv-stats" -H "X-API-Key: $KEY" ``` Unlock rates and revenue per PPV message, so you can tell which sends actually earned. ## Vault media [#vault-media] Media IDs for `mediaFiles` and `previews` come from the vault, which lives on the [passthrough surface](/docs/two-surfaces) β€” see the **Content** tag in the [OnlyFans passthrough reference](/docs/of-api). Upload and vault management are not exposed on the CRM layer. `previews` should be a subset of `mediaFiles`: those items stay unlocked as a teaser while the rest sit behind the price. ## Pacing [#pacing] Sends are OnlyFans writes and hit the platform directly. See [Rate limits](/docs/rate-limits). The real send is **not** dispatched to a background worker and is **not** paced. It loops through recipients synchronously inside the HTTP request β€” up to 5,000 sends on one connection. Keep audiences small enough that the request completes, and pace by splitting the audience with `since`/`until` rather than relying on server-side throttling. --- # OnlyFans Passthrough (/docs/of-api) {/* Generated by scripts/gen-api.ts β€” edit that script, not this file. */} A thin, signed proxy over OnlyFans' own `/api2/v2` API. We load the account's saved session, route through its proxy, generate fresh signed headers, and return the response. Every request needs an `X-API-Key` header **and** a `user-id` header naming the connected account. Every response is wrapped: ```json { "success": true, "status_code": 200, "data": { "…OnlyFans' own payload…" } } ``` A `user-id` belonging to a Fansly account is rejected on this surface. Use the platform-neutral [CRM routes](/docs/crm) instead β€” they are Fansly-aware. Direct proxy to OnlyFans user profile & settings endpoints. **OnlyFans only.** Requires `X-API-Key` + `user-id` headers. OnlyFans subscriber endpoints (via proxy). **OnlyFans only** β€” Fansly accounts are rejected on this surface. OnlyFans subscription management (via proxy). **OnlyFans only** β€” Fansly accounts are rejected on this surface. OnlyFans chats & messages (via proxy). **OnlyFans only** β€” Fansly accounts are rejected on this surface. OnlyFans posts, vault, labels (via proxy). **OnlyFans only** β€” Fansly accounts are rejected on this surface. OnlyFans stories (via proxy). **OnlyFans only** β€” Fansly accounts are rejected on this surface. OnlyFans live streams (via proxy). **OnlyFans only** β€” Fansly accounts are rejected on this surface. OnlyFans campaign endpoints (via proxy). **OnlyFans only** β€” Fansly accounts are rejected on this surface. OnlyFans promotions & trials (via proxy). **OnlyFans only** β€” Fansly accounts are rejected on this surface. OnlyFans user lists (via proxy). **OnlyFans only** β€” Fansly accounts are rejected on this surface. OnlyFans payout & payment endpoints (via proxy). **OnlyFans only** β€” Fansly accounts are rejected on this surface. OnlyFans notification endpoints (via proxy). **OnlyFans only** β€” Fansly accounts are rejected on this surface. OnlyFans helper/manager accounts (via proxy). **OnlyFans only** β€” Fansly accounts are rejected on this surface. Other OnlyFans endpoints. **OnlyFans only** β€” Fansly accounts are rejected on this surface. *433 endpoints, generated from the [OpenAPI 3.1 spec](https://theonlyapi.com/api/openapi.json).* --- # Campaigns (/docs/of-api/campaigns) {/* Generated by scripts/gen-api.ts β€” edit that script, not this file. */} OnlyFans campaign endpoints (via proxy). **OnlyFans only** β€” Fansly accounts are rejected on this surface. | Method | Endpoint | Path | | ------ | --------------------------------------------------------------------------- | ------------------------------------------- | | `GET` | [List campaigns](/docs/of-api/campaigns/list-campaigns-get) | `/api2/v2/campaigns` | | `POST` | [Create campaign](/docs/of-api/campaigns/create-campaign-post) | `/api2/v2/campaigns` | | `GET` | [Get campaign conversions](/docs/of-api/campaigns/get-campaign-conversions) | `/api2/v2/campaigns/{campaign_id}/claimers` | --- # Create campaign (/docs/of-api/campaigns/create-campaign-post) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/campaigns` **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` - `name` (string) β€” e.g. `"My Campaign"`. ## Responses ### 200 β€” Campaign created - `id` (integer) β€” e.g. `12345`. - `campaignName` (string) β€” e.g. `"My Campaign"`. - `campaignCode` (string) β€” Short code / slug used in the tracking URL. - `countTransitions` (integer | object) β€” Number of link clicks. May be an integer or `{ count, date }` object when stats=true. - `countSubscribers` (integer | object) β€” Number of subscribers gained through this campaign. May be an integer or `{ count, date }` object. - `createdAt` (string) - `sharedWith` (object[]) β€” Users this campaign link is shared with. - `id` (integer) - `name` (string) - `username` (string) - `displayName` (string) - `about` (string) - `avatar` (string) β€” Avatar URL. - `avatarThumbs` (object) - `c50` (string) - `c144` (string) - `header` (string) β€” Profile header/banner URL. - `email` (string) - `isVerified` (boolean) - `isPerformer` (boolean) - `canEarn` (boolean) - `tipsEnabled` (boolean) - `subscribedBy` (boolean) β€” Whether you are subscribed to this user. - `subscribersCount` (integer) - `subscribesCount` (integer) - `postsCount` (integer) - `photosCount` (integer) - `videosCount` (integer) - `audiosCount` (integer) - `friendsCount` (integer) - `joinDate` (string) - `firstPublishedPostDate` (string) - `subscribePrice` (number) - `chatMessagesCount` (integer) β€” Unread chat messages. - `countPriorityChat` (integer) - `countPinnedChat` (integer) - `hasPurchasedPosts` (boolean) - `paidFeed` (boolean) - `openseaInfo` (object) ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/campaigns" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{"name":"My Campaign"}' ``` --- # Get campaign conversions (/docs/of-api/campaigns/get-campaign-conversions) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/campaigns/{campaign_id}/claimers` **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `campaign_id` (string, required) ## Query parameters - `limit` (integer) β€” Default `10`. - `offset` (integer) β€” Default `0`. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Claimer list - `list` (object[]) - `id` (integer) - `name` (string) - `username` (string) - `displayName` (string) - `about` (string) - `avatar` (string) β€” Avatar URL. - `avatarThumbs` (object) - `c50` (string) - `c144` (string) - `header` (string) β€” Profile header/banner URL. - `email` (string) - `isVerified` (boolean) - `isPerformer` (boolean) - `canEarn` (boolean) - `tipsEnabled` (boolean) - `subscribedBy` (boolean) β€” Whether you are subscribed to this user. - `subscribersCount` (integer) - `subscribesCount` (integer) - `postsCount` (integer) - `photosCount` (integer) - `videosCount` (integer) - `audiosCount` (integer) - `friendsCount` (integer) - `joinDate` (string) - `firstPublishedPostDate` (string) - `subscribePrice` (number) - `chatMessagesCount` (integer) β€” Unread chat messages. - `countPriorityChat` (integer) - `countPinnedChat` (integer) - `hasPurchasedPosts` (boolean) - `paidFeed` (boolean) - `openseaInfo` (object) - `hasMore` (boolean) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/campaigns/{campaign_id}/claimers" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # List campaigns (/docs/of-api/campaigns/list-campaigns-get) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/campaigns` **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Query parameters - `limit` (integer) β€” Default `10`. - `offset` (integer) β€” Default `0`. - `pagination` (integer) β€” Default `1`. - `stats` (string) β€” Default `true`. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Campaign list - `list` (object[]) - `id` (integer) β€” e.g. `12345`. - `campaignName` (string) β€” e.g. `"My Campaign"`. - `campaignCode` (string) β€” Short code / slug used in the tracking URL. - `countTransitions` (integer | object) β€” Number of link clicks. May be an integer or `{ count, date }` object when stats=true. - `countSubscribers` (integer | object) β€” Number of subscribers gained through this campaign. May be an integer or `{ count, date }` object. - `createdAt` (string) - `sharedWith` (object[]) β€” Users this campaign link is shared with. - `id` (integer) - `name` (string) - `username` (string) - `displayName` (string) - `about` (string) - `avatar` (string) β€” Avatar URL. - `avatarThumbs` (object) - `header` (string) β€” Profile header/banner URL. - `email` (string) - `isVerified` (boolean) - `isPerformer` (boolean) - `canEarn` (boolean) - `tipsEnabled` (boolean) - `subscribedBy` (boolean) β€” Whether you are subscribed to this user. - `subscribersCount` (integer) - `subscribesCount` (integer) - `postsCount` (integer) - `photosCount` (integer) - `videosCount` (integer) - `audiosCount` (integer) - `friendsCount` (integer) - `joinDate` (string) - `firstPublishedPostDate` (string) - `subscribePrice` (number) - `chatMessagesCount` (integer) β€” Unread chat messages. - `countPriorityChat` (integer) - `countPinnedChat` (integer) - `hasPurchasedPosts` (boolean) - `paidFeed` (boolean) - `openseaInfo` (object) - `hasMore` (boolean) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/campaigns" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Content (/docs/of-api/content) {/* Generated by scripts/gen-api.ts β€” edit that script, not this file. */} OnlyFans posts, vault, labels (via proxy). **OnlyFans only** β€” Fansly accounts are rejected on this surface. | Method | Endpoint | Path | | -------- | --------------------------------------------------------------------------------------------- | ------------------------------------------------------------- | | `DELETE` | [Delete a comment](/docs/of-api/content/delete-a-comment) | `/api2/v2/comments/{comment_id}` | | `POST` | [Like a comment](/docs/of-api/content/like-a-comment) | `/api2/v2/comments/{comment_id}/like` | | `DELETE` | [Unlike a comment](/docs/of-api/content/unlike-a-comment) | `/api2/v2/comments/{comment_id}/like` | | `POST` | [Pin a comment](/docs/of-api/content/pin-a-comment) | `/api2/v2/comments/{comment_id}/pin` | | `DELETE` | [Unpin a comment](/docs/of-api/content/unpin-a-comment) | `/api2/v2/comments/{comment_id}/pin` | | `GET` | [Get user labels](/docs/of-api/content/get-user-labels) | `/api2/v2/labels` | | `GET` | [Get posts feed](/docs/of-api/content/get-posts-feed) | `/api2/v2/posts` | | `POST` | [Create a new post](/docs/of-api/content/create-a-new-post) | `/api2/v2/posts` | | `GET` | [Get specific post](/docs/of-api/content/get-specific-post) | `/api2/v2/posts/{post_id}` | | `POST` | [Bookmark a post](/docs/of-api/content/bookmark-a-post) | `/api2/v2/posts/{post_id}/bookmarks` | | `DELETE` | [Remove post from bookmarks](/docs/of-api/content/remove-post-from-bookmarks) | `/api2/v2/posts/{post_id}/bookmarks` | | `GET` | [Get post comments](/docs/of-api/content/get-post-comments) | `/api2/v2/posts/{post_id}/comments` | | `POST` | [Like / favorite a post](/docs/of-api/content/like-favorite-a-post) | `/api2/v2/posts/{post_id}/favorites` | | `POST` | [Add post to favorites](/docs/of-api/content/add-post-to-favorites) | `/api2/v2/posts/{post_id}/favorites/{author_id}` | | `GET` | [Count fundraising contributors](/docs/of-api/content/count-fundraising-contributors) | `/api2/v2/posts/{post_id}/fund-raising-contributors/count` | | `PUT` | [Hide a post](/docs/of-api/content/hide-a-post) | `/api2/v2/posts/{post_id}/hide` | | `POST` | [Vote on a post poll](/docs/of-api/content/vote-on-a-post-poll) | `/api2/v2/posts/{post_id}/vote` | | `GET` | [Get bookmarked posts](/docs/of-api/content/get-bookmarked-posts) | `/api2/v2/posts/bookmarks` | | `GET` | [Get bookmark categories](/docs/of-api/content/get-bookmark-categories) | `/api2/v2/posts/bookmarks/categories` | | `PATCH` | [Rename bookmark category](/docs/of-api/content/rename-bookmark-category) | `/api2/v2/posts/bookmarks/categories/{category_id}` | | `DELETE` | [Delete a bookmark category](/docs/of-api/content/delete-a-bookmark-category) | `/api2/v2/posts/bookmarks/categories/{category_id}` | | `POST` | [Add post to bookmark category](/docs/of-api/content/add-post-to-bookmark-category) | `/api2/v2/posts/bookmarks/categories/{category_id}/{post_id}` | | `POST` | [Sort bookmark categories](/docs/of-api/content/sort-bookmark-categories) | `/api2/v2/posts/bookmarks/categories/sort` | | `POST` | [Sort pinned paid posts](/docs/of-api/content/sort-pinned-paid-posts) | `/api2/v2/posts/paid/pin/sort` | | `POST` | [Reorder pinned posts](/docs/of-api/content/reorder-pinned-posts) | `/api2/v2/posts/pinned/sort` | | `POST` | [Report post view/interaction stats](/docs/of-api/content/report-post-view-interaction-stats) | `/api2/v2/posts/stats-collect` | | `POST` | [Create release form link](/docs/of-api/content/create-release-form-link) | `/api2/v2/release-form-links` | | `POST` | [Attach release form](/docs/of-api/content/attach-release-form) | `/api2/v2/release-forms/attach` | | `GET` | [Get scheduled posts](/docs/of-api/content/get-scheduled-posts) | `/api2/v2/schedules` | | `PUT` | [Publish a scheduled item](/docs/of-api/content/publish-a-scheduled-item) | `/api2/v2/schedules/{schedule_id}/publish` | | `GET` | [Get scheduled-post counts per day](/docs/of-api/content/get-scheduled-post-counts-per-day) | `/api2/v2/schedules/counters` | | `POST` | [Create signed media upload](/docs/of-api/content/create-signed-media-upload) | `/api2/v2/upload/signed/create` | | `POST` | [Finish signed upload](/docs/of-api/content/finish-signed-upload) | `/api2/v2/upload/signed/finish` | | `GET` | [Get DRM certificate](/docs/of-api/content/get-drm-certificate) | `/api2/v2/users/media/drm/certificate` | | `GET` | [Get 'on this day' posts](/docs/of-api/content/get-on-this-day-posts) | `/api2/v2/users/posts/on-this-day` | | `GET` | [Get vault lists (folders)](/docs/of-api/content/get-vault-lists-folders) | `/api2/v2/vault/lists` | | `GET` | [Get vault media list](/docs/of-api/content/get-vault-media-list) | `/api2/v2/vault/lists/{list_id}` | | `PATCH` | [Rename a vault list](/docs/of-api/content/rename-a-vault-list) | `/api2/v2/vault/lists/{list_id}` | | `DELETE` | [Delete vault list](/docs/of-api/content/delete-vault-list) | `/api2/v2/vault/lists/{list_id}` | | `POST` | [Add media to vault list](/docs/of-api/content/add-media-to-vault-list) | `/api2/v2/vault/lists/{list_id}/media` | | `POST` | [Sort vault lists](/docs/of-api/content/sort-vault-lists) | `/api2/v2/vault/lists/sort` | | `GET` | [Get vault media](/docs/of-api/content/get-vault-media) | `/api2/v2/vault/media` | | `GET` | [Get vault media item](/docs/of-api/content/get-vault-media-item) | `/api2/v2/vault/media/{media_id}` | | `PUT` | [Attach vault media to post/message](/docs/of-api/content/attach-vault-media-to-post-message) | `/api2/v2/vault/media/{media_id}/attach` | | `GET` | [Get posts using a vault media item](/docs/of-api/content/get-posts-using-a-vault-media-item) | `/api2/v2/vault/media/{media_id}/posts` | | `GET` | [Get vault media release forms](/docs/of-api/content/get-vault-media-release-forms) | `/api2/v2/vault/media/{media_id}/release-forms` | | `GET` | [Find vault media by MD5 (dedupe)](/docs/of-api/content/find-vault-media-by-md5-dedupe) | `/api2/v2/vault/media/hash` | | `PUT` | [Hide vault media](/docs/of-api/content/hide-vault-media) | `/api2/v2/vault/media/hidden` | | `GET` | [Get vault media being processed](/docs/of-api/content/get-vault-media-being-processed) | `/api2/v2/vault/media/processing` | | `GET` | [Get vault media types present](/docs/of-api/content/get-vault-media-types-present) | `/api2/v2/vault/media/types` | --- # Add media to vault list (/docs/of-api/content/add-media-to-vault-list) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/vault/lists/{list_id}/media` Add one or more media items to a vault list (folder) for organization. **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `list_id` (integer, required) β€” Vault list ID. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` (required) - `mediaIds` (integer[], required) β€” Array of media IDs to add to the list. e.g. `[12345,67890]`. ## Responses ### 200 β€” Media added to list ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/vault/lists/{list_id}/media" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{"mediaIds":[12345,67890]}' ``` --- # Add post to bookmark category (/docs/of-api/content/add-post-to-bookmark-category) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/posts/bookmarks/categories/{category_id}/{post_id}` Adds a post to a bookmark category. Called as ({categoryId, postId}). **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `category_id` (string, required) β€” ID of the bookmark category. - `post_id` (string, required) β€” ID of the post to add. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/posts/bookmarks/categories/{category_id}/{post_id}" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Add post to favorites (/docs/of-api/content/add-post-to-favorites) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/posts/{post_id}/favorites/{author_id}` Marks the given post (by the specified author) as a favorite for the current user. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `post_id` (string, required) β€” ID of the post to favorite. - `author_id` (string, required) β€” User ID of the post's author. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/posts/{post_id}/favorites/{author_id}" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Attach release form (/docs/of-api/content/attach-release-form) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/release-forms/attach` Attaches a release form (content consent document) to content. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/release-forms/attach" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Attach vault media to post/message (/docs/of-api/content/attach-vault-media-to-post-message) `PUT https://theonlyapi.com/api/crm/your-crm-id/api2/v2/vault/media/{media_id}/attach` Attach a media item from the vault to an existing post or message. The media must already be uploaded. **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `media_id` (integer, required) β€” Vault media ID. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` - `postId` (integer) β€” Post ID to attach media to. - `messageId` (integer) β€” Message ID to attach media to. ## Responses ### 200 β€” Media attached ## Example ```bash curl -X PUT "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/vault/media/{media_id}/attach" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Bookmark a post (/docs/of-api/content/bookmark-a-post) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/posts/{post_id}/bookmarks` Adds a post to bookmarks; an optional chat_group_id body targets a specific bookmark group. DELETE on the same path removes the bookmark. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `post_id` (string, required) β€” ID of the post to bookmark. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` - `chat_group_id` (string) β€” Optional bookmark/chat group id; basic call sends no body. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/posts/{post_id}/bookmarks" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Count fundraising contributors (/docs/of-api/content/count-fundraising-contributors) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/posts/{post_id}/fund-raising-contributors/count` Returns the number of contributors to a post's fundraising campaign. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `post_id` (string, required) β€” ID of the post. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/posts/{post_id}/fund-raising-contributors/count" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Create a new post (/docs/of-api/content/create-a-new-post) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/posts` Create a new post on your profile. Supports text, media attachments, PPV pricing, polls, scheduled publishing (`isScheduled` + `scheduledDate`), and expiration dates. **Attaching a freshly uploaded file β€” use `mediaFiles`, not `media`.** `POST /accounts/{of_user_id}/media` returns a `media` object; put it in a **`mediaFiles`** array here, unchanged and complete. Verified live 2026-08-06, and the failure mode is silent β€” OnlyFans returns `200` and simply attaches nothing if you get this wrong: | body | result | |---|---| | `mediaFiles: [{processId, host, thumbId, name, extra}]` | media attached βœ… | | `media: [{…same object…}]` | post created, **0 media** | | `mediaFiles: [{processId}]` only | post created, **0 media** | So pass the whole object through β€” dropping `thumbId` or `name` silently loses the attachment. The vault row for the media is created by this call and appears in `GET /api2/v2/vault/media` roughly 10–15 seconds later. It survives deletion of the post. Media already in the vault is referenced by its integer ID from `GET /api2/v2/vault/media`. **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` (required) - `text` (string) β€” Post text / caption. e.g. `"New exclusive content! πŸ”₯"`. - `rawText` (string) β€” Raw text without formatting (used internally for search/indexing). - `price` (number) β€” PPV price in USD. If set, the post is locked behind a paywall. e.g. `15`. - `lockedText` (boolean) β€” If true, text content is hidden until PPV is purchased. Default `false`. - `media` (integer[]) β€” Media to attach: integer vault IDs (from `GET /api2/v2/vault/media`), and/or the `media` object returned by `POST /accounts/{of_user_id}/media` for a file you just uploaded. e.g. `[12345,67890]`. - `preview` (integer[]) β€” Preview media IDs visible before purchasing PPV content. - `postedAt` (string) β€” Schedule date for the post (ISO 8601). If in the future, the post is scheduled. e.g. `"2025-06-15T14:00:00.000Z"`. - `postedAtPrecise` (string) β€” Precise timestamp string (unix ms). Used internally for ordering. - `expiredAt` (string) β€” Expiration date β€” post auto-deletes after this time. e.g. `"2025-07-15T14:00:00.000Z"`. - `isPublishedWithPeriod` (boolean) β€” Whether the post is published for a specific time period (used with expiredAt). Default `false`. - `voting` (string[]) β€” Poll options. Each item is a poll choice string. Adds a poll/vote to the post. e.g. `["Option A","Option B","Option C"]`. - `linkedPosts` (integer[]) β€” Array of post IDs to link to this post (related content). - `releaseForms` (integer[]) β€” Release form IDs for compliance when media features other people. - `streamId` (integer) β€” Link this post to a live stream by stream ID. ## Responses ### 200 β€” Post created - `id` (integer) - `text` (string) - `rawText` (string) - `price` (number) - `isOpened` (boolean) - `isPinned` (boolean) - `postedAt` (string) - `postedAtPrecise` (string) - `expiredAt` (string) - `commentsCount` (integer) - `favoritesCount` (integer) - `tipsAmount` (number) - `media` (object[]) - `id` (integer) β€” Stable OnlyFans media ID β€” the only persistent identifier for the item. - `type` ("photo" | "video" | "audio" | "gif") - `createdAt` (string) - `duration` (integer) β€” Duration in seconds (video/audio; 0 for photos). - `convertedToVideo` (boolean) - `canView` (boolean) - `isReady` (boolean) β€” False while OnlyFans is still processing/transcoding the upload. - `hasError` (boolean) - `hasPosts` (boolean) β€” Whether the media is attached to any post. - `hasCustomPreview` (boolean) - `counters` (object) β€” Engagement counters (present on the vault view). - `buyersCount` (integer) - `likesCount` (integer) - `tipsSumm` (number) - `listStates` (object[]) β€” Which vault lists (folders) this media belongs to. - `id` (integer) β€” Vault list ID. - `name` (string) β€” Vault list name. - `hasMedia` (boolean) - `canAddMedia` (boolean) - `files` (object) β€” Signed, time-limited CDN URLs at several resolutions. `size` is frequently `0` β€” do not rely on it. - `full` (object) - `preview` (object) - `thumb` (object) - `squarePreview` (object) - `videoSources` (object) β€” Per-resolution video URLs (e.g. `240`, `720`); entries are null when not applicable. - `author` (object) - `canComment` (boolean) - `canEdit` (boolean) - `hasVoting` (boolean) - `voting` (object[]) - `id` (integer) - `text` (string) - `votesCount` (integer) - `isSelected` (boolean) ## Example **Simple text post** ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/posts" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{"text":"Happy Monday everyone! ❀️"}' ``` **Post with media** ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/posts" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{"text":"New photoset just dropped!","media":[12345,67890,11111]}' ``` **Pay-per-view post** ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/posts" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{"text":"Unlock to see the full set πŸ”’","media":[12345,67890],"preview":[12345],"price":25,"lockedText":false}' ``` **Post with a poll** ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/posts" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{"text":"What should I post next?","voting":["Beach photoshoot","Gym content","Behind the scenes"]}' ``` **Scheduled post** ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/posts" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{"text":"Coming soon...","media":[12345],"postedAt":"2025-06-20T18:00:00.000Z"}' ``` --- # Create release form link (/docs/of-api/content/create-release-form-link) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/release-form-links` Creates a release-form link (content consent document link) from the supplied data. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/release-form-links" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Create signed media upload (/docs/of-api/content/create-signed-media-upload) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/upload/signed/create` Stage 1 of OnlyFans' media upload. Returns pre-signed S3 URL(s) that you then PUT the bytes to. **Body** (verified live 2026-08-06): ```json { "key": "upload/{uuid4}/{nonce}/{url-encoded-lowercased-filename}", "parts": 1, "contentType": "image/jpeg", "secure": false } ``` The `key` prefix comes from `GET /api2/v2/init` β†’ `upload.s3.uploadPath` (`upload/`, or `upload/secure/` when `secure` is true). `parts` is `floor(size / 5242880) + 1` for files β‰₯ 5 MiB, else `1`. **A wrong or missing `key` is what produces `400 {"error":{"message":"Bad key"}}`** β€” the field really is named `key`, and it must be a path under the account's upload prefix. Response: `{ keys: [{putUrl}], uploadId, putUrl, getUrl }`. Multipart when `keys[]` is populated and the file is β‰₯ 5 MiB; otherwise PUT the whole file to `putUrl`. **You normally don't call this directly** β€” `POST /accounts/{of_user_id}/media` runs all four stages for you. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` (required) - `key` (string, required) β€” Storage PATH, not a filename β€” `{uploadPath}{uuid4}/{nonce}/{url-encoded lowercased filename}`. `uploadPath` comes from GET /api2/v2/init β†’ `upload.s3.uploadPath` (`upload/`, or `upload/secure/` when secure=true). A missing or malformed value is what returns `400 Bad key`. e.g. `"upload/0e683d4d-1726-4506-a04d-2a5d05f5b9e1/1031326954680/photo.jpg"`. - `parts` (integer, required) β€” Number of 5 MiB S3 parts: `floor(size / 5242880) + 1` for files β‰₯ 5 MiB, otherwise 1. e.g. `1`. - `contentType` (string, required) β€” MIME type of the file. `.heic` must be sent as `image/heic`. e.g. `"image/jpeg"`. - `secure` (boolean) β€” Use the secure (DRM) upload prefix instead of the standard one. Default `false`. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/upload/signed/create" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{"key":"upload/0e683d4d-1726-4506-a04d-2a5d05f5b9e1/1031326954680/photo.jpg","parts":1,"contentType":"image/jpeg","secure":false}' ``` --- # Delete a bookmark category (/docs/of-api/content/delete-a-bookmark-category) `DELETE https://theonlyapi.com/api/crm/your-crm-id/api2/v2/posts/bookmarks/categories/{category_id}` Deletes a post-bookmark category by id. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `category_id` (string, required) β€” Id of the bookmark category to delete. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/posts/bookmarks/categories/{category_id}" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Delete a comment (/docs/of-api/content/delete-a-comment) `DELETE https://theonlyapi.com/api/crm/your-crm-id/api2/v2/comments/{comment_id}` Deletes a specific comment by its id. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `comment_id` (string, required) β€” Id of the comment to delete. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/comments/{comment_id}" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Delete vault list (/docs/of-api/content/delete-vault-list) `DELETE https://theonlyapi.com/api/crm/your-crm-id/api2/v2/vault/lists/{list_id}` Deletes a vault media list, optionally also clearing its media. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `list_id` (string, required) β€” ID of the vault media list. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/vault/lists/{list_id}" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Find vault media by MD5 (dedupe) (/docs/of-api/content/find-vault-media-by-md5-dedupe) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/vault/media/hash` **Deduplication / fileβ†’vault-item lookup.** Given the MD5 of an original file, returns the matching vault media if that exact byte content was previously uploaded, or `404 Media Not Found` if not. This is the ONLY content-based way to correlate a local file with an existing vault item β€” OnlyFans stores no filename or hash on the media object. The hash is the MD5 of the **original uploaded bytes**: hashing a downloaded/CDN copy will NOT match (the served file differs from the original), and a file that was re-encoded/re-exported after upload will not match either. In that case, capture the media `id` at upload time and keep your own `source β†’ id` map. Response is wrapped in the passthrough envelope. **OnlyFans only.** **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Query parameters - `h` (string, required) β€” MD5 hex digest of the ORIGINAL uploaded file bytes. Note the parameter is `h`, not `hash` β€” this was documented as `hash` in error until 2026-08-06. For a single-part upload the S3 ETag returned by `POST /accounts/{of_user_id}/media` is exactly this MD5, so you can feed it straight back in. - `size` (integer, required) β€” Size of the original file in bytes. OnlyFans' own client always sends this alongside `h`. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Matching media, wrapped in the passthrough envelope On no match: `success:false`, `status_code:404`, and `data.error.message = "Media Not Found"`. - `success` (boolean) - `status_code` (integer) - `data` (object) β€” Media item (photo/video/audio/gif). Returned by the vault endpoints and embedded in posts, messages, and stories. **No source fingerprint exists.** OnlyFans does NOT expose an original filename, content hash, upload source ID, or any immutable content fingerprint on this object β€” `id` is the only stable identifier. To correlate a local file with an existing vault item, use `GET /api2/v2/vault/media/hash?hash={md5}`. `files.*.size` is frequently `0` and must never be used as a fingerprint. - `id` (integer) β€” Stable OnlyFans media ID β€” the only persistent identifier for the item. - `type` ("photo" | "video" | "audio" | "gif") - `createdAt` (string) - `duration` (integer) β€” Duration in seconds (video/audio; 0 for photos). - `convertedToVideo` (boolean) - `canView` (boolean) - `isReady` (boolean) β€” False while OnlyFans is still processing/transcoding the upload. - `hasError` (boolean) - `hasPosts` (boolean) β€” Whether the media is attached to any post. - `hasCustomPreview` (boolean) - `counters` (object) β€” Engagement counters (present on the vault view). - `buyersCount` (integer) - `likesCount` (integer) - `tipsSumm` (number) - `listStates` (object[]) β€” Which vault lists (folders) this media belongs to. - `id` (integer) β€” Vault list ID. - `name` (string) β€” Vault list name. - `hasMedia` (boolean) - `canAddMedia` (boolean) - `files` (object) β€” Signed, time-limited CDN URLs at several resolutions. `size` is frequently `0` β€” do not rely on it. - `full` (object) - `preview` (object) - `thumb` (object) - `squarePreview` (object) - `videoSources` (object) β€” Per-resolution video URLs (e.g. `240`, `720`); entries are null when not applicable. ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/vault/media/hash" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Finish signed upload (/docs/of-api/content/finish-signed-upload) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/upload/signed/finish` Stage 3 of OnlyFans' media upload β€” completes an S3 **multipart** upload after every part has been PUT. **Body** (verified live 2026-08-06): ```json { "key": "", "parts": [{ "ETag": "\"abc…\"", "PartNumber": 1 }], "uploadId": "", "secure": false } ``` Returns `{ "ETag": "…" }` for the assembled object. Single-part uploads (< 5 MiB) **skip this call** β€” the ETag comes straight off the S3 PUT response. Note that neither this nor `create` puts anything in the vault; a fourth stage hands the S3 descriptor to OnlyFans' converter host (`GET /api2/v2/init` β†’ `upload.geoUploadHosts`). `POST /accounts/{of_user_id}/media` does all of it for you. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` (required) - `key` (string, required) β€” The same `key` passed to upload/signed/create. e.g. `"upload/0e683d4d-1726-4506-a04d-2a5d05f5b9e1/1031326954680/photo.jpg"`. - `parts` (object[], required) β€” One entry per uploaded S3 part, in order. `ETag` is the quoted value from that part's PUT response header. - `ETag` (string, required) β€” e.g. `"\"5623a10f3404a04d201a8e38aea195d6\""`. - `PartNumber` (integer, required) β€” e.g. `1`. - `uploadId` (string, required) β€” The `uploadId` returned by upload/signed/create. - `secure` (boolean) β€” Must match the value used on create. Default `false`. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/upload/signed/finish" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{"key":"upload/0e683d4d-1726-4506-a04d-2a5d05f5b9e1/1031326954680/photo.jpg","parts":[{"ETag":"\"5623a10f3404a04d201a8e38aea195d6\"","PartNumber":1}],"uploadId":"2~abc123","secure":false}' ``` --- # Get bookmark categories (/docs/of-api/content/get-bookmark-categories) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/posts/bookmarks/categories` **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Categories list - `[]` array of: - `id` (string) β€” 'all' for all bookmarks, or numeric ID. - `name` (string) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/posts/bookmarks/categories" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get bookmarked posts (/docs/of-api/content/get-bookmarked-posts) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/posts/bookmarks` **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Query parameters - `limit` (integer) β€” Default `10`. - `offset` (integer) β€” Default `0`. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Bookmarked posts - `list` (object[]) - `id` (integer) - `text` (string) - `rawText` (string) - `price` (number) - `isOpened` (boolean) - `isPinned` (boolean) - `postedAt` (string) - `postedAtPrecise` (string) - `expiredAt` (string) - `commentsCount` (integer) - `favoritesCount` (integer) - `tipsAmount` (number) - `media` (object[]) - `id` (integer) β€” Stable OnlyFans media ID β€” the only persistent identifier for the item. - `type` ("photo" | "video" | "audio" | "gif") - `createdAt` (string) - `duration` (integer) β€” Duration in seconds (video/audio; 0 for photos). - `convertedToVideo` (boolean) - `canView` (boolean) - `isReady` (boolean) β€” False while OnlyFans is still processing/transcoding the upload. - `hasError` (boolean) - `hasPosts` (boolean) β€” Whether the media is attached to any post. - `hasCustomPreview` (boolean) - `counters` (object) β€” Engagement counters (present on the vault view). - `listStates` (object[]) β€” Which vault lists (folders) this media belongs to. - `files` (object) β€” Signed, time-limited CDN URLs at several resolutions. `size` is frequently `0` β€” do not rely on it. - `videoSources` (object) β€” Per-resolution video URLs (e.g. `240`, `720`); entries are null when not applicable. - `author` (object) - `canComment` (boolean) - `canEdit` (boolean) - `hasVoting` (boolean) - `voting` (object[]) - `id` (integer) - `text` (string) - `votesCount` (integer) - `isSelected` (boolean) - `hasMore` (boolean) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/posts/bookmarks" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get DRM certificate (/docs/of-api/content/get-drm-certificate) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/media/drm/certificate` Retrieves the DRM certificate used for protected media playback. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. βœ“ **Verified live** against a real OnlyFans account (2026-07-30); the `data` schema below is the real response shape. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response β€” verified live; `data` is the real shape. - `success` (boolean) - `status_code` (integer) - `data` (string) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/media/drm/certificate" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get 'on this day' posts (/docs/of-api/content/get-on-this-day-posts) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/posts/on-this-day` Retrieves the current user's posts from this date in previous years ('on this day' memories). **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. βœ“ **Verified live** against a real OnlyFans account (2026-07-30); the `data` schema below is the real response shape. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response β€” verified live; `data` is the real shape. - `success` (boolean) - `status_code` (integer) - `data` (any[]) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/posts/on-this-day" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get post comments (/docs/of-api/content/get-post-comments) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/posts/{post_id}/comments` **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `post_id` (string, required) ## Query parameters - `limit` (integer) β€” Default `10`. - `offset` (integer) β€” Default `0`. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Comments list - `list` (object[]) - `id` (integer) - `text` (string) - `author` (object) β€” Full OnlyFans user profile object. - `id` (integer) - `name` (string) - `username` (string) - `displayName` (string) - `about` (string) - `avatar` (string) β€” Avatar URL. - `avatarThumbs` (object) - `header` (string) β€” Profile header/banner URL. - `email` (string) - `isVerified` (boolean) - `isPerformer` (boolean) - `canEarn` (boolean) - `tipsEnabled` (boolean) - `subscribedBy` (boolean) β€” Whether you are subscribed to this user. - `subscribersCount` (integer) - `subscribesCount` (integer) - `postsCount` (integer) - `photosCount` (integer) - `videosCount` (integer) - `audiosCount` (integer) - `friendsCount` (integer) - `joinDate` (string) - `firstPublishedPostDate` (string) - `subscribePrice` (number) - `chatMessagesCount` (integer) β€” Unread chat messages. - `countPriorityChat` (integer) - `countPinnedChat` (integer) - `hasPurchasedPosts` (boolean) - `paidFeed` (boolean) - `openseaInfo` (object) - `createdAt` (string) - `likesCount` (integer) - `hasMore` (boolean) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/posts/{post_id}/comments" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get posts feed (/docs/of-api/content/get-posts-feed) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/posts` **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Query parameters - `limit` (integer) β€” Default `10`. - `offset` (integer) β€” Default `0`. - `format` (string) β€” Default `infinite`. - `skip_users` (string) β€” Default `all`. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Posts list - `list` (object[]) - `id` (integer) - `text` (string) - `rawText` (string) - `price` (number) - `isOpened` (boolean) - `isPinned` (boolean) - `postedAt` (string) - `postedAtPrecise` (string) - `expiredAt` (string) - `commentsCount` (integer) - `favoritesCount` (integer) - `tipsAmount` (number) - `media` (object[]) - `id` (integer) β€” Stable OnlyFans media ID β€” the only persistent identifier for the item. - `type` ("photo" | "video" | "audio" | "gif") - `createdAt` (string) - `duration` (integer) β€” Duration in seconds (video/audio; 0 for photos). - `convertedToVideo` (boolean) - `canView` (boolean) - `isReady` (boolean) β€” False while OnlyFans is still processing/transcoding the upload. - `hasError` (boolean) - `hasPosts` (boolean) β€” Whether the media is attached to any post. - `hasCustomPreview` (boolean) - `counters` (object) β€” Engagement counters (present on the vault view). - `listStates` (object[]) β€” Which vault lists (folders) this media belongs to. - `files` (object) β€” Signed, time-limited CDN URLs at several resolutions. `size` is frequently `0` β€” do not rely on it. - `videoSources` (object) β€” Per-resolution video URLs (e.g. `240`, `720`); entries are null when not applicable. - `author` (object) - `canComment` (boolean) - `canEdit` (boolean) - `hasVoting` (boolean) - `voting` (object[]) - `id` (integer) - `text` (string) - `votesCount` (integer) - `isSelected` (boolean) - `hasMore` (boolean) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/posts" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get posts using a vault media item (/docs/of-api/content/get-posts-using-a-vault-media-item) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/vault/media/{media_id}/posts` List posts that use a specific vault media item. Response is wrapped in the passthrough envelope. **OnlyFans only.** **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `media_id` (integer, required) β€” Vault media ID. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 Posts referencing the media, wrapped in the passthrough envelope. - `success` (boolean) - `status_code` (integer) - `data` (object) - `list` (object[]) - `id` (integer) - `text` (string) - `rawText` (string) - `price` (number) - `isOpened` (boolean) - `isPinned` (boolean) - `postedAt` (string) - `postedAtPrecise` (string) - `expiredAt` (string) - `commentsCount` (integer) - `favoritesCount` (integer) - `tipsAmount` (number) - `media` (object[]) - `author` (object) - `canComment` (boolean) - `canEdit` (boolean) - `hasVoting` (boolean) - `voting` (object[]) - `hasMore` (boolean) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/vault/media/{media_id}/posts" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get scheduled-post counts per day (/docs/of-api/content/get-scheduled-post-counts-per-day) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/schedules/counters` **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Scheduled-post counts, wrapped in the passthrough envelope `data.list` is an OBJECT keyed by ISO date (e.g. "2026-07-28") whose value is `{ post: }` β€” it is NOT an array. - `success` (boolean) - `status_code` (integer) - `data` (object) - `list` (object) β€” Keyed by ISO date string. - `syncInProcess` (boolean) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/schedules/counters" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get scheduled posts (/docs/of-api/content/get-scheduled-posts) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/schedules` **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Query parameters - `limit` (integer) β€” Default `10`. - `offset` (integer) β€” Default `0`. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Scheduled posts - `list` (object[]) - `id` (integer) - `text` (string) - `rawText` (string) - `price` (number) - `isOpened` (boolean) - `isPinned` (boolean) - `postedAt` (string) - `postedAtPrecise` (string) - `expiredAt` (string) - `commentsCount` (integer) - `favoritesCount` (integer) - `tipsAmount` (number) - `media` (object[]) - `id` (integer) β€” Stable OnlyFans media ID β€” the only persistent identifier for the item. - `type` ("photo" | "video" | "audio" | "gif") - `createdAt` (string) - `duration` (integer) β€” Duration in seconds (video/audio; 0 for photos). - `convertedToVideo` (boolean) - `canView` (boolean) - `isReady` (boolean) β€” False while OnlyFans is still processing/transcoding the upload. - `hasError` (boolean) - `hasPosts` (boolean) β€” Whether the media is attached to any post. - `hasCustomPreview` (boolean) - `counters` (object) β€” Engagement counters (present on the vault view). - `listStates` (object[]) β€” Which vault lists (folders) this media belongs to. - `files` (object) β€” Signed, time-limited CDN URLs at several resolutions. `size` is frequently `0` β€” do not rely on it. - `videoSources` (object) β€” Per-resolution video URLs (e.g. `240`, `720`); entries are null when not applicable. - `author` (object) - `canComment` (boolean) - `canEdit` (boolean) - `hasVoting` (boolean) - `voting` (object[]) - `id` (integer) - `text` (string) - `votesCount` (integer) - `isSelected` (boolean) - `hasMore` (boolean) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/schedules" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get specific post (/docs/of-api/content/get-specific-post) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/posts/{post_id}` **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `post_id` (string, required) ## Query parameters - `skip_users` (string) β€” Default `all`. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Post object - `id` (integer) - `text` (string) - `rawText` (string) - `price` (number) - `isOpened` (boolean) - `isPinned` (boolean) - `postedAt` (string) - `postedAtPrecise` (string) - `expiredAt` (string) - `commentsCount` (integer) - `favoritesCount` (integer) - `tipsAmount` (number) - `media` (object[]) - `id` (integer) β€” Stable OnlyFans media ID β€” the only persistent identifier for the item. - `type` ("photo" | "video" | "audio" | "gif") - `createdAt` (string) - `duration` (integer) β€” Duration in seconds (video/audio; 0 for photos). - `convertedToVideo` (boolean) - `canView` (boolean) - `isReady` (boolean) β€” False while OnlyFans is still processing/transcoding the upload. - `hasError` (boolean) - `hasPosts` (boolean) β€” Whether the media is attached to any post. - `hasCustomPreview` (boolean) - `counters` (object) β€” Engagement counters (present on the vault view). - `buyersCount` (integer) - `likesCount` (integer) - `tipsSumm` (number) - `listStates` (object[]) β€” Which vault lists (folders) this media belongs to. - `id` (integer) β€” Vault list ID. - `name` (string) β€” Vault list name. - `hasMedia` (boolean) - `canAddMedia` (boolean) - `files` (object) β€” Signed, time-limited CDN URLs at several resolutions. `size` is frequently `0` β€” do not rely on it. - `full` (object) - `preview` (object) - `thumb` (object) - `squarePreview` (object) - `videoSources` (object) β€” Per-resolution video URLs (e.g. `240`, `720`); entries are null when not applicable. - `author` (object) - `canComment` (boolean) - `canEdit` (boolean) - `hasVoting` (boolean) - `voting` (object[]) - `id` (integer) - `text` (string) - `votesCount` (integer) - `isSelected` (boolean) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/posts/{post_id}" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get user labels (/docs/of-api/content/get-user-labels) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/labels` **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Query parameters - `limit` (integer) β€” Default `10`. - `offset` (integer) β€” Default `0`. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Labels list - `list` (object[]) - `id` (integer) - `name` (string) - `postsCount` (integer) - `type` (string) - `hasMore` (boolean) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/labels" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get vault lists (folders) (/docs/of-api/content/get-vault-lists-folders) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/vault/lists` List the vault folders for an account. **`view=main` is required** β€” omitting it makes OnlyFans respond `400 Bad view param` (passed through verbatim). The response is wrapped in the standard passthrough envelope (`{ success, status_code, data }`); the OnlyFans body is under `data`, where `data.list` is the folder array and `data.all` carries global counts across the whole vault. **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Query parameters - `view` ("main", required) β€” Required by OnlyFans. Use `main` β€” it returns the folder list plus the `all` bucket of global counts. Omitting it returns `400 Bad view param`. Default `main`. - `limit` (integer) β€” Default `10`. - `offset` (integer) β€” Default `0`. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Vault folders, wrapped in the passthrough envelope. - `success` (boolean) - `status_code` (integer) - `data` (object) - `all` (object) β€” Pseudo-folder holding global counts across the entire vault. - `photosCount` (integer) - `videosCount` (integer) - `gifsCount` (integer) - `audiosCount` (integer) - `list` (object[]) - `id` (integer) - `name` (string) - `photosCount` (integer) - `videosCount` (integer) - `gifsCount` (integer) - `audiosCount` (integer) - `hasMedia` (boolean) - `canUpdate` (boolean) - `canDelete` (boolean) - `medias` (object[]) β€” A few thumbnail previews (type + url) used as the folder cover. - `hasMore` (boolean) - `order` (string) - `sort` (string) - `canCreateVaultLists` (boolean) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/vault/lists" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get vault media (/docs/of-api/content/get-vault-media) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/vault/media` List vault media items. This is how you obtain the integer media IDs referenced by post creation, story creation, and messages. **Uploading new media:** use `POST /accounts/{of_user_id}/media`. A freshly uploaded file will **not** show up in this list right away β€” OnlyFans creates the vault entry when a post/message/story consumes the upload's `processId`, not at upload time. That is OnlyFans' own behaviour, not a limitation of this API: there is no upload-to-vault endpoint anywhere in the OnlyFans web client. (A `POST /api2/v2/media` upload route was documented in error until 2026-08-06 β€” it never existed and OnlyFans answers it with 404.) **Filtering (supported, but previously undocumented):** `list={list_id}` restricts results to one folder, `field=recent` chooses the ordering field, and `sort=asc|desc` the direction β€” combine with `limit`/`offset` for paging. The response is wrapped in the standard passthrough envelope; the OnlyFans body (`{ list, hasMore }`) is under `data`. **Matching a local file to an existing item:** the media object carries no filename or hash β€” use `GET /api2/v2/vault/media/hash?h={md5}&size={bytes}` instead. **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Query parameters - `list` (integer) β€” Restrict results to a single vault folder (a list ID from GET /vault/lists). - `field` ("recent") β€” Ordering field. `recent` orders by upload time. Default `recent`. - `sort` ("asc" | "desc") β€” Sort direction. Default `desc`. - `limit` (integer) β€” Default `24`. - `offset` (integer) β€” Default `0`. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Media items, wrapped in the passthrough envelope. - `success` (boolean) - `status_code` (integer) - `data` (object) - `list` (object[]) - `id` (integer) β€” Stable OnlyFans media ID β€” the only persistent identifier for the item. - `type` ("photo" | "video" | "audio" | "gif") - `createdAt` (string) - `duration` (integer) β€” Duration in seconds (video/audio; 0 for photos). - `convertedToVideo` (boolean) - `canView` (boolean) - `isReady` (boolean) β€” False while OnlyFans is still processing/transcoding the upload. - `hasError` (boolean) - `hasPosts` (boolean) β€” Whether the media is attached to any post. - `hasCustomPreview` (boolean) - `counters` (object) β€” Engagement counters (present on the vault view). - `listStates` (object[]) β€” Which vault lists (folders) this media belongs to. - `files` (object) β€” Signed, time-limited CDN URLs at several resolutions. `size` is frequently `0` β€” do not rely on it. - `videoSources` (object) β€” Per-resolution video URLs (e.g. `240`, `720`); entries are null when not applicable. - `hasMore` (boolean) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/vault/media" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get vault media being processed (/docs/of-api/content/get-vault-media-being-processed) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/vault/media/processing` List media still being processed/transcoded by OnlyFans (items whose `isReady` is false). `data` carries its OWN `success` flag alongside `list` β€” distinct from the outer envelope's `success`. Response is wrapped in the passthrough envelope. **OnlyFans only.** **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 Media currently processing, wrapped in the passthrough envelope. - `success` (boolean) - `status_code` (integer) - `data` (object) - `is_processing` (boolean) - `success` (boolean) β€” OnlyFans' own flag, nested inside data. - `list` (object[]) - `id` (integer) β€” Stable OnlyFans media ID β€” the only persistent identifier for the item. - `type` ("photo" | "video" | "audio" | "gif") - `createdAt` (string) - `duration` (integer) β€” Duration in seconds (video/audio; 0 for photos). - `convertedToVideo` (boolean) - `canView` (boolean) - `isReady` (boolean) β€” False while OnlyFans is still processing/transcoding the upload. - `hasError` (boolean) - `hasPosts` (boolean) β€” Whether the media is attached to any post. - `hasCustomPreview` (boolean) - `counters` (object) β€” Engagement counters (present on the vault view). - `listStates` (object[]) β€” Which vault lists (folders) this media belongs to. - `files` (object) β€” Signed, time-limited CDN URLs at several resolutions. `size` is frequently `0` β€” do not rely on it. - `videoSources` (object) β€” Per-resolution video URLs (e.g. `240`, `720`); entries are null when not applicable. ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/vault/media/processing" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get vault media item (/docs/of-api/content/get-vault-media-item) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/vault/media/{media_id}` Get a single vault media item by ID. Response is wrapped in the passthrough envelope; the OnlyFans media object is under `data`. **OnlyFans only.** **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `media_id` (integer, required) β€” Vault media ID. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” The media item, wrapped in the passthrough envelope. - `success` (boolean) - `status_code` (integer) - `data` (object) β€” Media item (photo/video/audio/gif). Returned by the vault endpoints and embedded in posts, messages, and stories. **No source fingerprint exists.** OnlyFans does NOT expose an original filename, content hash, upload source ID, or any immutable content fingerprint on this object β€” `id` is the only stable identifier. To correlate a local file with an existing vault item, use `GET /api2/v2/vault/media/hash?hash={md5}`. `files.*.size` is frequently `0` and must never be used as a fingerprint. - `id` (integer) β€” Stable OnlyFans media ID β€” the only persistent identifier for the item. - `type` ("photo" | "video" | "audio" | "gif") - `createdAt` (string) - `duration` (integer) β€” Duration in seconds (video/audio; 0 for photos). - `convertedToVideo` (boolean) - `canView` (boolean) - `isReady` (boolean) β€” False while OnlyFans is still processing/transcoding the upload. - `hasError` (boolean) - `hasPosts` (boolean) β€” Whether the media is attached to any post. - `hasCustomPreview` (boolean) - `counters` (object) β€” Engagement counters (present on the vault view). - `buyersCount` (integer) - `likesCount` (integer) - `tipsSumm` (number) - `listStates` (object[]) β€” Which vault lists (folders) this media belongs to. - `id` (integer) β€” Vault list ID. - `name` (string) β€” Vault list name. - `hasMedia` (boolean) - `canAddMedia` (boolean) - `files` (object) β€” Signed, time-limited CDN URLs at several resolutions. `size` is frequently `0` β€” do not rely on it. - `full` (object) - `preview` (object) - `thumb` (object) - `squarePreview` (object) - `videoSources` (object) β€” Per-resolution video URLs (e.g. `240`, `720`); entries are null when not applicable. ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/vault/media/{media_id}" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get vault media list (/docs/of-api/content/get-vault-media-list) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/vault/lists/{list_id}` Retrieves a single vault media list by id. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `list_id` (string, required) β€” ID of the vault list. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/vault/lists/{list_id}" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get vault media release forms (/docs/of-api/content/get-vault-media-release-forms) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/vault/media/{media_id}/release-forms` Returns the release forms attached to a vault media item identified by media_id. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `media_id` (string, required) β€” ID of the vault media item. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/vault/media/{media_id}/release-forms" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get vault media types present (/docs/of-api/content/get-vault-media-types-present) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/vault/media/types` Report which media types exist in the vault. `data` is a flat object of booleans (NOT counts) β€” one per type. Response is wrapped in the passthrough envelope. **OnlyFans only.** **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 Booleans for which media types are present, wrapped in the passthrough envelope. - `success` (boolean) - `status_code` (integer) - `data` (object) - `hasPhoto` (boolean) - `hasVideo` (boolean) - `hasGif` (boolean) - `hasAudio` (boolean) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/vault/media/types" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Hide a post (/docs/of-api/content/hide-a-post) `PUT https://theonlyapi.com/api/crm/your-crm-id/api2/v2/posts/{post_id}/hide` Hides the specified post. Defined alongside post pin, favorite, vote and delete calls. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `post_id` (string, required) β€” ID of the post to hide. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X PUT "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/posts/{post_id}/hide" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Hide vault media (/docs/of-api/content/hide-vault-media) `PUT https://theonlyapi.com/api/crm/your-crm-id/api2/v2/vault/media/hidden` Marks the given vault media items as hidden. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` - `mediaIds` (any[]) β€” Ids of the vault media to hide. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X PUT "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/vault/media/hidden" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Like a comment (/docs/of-api/content/like-a-comment) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/comments/{comment_id}/like` Adds a like to the specified comment. Paired with a DELETE on the same path to unlike, plus comment pin/delete calls. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `comment_id` (string, required) β€” ID of the comment to like. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/comments/{comment_id}/like" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Like / favorite a post (/docs/of-api/content/like-favorite-a-post) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/posts/{post_id}/favorites` **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `post_id` (string, required) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Post liked ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/posts/{post_id}/favorites" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Pin a comment (/docs/of-api/content/pin-a-comment) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/comments/{comment_id}/pin` Pins the specified comment. Paired with a DELETE on the same path to unpin. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `comment_id` (string, required) β€” ID of the comment to pin. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/comments/{comment_id}/pin" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Publish a scheduled item (/docs/of-api/content/publish-a-scheduled-item) `PUT https://theonlyapi.com/api/crm/your-crm-id/api2/v2/schedules/{schedule_id}/publish` Publishes a scheduled entity (e.g. queued post/stream) immediately by its schedule id. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `schedule_id` (string, required) β€” ID of the scheduled item to publish. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X PUT "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/schedules/{schedule_id}/publish" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Remove post from bookmarks (/docs/of-api/content/remove-post-from-bookmarks) `DELETE https://theonlyapi.com/api/crm/your-crm-id/api2/v2/posts/{post_id}/bookmarks` Removes the given post from the user's bookmarks; an optional chat_group_id can scope the removal to a specific bookmark group. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `post_id` (string, required) β€” Id of the post to un-bookmark. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/posts/{post_id}/bookmarks" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Rename a vault list (/docs/of-api/content/rename-a-vault-list) `PATCH https://theonlyapi.com/api/crm/your-crm-id/api2/v2/vault/lists/{list_id}` Renames a media vault list identified by list id. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `list_id` (string, required) β€” ID of the vault list. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` - `name` (string) β€” New name for the vault list. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X PATCH "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/vault/lists/{list_id}" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Rename bookmark category (/docs/of-api/content/rename-bookmark-category) `PATCH https://theonlyapi.com/api/crm/your-crm-id/api2/v2/posts/bookmarks/categories/{category_id}` Renames a post-bookmark category (DELETE removes it, POST creates one). **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `category_id` (string, required) β€” ID of the bookmark category. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` - `name` (string) β€” New category name. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X PATCH "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/posts/bookmarks/categories/{category_id}" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Reorder pinned posts (/docs/of-api/content/reorder-pinned-posts) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/posts/pinned/sort` Change the display order of your pinned posts on your profile. **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` (required) - `order` (integer[], required) β€” Ordered array of pinned post IDs. First ID appears first on profile. e.g. `[999,888,777]`. ## Responses ### 200 β€” Pin order updated ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/posts/pinned/sort" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{"order":[999,888,777]}' ``` --- # Report post view/interaction stats (/docs/of-api/content/report-post-view-interaction-stats) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/posts/stats-collect` Submit post view and interaction analytics. Used by the client to report which posts were viewed, scrolled past, or interacted with. **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` - `actions` (object[], required) β€” Array of post interaction events. - `postId` (integer) - `type` (string) β€” Action type (e.g. 'view', 'scroll', 'click'). ## Responses ### 200 β€” Stats collected ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/posts/stats-collect" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{"actions":[{}]}' ``` --- # Sort bookmark categories (/docs/of-api/content/sort-bookmark-categories) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/posts/bookmarks/categories/sort` Sets the sort order of post bookmark categories. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/posts/bookmarks/categories/sort" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Sort pinned paid posts (/docs/of-api/content/sort-pinned-paid-posts) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/posts/paid/pin/sort` Reorders the creator's pinned paid posts. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/posts/paid/pin/sort" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Sort vault lists (/docs/of-api/content/sort-vault-lists) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/vault/lists/sort` Reorders the creator's vault media lists. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/vault/lists/sort" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Unlike a comment (/docs/of-api/content/unlike-a-comment) `DELETE https://theonlyapi.com/api/crm/your-crm-id/api2/v2/comments/{comment_id}/like` Removes the current user's like from a comment (POST on the same path adds a like). **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `comment_id` (string, required) β€” ID of the comment to unlike. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/comments/{comment_id}/like" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Unpin a comment (/docs/of-api/content/unpin-a-comment) `DELETE https://theonlyapi.com/api/crm/your-crm-id/api2/v2/comments/{comment_id}/pin` Removes the pinned status from a comment. The paired POST /comments/{id}/pin pins it. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `comment_id` (string, required) β€” ID of the comment to unpin. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/comments/{comment_id}/pin" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Vote on a post poll (/docs/of-api/content/vote-on-a-post-poll) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/posts/{post_id}/vote` Submit a vote on a post that has a poll attached. Get the `optionId` from the post's `voting` array. **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `post_id` (string, required) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` (required) - `optionId` (integer, required) β€” The poll option ID to vote for (from the post's voting array). ## Responses ### 200 β€” Vote recorded ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/posts/{post_id}/vote" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{"optionId":0}' ``` --- # Helpers (/docs/of-api/helpers) {/* Generated by scripts/gen-api.ts β€” edit that script, not this file. */} OnlyFans helper/manager accounts (via proxy). **OnlyFans only** β€” Fansly accounts are rejected on this surface. | Method | Endpoint | Path | | ------ | --------------------------------------------------------------------- | ------------------------------ | | `GET` | [List account helpers](/docs/of-api/helpers/list-account-helpers) | `/api2/v2/helpers` | | `GET` | [Get helper permissions](/docs/of-api/helpers/get-helper-permissions) | `/api2/v2/helpers/permissions` | --- # Get helper permissions (/docs/of-api/helpers/get-helper-permissions) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/helpers/permissions` **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Permissions config ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/helpers/permissions" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # List account helpers (/docs/of-api/helpers/list-account-helpers) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/helpers` **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Helper list - `[]` array of: - `userId` (integer) - `user` (object) β€” Full OnlyFans user profile object. - `id` (integer) - `name` (string) - `username` (string) - `displayName` (string) - `about` (string) - `avatar` (string) β€” Avatar URL. - `avatarThumbs` (object) - `c50` (string) - `c144` (string) - `header` (string) β€” Profile header/banner URL. - `email` (string) - `isVerified` (boolean) - `isPerformer` (boolean) - `canEarn` (boolean) - `tipsEnabled` (boolean) - `subscribedBy` (boolean) β€” Whether you are subscribed to this user. - `subscribersCount` (integer) - `subscribesCount` (integer) - `postsCount` (integer) - `photosCount` (integer) - `videosCount` (integer) - `audiosCount` (integer) - `friendsCount` (integer) - `joinDate` (string) - `firstPublishedPostDate` (string) - `subscribePrice` (number) - `chatMessagesCount` (integer) β€” Unread chat messages. - `countPriorityChat` (integer) - `countPinnedChat` (integer) - `hasPurchasedPosts` (boolean) - `paidFeed` (boolean) - `openseaInfo` (object) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/helpers" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Lists (/docs/of-api/lists) {/* Generated by scripts/gen-api.ts β€” edit that script, not this file. */} OnlyFans user lists (via proxy). **OnlyFans only** β€” Fansly accounts are rejected on this surface. | Method | Endpoint | Path | | -------- | ------------------------------------------------------------------------------------- | ---------------------------------------------------------------- | | `GET` | [Get a label by ID](/docs/of-api/lists/get-a-label-by-id) | `/api2/v2/labels/{label_id}` | | `PATCH` | [Rename a label](/docs/of-api/lists/rename-a-label) | `/api2/v2/labels/{label_id}` | | `DELETE` | [Delete a label](/docs/of-api/lists/delete-a-label) | `/api2/v2/labels/{label_id}` | | `DELETE` | [Remove post from label](/docs/of-api/lists/remove-post-from-label) | `/api2/v2/labels/{label_id}/post/{post_id}` | | `POST` | [Add posts to label](/docs/of-api/lists/add-posts-to-label) | `/api2/v2/labels/{label_id}/posts` | | `DELETE` | [Remove all posts from label](/docs/of-api/lists/remove-all-posts-from-label) | `/api2/v2/labels/{label_id}/posts` | | `POST` | [Sort labels](/docs/of-api/lists/sort-labels) | `/api2/v2/labels/sort` | | `GET` | [Get user lists](/docs/of-api/lists/get-user-lists) | `/api2/v2/lists` | | `POST` | [Create a new list](/docs/of-api/lists/create-a-new-list) | `/api2/v2/lists` | | `GET` | [Get a user list](/docs/of-api/lists/get-a-user-list) | `/api2/v2/lists/{list_id}` | | `PATCH` | [Update a list](/docs/of-api/lists/update-a-list) | `/api2/v2/lists/{list_id}` | | `DELETE` | [Delete a list](/docs/of-api/lists/delete-a-list) | `/api2/v2/lists/{list_id}` | | `POST` | [Sort users in list](/docs/of-api/lists/sort-users-in-list) | `/api2/v2/lists/{list_id}/sort` | | `GET` | [Get users in a list](/docs/of-api/lists/get-users-in-a-list) | `/api2/v2/lists/{list_id}/users` | | `POST` | [Add claimers to list](/docs/of-api/lists/add-claimers-to-list) | `/api2/v2/lists/{list_id}/users/{type}/{id}/claims` | | `POST` | [Add user to list](/docs/of-api/lists/add-user-to-list) | `/api2/v2/lists/{list_id}/users/{user_id}` | | `DELETE` | [Remove user from list](/docs/of-api/lists/remove-user-from-list) | `/api2/v2/lists/{list_id}/users/{user_id}` | | `POST` | [Pin user in list](/docs/of-api/lists/pin-user-in-list) | `/api2/v2/lists/{list_id}/users/{user_id}/pin` | | `POST` | [Add award-winning users to list](/docs/of-api/lists/add-award-winning-users-to-list) | `/api2/v2/lists/{list_id}/users/awards/{year}/{month}` | | `POST` | [Add campaign claimers to list](/docs/of-api/lists/add-campaign-claimers-to-list) | `/api2/v2/lists/{list_id}/users/campaign/{campaign_id}/claimers` | | `POST` | [Add media buyers to list](/docs/of-api/lists/add-media-buyers-to-list) | `/api2/v2/lists/{list_id}/users/media/{media_id}/buyers` | | `POST` | [Sort pinned list users](/docs/of-api/lists/sort-pinned-list-users) | `/api2/v2/lists/{list_id}/users/pinned/sort` | | `POST` | [Add queue buyers to list](/docs/of-api/lists/add-queue-buyers-to-list) | `/api2/v2/lists/{list_id}/users/queue/{queue_id}/buyers` | | `POST` | [Add story viewers to list](/docs/of-api/lists/add-story-viewers-to-list) | `/api2/v2/lists/{list_id}/users/story/{story_id}/{type}` | | `POST` | [Add stream audience to list](/docs/of-api/lists/add-stream-audience-to-list) | `/api2/v2/lists/{list_id}/users/stream/{stream_id}/{type}` | | `DELETE` | [Remove stream users from list](/docs/of-api/lists/remove-stream-users-from-list) | `/api2/v2/lists/{list_id}/users/stream/{stream_id}/{type}` | | `POST` | [Add subscribers to list](/docs/of-api/lists/add-subscribers-to-list) | `/api2/v2/lists/{list_id}/users/subscribers` | | `POST` | [Add top subscribers to list](/docs/of-api/lists/add-top-subscribers-to-list) | `/api2/v2/lists/{list_id}/users/top-subscribers` | | `GET` | [Check list membership](/docs/of-api/lists/check-list-membership) | `/api2/v2/lists/check/{list_id}/{user_id}` | | `POST` | [Sort user lists](/docs/of-api/lists/sort-user-lists) | `/api2/v2/lists/sort` | | `POST` | [Add users to lists](/docs/of-api/lists/add-users-to-lists) | `/api2/v2/lists/users` | --- # Add award-winning users to list (/docs/of-api/lists/add-award-winning-users-to-list) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/lists/{list_id}/users/awards/{year}/{month}` Adds users who received awards in the given year/month to the specified list. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `list_id` (string, required) β€” ID of the list. - `year` (string, required) β€” Year of the awards period. - `month` (string, required) β€” Month of the awards period. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/lists/{list_id}/users/awards/{year}/{month}" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Add campaign claimers to list (/docs/of-api/lists/add-campaign-claimers-to-list) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/lists/{list_id}/users/campaign/{campaign_id}/claimers` Adds the users who claimed a campaign to a custom list. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `list_id` (string, required) β€” ID of the list. - `campaign_id` (string, required) β€” ID of the campaign whose claimers are added. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/lists/{list_id}/users/campaign/{campaign_id}/claimers" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Add claimers to list (/docs/of-api/lists/add-claimers-to-list) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/lists/{list_id}/users/{type}/{id}/claims` Adds users who claimed a given entity (identified by type and id) to the specified list. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `list_id` (string, required) β€” ID of the target list. - `type` (string, required) β€” Claim entity type. - `id` (string, required) β€” ID of the entity of the given type. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/lists/{list_id}/users/{type}/{id}/claims" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Add media buyers to list (/docs/of-api/lists/add-media-buyers-to-list) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/lists/{list_id}/users/media/{media_id}/buyers` Adds users who purchased a given media item to a list (bulk add by media). **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `list_id` (string, required) β€” ID of the target list. - `media_id` (string, required) β€” ID of the media whose buyers are added. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/lists/{list_id}/users/media/{media_id}/buyers" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Add posts to label (/docs/of-api/lists/add-posts-to-label) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/labels/{label_id}/posts` Adds one or more posts to a label. Called as (labelId, posts[]). **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `label_id` (string, required) β€” ID of the label. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` - `posts` (any[]) β€” IDs of the posts to add to the label. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/labels/{label_id}/posts" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Add queue buyers to list (/docs/of-api/lists/add-queue-buyers-to-list) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/lists/{list_id}/users/queue/{queue_id}/buyers` Adds users who bought from a given queue to a list (bulk add by queue). **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `list_id` (string, required) β€” ID of the target list. - `queue_id` (string, required) β€” ID of the queue whose buyers are added. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/lists/{list_id}/users/queue/{queue_id}/buyers" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Add story viewers to list (/docs/of-api/lists/add-story-viewers-to-list) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/lists/{list_id}/users/story/{story_id}/{type}` Adds users who interacted with a given story (by interaction type) to the specified list. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `list_id` (string, required) β€” ID of the target list. - `story_id` (string, required) β€” ID of the story. - `type` (string, required) β€” Interaction type used to select users. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/lists/{list_id}/users/story/{story_id}/{type}" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Add stream audience to list (/docs/of-api/lists/add-stream-audience-to-list) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/lists/{list_id}/users/stream/{stream_id}/{type}` Adds users from a live stream (matching the given type/criteria) to a list, optionally filtered by tip/subscription thresholds. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `list_id` (string, required) β€” Id of the target list. - `stream_id` (string, required) β€” Id of the stream whose audience is added. - `type` (string, required) β€” Audience segment/type key (e.g. viewers/tippers). ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` - `tippedOver` (number) β€” Only include users who tipped over this amount. - `subscribedOver` (number) β€” Only include users subscribed over this threshold. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/lists/{list_id}/users/stream/{stream_id}/{type}" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Add subscribers to list (/docs/of-api/lists/add-subscribers-to-list) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/lists/{list_id}/users/subscribers` Adds subscribers to the list identified by list_id. Enclosing fn is addSubscribersToList. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `list_id` (string, required) β€” ID of the list to add subscribers to. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/lists/{list_id}/users/subscribers" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Add top subscribers to list (/docs/of-api/lists/add-top-subscribers-to-list) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/lists/{list_id}/users/top-subscribers` Adds the account's top subscribers to the given list (addTopSubscribersToList). **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `list_id` (string, required) β€” ID of the list to add top subscribers to. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/lists/{list_id}/users/top-subscribers" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Add user to list (/docs/of-api/lists/add-user-to-list) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/lists/{list_id}/users/{user_id}` **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `list_id` (string, required) - `user_id` (string, required) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” User added ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/lists/{list_id}/users/{user_id}" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Add users to lists (/docs/of-api/lists/add-users-to-lists) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/lists/users` Adds users to one or more lists in bulk. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/lists/users" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Check list membership (/docs/of-api/lists/check-list-membership) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/lists/check/{list_id}/{user_id}` Checks whether a given user belongs to a specific list. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `list_id` (string, required) β€” ID of the list. - `user_id` (string, required) β€” ID of the user to check. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/lists/check/{list_id}/{user_id}" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Create a new list (/docs/of-api/lists/create-a-new-list) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/lists` **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` - `name` (string) β€” e.g. `"My List"`. ## Responses ### 200 β€” List created ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/lists" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{"name":"My List"}' ``` --- # Delete a label (/docs/of-api/lists/delete-a-label) `DELETE https://theonlyapi.com/api/crm/your-crm-id/api2/v2/labels/{label_id}` Deletes a label identified by label id. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `label_id` (string, required) β€” ID of the label to delete. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/labels/{label_id}" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Delete a list (/docs/of-api/lists/delete-a-list) `DELETE https://theonlyapi.com/api/crm/your-crm-id/api2/v2/lists/{list_id}` Deletes a user list by id (GET retrieves it, PATCH renames/updates it). **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `list_id` (string, required) β€” ID of the list to delete. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/lists/{list_id}" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get a label by ID (/docs/of-api/lists/get-a-label-by-id) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/labels/{label_id}` Retrieves a single content label by its ID. Sibling calls create, rename, sort and delete labels. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `label_id` (string, required) β€” ID of the label to retrieve. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/labels/{label_id}" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get a user list (/docs/of-api/lists/get-a-user-list) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/lists/{list_id}` Retrieves a single user list identified by list_id. Enclosing fn is getUsersList. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `list_id` (string, required) β€” ID of the list to retrieve. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/lists/{list_id}" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get user lists (/docs/of-api/lists/get-user-lists) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/lists` **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Query parameters - `limit` (integer) β€” Default `10`. - `offset` (integer) β€” Default `0`. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Lists - `list` (object[]) - `id` (integer) - `name` (string) - `type` (string) β€” List type (e.g. 'archived', 'private_archived', or standard). - `postsCount` (integer) - `usersCount` (integer) - `customOrderEnabled` (boolean) - `hasMore` (boolean) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/lists" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get users in a list (/docs/of-api/lists/get-users-in-a-list) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/lists/{list_id}/users` **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `list_id` (string, required) ## Query parameters - `limit` (integer) β€” Default `10`. - `offset` (integer) β€” Default `0`. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” User list - `list` (object[]) - `id` (integer) - `name` (string) - `username` (string) - `displayName` (string) - `about` (string) - `avatar` (string) β€” Avatar URL. - `avatarThumbs` (object) - `c50` (string) - `c144` (string) - `header` (string) β€” Profile header/banner URL. - `email` (string) - `isVerified` (boolean) - `isPerformer` (boolean) - `canEarn` (boolean) - `tipsEnabled` (boolean) - `subscribedBy` (boolean) β€” Whether you are subscribed to this user. - `subscribersCount` (integer) - `subscribesCount` (integer) - `postsCount` (integer) - `photosCount` (integer) - `videosCount` (integer) - `audiosCount` (integer) - `friendsCount` (integer) - `joinDate` (string) - `firstPublishedPostDate` (string) - `subscribePrice` (number) - `chatMessagesCount` (integer) β€” Unread chat messages. - `countPriorityChat` (integer) - `countPinnedChat` (integer) - `hasPurchasedPosts` (boolean) - `paidFeed` (boolean) - `openseaInfo` (object) - `hasMore` (boolean) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/lists/{list_id}/users" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Pin user in list (/docs/of-api/lists/pin-user-in-list) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/lists/{list_id}/users/{user_id}/pin` Pins a user to the top of a custom list. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `list_id` (string, required) β€” ID of the list. - `user_id` (string, required) β€” ID of the user to pin. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/lists/{list_id}/users/{user_id}/pin" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Remove all posts from label (/docs/of-api/lists/remove-all-posts-from-label) `DELETE https://theonlyapi.com/api/crm/your-crm-id/api2/v2/labels/{label_id}/posts` Removes all posts from the specified label. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `label_id` (string, required) β€” Id of the label to clear. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/labels/{label_id}/posts" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Remove post from label (/docs/of-api/lists/remove-post-from-label) `DELETE https://theonlyapi.com/api/crm/your-crm-id/api2/v2/labels/{label_id}/post/{post_id}` Removes a single post from the specified label. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `label_id` (string, required) β€” ID of the label. - `post_id` (string, required) β€” ID of the post to remove from the label. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/labels/{label_id}/post/{post_id}" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Remove stream users from list (/docs/of-api/lists/remove-stream-users-from-list) `DELETE https://theonlyapi.com/api/crm/your-crm-id/api2/v2/lists/{list_id}/users/stream/{stream_id}/{type}` Removes stream-derived users (e.g. viewers who tipped or subscribed over a threshold) of a given type from a list. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `list_id` (string, required) β€” ID of the list. - `stream_id` (string, required) β€” ID of the stream. - `type` (string, required) β€” User selection type (passed as the trailing path segment). ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/lists/{list_id}/users/stream/{stream_id}/{type}" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Remove user from list (/docs/of-api/lists/remove-user-from-list) `DELETE https://theonlyapi.com/api/crm/your-crm-id/api2/v2/lists/{list_id}/users/{user_id}` **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `list_id` (string, required) - `user_id` (string, required) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” User removed ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/lists/{list_id}/users/{user_id}" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Rename a label (/docs/of-api/lists/rename-a-label) `PATCH https://theonlyapi.com/api/crm/your-crm-id/api2/v2/labels/{label_id}` Renames the label identified by label_id to the provided name. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `label_id` (string, required) β€” ID of the label to rename. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` - `name` (string) β€” New label name. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X PATCH "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/labels/{label_id}" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Sort labels (/docs/of-api/lists/sort-labels) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/labels/sort` Reorders the user's labels according to the supplied order. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/labels/sort" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Sort pinned list users (/docs/of-api/lists/sort-pinned-list-users) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/lists/{list_id}/users/pinned/sort` Reorders the pinned users within a list identified by list_id, per the provided order. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `list_id` (string, required) β€” ID of the list whose pinned users are sorted. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` - `order` (any[]) β€” Desired ordering of pinned user IDs. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/lists/{list_id}/users/pinned/sort" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Sort user lists (/docs/of-api/lists/sort-user-lists) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/lists/sort` Persists a new ordering of the user's lists. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/lists/sort" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Sort users in list (/docs/of-api/lists/sort-users-in-list) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/lists/{list_id}/sort` Sorts the users within a list. Called as sortListUsers({listId, data}). **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `list_id` (string, required) β€” ID of the list. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/lists/{list_id}/sort" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Update a list (/docs/of-api/lists/update-a-list) `PATCH https://theonlyapi.com/api/crm/your-crm-id/api2/v2/lists/{list_id}` Updates the given user list (getUsersList/updateList module). Sibling calls create, delete and sort lists. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `list_id` (string, required) β€” ID of the list to update. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X PATCH "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/lists/{list_id}" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Messaging (/docs/of-api/messaging) {/* Generated by scripts/gen-api.ts β€” edit that script, not this file. */} OnlyFans chats & messages (via proxy). **OnlyFans only** β€” Fansly accounts are rejected on this surface. | Method | Endpoint | Path | | -------- | --------------------------------------------------------------------------------------------------- | ------------------------------------------------ | | `GET` | [List recent chats](/docs/of-api/messaging/list-recent-chats) | `/api2/v2/chats` | | `POST` | [Mark chat as read](/docs/of-api/messaging/mark-chat-as-read) | `/api2/v2/chats/{user_id}/mark-as-read` | | `GET` | [Get chat messages](/docs/of-api/messaging/get-chat-messages) | `/api2/v2/chats/{user_id}/messages` | | `POST` | [Send a message](/docs/of-api/messaging/send-a-message) | `/api2/v2/chats/{user_id}/messages` | | `GET` | [Get single chat message](/docs/of-api/messaging/get-single-chat-message) | `/api2/v2/chats/{user_id}/messages/{message_id}` | | `GET` | [Search messages in chat](/docs/of-api/messaging/search-messages-in-chat) | `/api2/v2/chats/{user_id}/messages/search` | | `POST` | [Mark chats as read](/docs/of-api/messaging/mark-chats-as-read) | `/api2/v2/chats/mark-as-read` | | `PUT` | [Hide a message](/docs/of-api/messaging/hide-a-message) | `/api2/v2/messages/{message_id}/hide` | | `POST` | [Like / react to a message](/docs/of-api/messaging/like-react-to-a-message) | `/api2/v2/messages/{message_id}/like` | | `GET` | [Get queued mass messages](/docs/of-api/messaging/get-queued-mass-messages) | `/api2/v2/messages/queue` | | `POST` | [Create a mass message](/docs/of-api/messaging/create-a-mass-message) | `/api2/v2/messages/queue` | | `PUT` | [Update queued message](/docs/of-api/messaging/update-queued-message) | `/api2/v2/messages/queue/{queue_id}` | | `DELETE` | [Delete queued message](/docs/of-api/messaging/delete-queued-message) | `/api2/v2/messages/queue/{queue_id}` | | `POST` | [Calculate mass message audience size](/docs/of-api/messaging/calculate-mass-message-audience-size) | `/api2/v2/messages/queue/size` | | `GET` | [Get message templates](/docs/of-api/messaging/get-message-templates) | `/api2/v2/messages/templates` | | `DELETE` | [Delete message template](/docs/of-api/messaging/delete-message-template) | `/api2/v2/messages/templates/{template_id}` | | `POST` | [Set reply-on-subscribe template](/docs/of-api/messaging/set-reply-on-subscribe-template) | `/api2/v2/messages/templates/reply_on_subscribe` | --- # Calculate mass message audience size (/docs/of-api/messaging/calculate-mass-message-audience-size) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/messages/queue/size` Preview how many users would receive a mass message given the buyer filter criteria. **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` - `queueBuyers` (object[]) β€” Same filter array as used in POST /messages/queue. Empty = all subscribers. e.g. `[]`. ## Responses ### 200 β€” Audience size estimate - `size` (integer) β€” Number of users who would receive the message. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/messages/queue/size" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{"queueBuyers":[]}' ``` --- # Create a mass message (/docs/of-api/messaging/create-a-mass-message) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/messages/queue` Queue a mass message to be sent to multiple subscribers. You can target all subscribers, specific lists, or exclude certain users. **Attaching media:** `POST /accounts/{of_user_id}/media` (raw bytes or a `source_url` we fetch for you) returns a `media` object β€” pass it through here. Media already in the vault is referenced by its integer ID from `GET /api2/v2/vault/media`. **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` (required) - `text` (string) β€” Message text. e.g. `"Special offer just for you! 🎁"`. - `mediaFiles` (integer[]) β€” Media IDs from vault. - `price` (number) β€” PPV price for locked content. - `lockedText` (boolean) β€” Default `false`. - `releaseForms` (integer[]) - `queueBuyers` (object[]) β€” Target audience filters. Empty array = all subscribers. Can specify list IDs or user groups. e.g. `[]`. ## Responses ### 200 β€” Mass message queued successfully ## Example **Mass message to all subscribers** ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/messages/queue" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{"text":"Happy weekend! Check your DMs for a surprise 🎁","mediaFiles":[12345],"price":5,"queueBuyers":[]}' ``` --- # Delete message template (/docs/of-api/messaging/delete-message-template) `DELETE https://theonlyapi.com/api/crm/your-crm-id/api2/v2/messages/templates/{template_id}` Deletes a saved message template. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `template_id` (string, required) β€” ID of the message template to delete. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/messages/templates/{template_id}" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Delete queued message (/docs/of-api/messaging/delete-queued-message) `DELETE https://theonlyapi.com/api/crm/your-crm-id/api2/v2/messages/queue/{queue_id}` Deletes a queued (scheduled) mass message by its queue ID. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `queue_id` (string, required) β€” ID of the queued/scheduled message. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/messages/queue/{queue_id}" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get chat messages (/docs/of-api/messaging/get-chat-messages) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/chats/{user_id}/messages` **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `user_id` (string, required) ## Query parameters - `limit` (integer) β€” Default `20`. - `order` (string) β€” Default `desc`. - `id` (integer) β€” Message ID cursor for pagination. Returns messages before/after this ID depending on order. - `skip_users` (string) β€” Default `all`. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Message list - `list` (object[]) - `id` (integer) - `text` (string) - `price` (number) - `isFromQueue` (boolean) - `isOpened` (boolean) - `isNew` (boolean) - `createdAt` (string) - `changedAt` (string) - `isFree` (boolean) - `media` (object[]) - `id` (integer) β€” Stable OnlyFans media ID β€” the only persistent identifier for the item. - `type` ("photo" | "video" | "audio" | "gif") - `createdAt` (string) - `duration` (integer) β€” Duration in seconds (video/audio; 0 for photos). - `convertedToVideo` (boolean) - `canView` (boolean) - `isReady` (boolean) β€” False while OnlyFans is still processing/transcoding the upload. - `hasError` (boolean) - `hasPosts` (boolean) β€” Whether the media is attached to any post. - `hasCustomPreview` (boolean) - `counters` (object) β€” Engagement counters (present on the vault view). - `listStates` (object[]) β€” Which vault lists (folders) this media belongs to. - `files` (object) β€” Signed, time-limited CDN URLs at several resolutions. `size` is frequently `0` β€” do not rely on it. - `videoSources` (object) β€” Per-resolution video URLs (e.g. `240`, `720`); entries are null when not applicable. - `fromUser` (object) - `hasMore` (boolean) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/chats/{user_id}/messages" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get message templates (/docs/of-api/messaging/get-message-templates) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/messages/templates` Get saved message templates for quick replies. **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Template list - `[]` array of: - `id` (integer) - `name` (string) - `content` (string) - `createdAt` (string) - `updatedAt` (string) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/messages/templates" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get queued mass messages (/docs/of-api/messaging/get-queued-mass-messages) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/messages/queue` List all scheduled/queued mass messages. These are messages waiting to be sent to multiple users. **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Query parameters - `limit` (integer) β€” Default `10`. - `offset` (integer) β€” Default `0`. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Queue list - `list` (object[]) - `hasMore` (boolean) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/messages/queue" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get single chat message (/docs/of-api/messaging/get-single-chat-message) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/chats/{user_id}/messages/{message_id}` Retrieves a specific message within the chat with a given user. Called as getMessage({userId, groupId}). **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `user_id` (string, required) β€” ID of the user the chat is with. - `message_id` (string, required) β€” ID of the message (passed as groupId in the caller). ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/chats/{user_id}/messages/{message_id}" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Hide a message (/docs/of-api/messaging/hide-a-message) `PUT https://theonlyapi.com/api/crm/your-crm-id/api2/v2/messages/{message_id}/hide` Hides a chat message identified by message_id. The request body carries hide options. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `message_id` (string, required) β€” ID of the message to hide. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X PUT "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/messages/{message_id}/hide" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Like / react to a message (/docs/of-api/messaging/like-react-to-a-message) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/messages/{message_id}/like` Send a like reaction to a specific message in a chat. **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `message_id` (integer, required) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` - `withUserId` (integer) β€” The user ID of the chat partner (recipient of the like notification). ## Responses ### 200 β€” Message liked ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/messages/{message_id}/like" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # List recent chats (/docs/of-api/messaging/list-recent-chats) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/chats` **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Query parameters - `limit` (integer) β€” Default `10`. - `offset` (integer) β€” Default `0`. - `order` (string) β€” Default `recent`. - `skip_users` (string) β€” Default `all`. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Chat list - `list` (object[]) - `id` (integer) - `withUser` (object) β€” Full OnlyFans user profile object. - `id` (integer) - `name` (string) - `username` (string) - `displayName` (string) - `about` (string) - `avatar` (string) β€” Avatar URL. - `avatarThumbs` (object) - `header` (string) β€” Profile header/banner URL. - `email` (string) - `isVerified` (boolean) - `isPerformer` (boolean) - `canEarn` (boolean) - `tipsEnabled` (boolean) - `subscribedBy` (boolean) β€” Whether you are subscribed to this user. - `subscribersCount` (integer) - `subscribesCount` (integer) - `postsCount` (integer) - `photosCount` (integer) - `videosCount` (integer) - `audiosCount` (integer) - `friendsCount` (integer) - `joinDate` (string) - `firstPublishedPostDate` (string) - `subscribePrice` (number) - `chatMessagesCount` (integer) β€” Unread chat messages. - `countPriorityChat` (integer) - `countPinnedChat` (integer) - `hasPurchasedPosts` (boolean) - `paidFeed` (boolean) - `openseaInfo` (object) - `lastMessage` (object) β€” An OnlyFans chat message object. - `id` (integer) - `text` (string) - `price` (number) - `isFromQueue` (boolean) - `isOpened` (boolean) - `isNew` (boolean) - `createdAt` (string) - `changedAt` (string) - `isFree` (boolean) - `media` (object[]) - `fromUser` (object) - `unreadMessagesCount` (integer) - `hasMore` (boolean) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/chats" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Mark chat as read (/docs/of-api/messaging/mark-chat-as-read) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/chats/{user_id}/mark-as-read` **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `user_id` (string, required) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Marked as read ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/chats/{user_id}/mark-as-read" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Mark chats as read (/docs/of-api/messaging/mark-chats-as-read) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/chats/mark-as-read` Marks one or more chats as read for the current user. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/chats/mark-as-read" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Search messages in chat (/docs/of-api/messaging/search-messages-in-chat) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/chats/{user_id}/messages/search` **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `user_id` (string, required) ## Query parameters - `query` (string, required) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Search results - `list` (object[]) - `id` (integer) - `text` (string) - `price` (number) - `isFromQueue` (boolean) - `isOpened` (boolean) - `isNew` (boolean) - `createdAt` (string) - `changedAt` (string) - `isFree` (boolean) - `media` (object[]) - `id` (integer) β€” Stable OnlyFans media ID β€” the only persistent identifier for the item. - `type` ("photo" | "video" | "audio" | "gif") - `createdAt` (string) - `duration` (integer) β€” Duration in seconds (video/audio; 0 for photos). - `convertedToVideo` (boolean) - `canView` (boolean) - `isReady` (boolean) β€” False while OnlyFans is still processing/transcoding the upload. - `hasError` (boolean) - `hasPosts` (boolean) β€” Whether the media is attached to any post. - `hasCustomPreview` (boolean) - `counters` (object) β€” Engagement counters (present on the vault view). - `listStates` (object[]) β€” Which vault lists (folders) this media belongs to. - `files` (object) β€” Signed, time-limited CDN URLs at several resolutions. `size` is frequently `0` β€” do not rely on it. - `videoSources` (object) β€” Per-resolution video URLs (e.g. `240`, `720`); entries are null when not applicable. - `fromUser` (object) - `hasMore` (boolean) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/chats/{user_id}/messages/search" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Send a message (/docs/of-api/messaging/send-a-message) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/chats/{user_id}/messages` Send a direct message to a user. Supports text, media attachments (uploaded via the media upload endpoint first), PPV pricing, and locked text. Media must be uploaded to the vault first, then referenced by ID in the `mediaFiles` array. **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `user_id` (string, required) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` (required) - `text` (string) β€” Message text content. e.g. `"Hello! Check out this exclusive content πŸ”₯"`. - `mediaFiles` (integer[]) β€” Media to attach. Two accepted forms: * an integer vault ID of media already in the vault (list them with `GET /api2/v2/vault/media`) * the `media` object returned by `POST /accounts/{of_user_id}/media` β€” a freshly uploaded file is referenced by `processId`, not a vault ID Upload new files with `POST /accounts/{of_user_id}/media` (raw bytes, or a `source_url` we fetch for you). e.g. `[12345,67890]`. - `price` (number) β€” PPV price in USD. If set, the message content is locked behind a paywall. e.g. `9.99`. - `lockedText` (boolean) β€” If true, the text is hidden until the user pays the PPV price. Default `false`. - `releaseForms` (integer[]) β€” Release form IDs for compliance. Required if media contains other people. - `replyToMessage` (integer) β€” Message ID to reply to (creates a threaded reply). ## Responses ### 200 β€” Message sent successfully - `id` (integer) - `text` (string) - `price` (number) - `isFromQueue` (boolean) - `isOpened` (boolean) - `isNew` (boolean) - `createdAt` (string) - `changedAt` (string) - `isFree` (boolean) - `media` (object[]) - `id` (integer) β€” Stable OnlyFans media ID β€” the only persistent identifier for the item. - `type` ("photo" | "video" | "audio" | "gif") - `createdAt` (string) - `duration` (integer) β€” Duration in seconds (video/audio; 0 for photos). - `convertedToVideo` (boolean) - `canView` (boolean) - `isReady` (boolean) β€” False while OnlyFans is still processing/transcoding the upload. - `hasError` (boolean) - `hasPosts` (boolean) β€” Whether the media is attached to any post. - `hasCustomPreview` (boolean) - `counters` (object) β€” Engagement counters (present on the vault view). - `buyersCount` (integer) - `likesCount` (integer) - `tipsSumm` (number) - `listStates` (object[]) β€” Which vault lists (folders) this media belongs to. - `id` (integer) β€” Vault list ID. - `name` (string) β€” Vault list name. - `hasMedia` (boolean) - `canAddMedia` (boolean) - `files` (object) β€” Signed, time-limited CDN URLs at several resolutions. `size` is frequently `0` β€” do not rely on it. - `full` (object) - `preview` (object) - `thumb` (object) - `squarePreview` (object) - `videoSources` (object) β€” Per-resolution video URLs (e.g. `240`, `720`); entries are null when not applicable. - `fromUser` (object) ## Example **Simple text message** ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/chats/{user_id}/messages" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{"text":"Hey! How are you?"}' ``` **Message with media attachments** ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/chats/{user_id}/messages" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{"text":"Here's your exclusive content!","mediaFiles":[12345,67890]}' ``` **Pay-per-view message** ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/chats/{user_id}/messages" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{"text":"Unlock to see πŸ”’","mediaFiles":[12345],"price":15,"lockedText":true}' ``` --- # Set reply-on-subscribe template (/docs/of-api/messaging/set-reply-on-subscribe-template) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/messages/templates/reply_on_subscribe` Creates or updates the automatic welcome message template sent when a fan subscribes. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/messages/templates/reply_on_subscribe" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Update queued message (/docs/of-api/messaging/update-queued-message) `PUT https://theonlyapi.com/api/crm/your-crm-id/api2/v2/messages/queue/{queue_id}` Updates a queued/scheduled message identified by its queue id with new message data. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `queue_id` (string, required) β€” ID of the queued/scheduled message. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X PUT "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/messages/queue/{queue_id}" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Misc (/docs/of-api/misc) {/* Generated by scripts/gen-api.ts β€” edit that script, not this file. */} Other OnlyFans endpoints. **OnlyFans only** β€” Fansly accounts are rejected on this surface. | Method | Endpoint | Path | | -------- | -------------------------------------------------------------------------------------- | ------------------------------------------------------- | | `POST` | [Record address statistics](/docs/of-api/misc/record-address-statistics) | `/api2/v2/address/stat` | | `POST` | [Submit consent form](/docs/of-api/misc/submit-consent-form) | `/api2/v2/consent-form` | | `POST` | [Expand address for country](/docs/of-api/misc/expand-address-for-country) | `/api2/v2/countries/{country_id}/address/expand` | | `GET` | [List states for a country](/docs/of-api/misc/list-states-for-a-country) | `/api2/v2/countries/{country_id}/states` | | `GET` | [Get guest details](/docs/of-api/misc/get-guest-details) | `/api2/v2/guests/{guest_id}` | | `POST` | [Assign a guest](/docs/of-api/misc/assign-a-guest) | `/api2/v2/guests/{guest_id}/assign` | | `GET` | [App initialization data](/docs/of-api/misc/app-initialization-data) | `/api2/v2/init` | | `GET` | [Get client IP address](/docs/of-api/misc/get-client-ip-address) | `/api2/v2/ip` | | `GET` | [List states for country](/docs/of-api/misc/list-states-for-country) | `/api2/v2/iso/countries/{country_id}/states` | | `POST` | [Submit a legal inquiry](/docs/of-api/misc/submit-a-legal-inquiry) | `/api2/v2/legal-inquiry` | | `GET` | [Get legal inquiry](/docs/of-api/misc/get-legal-inquiry) | `/api2/v2/legal-inquiry/{inquiry_id}` | | `POST` | [Submit legal inquiry response](/docs/of-api/misc/submit-legal-inquiry-response) | `/api2/v2/legal-inquiry/{inquiry_id}` | | `GET` | [Get legal inquiry history](/docs/of-api/misc/get-legal-inquiry-history) | `/api2/v2/legal-inquiry/{inquiry_id}/history` | | `GET` | [Get legal inquiry update](/docs/of-api/misc/get-legal-inquiry-update) | `/api2/v2/legal-inquiry/{inquiry_id}/update/{hash}` | | `POST` | [Update a legal inquiry](/docs/of-api/misc/update-a-legal-inquiry) | `/api2/v2/legal-inquiry/{inquiry_id}/update/{hash}` | | `POST` | [Submit legal inquiry by counsel](/docs/of-api/misc/submit-legal-inquiry-by-counsel) | `/api2/v2/legal-inquiry/by-counsel` | | `POST` | [Change legal inquiry status](/docs/of-api/misc/change-legal-inquiry-status) | `/api2/v2/legal-inquiry/change-status/{inquiry_id}` | | `GET` | [Get legal inquiry form params](/docs/of-api/misc/get-legal-inquiry-form-params) | `/api2/v2/legal-inquiry/params` | | `POST` | [Send legal inquiry notification](/docs/of-api/misc/send-legal-inquiry-notification) | `/api2/v2/legal-inquiry/send-notification/{inquiry_id}` | | `POST` | [Submit client-side log entry](/docs/of-api/misc/submit-client-side-log-entry) | `/api2/v2/log` | | `GET` | [Get messages earnings chart](/docs/of-api/misc/get-messages-earnings-chart) | `/api2/v2/messages/queue/chart` | | `POST` | [Submit contact form](/docs/of-api/misc/submit-contact-form) | `/api2/v2/pages/contacts` | | `GET` | [Get payouts chart stats](/docs/of-api/misc/get-payouts-chart-stats) | `/api2/v2/payouts/chart` | | `GET` | [Get VAT payouts chart stats](/docs/of-api/misc/get-vat-payouts-chart-stats) | `/api2/v2/payouts/vat/chart` | | `GET` | [Get posts earnings chart](/docs/of-api/misc/get-posts-earnings-chart) | `/api2/v2/posts/chart` | | `GET` | [Get top posts stats](/docs/of-api/misc/get-top-posts-stats) | `/api2/v2/posts/top` | | `GET` | [Get promotions statistics chart](/docs/of-api/misc/get-promotions-statistics-chart) | `/api2/v2/promotions/chart` | | `POST` | [Upload release form document](/docs/of-api/misc/upload-release-form-document) | `/api2/v2/release-form-documents` | | `POST` | [Start release form link](/docs/of-api/misc/start-release-form-link) | `/api2/v2/release-form-links/{link_id}/start` | | `POST` | [Generate release form link URL](/docs/of-api/misc/generate-release-form-link-url) | `/api2/v2/release-form-links/{link_id}/url` | | `POST` | [Submit release form proof](/docs/of-api/misc/submit-release-form-proof) | `/api2/v2/release-form-proof` | | `GET` | [Get partner release forms](/docs/of-api/misc/get-partner-release-forms) | `/api2/v2/release-forms/partner/{partner_id}` | | `PATCH` | [Rename a release form](/docs/of-api/misc/rename-a-release-form) | `/api2/v2/release-forms/rename` | | `PATCH` | [Toggle release form visibility](/docs/of-api/misc/toggle-release-form-visibility) | `/api2/v2/release-forms/toggle-show` | | `GET` | [List content report reasons](/docs/of-api/misc/list-content-report-reasons) | `/api2/v2/reports/reasons` | | `GET` | [Get report reason detail options](/docs/of-api/misc/get-report-reason-detail-options) | `/api2/v2/reports/reasons/{reason_id}/details-options` | | `DELETE` | [Delete Shopify store](/docs/of-api/misc/delete-shopify-store) | `/api2/v2/shopify/stores/{store_id}` | | `GET` | [Get stories statistics chart](/docs/of-api/misc/get-stories-statistics-chart) | `/api2/v2/stories/chart` | | `GET` | [Get top stories stats](/docs/of-api/misc/get-top-stories-stats) | `/api2/v2/stories/top` | | `GET` | [Get streaks over date range](/docs/of-api/misc/get-streaks-over-date-range) | `/api2/v2/streaks` | | `GET` | [Get top streaks](/docs/of-api/misc/get-top-streaks) | `/api2/v2/streaks/top` | | `GET` | [Get streams stats chart](/docs/of-api/misc/get-streams-stats-chart) | `/api2/v2/streams/chart` | | `GET` | [Get top streams stats](/docs/of-api/misc/get-top-streams-stats) | `/api2/v2/streams/top` | | `GET` | [Get subscribers statistics chart](/docs/of-api/misc/get-subscribers-statistics-chart) | `/api2/v2/subscriptions/subscribers/chart` | | `GET` | [Get latest subscribers](/docs/of-api/misc/get-latest-subscribers) | `/api2/v2/subscriptions/subscribers/latest` | | `GET` | [Get top subscribers stats](/docs/of-api/misc/get-top-subscribers-stats) | `/api2/v2/subscriptions/subscribers/top` | | `PUT` | [Update a localization text](/docs/of-api/misc/update-a-localization-text) | `/api2/v2/texts/{code}` | | `POST` | [Search localization texts](/docs/of-api/misc/search-localization-texts) | `/api2/v2/texts/search` | | `GET` | [Get trials chart stats](/docs/of-api/misc/get-trials-chart-stats) | `/api2/v2/trials/chart` | | `GET` | [Get trial link statistics](/docs/of-api/misc/get-trial-link-statistics) | `/api2/v2/trials/stats` | | `POST` | [Report user click statistics](/docs/of-api/misc/report-user-click-statistics) | `/api2/v2/users/clicks-stats` | | `POST` | [Submit license form](/docs/of-api/misc/submit-license-form) | `/api2/v2/users/license_form` | | `GET` | [List referrals](/docs/of-api/misc/list-referrals) | `/api2/v2/users/me/referrals` | | `GET` | [Get messages statistics by type](/docs/of-api/misc/get-messages-statistics-by-type) | `/api2/v2/users/me/stats/messages/{type}` | | `GET` | [Get top fans stats](/docs/of-api/misc/get-top-fans-stats) | `/api2/v2/users/me/stats/top/fan` | | `GET` | [Get top messages stats](/docs/of-api/misc/get-top-messages-stats) | `/api2/v2/users/me/stats/top/message` | | `GET` | [Get top posts statistics](/docs/of-api/misc/get-top-posts-statistics) | `/api2/v2/users/me/stats/top/post` | | `GET` | [Get top stories stats](/docs/of-api/misc/get-top-stories-stats-get) | `/api2/v2/users/me/stats/top/story` | | `GET` | [Get top streams stats](/docs/of-api/misc/get-top-streams-stats-get) | `/api2/v2/users/me/stats/top/stream` | | `POST` | [Confirm terms acceptance](/docs/of-api/misc/confirm-terms-acceptance) | `/api2/v2/users/terms/confirm` | | `POST` | [Create a support ticket](/docs/of-api/misc/create-a-support-ticket) | `/api2/v2/users/tickets` | | `GET` | [Get support ticket](/docs/of-api/misc/get-support-ticket) | `/api2/v2/users/tickets/{ticket_id}` | | `PUT` | [Mark support ticket as read](/docs/of-api/misc/mark-support-ticket-as-read) | `/api2/v2/users/tickets/{ticket_id}/read` | | `PUT` | [Reopen a support ticket](/docs/of-api/misc/reopen-a-support-ticket) | `/api2/v2/users/tickets/{ticket_id}/reopen` | | `POST` | [Reply to support ticket](/docs/of-api/misc/reply-to-support-ticket) | `/api2/v2/users/tickets/{ticket_id}/reply` | | `POST` | [Mark support ticket solved](/docs/of-api/misc/mark-support-ticket-solved) | `/api2/v2/users/tickets/{ticket_id}/solve` | | `POST` | [Check support ticket allowed](/docs/of-api/misc/check-support-ticket-allowed) | `/api2/v2/users/tickets/allowed` | | `GET` | [Get support ticket subjects](/docs/of-api/misc/get-support-ticket-subjects) | `/api2/v2/users/tickets/form_subjects` | | `GET` | [Get state for a ZIP code](/docs/of-api/misc/get-state-for-a-zip-code) | `/api2/v2/zip/{zip_code}/state` | --- # App initialization data (/docs/of-api/misc/app-initialization-data) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/init` Returns comprehensive initialization data including authenticated user profile, feature flags, chat counts, and app configuration. **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Init payload - `user` (object) β€” Full OnlyFans user profile object. - `id` (integer) - `name` (string) - `username` (string) - `displayName` (string) - `about` (string) - `avatar` (string) β€” Avatar URL. - `avatarThumbs` (object) - `c50` (string) - `c144` (string) - `header` (string) β€” Profile header/banner URL. - `email` (string) - `isVerified` (boolean) - `isPerformer` (boolean) - `canEarn` (boolean) - `tipsEnabled` (boolean) - `subscribedBy` (boolean) β€” Whether you are subscribed to this user. - `subscribersCount` (integer) - `subscribesCount` (integer) - `postsCount` (integer) - `photosCount` (integer) - `videosCount` (integer) - `audiosCount` (integer) - `friendsCount` (integer) - `joinDate` (string) - `firstPublishedPostDate` (string) - `subscribePrice` (number) - `chatMessagesCount` (integer) β€” Unread chat messages. - `countPriorityChat` (integer) - `countPinnedChat` (integer) - `hasPurchasedPosts` (boolean) - `paidFeed` (boolean) - `openseaInfo` (object) - `chatMessagesCount` (integer) - `countPriorityChat` (integer) - `countPinnedChat` (integer) - `hasPurchasedPosts` (boolean) - `paidFeed` (boolean) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/init" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Assign a guest (/docs/of-api/misc/assign-a-guest) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/guests/{guest_id}/assign` Assigns a guest (co-performer/guest record) identified by guest_id. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `guest_id` (string, required) β€” Id of the guest to assign. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/guests/{guest_id}/assign" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Change legal inquiry status (/docs/of-api/misc/change-legal-inquiry-status) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/legal-inquiry/change-status/{inquiry_id}` Changes the status of a legal inquiry. Part of the legal-inquiry (static-law) module. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `inquiry_id` (string, required) β€” ID of the legal inquiry. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/legal-inquiry/change-status/{inquiry_id}" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Check support ticket allowed (/docs/of-api/misc/check-support-ticket-allowed) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/tickets/allowed` Checks whether the user is allowed to create a support ticket (part of the users/tickets support module). **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/tickets/allowed" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Confirm terms acceptance (/docs/of-api/misc/confirm-terms-acceptance) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/terms/confirm` Confirms the user's acceptance of updated terms. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/terms/confirm" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Create a support ticket (/docs/of-api/misc/create-a-support-ticket) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/tickets` Creates a new support ticket for the current user. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/tickets" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Delete Shopify store (/docs/of-api/misc/delete-shopify-store) `DELETE https://theonlyapi.com/api/crm/your-crm-id/api2/v2/shopify/stores/{store_id}` Disconnects/removes a linked Shopify store by ID. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `store_id` (string, required) β€” ID of the linked Shopify store. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/shopify/stores/{store_id}" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Expand address for country (/docs/of-api/misc/expand-address-for-country) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/countries/{country_id}/address/expand` Expands/resolves a partial address (by its hash) for a given country, optionally in Latin transliteration. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `country_id` (string, required) β€” ID of the country for address expansion. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` - `hash` (string) β€” Address identifier/hash to expand (addressId). - `isLatin` (boolean) β€” Whether to return Latin-script address. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/countries/{country_id}/address/expand" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Generate release form link URL (/docs/of-api/misc/generate-release-form-link-url) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/release-form-links/{link_id}/url` Generates/returns a shareable URL for a release form link identified by link_id. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `link_id` (string, required) β€” Id of the release form link. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/release-form-links/{link_id}/url" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get client IP address (/docs/of-api/misc/get-client-ip-address) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/ip` Returns the caller's IP address as seen by the API. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. βœ“ **Verified live** against a real OnlyFans account (2026-07-30); the `data` schema below is the real response shape. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response β€” verified live; `data` is the real shape. - `success` (boolean) - `status_code` (integer) - `data` (object) - `ip` (string) - `geo` (object) - `connectionType` (string) - `userType` (string) - `subdivisionConfidence` (string) - `postalConfidence` (string) - `isp` (string) - `domain` (string) - `countryConfidence` (string) - `cityConfidence` (string) - `legitimateProxy` (string) - `regionName` (string) - `region` (string) - `regionGeonameid` (string) - `registeredCountryInEu` (string) - `registeredCountryName` (string) - `registeredCountryIso` (string) - `registeredCountryGeonameid` (string) - `postalCode` (string) - `locationTimezone` (string) - `locationMetrocode` (string) - `longitude` (string) - `latitude` (string) - `locationAccuracyRadius` (string) - `countryInEu` (string) - `countryName` (string) - `countryCode` (string) - `countryGeonameid` (string) - `continentName` (string) - `continentGeonameid` (string) - `continentCode` (string) - `cityGeonameid` (string) - `city` (string) - `cityBuildDate` (string) - `isEurope` (boolean) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/ip" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get guest details (/docs/of-api/misc/get-guest-details) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/guests/{guest_id}` Retrieves a guest record by id. Guests appear alongside release-form and guest-assign endpoints (people tagged in content). **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `guest_id` (string, required) β€” ID of the guest. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/guests/{guest_id}" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get latest subscribers (/docs/of-api/misc/get-latest-subscribers) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/subscriptions/subscribers/latest` Returns the latest subscribers within a date range, grouped by the given field. The dynamic path segment is actually the querystring. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. βœ“ **Verified live** against a real OnlyFans account (2026-07-30); the `data` schema below is the real response shape. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Query parameters - `startDate` (string, required) β€” Start of the date range. - `endDate` (string, required) β€” End of the date range. - `by` (string) β€” Grouping/aggregation field. - `offset` (string) β€” Pagination offset. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response β€” verified live; `data` is the real shape. - `success` (boolean) - `status_code` (integer) - `data` (object) - `users` (object[]) - `view` (string) - `avatar` (null) - `avatarThumbs` (null) - `header` (null) - `headerSize` (null) - `headerThumbs` (null) - `id` (integer) - `name` (string) - `username` (string) - `canLookStory` (boolean) - `canCommentStory` (boolean) - `hasNotViewedStory` (boolean) - `isVerified` (boolean) - `canPayInternal` (boolean) - `hasScheduledStream` (boolean) - `hasStream` (boolean) - `hasStories` (boolean) - `tipsEnabled` (boolean) - `tipsTextEnabled` (boolean) - `tipsMin` (integer) - `tipsMinInternal` (integer) - `tipsMax` (integer) - `canEarn` (boolean) - `canAddSubscriber` (boolean) - `subscribePrice` (integer) - `displayName` (string) - `notice` (string) - `isActive` (boolean) - `isRestricted` (boolean) - `canRestrict` (boolean) - `subscribedBy` (boolean) - `subscribedByExpire` (boolean) - `subscribedByExpireDate` (string) - `subscribedByAutoprolong` (boolean) - `subscribedIsExpiredNow` (boolean) - `currentSubscribePrice` (integer) - `subscribedOn` (boolean) - `subscribedOnExpire` (boolean) - `subscribedOnExpiredNow` (boolean) - `subscribedOnDuration` (string) - `listsStates` (any[]) - `canReport` (boolean) - `canReceiveChatMessage` (boolean) - `hideChat` (boolean) - `lastSeen` (string) - `isPerformer` (boolean) - `isRealPerformer` (boolean) - `subscribedByData` (object) - `subscribedOnData` (object) - `canTrialSend` (boolean) - `isBlocked` (boolean) - `canUnsubscribe` (boolean) - `isPendingAutoprolong` (boolean) - `offset` (integer) - `hasMore` (boolean) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/subscriptions/subscribers/latest" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get legal inquiry (/docs/of-api/misc/get-legal-inquiry) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/legal-inquiry/{inquiry_id}` Retrieves a legal inquiry (e.g. legal/DMCA request) by ID. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `inquiry_id` (string, required) β€” ID of the legal inquiry. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/legal-inquiry/{inquiry_id}" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get legal inquiry form params (/docs/of-api/misc/get-legal-inquiry-form-params) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/legal-inquiry/params` Returns the parameter/option definitions used to build the legal inquiry form. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. βœ“ **Verified live** against a real OnlyFans account (2026-07-30); the `data` schema below is the real response shape. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response β€” verified live; `data` is the real shape. - `success` (boolean) - `status_code` (integer) - `data` (object) - `newReportsCount` (integer) - `fileAllowedExtensions` (string[]) - `legalInquiry` (object) - `matterTypes` (object[]) - `additional` (object) - `category` (object[]) - `subject` (object[]) - `gdprOptions` (object) - `groups` (object) - `reports` (object) - `highPrioritySubjects` (string[]) - `success` (boolean) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/legal-inquiry/params" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get legal inquiry history (/docs/of-api/misc/get-legal-inquiry-history) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/legal-inquiry/{inquiry_id}/history` Returns the history/audit trail for a legal inquiry by id (from the legal/law module). **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `inquiry_id` (string, required) β€” ID of the legal inquiry. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/legal-inquiry/{inquiry_id}/history" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get legal inquiry update (/docs/of-api/misc/get-legal-inquiry-update) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/legal-inquiry/{inquiry_id}/update/{hash}` Retrieves a specific update of a legal inquiry identified by inquiry_id, addressed by an update hash. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `inquiry_id` (string, required) β€” ID of the legal inquiry. - `hash` (string, required) β€” Hash identifying the specific inquiry update. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/legal-inquiry/{inquiry_id}/update/{hash}" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get messages earnings chart (/docs/of-api/misc/get-messages-earnings-chart) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/messages/queue/chart` Returns time-series earnings/statistics for queued messages. The dynamic path segment is a built querystring. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. βœ“ **Verified live** against a real OnlyFans account (2026-07-30); the `data` schema below is the real response shape. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Query parameters - `startDate` (string, required) β€” Start of the date range. - `endDate` (string, required) β€” End of the date range. - `withTotal` (string) β€” Include totals in the response. - `filter` (string) β€” Metric filter (built from 'by' and 'by2' arguments). ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response β€” verified live; `data` is the real shape. - `success` (boolean) - `status_code` (integer) - `data` (object) - `purchases` (object) - `chart` (object[]) - `messages` (object) - `chart` (object[]) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/messages/queue/chart" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get messages statistics by type (/docs/of-api/misc/get-messages-statistics-by-type) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/me/stats/messages/{type}` Returns the current user's messaging statistics for a given type (default 'all') over a date range, paginated and searchable. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `type` (string, required) β€” Message stats type/segment (default 'all'). ## Query parameters - `startDate` (string) β€” Start of the date range. - `endDate` (string) β€” End of the date range. - `limit` (string) β€” Max number of rows. - `query` (string) β€” Search term. - `offset` (string) β€” Pagination offset. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/me/stats/messages/{type}" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get partner release forms (/docs/of-api/misc/get-partner-release-forms) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/release-forms/partner/{partner_id}` Retrieves release forms associated with a partner identified by partner id. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `partner_id` (string, required) β€” ID of the partner whose release forms are fetched. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/release-forms/partner/{partner_id}" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get payouts chart stats (/docs/of-api/misc/get-payouts-chart-stats) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/chart` Returns payouts chart statistics (amount/count) over a date range. The dynamic path segment is the serialized querystring. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. βœ“ **Verified live** against a real OnlyFans account (2026-07-30); the `data` schema below is the real response shape. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Query parameters - `startDate` (string, required) β€” Range start date. - `endDate` (string, required) β€” Range end date. - `withTotal` (string) β€” Include totals (set true). - `withChart` (string) β€” Include chart series (set true). - `filter` (string) β€” Chart amount/count filter. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response β€” verified live; `data` is the real shape. - `success` (boolean) - `status_code` (integer) - `data` (any[]) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/chart" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get posts earnings chart (/docs/of-api/misc/get-posts-earnings-chart) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/posts/chart` Returns time-series earnings/statistics for posts. The dynamic path segment is a built querystring, not an id. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. βœ“ **Verified live** against a real OnlyFans account (2026-07-30); the `data` schema below is the real response shape. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Query parameters - `startDate` (string, required) β€” Start of the date range. - `endDate` (string, required) β€” End of the date range. - `withTotal` (string) β€” Include totals in the response. - `filter` (string) β€” Metric filter (built from the 'by' argument plus posts). ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response β€” verified live; `data` is the real shape. - `success` (boolean) - `status_code` (integer) - `data` (object) - `posts` (object) - `chart` (object[]) - `purchases` (object) - `chart` (object[]) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/posts/chart" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get promotions statistics chart (/docs/of-api/misc/get-promotions-statistics-chart) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/promotions/chart` Returns chart/statistics data for promotions over a date range. Path segment is static; the trailing token is a serialized query string. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. βœ“ **Verified live** against a real OnlyFans account (2026-07-30); the `data` schema below is the real response shape. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Query parameters - `startDate` (string) β€” Start of the date range. - `endDate` (string) β€” End of the date range. - `stats` (string) β€” Stats flag (set to 1). ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response β€” verified live; `data` is the real shape. - `success` (boolean) - `status_code` (integer) - `data` (object) - `claims` (object) - `chart` (object[]) - `total` (integer) - `offers` (object) - `chart` (object[]) - `total` (integer) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/promotions/chart" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get report reason detail options (/docs/of-api/misc/get-report-reason-detail-options) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/reports/reasons/{reason_id}/details-options` Retrieves the detail options available for a specific report reason. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `reason_id` (string, required) β€” ID of the report reason. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/reports/reasons/{reason_id}/details-options" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get state for a ZIP code (/docs/of-api/misc/get-state-for-a-zip-code) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/zip/{zip_code}/state` Looks up the state/region associated with a given ZIP code, used by payouts address forms. Defined in the payouts/address module. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `zip_code` (string, required) β€” ZIP/postal code to resolve to a state. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/zip/{zip_code}/state" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get stories statistics chart (/docs/of-api/misc/get-stories-statistics-chart) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/stories/chart` Returns time-series chart data for stories earnings/activity over a date range. The `{id}` in path_raw is actually the querystring appended by the Zq helper. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. βœ“ **Verified live** against a real OnlyFans account (2026-07-30); the `data` schema below is the real response shape. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Query parameters - `startDate` (string, required) β€” Range start date. - `endDate` (string, required) β€” Range end date. - `withTotal` (string) β€” Whether to include totals. - `by` (string) β€” Grouping/breakdown key. - `filter` (string) β€” Filter object (e.g. {stories:'stories'}). ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response β€” verified live; `data` is the real shape. - `success` (boolean) - `status_code` (integer) - `data` (object) - `tips` (object) - `chart` (object[]) - `stories` (object) - `chart` (object[]) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/stories/chart" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get streaks over date range (/docs/of-api/misc/get-streaks-over-date-range) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streaks` Retrieves subscriber/engagement streak statistics over a date range. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. βœ“ **Verified live** against a real OnlyFans account (2026-07-30); the `data` schema below is the real response shape. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Query parameters - `startDate` (string) β€” Start of date range. - `endDate` (string) β€” End of date range. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response β€” verified live; `data` is the real shape. - `success` (boolean) - `status_code` (integer) - `data` (object) - `list` (object[]) - `id` (integer) - `startDate` (string) - `endDate` (string) - `isActive` (boolean) - `postsCount` (integer) - `daysCount` (integer) - `streamsDuration` (integer) - `storiesCount` (integer) - `chatsCount` (integer) - `frozenDays` (any[]) - `hasMore` (boolean) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streaks" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get streams stats chart (/docs/of-api/misc/get-streams-stats-chart) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/chart` Returns time-series chart data for live-stream statistics over a date range. The dynamic path segment is actually the querystring. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. βœ“ **Verified live** against a real OnlyFans account (2026-07-30); the `data` schema below is the real response shape. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Query parameters - `startDate` (string, required) β€” Start of the date range. - `endDate` (string, required) β€” End of the date range. - `withTotal` (string) β€” Whether to include totals. - `filter` (string) β€” Filter object (keyed by the 'by' field, plus duration). ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response β€” verified live; `data` is the real shape. - `success` (boolean) - `status_code` (integer) - `data` (object) - `duration` (object) - `chart` (object[]) - `purchases` (object) - `chart` (object[]) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/chart" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get subscribers statistics chart (/docs/of-api/misc/get-subscribers-statistics-chart) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/subscriptions/subscribers/chart` Returns chart/statistics data for subscribers over a date range, groupable via 'by'. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. βœ“ **Verified live** against a real OnlyFans account (2026-07-30); the `data` schema below is the real response shape. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Query parameters - `startDate` (string) β€” Start of the date range. - `endDate` (string) β€” End of the date range. - `by` (string) β€” Grouping/breakdown dimension. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response β€” verified live; `data` is the real shape. - `success` (boolean) - `status_code` (integer) - `data` (object) - `earnings` (object[]) - `date` (string) - `count` (integer) - `subscribes` (object[]) - `date` (string) - `count` (integer) - `total` (integer) - `subscribers` (integer) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/subscriptions/subscribers/chart" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get support ticket (/docs/of-api/misc/get-support-ticket) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/tickets/{ticket_id}` Retrieves a support ticket by id. Grouped with ticket reply/comments/solve/reopen endpoints. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `ticket_id` (string, required) β€” ID of the support ticket. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/tickets/{ticket_id}" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get support ticket subjects (/docs/of-api/misc/get-support-ticket-subjects) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/tickets/form_subjects` Returns the selectable subject options for the support-ticket creation form. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. βœ“ **Verified live** against a real OnlyFans account (2026-07-30); the `data` schema below is the real response shape. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response β€” verified live; `data` is the real shape. - `success` (boolean) - `status_code` (integer) - `data` (object) - `items` (object[]) - `id` (integer) - `title` (string) - `items` (any[]) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/tickets/form_subjects" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get top fans stats (/docs/of-api/misc/get-top-fans-stats) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/me/stats/top/fan` Returns the current user's top-fan statistics over a date range. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. βœ“ **Verified live** against a real OnlyFans account (2026-07-30); the `data` schema below is the real response shape. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Query parameters - `startDate` (string, required) β€” Range start date. - `endDate` (string, required) β€” Range end date. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response β€” verified live; `data` is the real shape. - `success` (boolean) - `status_code` (integer) - `data` (object) - `total` (object) - `view` (string) - `avatar` (null) - `avatarThumbs` (null) - `header` (null) - `headerSize` (null) - `headerThumbs` (null) - `id` (integer) - `name` (string) - `username` (string) - `canLookStory` (boolean) - `canCommentStory` (boolean) - `hasNotViewedStory` (boolean) - `isVerified` (boolean) - `canPayInternal` (boolean) - `hasScheduledStream` (boolean) - `hasStream` (boolean) - `hasStories` (boolean) - `tipsEnabled` (boolean) - `tipsTextEnabled` (boolean) - `tipsMin` (integer) - `tipsMinInternal` (integer) - `tipsMax` (integer) - `canEarn` (boolean) - `canAddSubscriber` (boolean) - `subscribePrice` (integer) - `displayName` (string) - `notice` (string) - `isActive` (boolean) - `isRestricted` (boolean) - `canRestrict` (boolean) - `subscribedBy` (boolean) - `subscribedByExpire` (boolean) - `subscribedByExpireDate` (string) - `subscribedByAutoprolong` (boolean) - `subscribedIsExpiredNow` (boolean) - `currentSubscribePrice` (integer) - `subscribedOn` (null) - `subscribedOnExpire` (boolean) - `subscribedOnExpiredNow` (boolean) - `subscribedOnDuration` (string) - `listsStates` (object[]) - `canReport` (boolean) - `canReceiveChatMessage` (boolean) - `hideChat` (boolean) - `lastSeen` (string) - `isPerformer` (boolean) - `isRealPerformer` (boolean) - `subscribedByData` (object) - `subscribedOnData` (object) - `canTrialSend` (boolean) - `isBlocked` (boolean) - `canUnsubscribe` (boolean) - `isPendingAutoprolong` (boolean) - `subscriptions` (object) - `view` (string) - `avatar` (null) - `avatarThumbs` (null) - `header` (null) - `headerSize` (null) - `headerThumbs` (null) - `id` (integer) - `name` (string) - `username` (string) - `canLookStory` (boolean) - `canCommentStory` (boolean) - `hasNotViewedStory` (boolean) - `isVerified` (boolean) - `canPayInternal` (boolean) - `hasScheduledStream` (boolean) - `hasStream` (boolean) - `hasStories` (boolean) - `tipsEnabled` (boolean) - `tipsTextEnabled` (boolean) - `tipsMin` (integer) - `tipsMinInternal` (integer) - `tipsMax` (integer) - `canEarn` (boolean) - `canAddSubscriber` (boolean) - `subscribePrice` (integer) - `displayName` (string) - `notice` (string) - `isActive` (boolean) - `isRestricted` (boolean) - `canRestrict` (boolean) - `subscribedBy` (boolean) - `subscribedByExpire` (boolean) - `subscribedByExpireDate` (string) - `subscribedByAutoprolong` (boolean) - `subscribedIsExpiredNow` (boolean) - `currentSubscribePrice` (integer) - `subscribedOn` (null) - `subscribedOnExpire` (boolean) - `subscribedOnExpiredNow` (boolean) - `subscribedOnDuration` (string) - `listsStates` (object[]) - `canReport` (boolean) - `canReceiveChatMessage` (boolean) - `hideChat` (boolean) - `lastSeen` (string) - `isPerformer` (boolean) - `isRealPerformer` (boolean) - `subscribedByData` (object) - `subscribedOnData` (object) - `canTrialSend` (boolean) - `isBlocked` (boolean) - `canUnsubscribe` (boolean) - `isPendingAutoprolong` (boolean) - `tips` (object) - `view` (string) - `avatar` (null) - `avatarThumbs` (null) - `header` (null) - `headerSize` (null) - `headerThumbs` (null) - `id` (integer) - `name` (string) - `username` (string) - `canLookStory` (boolean) - `canCommentStory` (boolean) - `hasNotViewedStory` (boolean) - `isVerified` (boolean) - `canPayInternal` (boolean) - `hasScheduledStream` (boolean) - `hasStream` (boolean) - `hasStories` (boolean) - `tipsEnabled` (boolean) - `tipsTextEnabled` (boolean) - `tipsMin` (integer) - `tipsMinInternal` (integer) - `tipsMax` (integer) - `canEarn` (boolean) - `canAddSubscriber` (boolean) - `subscribePrice` (integer) - `displayName` (string) - `notice` (string) - `isActive` (boolean) - `isRestricted` (boolean) - `canRestrict` (boolean) - `subscribedBy` (boolean) - `subscribedByExpire` (boolean) - `subscribedByExpireDate` (string) - `subscribedByAutoprolong` (boolean) - `subscribedIsExpiredNow` (boolean) - `currentSubscribePrice` (integer) - `subscribedOn` (boolean) - `subscribedOnExpire` (boolean) - `subscribedOnExpiredNow` (boolean) - `subscribedOnDuration` (string) - `listsStates` (object[]) - `canReport` (boolean) - `canReceiveChatMessage` (boolean) - `hideChat` (boolean) - `lastSeen` (string) - `isPerformer` (boolean) - `isRealPerformer` (boolean) - `subscribedByData` (object) - `subscribedOnData` (object) - `canTrialSend` (boolean) - `isBlocked` (boolean) - `canUnsubscribe` (boolean) - `isPendingAutoprolong` (boolean) - `messages` (object) - `view` (string) - `avatar` (null) - `avatarThumbs` (null) - `header` (null) - `headerSize` (null) - `headerThumbs` (null) - `id` (integer) - `name` (string) - `username` (string) - `canLookStory` (boolean) - `canCommentStory` (boolean) - `hasNotViewedStory` (boolean) - `isVerified` (boolean) - `canPayInternal` (boolean) - `hasScheduledStream` (boolean) - `hasStream` (boolean) - `hasStories` (boolean) - `tipsEnabled` (boolean) - `tipsTextEnabled` (boolean) - `tipsMin` (integer) - `tipsMinInternal` (integer) - `tipsMax` (integer) - `canEarn` (boolean) - `canAddSubscriber` (boolean) - `subscribePrice` (integer) - `displayName` (string) - `notice` (string) - `isActive` (boolean) - `isRestricted` (boolean) - `canRestrict` (boolean) - `subscribedBy` (boolean) - `subscribedByExpire` (boolean) - `subscribedByExpireDate` (string) - `subscribedByAutoprolong` (boolean) - `subscribedIsExpiredNow` (boolean) - `currentSubscribePrice` (integer) - `subscribedOn` (null) - `subscribedOnExpire` (boolean) - `subscribedOnExpiredNow` (boolean) - `subscribedOnDuration` (string) - `listsStates` (object[]) - `canReport` (boolean) - `canReceiveChatMessage` (boolean) - `hideChat` (boolean) - `lastSeen` (string) - `isPerformer` (boolean) - `isRealPerformer` (boolean) - `subscribedByData` (object) - `subscribedOnData` (object) - `canTrialSend` (boolean) - `isBlocked` (boolean) - `canUnsubscribe` (boolean) - `isPendingAutoprolong` (boolean) - `streams` (null) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/me/stats/top/fan" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get top messages stats (/docs/of-api/misc/get-top-messages-stats) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/me/stats/top/message` Returns statistics on the current user's top-performing messages over a date range. The `{id}` in path_raw is the appended querystring. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. βœ“ **Verified live** against a real OnlyFans account (2026-07-30); the `data` schema below is the real response shape. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Query parameters - `startDate` (string, required) β€” Range start date. - `endDate` (string, required) β€” Range end date. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response β€” verified live; `data` is the real shape. - `success` (boolean) - `status_code` (integer) - `data` (object) - `purchases` (object) - `id` (integer) - `date` (string) - `responseType` (string) - `text` (string) - `rawText` (string) - `giphyId` (null) - `isFree` (boolean) - `isMediaReady` (boolean) - `mediaCount` (integer) - `media` (object[]) - `previews` (any[]) - `isTip` (boolean) - `isReportedByMe` (boolean) - `viewedCount` (integer) - `sentCount` (integer) - `isCanceled` (boolean) - `template` (string) - `canUnsend` (boolean) - `unsendSeconds` (integer) - `price` (string) - `purchasedCount` (integer) - `canSendMessageToBuyers` (boolean) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/me/stats/top/message" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get top posts statistics (/docs/of-api/misc/get-top-posts-statistics) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/me/stats/top/post` Returns the current user's top-performing posts statistics for a date range. Sibling calls fetch top story/stream/stream stats. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. βœ“ **Verified live** against a real OnlyFans account (2026-07-30); the `data` schema below is the real response shape. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Query parameters - `startDate` (string) β€” Start of the date range. - `endDate` (string) β€” End of the date range. - `skip_users` (string) β€” Whether to omit expanded user objects (set to 'all'). ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response β€” verified live; `data` is the real shape. - `success` (boolean) - `status_code` (integer) - `data` (object) - `purchases` (null) - `tips` (object) - `author` (object) - `responseType` (string) - `id` (integer) - `postedAt` (string) - `postedAtPrecise` (string) - `text` (string) - `isMarkdownDisabled` (boolean) - `canDelete` (boolean) - `canComment` (boolean) - `canEdit` (boolean) - `favoritesCount` (integer) - `mediaCount` (integer) - `isMediaReady` (boolean) - `isOpened` (boolean) - `canToggleFavorite` (boolean) - `stats` (object) - `commentsCount` (integer) - `tipsAmount` (string) - `rawText` (string) - `tweetSend` (boolean) - `media` (object[]) - `canViewMedia` (boolean) - `labelStates` (object[]) - `views` (object) - `author` (object) - `responseType` (string) - `id` (integer) - `postedAt` (string) - `postedAtPrecise` (string) - `text` (string) - `isMarkdownDisabled` (boolean) - `canDelete` (boolean) - `canComment` (boolean) - `canEdit` (boolean) - `isPinned` (boolean) - `favoritesCount` (integer) - `mediaCount` (integer) - `isMediaReady` (boolean) - `isOpened` (boolean) - `canToggleFavorite` (boolean) - `stats` (object) - `commentsCount` (integer) - `tipsAmount` (string) - `rawText` (string) - `tweetSend` (boolean) - `media` (object[]) - `canViewMedia` (boolean) - `labelStates` (object[]) - `likes` (object) - `author` (object) - `responseType` (string) - `id` (integer) - `postedAt` (string) - `postedAtPrecise` (string) - `text` (string) - `isMarkdownDisabled` (boolean) - `canDelete` (boolean) - `canComment` (boolean) - `canEdit` (boolean) - `isPinned` (boolean) - `favoritesCount` (integer) - `mediaCount` (integer) - `isMediaReady` (boolean) - `isOpened` (boolean) - `canToggleFavorite` (boolean) - `stats` (object) - `commentsCount` (integer) - `tipsAmount` (string) - `rawText` (string) - `tweetSend` (boolean) - `media` (object[]) - `canViewMedia` (boolean) - `labelStates` (object[]) - `comments` (object) - `author` (object) - `responseType` (string) - `id` (integer) - `postedAt` (string) - `postedAtPrecise` (string) - `isMarkdownDisabled` (boolean) - `canDelete` (boolean) - `canComment` (boolean) - `canEdit` (boolean) - `favoritesCount` (integer) - `mediaCount` (integer) - `isMediaReady` (boolean) - `isOpened` (boolean) - `canToggleFavorite` (boolean) - `stats` (object) - `commentsCount` (integer) - `tipsAmount` (string) - `tweetSend` (boolean) - `media` (object[]) - `canViewMedia` (boolean) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/me/stats/top/post" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get top posts stats (/docs/of-api/misc/get-top-posts-stats) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/posts/top` Returns top-performing posts statistics over a date range. The dynamic path segment is the serialized querystring. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Query parameters - `startDate` (string, required) β€” Range start date. - `endDate` (string, required) β€” Range end date. - `by` (string) β€” Metric to sort/group by. - `offset` (string) β€” Pagination offset. - `skip_users` (string) β€” Skip embedding user objects (set to all). ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/posts/top" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get top stories stats (/docs/of-api/misc/get-top-stories-stats) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/stories/top` Returns top-performing stories statistics for a date range, optionally grouped. The dynamic suffix in path_raw is the querystring. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Query parameters - `startDate` (string) β€” Range start date. - `endDate` (string) β€” Range end date. - `by` (string) β€” Grouping/metric field. - `offset` (string) β€” Pagination offset. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/stories/top" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get top stories stats (/docs/of-api/misc/get-top-stories-stats-get) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/me/stats/top/story` Retrieves top-performing story statistics over a date range. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. βœ“ **Verified live** against a real OnlyFans account (2026-07-30); the `data` schema below is the real response shape. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Query parameters - `startDate` (string, required) β€” Start of date range. - `endDate` (string, required) β€” End of date range. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response β€” verified live; `data` is the real shape. - `success` (boolean) - `status_code` (integer) - `data` (object) - `tips` (null) - `views` (object) - `id` (integer) - `userId` (integer) - `isReady` (boolean) - `hasPost` (boolean) - `isWatched` (boolean) - `media` (object[]) - `createdAt` (string) - `canvasHeight` (integer) - `canvasWidth` (integer) - `question` (object) - `viewersCount` (integer) - `viewers` (object[]) - `commentsCount` (integer) - `canDelete` (boolean) - `isHighlightCover` (boolean) - `isLastInHighlight` (boolean) - `tipsAmount` (string) - `tipsAmountRaw` (integer) - `tipsCount` (integer) - `likesCount` (integer) - `releaseForms` (any[]) - `likes` (object) - `id` (integer) - `userId` (integer) - `isReady` (boolean) - `hasPost` (boolean) - `isWatched` (boolean) - `media` (object[]) - `createdAt` (string) - `canvasHeight` (integer) - `canvasWidth` (integer) - `question` (object) - `viewersCount` (integer) - `viewers` (object[]) - `commentsCount` (integer) - `canDelete` (boolean) - `isHighlightCover` (boolean) - `isLastInHighlight` (boolean) - `tipsAmount` (string) - `tipsAmountRaw` (integer) - `tipsCount` (integer) - `likesCount` (integer) - `releaseForms` (any[]) - `comments` (object) - `id` (integer) - `userId` (integer) - `isReady` (boolean) - `hasPost` (boolean) - `isWatched` (boolean) - `media` (object[]) - `createdAt` (string) - `canvasHeight` (integer) - `canvasWidth` (integer) - `question` (object) - `viewersCount` (integer) - `viewers` (object[]) - `commentsCount` (integer) - `canDelete` (boolean) - `isHighlightCover` (boolean) - `isLastInHighlight` (boolean) - `tipsAmount` (string) - `tipsAmountRaw` (integer) - `tipsCount` (integer) - `likesCount` (integer) - `releaseForms` (any[]) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/me/stats/top/story" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get top streaks (/docs/of-api/misc/get-top-streaks) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streaks/top` Returns the top fan streaks for the creator. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. βœ“ **Verified live** against a real OnlyFans account (2026-07-30); the `data` schema below is the real response shape. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response β€” verified live; `data` is the real shape. - `success` (boolean) - `status_code` (integer) - `data` (object) - `id` (integer) - `startDate` (string) - `endDate` (string) - `isActive` (boolean) - `postsCount` (integer) - `daysCount` (integer) - `streamsDuration` (integer) - `storiesCount` (integer) - `chatsCount` (integer) - `frozenDays` (string[]) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streaks/top" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get top streams stats (/docs/of-api/misc/get-top-streams-stats) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/top` Returns top-performing live streams over a date range, ranked (default by purchases) with pagination. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Query parameters - `startDate` (string, required) β€” Range start date. - `endDate` (string, required) β€” Range end date. - `limit` (string) β€” Page size (default 10). - `offset` (string) β€” Pagination offset (default 0). - `by` (string) β€” Ranking metric (default 'purchases'). ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/top" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get top streams stats (/docs/of-api/misc/get-top-streams-stats-get) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/me/stats/top/stream` Returns the current user's top-performing streams statistics for a date range. The dynamic suffix in path_raw is the querystring. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. βœ“ **Verified live** against a real OnlyFans account (2026-07-30); the `data` schema below is the real response shape. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Query parameters - `startDate` (string) β€” Range start date. - `endDate` (string) β€” Range end date. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response β€” verified live; `data` is the real shape. - `success` (boolean) - `status_code` (integer) - `data` (object) - `purchases` (null) - `tips` (null) - `views` (null) - `likes` (null) - `comments` (null) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/me/stats/top/stream" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get top subscribers stats (/docs/of-api/misc/get-top-subscribers-stats) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/subscriptions/subscribers/top` Retrieves top subscribers over a date range (statistics context). **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. βœ“ **Verified live** against a real OnlyFans account (2026-07-30); the `data` schema below is the real response shape. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Query parameters - `startDate` (string, required) β€” Start of date range. - `endDate` (string, required) β€” End of date range. - `by` (string) β€” Metric to rank by. - `offset` (string) β€” Pagination offset. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response β€” verified live; `data` is the real shape. - `success` (boolean) - `status_code` (integer) - `data` (object) - `users` (object[]) - `view` (string) - `avatar` (null) - `avatarThumbs` (null) - `header` (null) - `headerSize` (null) - `headerThumbs` (null) - `id` (integer) - `name` (string) - `username` (string) - `canLookStory` (boolean) - `canCommentStory` (boolean) - `hasNotViewedStory` (boolean) - `isVerified` (boolean) - `canPayInternal` (boolean) - `hasScheduledStream` (boolean) - `hasStream` (boolean) - `hasStories` (boolean) - `tipsEnabled` (boolean) - `tipsTextEnabled` (boolean) - `tipsMin` (integer) - `tipsMinInternal` (integer) - `tipsMax` (integer) - `canEarn` (boolean) - `canAddSubscriber` (boolean) - `subscribePrice` (integer) - `displayName` (string) - `notice` (string) - `isActive` (boolean) - `isRestricted` (boolean) - `canRestrict` (boolean) - `subscribedBy` (boolean) - `subscribedByExpire` (boolean) - `subscribedByExpireDate` (string) - `subscribedByAutoprolong` (boolean) - `subscribedIsExpiredNow` (boolean) - `currentSubscribePrice` (integer) - `subscribedOn` (null) - `subscribedOnExpire` (boolean) - `subscribedOnExpiredNow` (boolean) - `subscribedOnDuration` (string) - `listsStates` (any[]) - `canReport` (boolean) - `canReceiveChatMessage` (boolean) - `hideChat` (boolean) - `lastSeen` (string) - `isPerformer` (boolean) - `isRealPerformer` (boolean) - `subscribedByData` (object) - `subscribedOnData` (object) - `canTrialSend` (boolean) - `isBlocked` (boolean) - `canUnsubscribe` (boolean) - `isPendingAutoprolong` (boolean) - `hasMore` (boolean) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/subscriptions/subscribers/top" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get trial link statistics (/docs/of-api/misc/get-trial-link-statistics) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/trials/stats` Returns statistics for free-trial links over a date range with pagination. The dynamic suffix in path_raw is the querystring. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. βœ“ **Verified live** against a real OnlyFans account (2026-07-30); the `data` schema below is the real response shape. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Query parameters - `offset` (string) β€” Pagination offset. - `startDate` (string) β€” Range start date. - `endDate` (string) β€” Range end date. - `limit` (string) β€” Max results. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response β€” verified live; `data` is the real shape. - `success` (boolean) - `status_code` (integer) - `data` (object) - `hasMore` (boolean) - `items` (any[]) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/trials/stats" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get trials chart stats (/docs/of-api/misc/get-trials-chart-stats) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/trials/chart` Returns trial statistics chart data over a date range. The dynamic path segment is the serialized querystring, not a path param. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. βœ“ **Verified live** against a real OnlyFans account (2026-07-30); the `data` schema below is the real response shape. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Query parameters - `startDate` (string, required) β€” Range start date. - `endDate` (string, required) β€” Range end date. - `stats` (string) β€” Include stats flag (set to 1). ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response β€” verified live; `data` is the real shape. - `success` (boolean) - `status_code` (integer) - `data` (object) - `claims` (object) - `chart` (object[]) - `total` (integer) - `offers` (object) - `chart` (object[]) - `total` (integer) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/trials/chart" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get VAT payouts chart stats (/docs/of-api/misc/get-vat-payouts-chart-stats) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/vat/chart` Returns VAT payouts chart statistics (amount/count) over a date range. The dynamic path segment is the serialized querystring. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. βœ“ **Verified live** against a real OnlyFans account (2026-07-30); the `data` schema below is the real response shape. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Query parameters - `startDate` (string, required) β€” Range start date. - `endDate` (string, required) β€” Range end date. - `withTotal` (string) β€” Include totals (defaults true). - `withChart` (string) β€” Include chart series (set true). - `filter` (string) β€” Chart amount/count filter. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response β€” verified live; `data` is the real shape. - `success` (boolean) - `status_code` (integer) - `data` (any[]) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/vat/chart" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # List content report reasons (/docs/of-api/misc/list-content-report-reasons) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/reports/reasons` Returns the list of available reasons for reporting content or users. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. βœ“ **Verified live** against a real OnlyFans account (2026-07-30); the `data` schema below is the real response shape. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response β€” verified live; `data` is the real shape. - `success` (boolean) - `status_code` (integer) - `data` (object[]) - `id` (integer) - `name` (string) - `code` (string) - `requiresIssue` (boolean) - `subReasons` (object[]) - `involves` (any[]) - `issues` (object) - `revenge_porn` (string) - `expose` (string) - `impersonation` (string) - `underage` (string) - `tm` (string) - `spam` (string) - `prostitution` (string) - `weapons` (string) - `drugs` (string) - `other` (string) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/reports/reasons" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # List referrals (/docs/of-api/misc/list-referrals) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/me/referrals` Returns the current user's referrals over a date range with pagination. The dynamic path segment is a built querystring. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. βœ“ **Verified live** against a real OnlyFans account (2026-07-30); the `data` schema below is the real response shape. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Query parameters - `startDate` (string) β€” Start of the date range. - `endDate` (string) β€” End of the date range. - `offset` (string) β€” Pagination offset. - `marker` (string) β€” Pagination marker. - `onlyPerformers` (string) β€” Only referred performers/creators. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response β€” verified live; `data` is the real shape. - `success` (boolean) - `status_code` (integer) - `data` (object) - `hasMore` (boolean) - `list` (any[]) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/me/referrals" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # List states for a country (/docs/of-api/misc/list-states-for-a-country) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/countries/{country_id}/states` Returns the list of states/regions for the specified country. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `country_id` (string, required) β€” Id of the country whose states are requested. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/countries/{country_id}/states" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # List states for country (/docs/of-api/misc/list-states-for-country) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/iso/countries/{country_id}/states` Returns the ISO list of states/regions for a given country. Reference/lookup data. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `country_id` (string, required) β€” ID of the country. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/iso/countries/{country_id}/states" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Mark support ticket as read (/docs/of-api/misc/mark-support-ticket-as-read) `PUT https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/tickets/{ticket_id}/read` Marks the given support ticket as read. Part of the users/tickets support module (reply, solve, reopen, comments). **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `ticket_id` (string, required) β€” ID of the support ticket. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X PUT "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/tickets/{ticket_id}/read" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Mark support ticket solved (/docs/of-api/misc/mark-support-ticket-solved) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/tickets/{ticket_id}/solve` Marks a user support ticket as solved. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `ticket_id` (string, required) β€” ID of the support ticket. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/tickets/{ticket_id}/solve" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Record address statistics (/docs/of-api/misc/record-address-statistics) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/address/stat` Posts address-related statistics data. Appears alongside GDPR, clicks-stats and accepted-cookies analytics calls. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/address/stat" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Rename a release form (/docs/of-api/misc/rename-a-release-form) `PATCH https://theonlyapi.com/api/crm/your-crm-id/api2/v2/release-forms/rename` Renames a content release form. Part of the release-forms module (attach, links, documents, toggle-show). **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X PATCH "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/release-forms/rename" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Reopen a support ticket (/docs/of-api/misc/reopen-a-support-ticket) `PUT https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/tickets/{ticket_id}/reopen` Reopens a previously closed support ticket identified by ticket_id. Body carries the reopen data. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `ticket_id` (string, required) β€” ID of the support ticket to reopen. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X PUT "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/tickets/{ticket_id}/reopen" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Reply to support ticket (/docs/of-api/misc/reply-to-support-ticket) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/tickets/{ticket_id}/reply` Posts a reply to the specified support ticket. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `ticket_id` (string, required) β€” ID of the support ticket. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/tickets/{ticket_id}/reply" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Report user click statistics (/docs/of-api/misc/report-user-click-statistics) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/clicks-stats` Sends a batch of user click/interaction statistics for tracking. The response is fire-and-forget (errors are swallowed via .catch). **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/clicks-stats" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Search localization texts (/docs/of-api/misc/search-localization-texts) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/texts/search` Searches localization strings by code and languages. Part of the i18n text system (texts.onlyfans.com). **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` - `code` (string) β€” Text/translation key to search. - `languages` (any[]) β€” Languages to search within. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/texts/search" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Send legal inquiry notification (/docs/of-api/misc/send-legal-inquiry-notification) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/legal-inquiry/send-notification/{inquiry_id}` Sends a notification for the specified legal inquiry. No request body is sent. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `inquiry_id` (string, required) β€” ID of the legal inquiry. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/legal-inquiry/send-notification/{inquiry_id}" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Start release form link (/docs/of-api/misc/start-release-form-link) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/release-form-links/{link_id}/start` Starts the flow for a release-form (consent) link identified by its id. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `link_id` (string, required) β€” ID of the release-form link. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/release-form-links/{link_id}/start" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Submit a legal inquiry (/docs/of-api/misc/submit-a-legal-inquiry) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/legal-inquiry` Creates/submits a new legal inquiry (takedown/legal request). **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/legal-inquiry" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Submit client-side log entry (/docs/of-api/misc/submit-client-side-log-entry) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/log` Sends a client log message with optional context data, logger name and level to the server-side logging endpoint. The context is wrapped with an `onlyfans.` logger name and a timestamp. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` - `message` (string) β€” Log message text. - `context` (object) β€” Arbitrary log data merged with logger name and timestamp. - `level` (string) β€” Log level, e.g. debug/info/error. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/log" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Submit consent form (/docs/of-api/misc/submit-consent-form) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/consent-form` Submits/creates a consent form. Grouped with release-form and release-form-proof endpoints for content compliance. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/consent-form" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Submit contact form (/docs/of-api/misc/submit-contact-form) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/pages/contacts` Submits the contact page form data. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/pages/contacts" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Submit legal inquiry by counsel (/docs/of-api/misc/submit-legal-inquiry-by-counsel) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/legal-inquiry/by-counsel` Submits a legal inquiry on behalf of legal counsel. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/legal-inquiry/by-counsel" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Submit legal inquiry response (/docs/of-api/misc/submit-legal-inquiry-response) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/legal-inquiry/{inquiry_id}` Submits data/response for a specific legal inquiry. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `inquiry_id` (string, required) β€” ID of the legal inquiry. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/legal-inquiry/{inquiry_id}" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Submit license form (/docs/of-api/misc/submit-license-form) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/license_form` Submits a license form for the current user (identity/creator license documentation). **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/license_form" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Submit release form proof (/docs/of-api/misc/submit-release-form-proof) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/release-form-proof` Submits proof for a content release form (consent documentation). **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/release-form-proof" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Toggle release form visibility (/docs/of-api/misc/toggle-release-form-visibility) `PATCH https://theonlyapi.com/api/crm/your-crm-id/api2/v2/release-forms/toggle-show` Toggles the show/visibility state of release forms. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X PATCH "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/release-forms/toggle-show" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Update a legal inquiry (/docs/of-api/misc/update-a-legal-inquiry) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/legal-inquiry/{inquiry_id}/update/{hash}` Submits an update to a legal inquiry identified by its ID and hash. Part of the legal-inquiry module (search, history, change-status). **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `inquiry_id` (string, required) β€” ID of the legal inquiry. - `hash` (string, required) β€” Update hash/token authorizing the update. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/legal-inquiry/{inquiry_id}/update/{hash}" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Update a localization text (/docs/of-api/misc/update-a-localization-text) `PUT https://theonlyapi.com/api/crm/your-crm-id/api2/v2/texts/{code}` Updates the localized text string for a given text code. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `code` (string, required) β€” Localization/text string code. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` - `text` (string) β€” New text content for the code. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X PUT "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/texts/{code}" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Upload release form document (/docs/of-api/misc/upload-release-form-document) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/release-form-documents` Uploads a release-form document (co-performer consent / model release). **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/release-form-documents" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Notifications (/docs/of-api/notifications) {/* Generated by scripts/gen-api.ts β€” edit that script, not this file. */} OnlyFans notification endpoints (via proxy). **OnlyFans only** β€” Fansly accounts are rejected on this surface. | Method | Endpoint | Path | | -------- | ------------------------------------------------------------------------------------------- | ----------------------------------------------------- | | `GET` | [Get user alerts](/docs/of-api/notifications/get-user-alerts) | `/api2/v2/users/alert` | | `DELETE` | [Delete user alert](/docs/of-api/notifications/delete-user-alert) | `/api2/v2/users/alert/{alert_id}` | | `DELETE` | [Dismiss a mass alert](/docs/of-api/notifications/dismiss-a-mass-alert) | `/api2/v2/users/mass-alert/{alert_id}` | | `GET` | [Get notifications](/docs/of-api/notifications/get-notifications-get) | `/api2/v2/users/notifications` | | `POST` | [Mark notification as read](/docs/of-api/notifications/mark-notification-as-read) | `/api2/v2/users/notifications/{notification_id}/read` | | `GET` | [Get unread notification count](/docs/of-api/notifications/get-unread-notification-count) | `/api2/v2/users/notifications/count` | | `POST` | [Mark all notifications as read](/docs/of-api/notifications/mark-all-notifications-as-read) | `/api2/v2/users/notifications/read` | | `GET` | [Get notification tabs order](/docs/of-api/notifications/get-notification-tabs-order) | `/api2/v2/users/notifications/settings/tabs-order` | | `POST` | [Save notification tabs order](/docs/of-api/notifications/save-notification-tabs-order) | `/api2/v2/users/notifications/settings/tabs-order` | | `PUT` | [Register PWA push token](/docs/of-api/notifications/register-pwa-push-token) | `/api2/v2/users/push-token/pwa` | --- # Delete user alert (/docs/of-api/notifications/delete-user-alert) `DELETE https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/alert/{alert_id}` Deletes a user alert by id. Related to users/mass-alert endpoints (creator alert broadcasts). **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `alert_id` (string, required) β€” ID of the alert to delete. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/alert/{alert_id}" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Dismiss a mass alert (/docs/of-api/notifications/dismiss-a-mass-alert) `DELETE https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/mass-alert/{alert_id}` Dismisses/deletes a mass alert notification identified by alert id. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `alert_id` (string, required) β€” ID of the mass alert to dismiss. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/mass-alert/{alert_id}" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get notification tabs order (/docs/of-api/notifications/get-notification-tabs-order) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/notifications/settings/tabs-order` Returns the user's configured ordering of notification tabs. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. βœ“ **Verified live** against a real OnlyFans account (2026-07-30); the `data` schema below is the real response shape. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response β€” verified live; `data` is the real shape. - `success` (boolean) - `status_code` (integer) - `data` (string[]) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/notifications/settings/tabs-order" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get notifications (/docs/of-api/notifications/get-notifications-get) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/notifications` **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Query parameters - `limit` (integer) β€” Default `20`. - `skip_users` (string) β€” Default `all`. - `format` (string) β€” Default `infinite`. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Notification list - `list` (object[]) - `hasMore` (boolean) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/notifications" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get unread notification count (/docs/of-api/notifications/get-unread-notification-count) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/notifications/count` **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Unread count - `count` (integer) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/notifications/count" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get user alerts (/docs/of-api/notifications/get-user-alerts) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/alert` Returns the current user's alert(s) banner data. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. βœ“ **Verified live** against a real OnlyFans account (2026-07-30); the `data` schema below is the real response shape. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response β€” verified live; `data` is the real shape. - `success` (boolean) - `status_code` (integer) - `data` (any[]) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/alert" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Mark all notifications as read (/docs/of-api/notifications/mark-all-notifications-as-read) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/notifications/read` **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Marked as read ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/notifications/read" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Mark notification as read (/docs/of-api/notifications/mark-notification-as-read) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/notifications/{notification_id}/read` Marks a single notification as read by its id. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `notification_id` (string, required) β€” Id of the notification to mark read. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/notifications/{notification_id}/read" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Register PWA push token (/docs/of-api/notifications/register-pwa-push-token) `PUT https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/push-token/pwa` Registers or updates the web-push (PWA) push notification token for the current user. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X PUT "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/push-token/pwa" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Save notification tabs order (/docs/of-api/notifications/save-notification-tabs-order) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/notifications/settings/tabs-order` Saves the ordering of the notification settings tabs. A GET on the same path retrieves the current order. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/notifications/settings/tabs-order" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Payouts (/docs/of-api/payouts) {/* Generated by scripts/gen-api.ts β€” edit that script, not this file. */} OnlyFans payout & payment endpoints (via proxy). **OnlyFans only** β€” Fansly accounts are rejected on this surface. | Method | Endpoint | Path | | -------- | ----------------------------------------------------------------------------------------------------- | ------------------------------------------------- | | `POST` | [Save address](/docs/of-api/payouts/save-address) | `/api2/v2/address` | | `GET` | [List alternative payment methods](/docs/of-api/payouts/list-alternative-payment-methods) | `/api2/v2/alternative-payment-methods` | | `DELETE` | [Delete alternative payment method](/docs/of-api/payouts/delete-alternative-payment-method) | `/api2/v2/alternative-payment-methods` | | `POST` | [Submit alternative payment method form](/docs/of-api/payouts/submit-alternative-payment-method-form) | `/api2/v2/alternative-payment-methods/form` | | `POST` | [Pay via alternative method](/docs/of-api/payouts/pay-via-alternative-method) | `/api2/v2/alternative-payment-methods/pay` | | `GET` | [Get PayPal payment method info](/docs/of-api/payouts/get-paypal-payment-method-info) | `/api2/v2/alternative-payment-methods/paypal` | | `GET` | [List payout-supported countries](/docs/of-api/payouts/list-payout-supported-countries) | `/api2/v2/countries/payouts` | | `GET` | [Get earnings chart](/docs/of-api/payouts/get-earnings-chart) | `/api2/v2/earnings/chart` | | `GET` | [Check if any transactions exist](/docs/of-api/payouts/check-if-any-transactions-exist) | `/api2/v2/payments/all/has-transactions` | | `GET` | [Get all payment transactions](/docs/of-api/payouts/get-all-payment-transactions) | `/api2/v2/payments/all/transactions` | | `GET` | [List saved payment cards](/docs/of-api/payouts/list-saved-payment-cards) | `/api2/v2/payments/cards` | | `PUT` | [Update a saved payment card](/docs/of-api/payouts/update-a-saved-payment-card) | `/api2/v2/payments/cards/{card_id}` | | `DELETE` | [Delete a payment card](/docs/of-api/payouts/delete-a-payment-card) | `/api2/v2/payments/cards/{card_id}` | | `PUT` | [Set default payment card](/docs/of-api/payouts/set-default-payment-card) | `/api2/v2/payments/cards/{card_id}/default` | | `POST` | [Verify a saved card](/docs/of-api/payouts/verify-a-saved-card) | `/api2/v2/payments/cards/{card_id}/verify` | | `POST` | [Submit a payment](/docs/of-api/payouts/submit-a-payment) | `/api2/v2/payments/pay` | | `GET` | [Get referral earnings balance](/docs/of-api/payouts/get-referral-earnings-balance) | `/api2/v2/payments/referrals/balance` | | `GET` | [Get payout account info](/docs/of-api/payouts/get-payout-account-info) | `/api2/v2/payouts/account` | | `GET` | [Get payout balances](/docs/of-api/payouts/get-payout-balances) | `/api2/v2/payouts/balances` | | `POST` | [Add payout bank account](/docs/of-api/payouts/add-payout-bank-account) | `/api2/v2/payouts/bank` | | `PATCH` | [Update bank payout details](/docs/of-api/payouts/update-bank-payout-details) | `/api2/v2/payouts/bank` | | `DELETE` | [Delete bank payout method](/docs/of-api/payouts/delete-bank-payout-method) | `/api2/v2/payouts/bank` | | `GET` | [Check if VAT documents allowed](/docs/of-api/payouts/check-if-vat-documents-allowed) | `/api2/v2/payouts/can-add-vat-documents` | | `GET` | [List chargebacks / disputes](/docs/of-api/payouts/list-chargebacks-disputes) | `/api2/v2/payouts/chargebacks` | | `GET` | [Get chargebacks chart data](/docs/of-api/payouts/get-chargebacks-chart-data) | `/api2/v2/payouts/chargebacks/chart` | | `GET` | [Get chargeback ratio](/docs/of-api/payouts/get-chargeback-ratio) | `/api2/v2/payouts/chargebacks/ratio` | | `GET` | [Check payout receive eligibility](/docs/of-api/payouts/check-payout-receive-eligibility) | `/api2/v2/payouts/check-receive` | | `GET` | [Get DAC7 tax info](/docs/of-api/payouts/get-dac7-tax-info) | `/api2/v2/payouts/dac7` | | `POST` | [Submit DAC7 tax information](/docs/of-api/payouts/submit-dac7-tax-information) | `/api2/v2/payouts/dac7` | | `GET` | [Download VAT document](/docs/of-api/payouts/download-vat-document) | `/api2/v2/payouts/download/vat/{vat_document_id}` | | `POST` | [Submit payout legal information](/docs/of-api/payouts/submit-payout-legal-information) | `/api2/v2/payouts/legal` | | `GET` | [Get payout legal form](/docs/of-api/payouts/get-payout-legal-form) | `/api2/v2/payouts/legal-form` | | `GET` | [Get payout legal info](/docs/of-api/payouts/get-payout-legal-info) | `/api2/v2/payouts/legal-info` | | `POST` | [Submit Instagram legal verification](/docs/of-api/payouts/submit-instagram-legal-verification) | `/api2/v2/payouts/legal/instagram` | | `POST` | [Submit Twitter legal info](/docs/of-api/payouts/submit-twitter-legal-info) | `/api2/v2/payouts/legal/twitter` | | `POST` | [Submit QST tax information](/docs/of-api/payouts/submit-qst-tax-information) | `/api2/v2/payouts/qst` | | `GET` | [Get referrals chart data](/docs/of-api/payouts/get-referrals-chart-data) | `/api2/v2/payouts/referrals/chart` | | `GET` | [List payout requests](/docs/of-api/payouts/list-payout-requests) | `/api2/v2/payouts/requests` | | `POST` | [Create payout request](/docs/of-api/payouts/create-payout-request-post) | `/api2/v2/payouts/requests` | | `GET` | [List referral payout requests](/docs/of-api/payouts/list-referral-payout-requests-get) | `/api2/v2/payouts/requests/referral` | | `GET` | [List Stripe payout requests](/docs/of-api/payouts/list-stripe-payout-requests) | `/api2/v2/payouts/requests/stripe` | | `GET` | [Get VAT info for payout request](/docs/of-api/payouts/get-vat-info-for-payout-request) | `/api2/v2/payouts/requests/vat/{request_id}` | | `GET` | [Get Stripe payout info](/docs/of-api/payouts/get-stripe-payout-info) | `/api2/v2/payouts/stripe` | | `POST` | [Create or update Stripe payout account](/docs/of-api/payouts/create-or-update-stripe-payout-account) | `/api2/v2/payouts/stripe/account` | | `GET` | [Get Stripe payout legal info](/docs/of-api/payouts/get-stripe-payout-legal-info) | `/api2/v2/payouts/stripe/legal` | | `POST` | [Submit Stripe payout legal info](/docs/of-api/payouts/submit-stripe-payout-legal-info) | `/api2/v2/payouts/stripe/legal` | | `POST` | [Submit payout tax info](/docs/of-api/payouts/submit-payout-tax-info) | `/api2/v2/payouts/tax` | | `POST` | [Submit taxpayer identification number](/docs/of-api/payouts/submit-taxpayer-identification-number) | `/api2/v2/payouts/tin` | | `GET` | [Get payout transactions](/docs/of-api/payouts/get-payout-transactions) | `/api2/v2/payouts/transactions` | | `GET` | [Get UK company payout data](/docs/of-api/payouts/get-uk-company-payout-data) | `/api2/v2/payouts/uk-company-data` | | `POST` | [Submit UK company payout data](/docs/of-api/payouts/submit-uk-company-payout-data) | `/api2/v2/payouts/uk-company-data` | | `GET` | [Get payout VAT info](/docs/of-api/payouts/get-payout-vat-info) | `/api2/v2/payouts/vat` | | `POST` | [Submit VAT number](/docs/of-api/payouts/submit-vat-number) | `/api2/v2/payouts/vat` | | `DELETE` | [Delete VAT number](/docs/of-api/payouts/delete-vat-number) | `/api2/v2/payouts/vat` | | `POST` | [Create a VAT request](/docs/of-api/payouts/create-a-vat-request) | `/api2/v2/payouts/vat-requests` | | `GET` | [List payout VAT records](/docs/of-api/payouts/list-payout-vat-records) | `/api2/v2/payouts/vats` | | `POST` | [Submit W-9 tax form](/docs/of-api/payouts/submit-w-9-tax-form) | `/api2/v2/payouts/w9` | | `POST` | [Submit W-9 address](/docs/of-api/payouts/submit-w-9-address) | `/api2/v2/payouts/w9/address` | | `POST` | [Verify W9 TIN](/docs/of-api/payouts/verify-w9-tin) | `/api2/v2/payouts/w9/tincheck` | --- # Add payout bank account (/docs/of-api/payouts/add-payout-bank-account) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/bank` Creates/saves a bank account for payouts. GET on the same path retrieves the current bank details. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/bank" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Check if any transactions exist (/docs/of-api/payouts/check-if-any-transactions-exist) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payments/all/has-transactions` Returns whether the account has any payment transactions across all payment sources. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. βœ“ **Verified live** against a real OnlyFans account (2026-07-30); the `data` schema below is the real response shape. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response β€” verified live; `data` is the real shape. - `success` (boolean) - `status_code` (integer) - `data` (object) - `hasTransactions` (boolean) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payments/all/has-transactions" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Check if VAT documents allowed (/docs/of-api/payouts/check-if-vat-documents-allowed) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/can-add-vat-documents` Returns whether the creator is currently allowed to add VAT documents to their payouts. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. βœ“ **Verified live** against a real OnlyFans account (2026-07-30); the `data` schema below is the real response shape. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response β€” verified live; `data` is the real shape. - `success` (boolean) - `status_code` (integer) - `data` (object) - `success` (boolean) - `errorMessage` (string) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/can-add-vat-documents" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Check payout receive eligibility (/docs/of-api/payouts/check-payout-receive-eligibility) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/check-receive` Checks whether the creator is able to receive payouts. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. βœ“ **Verified live** against a real OnlyFans account (2026-07-30); the `data` schema below is the real response shape. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response β€” verified live; `data` is the real shape. - `success` (boolean) - `status_code` (integer) - `data` (object) - `isVerifiedReason` (boolean) - `canReceiveManualPayout` (boolean) - `needUpdateBanking` (boolean) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/check-receive" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Create a VAT request (/docs/of-api/payouts/create-a-vat-request) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/vat-requests` Creates a VAT (value-added tax) request for payouts. Part of the payouts tax module (vat, qst, tax, dac7). **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/vat-requests" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Create or update Stripe payout account (/docs/of-api/payouts/create-or-update-stripe-payout-account) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/stripe/account` Submits Stripe connected-account details used for creator payouts. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/stripe/account" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Create payout request (/docs/of-api/payouts/create-payout-request-post) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/requests` **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` - `withdrawalAmount` (number) β€” e.g. `100`. ## Responses ### 200 β€” Payout requested ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/requests" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{"withdrawalAmount":100}' ``` --- # Delete a payment card (/docs/of-api/payouts/delete-a-payment-card) `DELETE https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payments/cards/{card_id}` Removes a saved payment card from the user's account. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `card_id` (string, required) β€” ID of the saved payment card to delete. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payments/cards/{card_id}" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Delete alternative payment method (/docs/of-api/payouts/delete-alternative-payment-method) `DELETE https://theonlyapi.com/api/crm/your-crm-id/api2/v2/alternative-payment-methods` Removes a saved alternative payment method, identified by id in the request body. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/alternative-payment-methods" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Delete bank payout method (/docs/of-api/payouts/delete-bank-payout-method) `DELETE https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/bank` Removes the creator's configured bank account used for payouts. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/bank" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Delete VAT number (/docs/of-api/payouts/delete-vat-number) `DELETE https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/vat` Removes the creator's VAT registration number. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/vat" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Download VAT document (/docs/of-api/payouts/download-vat-document) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/download/vat/{vat_document_id}` Downloads a specific VAT document/invoice for payouts by its id. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `vat_document_id` (string, required) β€” ID of the VAT document to download. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/download/vat/{vat_document_id}" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get all payment transactions (/docs/of-api/payouts/get-all-payment-transactions) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payments/all/transactions` **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Query parameters - `limit` (integer) β€” Default `20`. - `offset` (integer) β€” Default `0`. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” All transactions - `list` (object[]) - `hasMore` (boolean) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payments/all/transactions" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get chargeback ratio (/docs/of-api/payouts/get-chargeback-ratio) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/chargebacks/ratio` Returns the chargeback-to-transaction ratio for the given date range. **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Query parameters - `startDate` (string) - `endDate` (string) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Chargeback ratio - `chargebacksRatio` (number) β€” Ratio of chargebacks (0–1). ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/chargebacks/ratio" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get chargebacks chart data (/docs/of-api/payouts/get-chargebacks-chart-data) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/chargebacks/chart` Time-series chart data for chargebacks with totals and delta. **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Query parameters - `startDate` (string) - `endDate` (string) - `withTotal` (boolean) β€” Default `true`. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Chargebacks chart - `total` (number) β€” Total chargeback amount for the period. - `delta` (number) β€” Change vs previous period. - `chartAmount` (number[]) β€” Amount per time bucket. - `chartCount` (number[]) β€” Count per time bucket. ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/chargebacks/chart" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get DAC7 tax info (/docs/of-api/payouts/get-dac7-tax-info) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/dac7` Retrieves the creator's stored DAC7 (EU platform reporting) tax information for payouts. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. βœ“ **Verified live** against a real OnlyFans account (2026-07-30); the `data` schema below is the real response shape. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response β€” verified live; `data` is the real shape. - `success` (boolean) - `status_code` (integer) - `data` (object) - `status` (string) - `type` (string) - `firstName` (string) - `lastName` (string) - `address` (string) - `city` (string) - `state` (string) - `zip` (string) - `countryId` (integer) - `taxId` (string) - `issuingCountryId` (integer) - `vatNumber` (string) - `DOB` (string) - `cityOfBirth` (string) - `countryOfBirthId` (integer) - `countryOfResidenceId` (integer) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/dac7" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get earnings chart (/docs/of-api/payouts/get-earnings-chart) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/earnings/chart` **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Query parameters - `startDate` (string, required) - `endDate` (string) - `withTotal` (string) β€” Default `true`. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Earnings chart data - `total` (object) - `total` (number) β€” Total net earnings. - `gross` (number) β€” Total gross earnings. - `chartAmount` (number[]) β€” Earnings per time bucket. - `chartCount` (number[]) β€” Transaction count per time bucket. ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/earnings/chart" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get payout account info (/docs/of-api/payouts/get-payout-account-info) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/account` Get saved banking/payment method info for payouts. **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Banking info - `type` (string) β€” Payment method type. - `isVerified` (boolean) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/account" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get payout balances (/docs/of-api/payouts/get-payout-balances) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/balances` **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Balance data - `current` (number) β€” Current available balance. - `pending` (number) β€” Pending balance. - `total` (number) β€” Total lifetime earnings. ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/balances" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get payout legal form (/docs/of-api/payouts/get-payout-legal-form) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/legal-form` Retrieves the legal form data required for payouts (tax/identity legal form). **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. βœ“ **Verified live** against a real OnlyFans account (2026-07-30); the `data` schema below is the real response shape. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response β€” verified live; `data` is the real shape. - `success` (boolean) - `status_code` (integer) - `data` (object) - `realFirstName` (string) - `realLastName` (string) - `realBusinessName` (string) - `realAddress` (string) - `realCity` (string) - `realState` (string) - `realPostal` (string) - `realTwitter` (null) - `realInstagram` (string) - `privateWebsite` (null) - `dateOfBirth` (string) - `documentType` (object) - `values` (object[]) - `isAllowedDL` (boolean) - `isAllowedCustomW9Address` (boolean) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/legal-form" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get payout legal info (/docs/of-api/payouts/get-payout-legal-info) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/legal-info` Retrieves the creator's payout legal information. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. βœ“ **Verified live** against a real OnlyFans account (2026-07-30); the `data` schema below is the real response shape. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response β€” verified live; `data` is the real shape. - `success` (boolean) - `status_code` (integer) - `data` (object) - `isXXX` (boolean) - `isW9Required` (boolean) - `isW9Exist` (boolean) - `isRealIdImage` (boolean) - `canChangePayoutType` (boolean) - `ivStatus` (string) - `ivFailReason` (null) - `showIvButton` (boolean) - `canShowLegalForm` (boolean) - `payoutLegalApproveRejectReason` (null) - `hideBanking` (boolean) - `isCompany` (boolean) - `DAC7` (object) - `required` (boolean) - `type` (string) - `state` (string) - `error` (null) - `countryIds` (integer[]) - `DPR` (string[]) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/legal-info" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get payout transactions (/docs/of-api/payouts/get-payout-transactions) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/transactions` **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Query parameters - `startDate` (string) - `limit` (integer) β€” Default `50`. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Transaction list - `list` (object[]) - `hasMore` (boolean) - `marker` (string) - `nextMarker` (string) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/transactions" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get payout VAT info (/docs/of-api/payouts/get-payout-vat-info) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/vat` Retrieves the user's VAT information used for payouts (POST on the same path submits the VAT number). **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. βœ“ **Verified live** against a real OnlyFans account (2026-07-30); the `data` schema below is the real response shape. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response β€” verified live; `data` is the real shape. - `success` (boolean) - `status_code` (integer) - `data` (object) - `realFirstName` (string) - `realLastName` (string) - `creatorCompanyAddress` (null) - `creatorCompanyName` (null) - `creatorVatNumber` (string) - `creatorCountry` (null) - `creatorCountryCode` (null) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/vat" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get PayPal payment method info (/docs/of-api/payouts/get-paypal-payment-method-info) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/alternative-payment-methods/paypal` Returns the current PayPal alternative payment method configuration/status for the user. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. βœ“ **Verified live** against a real OnlyFans account (2026-07-30); the `data` schema below is the real response shape. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response β€” verified live; `data` is the real shape. - `success` (boolean) - `status_code` (integer) - `data` (object) - `paypalStatus` (any[]) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/alternative-payment-methods/paypal" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get referral earnings balance (/docs/of-api/payouts/get-referral-earnings-balance) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payments/referrals/balance` **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Referral balance - `balance` (number) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payments/referrals/balance" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get referrals chart data (/docs/of-api/payouts/get-referrals-chart-data) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/referrals/chart` Time-series chart data for referral earnings with totals and delta. **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Query parameters - `startDate` (string) - `endDate` (string) - `withTotal` (integer) β€” Default `1`. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Referrals chart - `total` (number) β€” Total referral earnings for the period. - `delta` (number) β€” Change vs previous period. - `chartAmount` (number[]) β€” Earnings per time bucket. - `chartCount` (number[]) β€” Referral count per time bucket. ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/referrals/chart" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get Stripe payout info (/docs/of-api/payouts/get-stripe-payout-info) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/stripe` Retrieves the creator's Stripe payout account information. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/stripe" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get Stripe payout legal info (/docs/of-api/payouts/get-stripe-payout-legal-info) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/stripe/legal` Retrieves the Stripe payout legal/agreement information for the creator. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/stripe/legal" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get UK company payout data (/docs/of-api/payouts/get-uk-company-payout-data) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/uk-company-data` Returns the creator's stored UK company details used for payouts/tax. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/uk-company-data" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get VAT info for payout request (/docs/of-api/payouts/get-vat-info-for-payout-request) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/requests/vat/{request_id}` Returns VAT details associated with a specific payout request. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `request_id` (string, required) β€” Id of the payout/VAT request. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/requests/vat/{request_id}" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # List alternative payment methods (/docs/of-api/payouts/list-alternative-payment-methods) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/alternative-payment-methods` Returns the available alternative (non-card) payment methods for the user. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. βœ“ **Verified live** against a real OnlyFans account (2026-07-30); the `data` schema below is the real response shape. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response β€” verified live; `data` is the real shape. - `success` (boolean) - `status_code` (integer) - `data` (any[]) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/alternative-payment-methods" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # List chargebacks / disputes (/docs/of-api/payouts/list-chargebacks-disputes) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/chargebacks` Paginated list of chargeback transactions. Uses marker-based pagination. **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Query parameters - `limit` (integer) β€” Default `10`. - `startDate` (string) β€” Filter start date. - `endDate` (string) β€” Filter end date. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Chargeback list - `list` (object[]) - `marker` (number) β€” Pagination marker (unix timestamp). - `hasMore` (boolean) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/chargebacks" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # List payout requests (/docs/of-api/payouts/list-payout-requests) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/requests` **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Payout request history - `list` (object[]) - `state` (string) β€” e.g. 'new', 'completed', 'rejected'. - `rejectReason` (string) - `amount` (number) - `createdAt` (string) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/requests" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # List payout-supported countries (/docs/of-api/payouts/list-payout-supported-countries) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/countries/payouts` Returns the list of countries supported/available for creator payouts. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. βœ“ **Verified live** against a real OnlyFans account (2026-07-30); the `data` schema below is the real response shape. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response β€” verified live; `data` is the real shape. - `success` (boolean) - `status_code` (integer) - `data` (object[]) - `id` (integer) - `code` (string) - `name` (string) - `hasStates` (boolean) - `hasZip` (boolean) - `canPay` (boolean) - `canHasW9Form` (boolean) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/countries/payouts" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # List payout VAT records (/docs/of-api/payouts/list-payout-vat-records) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/vats` Retrieves the list of VAT records associated with the creator's payouts. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. βœ“ **Verified live** against a real OnlyFans account (2026-07-30); the `data` schema below is the real response shape. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response β€” verified live; `data` is the real shape. - `success` (boolean) - `status_code` (integer) - `data` (object) - `list` (any[]) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/vats" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # List referral payout requests (/docs/of-api/payouts/list-referral-payout-requests-get) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/requests/referral` Paginated list of referral payout transactions. Uses marker-based pagination. **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Query parameters - `startDate` (string) - `endDate` (string) - `offset` (integer) β€” Default `0`. - `marker` (number) β€” Pagination marker from previous response. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Referral payout list - `list` (object[]) - `marker` (number) - `hasMore` (boolean) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/requests/referral" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # List saved payment cards (/docs/of-api/payouts/list-saved-payment-cards) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payments/cards` Returns the fan's saved payment cards. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. βœ“ **Verified live** against a real OnlyFans account (2026-07-30); the `data` schema below is the real response shape. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response β€” verified live; `data` is the real shape. - `success` (boolean) - `status_code` (integer) - `data` (any[]) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payments/cards" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # List Stripe payout requests (/docs/of-api/payouts/list-stripe-payout-requests) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/requests/stripe` Returns the creator's Stripe payout requests, paginated by lastPayoutId. The dynamic path segment is actually the querystring. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. βœ“ **Verified live** against a real OnlyFans account (2026-07-30); the `data` schema below is the real response shape. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Query parameters - `limit` (string) β€” Max number of results. - `lastPayoutId` (string) β€” Cursor: return requests after this payout ID. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response β€” verified live; `data` is the real shape. - `success` (boolean) - `status_code` (integer) - `data` (object) - `list` (any[]) - `marker` (integer) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/requests/stripe" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Pay via alternative method (/docs/of-api/payouts/pay-via-alternative-method) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/alternative-payment-methods/pay` Submits a payment through an alternative payment method (e.g. PayPal). Related GET/POST endpoints handle the alternative-payment-methods form and listing. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/alternative-payment-methods/pay" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Save address (/docs/of-api/payouts/save-address) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/address` Submits/saves an address for the user; appears alongside payout/Stripe and country endpoints, suggesting a payout or billing address. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/address" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Set default payment card (/docs/of-api/payouts/set-default-payment-card) `PUT https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payments/cards/{card_id}/default` Marks the specified saved payment card as the account's default card. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `card_id` (string, required) β€” ID of the saved payment card. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X PUT "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payments/cards/{card_id}/default" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Submit a payment (/docs/of-api/payouts/submit-a-payment) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payments/pay` Processes/submits a payment. Part of the payments module alongside 3ds-js and cards endpoints. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payments/pay" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Submit alternative payment method form (/docs/of-api/payouts/submit-alternative-payment-method-form) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/alternative-payment-methods/form` Submits the form for an alternative payment method. A GET on the same path retrieves the form definition. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/alternative-payment-methods/form" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Submit DAC7 tax information (/docs/of-api/payouts/submit-dac7-tax-information) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/dac7` Submits the creator's DAC7 (EU tax reporting) information. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/dac7" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Submit Instagram legal verification (/docs/of-api/payouts/submit-instagram-legal-verification) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/legal/instagram` Submits legal/identity verification information via an Instagram account for payouts. Sibling of payouts/legal and payouts/legal/twitter. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/legal/instagram" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Submit payout legal information (/docs/of-api/payouts/submit-payout-legal-information) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/legal` Submits the creator's legal/identity information required for payouts. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/legal" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Submit payout tax info (/docs/of-api/payouts/submit-payout-tax-info) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/tax` Submits creator tax information for the payouts flow. Body is passed as the payload property. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/tax" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Submit QST tax information (/docs/of-api/payouts/submit-qst-tax-information) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/qst` Submits the creator's QST (Quebec sales tax) information. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/qst" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Submit Stripe payout legal info (/docs/of-api/payouts/submit-stripe-payout-legal-info) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/stripe/legal` Submits legal information for a Stripe-based payout account. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/stripe/legal" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Submit taxpayer identification number (/docs/of-api/payouts/submit-taxpayer-identification-number) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/tin` Submits the creator's taxpayer identification number (TIN) for payout tax compliance. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` - `tin` (string) β€” Taxpayer identification number. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/tin" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Submit Twitter legal info (/docs/of-api/payouts/submit-twitter-legal-info) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/legal/twitter` Submits Twitter/X account legal verification information for the payouts legal flow. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/legal/twitter" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Submit UK company payout data (/docs/of-api/payouts/submit-uk-company-payout-data) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/uk-company-data` Submits UK company data (for company/business payout accounts) as part of payout onboarding. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/uk-company-data" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Submit VAT number (/docs/of-api/payouts/submit-vat-number) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/vat` Submits the creator's VAT registration number. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` - `vat` (string) β€” VAT registration number. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/vat" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Submit W-9 address (/docs/of-api/payouts/submit-w-9-address) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/w9/address` Submits the address associated with the creator's W-9 tax form. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/w9/address" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Submit W-9 tax form (/docs/of-api/payouts/submit-w-9-tax-form) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/w9` Submits the creator's IRS W-9 tax form data for payouts. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/w9" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Update a saved payment card (/docs/of-api/payouts/update-a-saved-payment-card) `PUT https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payments/cards/{card_id}` Updates the details of a saved payment card identified by card_id. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `card_id` (string, required) β€” Id of the saved payment card to update. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X PUT "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payments/cards/{card_id}" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Update bank payout details (/docs/of-api/payouts/update-bank-payout-details) `PATCH https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/bank` Partially updates the creator's bank account details used for payouts. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X PATCH "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/bank" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Verify a saved card (/docs/of-api/payouts/verify-a-saved-card) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payments/cards/{card_id}/verify` Verifies a stored payment card identified by card id, optionally with verification data. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `card_id` (string, required) β€” ID of the saved payment card. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payments/cards/{card_id}/verify" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Verify W9 TIN (/docs/of-api/payouts/verify-w9-tin) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/w9/tincheck` Runs a TIN (taxpayer ID) verification check for W9 payout tax information. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/payouts/w9/tincheck" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Promotions (/docs/of-api/promotions) {/* Generated by scripts/gen-api.ts β€” edit that script, not this file. */} OnlyFans promotions & trials (via proxy). **OnlyFans only** β€” Fansly accounts are rejected on this surface. | Method | Endpoint | Path | | -------- | -------------------------------------------------------------------------------------- | ------------------------------------------- | | `DELETE` | [Delete campaign](/docs/of-api/promotions/delete-campaign) | `/api2/v2/campaigns/{campaign_id}` | | `POST` | [Transition a campaign state](/docs/of-api/promotions/transition-a-campaign-state) | `/api2/v2/campaigns/transition` | | `GET` | [Get promotions](/docs/of-api/promotions/get-promotions) | `/api2/v2/promotions` | | `DELETE` | [Delete promotion](/docs/of-api/promotions/delete-promotion) | `/api2/v2/promotions/{promotion_id}` | | `POST` | [Finish a promotion](/docs/of-api/promotions/finish-a-promotion) | `/api2/v2/promotions/{promotion_id}/finish` | | `POST` | [Claim a promotion by code](/docs/of-api/promotions/claim-a-promotion-by-code) | `/api2/v2/promotions/claim` | | `POST` | [Send promotion invite](/docs/of-api/promotions/send-promotion-invite) | `/api2/v2/promotions/invite` | | `GET` | [Get promotion offer by ID](/docs/of-api/promotions/get-promotion-offer-by-id) | `/api2/v2/promotions/offer/{offer_id}` | | `DELETE` | [Delete a promotion offer](/docs/of-api/promotions/delete-a-promotion-offer) | `/api2/v2/promotions/offer/{offer_id}` | | `GET` | [Get active promotional offers](/docs/of-api/promotions/get-active-promotional-offers) | `/api2/v2/promotions/offers` | | `POST` | [Hide promotion offers](/docs/of-api/promotions/hide-promotion-offers) | `/api2/v2/promotions/offers/hide` | | `GET` | [Get free trial links](/docs/of-api/promotions/get-free-trial-links) | `/api2/v2/trials` | | `POST` | [Create a free trial link](/docs/of-api/promotions/create-a-free-trial-link) | `/api2/v2/trials` | | `PUT` | [Update trial link](/docs/of-api/promotions/update-trial-link) | `/api2/v2/trials/{trial_id}` | | `DELETE` | [Delete a trial link](/docs/of-api/promotions/delete-a-trial-link) | `/api2/v2/trials/{trial_id}` | | `POST` | [Check and reserve trial code](/docs/of-api/promotions/check-and-reserve-trial-code) | `/api2/v2/trials/check` | | `POST` | [Claim free trial by code](/docs/of-api/promotions/claim-free-trial-by-code) | `/api2/v2/trials/claim` | | `POST` | [Share trial access](/docs/of-api/promotions/share-trial-access) | `/api2/v2/trials/share-access` | | `DELETE` | [Revoke trial share access](/docs/of-api/promotions/revoke-trial-share-access) | `/api2/v2/trials/share-access` | | `GET` | [Get user promotions](/docs/of-api/promotions/get-user-promotions) | `/api2/v2/users/promotions` | --- # Check and reserve trial code (/docs/of-api/promotions/check-and-reserve-trial-code) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/trials/check` Validates a free-trial link code and reserves it for the current user. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` - `code` (string) β€” Trial link code to validate. - `reserve` (boolean) β€” Reserve the trial (sent as true). ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/trials/check" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Claim a promotion by code (/docs/of-api/promotions/claim-a-promotion-by-code) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/promotions/claim` Claims a promotional offer using a promo code. Sends the code with a strictAuthCheck flag. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` - `code` (string) β€” Promotion code to claim. - `strictAuthCheck` (integer) β€” Auth-check flag, sent as 1. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/promotions/claim" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Claim free trial by code (/docs/of-api/promotions/claim-free-trial-by-code) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/trials/claim` Claims a free-trial subscription offer using a trial code. The code is sent in the request body. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` - `code` (string) β€” Trial/promo code to claim. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/trials/claim" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Create a free trial link (/docs/of-api/promotions/create-a-free-trial-link) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/trials` **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Trial created ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/trials" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Delete a promotion offer (/docs/of-api/promotions/delete-a-promotion-offer) `DELETE https://theonlyapi.com/api/crm/your-crm-id/api2/v2/promotions/offer/{offer_id}` Deletes a single promotion offer identified by offer_id. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `offer_id` (string, required) β€” ID of the promotion offer to delete. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/promotions/offer/{offer_id}" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Delete a trial link (/docs/of-api/promotions/delete-a-trial-link) `DELETE https://theonlyapi.com/api/crm/your-crm-id/api2/v2/trials/{trial_id}` Deletes a free-trial subscription link/campaign identified by trial id. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `trial_id` (string, required) β€” ID of the trial to delete. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/trials/{trial_id}" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Delete campaign (/docs/of-api/promotions/delete-campaign) `DELETE https://theonlyapi.com/api/crm/your-crm-id/api2/v2/campaigns/{campaign_id}` Deletes a promotional campaign by id. Grouped with campaign share-access, claimers and trials endpoints. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `campaign_id` (string, required) β€” ID of the campaign to delete. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/campaigns/{campaign_id}" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Delete promotion (/docs/of-api/promotions/delete-promotion) `DELETE https://theonlyapi.com/api/crm/your-crm-id/api2/v2/promotions/{promotion_id}` Deletes a subscription promotion by its ID. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `promotion_id` (string, required) β€” ID of the promotion to delete. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/promotions/{promotion_id}" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Finish a promotion (/docs/of-api/promotions/finish-a-promotion) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/promotions/{promotion_id}/finish` Ends/finishes an active promotion campaign identified by promotion id. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `promotion_id` (string, required) β€” ID of the promotion to finish. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/promotions/{promotion_id}/finish" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get active promotional offers (/docs/of-api/promotions/get-active-promotional-offers) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/promotions/offers` **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Offers list - `[]` array of: - `id` (integer) - `type` (string) β€” Promotion type, e.g. 'promotion' or 'free_trial'. - `message` (string) - `rawMessage` (string) - `price` (number) β€” Discounted subscription price. - `subscribeDays` (integer) β€” Duration the promo subscription lasts. - `subscribeCounts` (integer) - `claimsCount` (integer) - `canClaim` (boolean) - `hasRelatedPromo` (boolean) - `isFinished` (boolean) - `createdAt` (string) - `finishedAt` (string) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/promotions/offers" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get free trial links (/docs/of-api/promotions/get-free-trial-links) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/trials` **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Query parameters - `limit` (integer) β€” Default `10`. - `offset` (integer) β€” Default `0`. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Trial links - `list` (object[]) - `id` (integer) - `code` (string) β€” Trial link code. - `isFinished` (boolean) - `sharedWith` (object[]) - `hasMore` (boolean) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/trials" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get promotion offer by ID (/docs/of-api/promotions/get-promotion-offer-by-id) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/promotions/offer/{offer_id}` Fetches a single promotion offer by its ID. Sibling calls in the module handle claiming trials/promotions and confirming emails. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `offer_id` (string, required) β€” ID of the promotion offer to retrieve. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/promotions/offer/{offer_id}" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get promotions (/docs/of-api/promotions/get-promotions) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/promotions` **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Query parameters - `limit` (integer) β€” Default `10`. - `offset` (integer) β€” Default `0`. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Promotions list, wrapped in the passthrough envelope NOTE: the array is under `data.items` (NOT `data.list`). OnlyFans ignores `limit` here β€” page with `offset` and watch `hasMore`. - `success` (boolean) - `status_code` (integer) - `data` (object) - `items` (object[]) - `id` (integer) - `type` (string) β€” Promotion type, e.g. 'promotion' or 'free_trial'. - `message` (string) - `rawMessage` (string) - `price` (number) β€” Discounted subscription price. - `subscribeDays` (integer) β€” Duration the promo subscription lasts. - `subscribeCounts` (integer) - `claimsCount` (integer) - `canClaim` (boolean) - `hasRelatedPromo` (boolean) - `isFinished` (boolean) - `createdAt` (string) - `finishedAt` (string) - `hasMore` (boolean) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/promotions" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get user promotions (/docs/of-api/promotions/get-user-promotions) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/promotions` Retrieves promotions available to the current user. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. βœ“ **Verified live** against a real OnlyFans account (2026-07-30); the `data` schema below is the real response shape. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response β€” verified live; `data` is the real shape. - `success` (boolean) - `status_code` (integer) - `data` (object[]) - `imageSrc` (string) - `url` (string) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/promotions" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Hide promotion offers (/docs/of-api/promotions/hide-promotion-offers) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/promotions/offers/hide` Hides the current promotion offers from view. Defined alongside promotions/offers list and delete calls. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/promotions/offers/hide" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Revoke trial share access (/docs/of-api/promotions/revoke-trial-share-access) `DELETE https://theonlyapi.com/api/crm/your-crm-id/api2/v2/trials/share-access` Revokes shared free-trial access. The request carries a body via the delete data option. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/trials/share-access" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Send promotion invite (/docs/of-api/promotions/send-promotion-invite) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/promotions/invite` Sends an invitation for a promotion/promo offer. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/promotions/invite" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Share trial access (/docs/of-api/promotions/share-trial-access) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/trials/share-access` Creates a shared free-trial access grant. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/trials/share-access" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Transition a campaign state (/docs/of-api/promotions/transition-a-campaign-state) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/campaigns/transition` Transitions a promotional campaign to a new state/status. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/campaigns/transition" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Update trial link (/docs/of-api/promotions/update-trial-link) `PUT https://theonlyapi.com/api/crm/your-crm-id/api2/v2/trials/{trial_id}` Updates a trial-subscription link by ID (e.g. finishes/deactivates it). No request body is sent. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `trial_id` (string, required) β€” ID of the trial link. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X PUT "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/trials/{trial_id}" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Stories (/docs/of-api/stories) {/* Generated by scripts/gen-api.ts β€” edit that script, not this file. */} OnlyFans stories (via proxy). **OnlyFans only** β€” Fansly accounts are rejected on this surface. | Method | Endpoint | Path | | -------- | --------------------------------------------------------------------------- | --------------------------------------------- | | `POST` | [Create story](/docs/of-api/stories/create-story) | `/api2/v2/stories` | | `POST` | [Like a story](/docs/of-api/stories/like-a-story) | `/api2/v2/stories/{story_id}/like` | | `DELETE` | [Unlike a story](/docs/of-api/stories/unlike-a-story) | `/api2/v2/stories/{story_id}/like` | | `GET` | [List story viewers](/docs/of-api/stories/list-story-viewers) | `/api2/v2/stories/{story_id}/viewers` | | `PUT` | [Mark story as watched](/docs/of-api/stories/mark-story-as-watched) | `/api2/v2/stories/{story_id}/watched` | | `DELETE` | [Delete a story answer](/docs/of-api/stories/delete-a-story-answer) | `/api2/v2/stories/answer/{answer_id}` | | `GET` | [Get archived stories](/docs/of-api/stories/get-archived-stories) | `/api2/v2/stories/archive` | | `POST` | [Create a story highlight](/docs/of-api/stories/create-a-story-highlight) | `/api2/v2/stories/highlights` | | `POST` | [Block user from stories](/docs/of-api/stories/block-user-from-stories) | `/api2/v2/stories/users/{user_id}/block` | | `DELETE` | [Unblock user from stories](/docs/of-api/stories/unblock-user-from-stories) | `/api2/v2/stories/users/{user_id}/block` | | `GET` | [List story-blocked users](/docs/of-api/stories/list-story-blocked-users) | `/api2/v2/stories/users/blocked` | | `GET` | [Get user's stories](/docs/of-api/stories/get-user-s-stories) | `/api2/v2/users/{user_id}/stories` | | `GET` | [Get story highlights](/docs/of-api/stories/get-story-highlights) | `/api2/v2/users/{user_id}/stories/highlights` | | `GET` | [Get your active stories](/docs/of-api/stories/get-your-active-stories) | `/api2/v2/users/me/stories` | | `POST` | [Create a new story](/docs/of-api/stories/create-a-new-story) | `/api2/v2/users/me/stories` | --- # Block user from stories (/docs/of-api/stories/block-user-from-stories) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/stories/users/{user_id}/block` Blocks the specified user from viewing the creator's stories. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `user_id` (string, required) β€” Id of the user to block from stories. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/stories/users/{user_id}/block" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Create a new story (/docs/of-api/stories/create-a-new-story) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/me/stories` Post a new story. Stories expire after 24 hours. **Attaching media:** `POST /accounts/{of_user_id}/media` (raw bytes or a `source_url` we fetch for you) returns a `media` object β€” pass it through here. Media already in the vault is referenced by its integer ID from `GET /api2/v2/vault/media`. **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` (required) - `media` (integer[]) β€” Array of media IDs from vault upload. At least one required. e.g. `[12345]`. - `question` (string) β€” Optional question text to display on the story (interactive Q&A). e.g. `"What should I post next?"`. ## Responses ### 200 β€” Story created - `id` (integer) - `userId` (integer) - `createdAt` (string) - `expiredAt` (string) - `isReady` (boolean) - `isWatched` (boolean) - `media` (object[]) - `id` (integer) β€” Stable OnlyFans media ID β€” the only persistent identifier for the item. - `type` ("photo" | "video" | "audio" | "gif") - `createdAt` (string) - `duration` (integer) β€” Duration in seconds (video/audio; 0 for photos). - `convertedToVideo` (boolean) - `canView` (boolean) - `isReady` (boolean) β€” False while OnlyFans is still processing/transcoding the upload. - `hasError` (boolean) - `hasPosts` (boolean) β€” Whether the media is attached to any post. - `hasCustomPreview` (boolean) - `counters` (object) β€” Engagement counters (present on the vault view). - `buyersCount` (integer) - `likesCount` (integer) - `tipsSumm` (number) - `listStates` (object[]) β€” Which vault lists (folders) this media belongs to. - `id` (integer) β€” Vault list ID. - `name` (string) β€” Vault list name. - `hasMedia` (boolean) - `canAddMedia` (boolean) - `files` (object) β€” Signed, time-limited CDN URLs at several resolutions. `size` is frequently `0` β€” do not rely on it. - `full` (object) - `preview` (object) - `thumb` (object) - `squarePreview` (object) - `videoSources` (object) β€” Per-resolution video URLs (e.g. `240`, `720`); entries are null when not applicable. - `question` (string) ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/me/stories" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{"media":[12345],"question":"What should I post next?"}' ``` --- # Create a story highlight (/docs/of-api/stories/create-a-story-highlight) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/stories/highlights` Save stories to a permanent highlight collection on your profile. Stories in highlights don't expire. **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` (required) - `title` (string) β€” Highlight title/name. e.g. `"Best Moments ✨"`. - `storyIds` (integer[]) β€” Story IDs to include in the highlight. e.g. `[111,222,333]`. - `cover` (integer) β€” Story ID to use as the highlight cover image. ## Responses ### 200 β€” Highlight created ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/stories/highlights" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{"title":"Best Moments ✨","storyIds":[111,222,333]}' ``` --- # Create story (/docs/of-api/stories/create-story) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/stories` Creates a new story for the current user. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/stories" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Delete a story answer (/docs/of-api/stories/delete-a-story-answer) `DELETE https://theonlyapi.com/api/crm/your-crm-id/api2/v2/stories/answer/{answer_id}` Deletes a viewer's answer/reply to a story (e.g. story question sticker) identified by answer id. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `answer_id` (string, required) β€” ID of the story answer to delete. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/stories/answer/{answer_id}" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get archived stories (/docs/of-api/stories/get-archived-stories) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/stories/archive` **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Archived stories - `[]` array of: - `id` (integer) - `userId` (integer) - `createdAt` (string) - `expiredAt` (string) - `isReady` (boolean) - `isWatched` (boolean) - `media` (object[]) - `id` (integer) β€” Stable OnlyFans media ID β€” the only persistent identifier for the item. - `type` ("photo" | "video" | "audio" | "gif") - `createdAt` (string) - `duration` (integer) β€” Duration in seconds (video/audio; 0 for photos). - `convertedToVideo` (boolean) - `canView` (boolean) - `isReady` (boolean) β€” False while OnlyFans is still processing/transcoding the upload. - `hasError` (boolean) - `hasPosts` (boolean) β€” Whether the media is attached to any post. - `hasCustomPreview` (boolean) - `counters` (object) β€” Engagement counters (present on the vault view). - `buyersCount` (integer) - `likesCount` (integer) - `tipsSumm` (number) - `listStates` (object[]) β€” Which vault lists (folders) this media belongs to. - `id` (integer) β€” Vault list ID. - `name` (string) β€” Vault list name. - `hasMedia` (boolean) - `canAddMedia` (boolean) - `files` (object) β€” Signed, time-limited CDN URLs at several resolutions. `size` is frequently `0` β€” do not rely on it. - `full` (object) - `preview` (object) - `thumb` (object) - `squarePreview` (object) - `videoSources` (object) β€” Per-resolution video URLs (e.g. `240`, `720`); entries are null when not applicable. - `question` (string) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/stories/archive" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get story highlights (/docs/of-api/stories/get-story-highlights) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/{user_id}/stories/highlights` **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `user_id` (string, required) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Highlights list - `[]` array of: - `id` (integer) - `title` (string) - `cover` (string) β€” Cover image URL. - `stories` (object[]) - `id` (integer) - `userId` (integer) - `createdAt` (string) - `expiredAt` (string) - `isReady` (boolean) - `isWatched` (boolean) - `media` (object[]) - `id` (integer) β€” Stable OnlyFans media ID β€” the only persistent identifier for the item. - `type` ("photo" | "video" | "audio" | "gif") - `createdAt` (string) - `duration` (integer) β€” Duration in seconds (video/audio; 0 for photos). - `convertedToVideo` (boolean) - `canView` (boolean) - `isReady` (boolean) β€” False while OnlyFans is still processing/transcoding the upload. - `hasError` (boolean) - `hasPosts` (boolean) β€” Whether the media is attached to any post. - `hasCustomPreview` (boolean) - `counters` (object) β€” Engagement counters (present on the vault view). - `listStates` (object[]) β€” Which vault lists (folders) this media belongs to. - `files` (object) β€” Signed, time-limited CDN URLs at several resolutions. `size` is frequently `0` β€” do not rely on it. - `videoSources` (object) β€” Per-resolution video URLs (e.g. `240`, `720`); entries are null when not applicable. - `question` (string) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/{user_id}/stories/highlights" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get user's stories (/docs/of-api/stories/get-user-s-stories) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/{user_id}/stories` **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `user_id` (string, required) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Story list - `[]` array of: - `id` (integer) - `userId` (integer) - `createdAt` (string) - `expiredAt` (string) - `isReady` (boolean) - `isWatched` (boolean) - `media` (object[]) - `id` (integer) β€” Stable OnlyFans media ID β€” the only persistent identifier for the item. - `type` ("photo" | "video" | "audio" | "gif") - `createdAt` (string) - `duration` (integer) β€” Duration in seconds (video/audio; 0 for photos). - `convertedToVideo` (boolean) - `canView` (boolean) - `isReady` (boolean) β€” False while OnlyFans is still processing/transcoding the upload. - `hasError` (boolean) - `hasPosts` (boolean) β€” Whether the media is attached to any post. - `hasCustomPreview` (boolean) - `counters` (object) β€” Engagement counters (present on the vault view). - `buyersCount` (integer) - `likesCount` (integer) - `tipsSumm` (number) - `listStates` (object[]) β€” Which vault lists (folders) this media belongs to. - `id` (integer) β€” Vault list ID. - `name` (string) β€” Vault list name. - `hasMedia` (boolean) - `canAddMedia` (boolean) - `files` (object) β€” Signed, time-limited CDN URLs at several resolutions. `size` is frequently `0` β€” do not rely on it. - `full` (object) - `preview` (object) - `thumb` (object) - `squarePreview` (object) - `videoSources` (object) β€” Per-resolution video URLs (e.g. `240`, `720`); entries are null when not applicable. - `question` (string) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/{user_id}/stories" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get your active stories (/docs/of-api/stories/get-your-active-stories) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/me/stories` **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Story list - `[]` array of: - `id` (integer) - `userId` (integer) - `createdAt` (string) - `expiredAt` (string) - `isReady` (boolean) - `isWatched` (boolean) - `media` (object[]) - `id` (integer) β€” Stable OnlyFans media ID β€” the only persistent identifier for the item. - `type` ("photo" | "video" | "audio" | "gif") - `createdAt` (string) - `duration` (integer) β€” Duration in seconds (video/audio; 0 for photos). - `convertedToVideo` (boolean) - `canView` (boolean) - `isReady` (boolean) β€” False while OnlyFans is still processing/transcoding the upload. - `hasError` (boolean) - `hasPosts` (boolean) β€” Whether the media is attached to any post. - `hasCustomPreview` (boolean) - `counters` (object) β€” Engagement counters (present on the vault view). - `buyersCount` (integer) - `likesCount` (integer) - `tipsSumm` (number) - `listStates` (object[]) β€” Which vault lists (folders) this media belongs to. - `id` (integer) β€” Vault list ID. - `name` (string) β€” Vault list name. - `hasMedia` (boolean) - `canAddMedia` (boolean) - `files` (object) β€” Signed, time-limited CDN URLs at several resolutions. `size` is frequently `0` β€” do not rely on it. - `full` (object) - `preview` (object) - `thumb` (object) - `squarePreview` (object) - `videoSources` (object) β€” Per-resolution video URLs (e.g. `240`, `720`); entries are null when not applicable. - `question` (string) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/me/stories" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Like a story (/docs/of-api/stories/like-a-story) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/stories/{story_id}/like` Likes the story identified by story_id. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `story_id` (string, required) β€” ID of the story to like. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/stories/{story_id}/like" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # List story-blocked users (/docs/of-api/stories/list-story-blocked-users) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/stories/users/blocked` Returns users blocked from viewing the current user's stories. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. βœ“ **Verified live** against a real OnlyFans account (2026-07-30); the `data` schema below is the real response shape. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response β€” verified live; `data` is the real shape. - `success` (boolean) - `status_code` (integer) - `data` (any[]) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/stories/users/blocked" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # List story viewers (/docs/of-api/stories/list-story-viewers) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/stories/{story_id}/viewers` Returns the list of viewers for a story, with pagination; a variant filters to only viewers who tipped. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `story_id` (string, required) β€” Id of the story. ## Query parameters - `limit` (string) β€” Page size. - `offset` (string) β€” Pagination offset. - `onlyWithTips` (string) β€” Return only viewers who tipped (used by one variant). ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/stories/{story_id}/viewers" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Mark story as watched (/docs/of-api/stories/mark-story-as-watched) `PUT https://theonlyapi.com/api/crm/your-crm-id/api2/v2/stories/{story_id}/watched` Marks a story as watched/seen by the current user. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `story_id` (string, required) β€” ID of the story to mark watched. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X PUT "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/stories/{story_id}/watched" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Unblock user from stories (/docs/of-api/stories/unblock-user-from-stories) `DELETE https://theonlyapi.com/api/crm/your-crm-id/api2/v2/stories/users/{user_id}/block` Removes a user from the story block list (unblocks them from viewing stories). **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `user_id` (string, required) β€” ID of the user to unblock. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/stories/users/{user_id}/block" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Unlike a story (/docs/of-api/stories/unlike-a-story) `DELETE https://theonlyapi.com/api/crm/your-crm-id/api2/v2/stories/{story_id}/like` Removes a like from the specified story. Paired with a POST on the same path to like it. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `story_id` (string, required) β€” ID of the story to unlike. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/stories/{story_id}/like" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Streams (/docs/of-api/streams) {/* Generated by scripts/gen-api.ts β€” edit that script, not this file. */} OnlyFans live streams (via proxy). **OnlyFans only** β€” Fansly accounts are rejected on this surface. | Method | Endpoint | Path | | -------- | --------------------------------------------------------------------------------------- | -------------------------------------------------------- | | `POST` | [Create / start a live stream](/docs/of-api/streams/create-start-a-live-stream) | `/api2/v2/streams` | | `GET` | [Get stream details](/docs/of-api/streams/get-stream-details) | `/api2/v2/streams/{stream_id}` | | `PATCH` | [Update a stream](/docs/of-api/streams/update-a-stream) | `/api2/v2/streams/{stream_id}` | | `DELETE` | [Delete a stream](/docs/of-api/streams/delete-a-stream) | `/api2/v2/streams/{stream_id}` | | `POST` | [Accept dual-stream invite](/docs/of-api/streams/accept-dual-stream-invite) | `/api2/v2/streams/{stream_id}/accept` | | `GET` | [Check if stream active](/docs/of-api/streams/check-if-stream-active) | `/api2/v2/streams/{stream_id}/active` | | `POST` | [Block stream viewer](/docs/of-api/streams/block-stream-viewer) | `/api2/v2/streams/{stream_id}/block` | | `POST` | [Cancel dual-stream request](/docs/of-api/streams/cancel-dual-stream-request) | `/api2/v2/streams/{stream_id}/cancel` | | `GET` | [Get a single stream comment](/docs/of-api/streams/get-a-single-stream-comment) | `/api2/v2/streams/{stream_id}/comments/{comment_id}` | | `DELETE` | [Delete stream comment](/docs/of-api/streams/delete-stream-comment) | `/api2/v2/streams/{stream_id}/comments/{comment_id}` | | `POST` | [Pin a stream comment](/docs/of-api/streams/pin-a-stream-comment) | `/api2/v2/streams/{stream_id}/comments/{comment_id}/pin` | | `DELETE` | [Unpin a stream comment](/docs/of-api/streams/unpin-a-stream-comment) | `/api2/v2/streams/{stream_id}/comments/{comment_id}/pin` | | `PUT` | [Save live stream cover](/docs/of-api/streams/save-live-stream-cover) | `/api2/v2/streams/{stream_id}/cover` | | `GET` | [Fetch stream covers](/docs/of-api/streams/fetch-stream-covers) | `/api2/v2/streams/{stream_id}/covers` | | `POST` | [Decline dual-stream invite](/docs/of-api/streams/decline-dual-stream-invite) | `/api2/v2/streams/{stream_id}/decline` | | `PUT` | [Finish a live stream](/docs/of-api/streams/finish-a-live-stream) | `/api2/v2/streams/{stream_id}/finish` | | `POST` | [Hide stream](/docs/of-api/streams/hide-stream) | `/api2/v2/streams/{stream_id}/hide` | | `GET` | [Check if current user is viewer](/docs/of-api/streams/check-if-current-user-is-viewer) | `/api2/v2/streams/{stream_id}/is-viewer` | | `POST` | [Join a dual stream](/docs/of-api/streams/join-a-dual-stream) | `/api2/v2/streams/{stream_id}/join` | | `POST` | [Kick a user from stream](/docs/of-api/streams/kick-a-user-from-stream) | `/api2/v2/streams/{stream_id}/kick` | | `POST` | [Add likes to stream](/docs/of-api/streams/add-likes-to-stream) | `/api2/v2/streams/{stream_id}/likes` | | `POST` | [Mark viewing a stream](/docs/of-api/streams/mark-viewing-a-stream) | `/api2/v2/streams/{stream_id}/look` | | `DELETE` | [Stop looking at a stream](/docs/of-api/streams/stop-looking-at-a-stream) | `/api2/v2/streams/{stream_id}/look` | | `PUT` | [Save stream as a post](/docs/of-api/streams/save-stream-as-a-post) | `/api2/v2/streams/{stream_id}/make-post` | | `POST` | [Set stream reminder](/docs/of-api/streams/set-stream-reminder) | `/api2/v2/streams/{stream_id}/reminder` | | `DELETE` | [Remove stream reminder](/docs/of-api/streams/remove-stream-reminder) | `/api2/v2/streams/{stream_id}/reminder` | | `GET` | [Get stream statistics](/docs/of-api/streams/get-stream-statistics) | `/api2/v2/streams/{stream_id}/stats` | | `POST` | [Share stream to Twitter](/docs/of-api/streams/share-stream-to-twitter) | `/api2/v2/streams/{stream_id}/tweet` | | `DELETE` | [Remove a user's stream comments](/docs/of-api/streams/remove-a-user-s-stream-comments) | `/api2/v2/streams/{stream_id}/user/{user_id}/comments` | | `POST` | [Accept dual-stream request](/docs/of-api/streams/accept-dual-stream-request) | `/api2/v2/streams/{stream_id}/users/{user_id}/accept` | | `POST` | [Cancel dual-stream invite](/docs/of-api/streams/cancel-dual-stream-invite) | `/api2/v2/streams/{stream_id}/users/{user_id}/cancel` | | `POST` | [Decline dual-stream request](/docs/of-api/streams/decline-dual-stream-request) | `/api2/v2/streams/{stream_id}/users/{user_id}/decline` | | `PUT` | [Add stream helper](/docs/of-api/streams/add-stream-helper) | `/api2/v2/streams/{stream_id}/users/{user_id}/helper` | | `DELETE` | [Remove stream helper](/docs/of-api/streams/remove-stream-helper) | `/api2/v2/streams/{stream_id}/users/{user_id}/helper` | | `POST` | [Invite user to dual stream](/docs/of-api/streams/invite-user-to-dual-stream) | `/api2/v2/streams/{stream_id}/users/{user_id}/invite` | | `GET` | [Get stream viewers](/docs/of-api/streams/get-stream-viewers) | `/api2/v2/streams/{stream_id}/viewers` | | `GET` | [Get a stream viewer](/docs/of-api/streams/get-a-stream-viewer) | `/api2/v2/streams/{stream_id}/viewers/{user_id}` | | `POST` | [Vote on a stream poll](/docs/of-api/streams/vote-on-a-stream-poll) | `/api2/v2/streams/{stream_id}/vote` | | `GET` | [Get active live streams](/docs/of-api/streams/get-active-live-streams) | `/api2/v2/streams/active` | | `GET` | [Stream discovery feed](/docs/of-api/streams/stream-discovery-feed) | `/api2/v2/streams/feed` | | `DELETE` | [Unblock stream viewer](/docs/of-api/streams/unblock-stream-viewer) | `/api2/v2/streams/users/{user_id}/block` | | `POST` | [Block stream viewer by name](/docs/of-api/streams/block-stream-viewer-by-name) | `/api2/v2/streams/users/{username}/block` | --- # Accept dual-stream invite (/docs/of-api/streams/accept-dual-stream-invite) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/accept` Accepts an invitation to join a dual (co-host) live stream identified by stream id (acceptDualStreamInvite). **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `stream_id` (string, required) β€” ID of the stream whose invite is accepted. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/accept" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Accept dual-stream request (/docs/of-api/streams/accept-dual-stream-request) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/users/{user_id}/accept` Accepts a user's request to join a dual/co-stream (acceptDualStreamRequest). Sibling calls decline, cancel or invite users. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `stream_id` (string, required) β€” ID of the stream. - `user_id` (string, required) β€” ID of the user whose dual-stream request is accepted. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/users/{user_id}/accept" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Add likes to stream (/docs/of-api/streams/add-likes-to-stream) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/likes` Adds a number of likes to a live stream (streamLikes). **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `stream_id` (string, required) β€” ID of the stream. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` - `likes` (number) β€” Number of likes to add. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/likes" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Add stream helper (/docs/of-api/streams/add-stream-helper) `PUT https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/users/{user_id}/helper` Grants a user helper (moderator) permissions on a live stream. Enclosing fn addStreamHelper. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `stream_id` (string, required) β€” ID of the live stream. - `user_id` (string, required) β€” ID of the user to grant helper role. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X PUT "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/users/{user_id}/helper" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Block stream viewer (/docs/of-api/streams/block-stream-viewer) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/block` Blocks a viewer in a live stream, optionally permanently. Called as blockStreamViewer({streamId, userId, isPermanent}). **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `stream_id` (string, required) β€” ID of the stream. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` - `userId` (string|number) β€” ID of the viewer to block. - `isPermanent` (boolean) β€” Whether the block is permanent (default false). ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/block" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Block stream viewer by name (/docs/of-api/streams/block-stream-viewer-by-name) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/users/{username}/block` Blocks a live-stream viewer identified by their username (blockStreamViewerByName). **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `username` (string, required) β€” Username of the stream viewer to block. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/users/{username}/block" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Cancel dual-stream invite (/docs/of-api/streams/cancel-dual-stream-invite) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/users/{user_id}/cancel` Cancels a pending dual-stream (co-stream) invite for a user. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `stream_id` (string, required) β€” ID of the stream. - `user_id` (string, required) β€” ID of the invited user. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/users/{user_id}/cancel" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Cancel dual-stream request (/docs/of-api/streams/cancel-dual-stream-request) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/cancel` Cancels a pending dual-stream (co-streaming) request for the given stream (enclosing fn cancelDualStreamRequest). **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `stream_id` (string, required) β€” Id of the stream whose dual-stream request is cancelled. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/cancel" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Check if current user is viewer (/docs/of-api/streams/check-if-current-user-is-viewer) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/is-viewer` Checks whether the current user is a viewer of the given stream (checkViewer). **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `stream_id` (string, required) β€” ID of the stream. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/is-viewer" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Check if stream active (/docs/of-api/streams/check-if-stream-active) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/active` Checks whether the specified live stream is currently active. Enclosing fn checkStreamActive. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `stream_id` (string, required) β€” ID of the live stream. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/active" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Create / start a live stream (/docs/of-api/streams/create-start-a-live-stream) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams` Start a new live stream. Returns stream configuration including the room ID and streaming credentials. **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` - `title` (string) β€” Stream title displayed to viewers. e.g. `"Friday night live! πŸŽ‰"`. - `description` (string) β€” Stream description. - `isFree` (boolean) β€” If true, stream is free for all. If false, only subscribers can watch. Default `false`. ## Responses ### 200 β€” Stream created - `id` (integer) - `title` (string) - `description` (string) - `isActive` (boolean) - `startedAt` (string) - `room` (string) - `thumbUrl` (string) - `viewersCount` (integer) - `likesCount` (integer) - `tipsAmount` (number) ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{"title":"Friday night live! πŸŽ‰","isFree":false}' ``` --- # Decline dual-stream invite (/docs/of-api/streams/decline-dual-stream-invite) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/decline` Declines an invitation to join a dual (co-host) live stream. Enclosing fn declineDualStreamInvite. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `stream_id` (string, required) β€” ID of the stream whose invite is declined. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/decline" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Decline dual-stream request (/docs/of-api/streams/decline-dual-stream-request) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/users/{user_id}/decline` Declines a dual-stream (co-stream) request from a user (declineDualStreamRequest). **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `stream_id` (string, required) β€” ID of the stream. - `user_id` (string, required) β€” ID of the requesting user. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/users/{user_id}/decline" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Delete a stream (/docs/of-api/streams/delete-a-stream) `DELETE https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}` Deletes a live stream identified by stream id. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `stream_id` (string, required) β€” ID of the stream to delete. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Delete stream comment (/docs/of-api/streams/delete-stream-comment) `DELETE https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/comments/{comment_id}` Removes a comment from a live stream. Called as removeComment(streamId, commentId). **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `stream_id` (string, required) β€” ID of the stream. - `comment_id` (string, required) β€” ID of the comment to remove. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/comments/{comment_id}" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Fetch stream covers (/docs/of-api/streams/fetch-stream-covers) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/covers` Fetches available cover images for a stream (fetchStreamCovers). Retries on HTTP 400. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `stream_id` (string, required) β€” ID of the stream. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/covers" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Finish a live stream (/docs/of-api/streams/finish-a-live-stream) `PUT https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/finish` Ends the live stream identified by stream_id. Enclosing fn is finishStream. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `stream_id` (string, required) β€” ID of the stream to finish. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X PUT "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/finish" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Get a single stream comment (/docs/of-api/streams/get-a-single-stream-comment) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/comments/{comment_id}` Fetches a single comment on a live stream by stream and comment id (enclosing fn getStreamComment). **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `stream_id` (string, required) β€” Id of the stream. - `comment_id` (string, required) β€” Id of the stream comment. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/comments/{comment_id}" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get a stream viewer (/docs/of-api/streams/get-a-stream-viewer) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/viewers/{user_id}` Retrieves details for a single viewer of a live stream. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `stream_id` (string, required) β€” ID of the stream. - `user_id` (string, required) β€” ID of the viewer user. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/viewers/{user_id}" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get active live streams (/docs/of-api/streams/get-active-live-streams) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/active` **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Active streams - `[]` array of: - `id` (integer) - `title` (string) - `description` (string) - `isActive` (boolean) - `startedAt` (string) - `room` (string) - `thumbUrl` (string) - `viewersCount` (integer) - `likesCount` (integer) - `tipsAmount` (number) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/active" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get stream details (/docs/of-api/streams/get-stream-details) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}` Retrieves a live stream by its id. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `stream_id` (string, required) β€” ID of the stream. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get stream statistics (/docs/of-api/streams/get-stream-statistics) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/stats` **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `stream_id` (string, required) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Stream stats - `viewersCount` (integer) - `likesCount` (integer) - `tipsAmount` (number) - `commentsCount` (integer) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/stats" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get stream viewers (/docs/of-api/streams/get-stream-viewers) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/viewers` **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `stream_id` (string, required) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Viewer list - `list` (object[]) - `id` (integer) - `name` (string) - `username` (string) - `displayName` (string) - `about` (string) - `avatar` (string) β€” Avatar URL. - `avatarThumbs` (object) - `c50` (string) - `c144` (string) - `header` (string) β€” Profile header/banner URL. - `email` (string) - `isVerified` (boolean) - `isPerformer` (boolean) - `canEarn` (boolean) - `tipsEnabled` (boolean) - `subscribedBy` (boolean) β€” Whether you are subscribed to this user. - `subscribersCount` (integer) - `subscribesCount` (integer) - `postsCount` (integer) - `photosCount` (integer) - `videosCount` (integer) - `audiosCount` (integer) - `friendsCount` (integer) - `joinDate` (string) - `firstPublishedPostDate` (string) - `subscribePrice` (number) - `chatMessagesCount` (integer) β€” Unread chat messages. - `countPriorityChat` (integer) - `countPinnedChat` (integer) - `hasPurchasedPosts` (boolean) - `paidFeed` (boolean) - `openseaInfo` (object) - `hasMore` (boolean) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/viewers" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Hide stream (/docs/of-api/streams/hide-stream) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/hide` Hides the specified live stream from the feed. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `stream_id` (string, required) β€” ID of the live stream to hide. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/hide" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Invite user to dual stream (/docs/of-api/streams/invite-user-to-dual-stream) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/users/{user_id}/invite` Invites a user to join a dual/co-stream. Called as inviteDualStream({streamId, userId}). **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `stream_id` (string, required) β€” ID of the stream. - `user_id` (string, required) β€” ID of the user to invite. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/users/{user_id}/invite" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Join a dual stream (/docs/of-api/streams/join-a-dual-stream) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/join` Requests to join a dual (co-host) live stream identified by stream_id. Enclosing fn is joinDualStreamRequest. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `stream_id` (string, required) β€” ID of the stream to join. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/join" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Kick a user from stream (/docs/of-api/streams/kick-a-user-from-stream) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/kick` Remove a viewer from the live stream (creator only). **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `stream_id` (string, required) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` - `userId` (integer, required) β€” User ID to kick from the stream. ## Responses ### 200 β€” User kicked ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/kick" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Mark viewing a stream (/docs/of-api/streams/mark-viewing-a-stream) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/look` Registers the current user as actively looking at the stream. Enclosing fn is streamLook. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `stream_id` (string, required) β€” ID of the stream being viewed. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/look" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Pin a stream comment (/docs/of-api/streams/pin-a-stream-comment) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/comments/{comment_id}/pin` Pins a comment within a live stream (DELETE on the same path unpins it). **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `stream_id` (string, required) β€” ID of the stream. - `comment_id` (string, required) β€” ID of the comment to pin. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/comments/{comment_id}/pin" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Remove a user's stream comments (/docs/of-api/streams/remove-a-user-s-stream-comments) `DELETE https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/user/{user_id}/comments` Removes all comments from a specific user within a live stream (removeComment by user). **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `stream_id` (string, required) β€” ID of the live stream. - `user_id` (string, required) β€” ID of the user whose comments are removed. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/user/{user_id}/comments" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Remove stream helper (/docs/of-api/streams/remove-stream-helper) `DELETE https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/users/{user_id}/helper` Removes a user's helper (moderator) role on a live stream. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `stream_id` (string, required) β€” ID of the stream. - `user_id` (string, required) β€” ID of the helper user. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/users/{user_id}/helper" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Remove stream reminder (/docs/of-api/streams/remove-stream-reminder) `DELETE https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/reminder` Removes the reminder the user set for the scheduled stream identified by stream_id. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `stream_id` (string, required) β€” ID of the stream to remove the reminder for. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/reminder" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Save live stream cover (/docs/of-api/streams/save-live-stream-cover) `PUT https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/cover` Saves/updates the cover image for a live stream (enclosing fn saveStreamCover). **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `stream_id` (string, required) β€” Id of the stream whose cover is set. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X PUT "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/cover" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Save stream as a post (/docs/of-api/streams/save-stream-as-a-post) `PUT https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/make-post` Saves a finished live stream as a feed post (saveStreamAsPost). Requires the stream ID and additional post fields. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `stream_id` (string, required) β€” ID of the stream to save as a post. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` - `id` (string) β€” Stream ID (echoed into the body). ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X PUT "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/make-post" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Set stream reminder (/docs/of-api/streams/set-stream-reminder) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/reminder` Sets a reminder for an upcoming/scheduled live stream. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `stream_id` (string, required) β€” ID of the stream. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/reminder" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Share stream to Twitter (/docs/of-api/streams/share-stream-to-twitter) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/tweet` Tweets/shares the live stream identified by stream_id with preview options. Enclosing fn is sendStreamTweet. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `stream_id` (string, required) β€” ID of the stream to tweet. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` - `tweetWithPreview` (boolean) β€” Include stream preview in tweet. - `tweetWithStillPreview` (boolean) β€” Include still-image preview in tweet. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/tweet" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Stop looking at a stream (/docs/of-api/streams/stop-looking-at-a-stream) `DELETE https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/look` Removes the current viewer's 'look' marker on a stream (streamUnlook). Paired with a POST on the same path (streamLook). **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `stream_id` (string, required) β€” ID of the stream. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/look" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Stream discovery feed (/docs/of-api/streams/stream-discovery-feed) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/feed` **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Stream feed - `list` (object[]) - `id` (integer) - `title` (string) - `description` (string) - `isActive` (boolean) - `startedAt` (string) - `room` (string) - `thumbUrl` (string) - `viewersCount` (integer) - `likesCount` (integer) - `tipsAmount` (number) - `hasMore` (boolean) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/feed" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Unblock stream viewer (/docs/of-api/streams/unblock-stream-viewer) `DELETE https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/users/{user_id}/block` Unblocks a previously blocked live-stream viewer by user ID. Enclosing fn unblockStreamViewerByUserId. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `user_id` (string, required) β€” ID of the viewer to unblock. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/users/{user_id}/block" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Unpin a stream comment (/docs/of-api/streams/unpin-a-stream-comment) `DELETE https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/comments/{comment_id}/pin` Removes the pin from a comment on a live stream. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `stream_id` (string, required) β€” Id of the stream. - `comment_id` (string, required) β€” Id of the pinned comment to unpin. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/comments/{comment_id}/pin" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Update a stream (/docs/of-api/streams/update-a-stream) `PATCH https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}` Updates properties of an existing live stream. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `stream_id` (string, required) β€” ID of the stream (taken from the body's id field). ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` - `id` (string) β€” Stream id (also used in the path). ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X PATCH "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Vote on a stream poll (/docs/of-api/streams/vote-on-a-stream-poll) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/vote` **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `stream_id` (string, required) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` - `optionId` (integer, required) β€” The poll option ID to vote for. ## Responses ### 200 β€” Vote recorded ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/streams/{stream_id}/vote" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{"optionId":0}' ``` --- # Subscribers (/docs/of-api/subscribers) {/* Generated by scripts/gen-api.ts β€” edit that script, not this file. */} OnlyFans subscriber endpoints (via proxy). **OnlyFans only** β€” Fansly accounts are rejected on this surface. | Method | Endpoint | Path | | ------ | ------------------------------------------------------------------------------------- | --------------------------------------------------- | | `GET` | [List subscribers](/docs/of-api/subscribers/list-subscribers-get) | `/api2/v2/subscriptions/subscribers` | | `GET` | [Top-spending subscribers](/docs/of-api/subscribers/top-spending-subscribers) | `/api2/v2/subscriptions/subscribers/awards` | | `GET` | [Subscriber awards count](/docs/of-api/subscribers/subscriber-awards-count) | `/api2/v2/subscriptions/subscribers/awards/count` | | `GET` | [Get subscriber count](/docs/of-api/subscribers/get-subscriber-count) | `/api2/v2/subscriptions/subscribers/count` | | `GET` | [Recently expired subscribers](/docs/of-api/subscribers/recently-expired-subscribers) | `/api2/v2/subscriptions/subscribers/recent-expired` | --- # Get subscriber count (/docs/of-api/subscribers/get-subscriber-count) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/subscriptions/subscribers/count` **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Count - `count` (integer) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/subscriptions/subscribers/count" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # List subscribers (/docs/of-api/subscribers/list-subscribers-get) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/subscriptions/subscribers` Full subscriber list with total-spent data. `data` is a **bare array** of subscriber (fan) profiles β€” no `{list, hasMore}` wrapper β€” page it with `limit`/`offset`. For a bounded active/expired roster on very large accounts prefer the CRM route `GET /accounts/{of_user_id}/subscribers/refresh` + `/subscribers/cached`. **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Query parameters - `limit` (integer) β€” Default `10`. - `offset` (integer) β€” Default `0`. - `type` ("all" | "active" | "expired") β€” Default `all`. - `format` (string) β€” Default `infinite`. - `filter[total_spent]` (integer) β€” Default `1`. - `more` (boolean) β€” Default `true`. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Subscriber list, wrapped in the passthrough envelope Each item is an OFUserProfile plus subscription-relationship fields (`subscribedBy`, `subscribedByExpireDate`, `subscribedOnData`, `currentSubscribePrice`, `listsStates`, tip limits). - `success` (boolean) - `status_code` (integer) - `data` (object[]) - `id` (integer) - `name` (string) - `username` (string) - `displayName` (string) - `about` (string) - `avatar` (string) β€” Avatar URL. - `avatarThumbs` (object) - `c50` (string) - `c144` (string) - `header` (string) β€” Profile header/banner URL. - `email` (string) - `isVerified` (boolean) - `isPerformer` (boolean) - `canEarn` (boolean) - `tipsEnabled` (boolean) - `subscribedBy` (boolean) β€” Whether you are subscribed to this user. - `subscribersCount` (integer) - `subscribesCount` (integer) - `postsCount` (integer) - `photosCount` (integer) - `videosCount` (integer) - `audiosCount` (integer) - `friendsCount` (integer) - `joinDate` (string) - `firstPublishedPostDate` (string) - `subscribePrice` (number) - `chatMessagesCount` (integer) β€” Unread chat messages. - `countPriorityChat` (integer) - `countPinnedChat` (integer) - `hasPurchasedPosts` (boolean) - `paidFeed` (boolean) - `openseaInfo` (object) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/subscriptions/subscribers" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Recently expired subscribers (/docs/of-api/subscribers/recently-expired-subscribers) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/subscriptions/subscribers/recent-expired` **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Expired subscriber list - `list` (object[]) - `id` (integer) - `name` (string) - `username` (string) - `displayName` (string) - `about` (string) - `avatar` (string) β€” Avatar URL. - `avatarThumbs` (object) - `c50` (string) - `c144` (string) - `header` (string) β€” Profile header/banner URL. - `email` (string) - `isVerified` (boolean) - `isPerformer` (boolean) - `canEarn` (boolean) - `tipsEnabled` (boolean) - `subscribedBy` (boolean) β€” Whether you are subscribed to this user. - `subscribersCount` (integer) - `subscribesCount` (integer) - `postsCount` (integer) - `photosCount` (integer) - `videosCount` (integer) - `audiosCount` (integer) - `friendsCount` (integer) - `joinDate` (string) - `firstPublishedPostDate` (string) - `subscribePrice` (number) - `chatMessagesCount` (integer) β€” Unread chat messages. - `countPriorityChat` (integer) - `countPinnedChat` (integer) - `hasPurchasedPosts` (boolean) - `paidFeed` (boolean) - `openseaInfo` (object) - `hasMore` (boolean) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/subscriptions/subscribers/recent-expired" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Subscriber awards count (/docs/of-api/subscribers/subscriber-awards-count) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/subscriptions/subscribers/awards/count` **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Count - `count` (integer) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/subscriptions/subscribers/awards/count" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Top-spending subscribers (/docs/of-api/subscribers/top-spending-subscribers) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/subscriptions/subscribers/awards` **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Query parameters - `limit` (integer) β€” Default `10`. - `offset` (integer) β€” Default `0`. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Awards list - `list` (object[]) - `id` (integer) - `name` (string) - `username` (string) - `displayName` (string) - `about` (string) - `avatar` (string) β€” Avatar URL. - `avatarThumbs` (object) - `c50` (string) - `c144` (string) - `header` (string) β€” Profile header/banner URL. - `email` (string) - `isVerified` (boolean) - `isPerformer` (boolean) - `canEarn` (boolean) - `tipsEnabled` (boolean) - `subscribedBy` (boolean) β€” Whether you are subscribed to this user. - `subscribersCount` (integer) - `subscribesCount` (integer) - `postsCount` (integer) - `photosCount` (integer) - `videosCount` (integer) - `audiosCount` (integer) - `friendsCount` (integer) - `joinDate` (string) - `firstPublishedPostDate` (string) - `subscribePrice` (number) - `chatMessagesCount` (integer) β€” Unread chat messages. - `countPriorityChat` (integer) - `countPinnedChat` (integer) - `hasPurchasedPosts` (boolean) - `paidFeed` (boolean) - `openseaInfo` (object) - `hasMore` (boolean) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/subscriptions/subscribers/awards" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Subscriptions (/docs/of-api/subscriptions) {/* Generated by scripts/gen-api.ts β€” edit that script, not this file. */} OnlyFans subscription management (via proxy). **OnlyFans only** β€” Fansly accounts are rejected on this surface. | Method | Endpoint | Path | | -------- | ----------------------------------------------------------------------------------------------------- | ------------------------------------------------------------ | | `PUT` | [Update a subscription](/docs/of-api/subscriptions/update-a-subscription) | `/api2/v2/subscriptions/{subscription_id}` | | `DELETE` | [Dismiss subscription attention flag](/docs/of-api/subscriptions/dismiss-subscription-attention-flag) | `/api2/v2/subscriptions/{subscription_id}/attention` | | `PUT` | [Apply subscription discount](/docs/of-api/subscriptions/apply-subscription-discount) | `/api2/v2/subscriptions/{subscription_id}/discount` | | `PUT` | [Hide posts from subscription](/docs/of-api/subscriptions/hide-posts-from-subscription) | `/api2/v2/subscriptions/{subscription_id}/hide-posts` | | `DELETE` | [Unhide subscription posts](/docs/of-api/subscriptions/unhide-subscription-posts) | `/api2/v2/subscriptions/{subscription_id}/hide-posts` | | `GET` | [Subscription payment history](/docs/of-api/subscriptions/subscription-payment-history) | `/api2/v2/subscriptions/{subscription_id}/history` | | `DELETE` | [Dismiss price-change hint](/docs/of-api/subscriptions/dismiss-price-change-hint) | `/api2/v2/subscriptions/{subscription_id}/price-change-hint` | | `PUT` | [Update subscription bundle](/docs/of-api/subscriptions/update-subscription-bundle) | `/api2/v2/subscriptions/bundles/{bundle_id}` | | `DELETE` | [Delete subscription bundle](/docs/of-api/subscriptions/delete-subscription-bundle) | `/api2/v2/subscriptions/bundles/{bundle_id}` | | `GET` | [List your subscriptions](/docs/of-api/subscriptions/list-your-subscriptions) | `/api2/v2/subscriptions/subscribes` | | `GET` | [Subscription count](/docs/of-api/subscriptions/subscription-count) | `/api2/v2/subscriptions/subscribes/count` | | `GET` | [List unsubscribe reasons](/docs/of-api/subscriptions/list-unsubscribe-reasons) | `/api2/v2/unsubscribe/reasons` | | `POST` | [Resubscribe to a user](/docs/of-api/subscriptions/resubscribe-to-a-user) | `/api2/v2/users/{user_id}/resubscribe` | | `POST` | [Subscribe to a user](/docs/of-api/subscriptions/subscribe-to-a-user) | `/api2/v2/users/{user_id}/subscribe` | | `DELETE` | [Unsubscribe from a user](/docs/of-api/subscriptions/unsubscribe-from-a-user) | `/api2/v2/users/{user_id}/unsubscribe` | --- # Apply subscription discount (/docs/of-api/subscriptions/apply-subscription-discount) `PUT https://theonlyapi.com/api/crm/your-crm-id/api2/v2/subscriptions/{subscription_id}/discount` Apply a percentage discount to a specific subscriber's subscription. Useful for retention or promotional pricing for individual fans. **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `subscription_id` (string, required) β€” Subscription ID to apply discount to. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` (required) - `discount` (integer, required) β€” Discount percentage (0-100). 0 removes the discount. e.g. `50`. - `period` (integer, required) β€” Number of months the discount is active (1-12). e.g. `3`. ## Responses ### 200 β€” Discount applied ## Example **50% off for 3 months** ```bash curl -X PUT "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/subscriptions/{subscription_id}/discount" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{"discount":50,"period":3}' ``` **Remove discount** ```bash curl -X PUT "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/subscriptions/{subscription_id}/discount" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{"discount":0,"period":1}' ``` --- # Delete subscription bundle (/docs/of-api/subscriptions/delete-subscription-bundle) `DELETE https://theonlyapi.com/api/crm/your-crm-id/api2/v2/subscriptions/bundles/{bundle_id}` Deletes a subscription bundle offer. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `bundle_id` (string, required) β€” ID of the subscription bundle to delete. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/subscriptions/bundles/{bundle_id}" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Dismiss price-change hint (/docs/of-api/subscriptions/dismiss-price-change-hint) `DELETE https://theonlyapi.com/api/crm/your-crm-id/api2/v2/subscriptions/{subscription_id}/price-change-hint` Dismisses the price-change hint/notice for a subscription. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `subscription_id` (string, required) β€” ID of the subscription. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/subscriptions/{subscription_id}/price-change-hint" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Dismiss subscription attention flag (/docs/of-api/subscriptions/dismiss-subscription-attention-flag) `DELETE https://theonlyapi.com/api/crm/your-crm-id/api2/v2/subscriptions/{subscription_id}/attention` Clears/dismisses the 'attention' flag on a subscription. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `subscription_id` (string, required) β€” Id of the subscription whose attention flag is cleared. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/subscriptions/{subscription_id}/attention" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Hide posts from subscription (/docs/of-api/subscriptions/hide-posts-from-subscription) `PUT https://theonlyapi.com/api/crm/your-crm-id/api2/v2/subscriptions/{subscription_id}/hide-posts` Hides posts from the given subscription in the user's feed. Paired with a DELETE on the same path to unhide. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `subscription_id` (string, required) β€” ID of the subscription (subscribed user) to hide posts from. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X PUT "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/subscriptions/{subscription_id}/hide-posts" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # List unsubscribe reasons (/docs/of-api/subscriptions/list-unsubscribe-reasons) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/unsubscribe/reasons` Returns the selectable reasons offered when a fan unsubscribes. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. βœ“ **Verified live** against a real OnlyFans account (2026-07-30); the `data` schema below is the real response shape. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response β€” verified live; `data` is the real shape. - `success` (boolean) - `status_code` (integer) - `data` (object[]) - `id` (integer) - `name` (string) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/unsubscribe/reasons" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # List your subscriptions (/docs/of-api/subscriptions/list-your-subscriptions) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/subscriptions/subscribes` Accounts you are subscribed to. **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Query parameters - `limit` (integer) β€” Default `10`. - `offset` (integer) β€” Default `0`. - `type` (string) β€” Default `active`. - `format` (string) β€” Default `infinite`. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Subscription list - `list` (object[]) - `id` (integer) - `name` (string) - `username` (string) - `displayName` (string) - `about` (string) - `avatar` (string) β€” Avatar URL. - `avatarThumbs` (object) - `c50` (string) - `c144` (string) - `header` (string) β€” Profile header/banner URL. - `email` (string) - `isVerified` (boolean) - `isPerformer` (boolean) - `canEarn` (boolean) - `tipsEnabled` (boolean) - `subscribedBy` (boolean) β€” Whether you are subscribed to this user. - `subscribersCount` (integer) - `subscribesCount` (integer) - `postsCount` (integer) - `photosCount` (integer) - `videosCount` (integer) - `audiosCount` (integer) - `friendsCount` (integer) - `joinDate` (string) - `firstPublishedPostDate` (string) - `subscribePrice` (number) - `chatMessagesCount` (integer) β€” Unread chat messages. - `countPriorityChat` (integer) - `countPinnedChat` (integer) - `hasPurchasedPosts` (boolean) - `paidFeed` (boolean) - `openseaInfo` (object) - `hasMore` (boolean) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/subscriptions/subscribes" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Resubscribe to a user (/docs/of-api/subscriptions/resubscribe-to-a-user) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/{user_id}/resubscribe` Resubscribes to the given user's account. Sibling of users/{id}/subscribe. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `user_id` (string, required) β€” ID of the user to resubscribe to. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/{user_id}/resubscribe" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Subscribe to a user (/docs/of-api/subscriptions/subscribe-to-a-user) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/{user_id}/subscribe` **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `user_id` (string, required) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Subscribed ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/{user_id}/subscribe" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Subscription count (/docs/of-api/subscriptions/subscription-count) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/subscriptions/subscribes/count` **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Count - `count` (integer) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/subscriptions/subscribes/count" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Subscription payment history (/docs/of-api/subscriptions/subscription-payment-history) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/subscriptions/{subscription_id}/history` **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `subscription_id` (string, required) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Payment history - `list` (object[]) - `hasMore` (boolean) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/subscriptions/{subscription_id}/history" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Unhide subscription posts (/docs/of-api/subscriptions/unhide-subscription-posts) `DELETE https://theonlyapi.com/api/crm/your-crm-id/api2/v2/subscriptions/{subscription_id}/hide-posts` Re-shows posts from a subscription previously hidden (PUT on the same path hides them). **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `subscription_id` (string, required) β€” ID of the subscription. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/subscriptions/{subscription_id}/hide-posts" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Unsubscribe from a user (/docs/of-api/subscriptions/unsubscribe-from-a-user) `DELETE https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/{user_id}/unsubscribe` **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `user_id` (string, required) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Unsubscribed ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/{user_id}/unsubscribe" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Update a subscription (/docs/of-api/subscriptions/update-a-subscription) `PUT https://theonlyapi.com/api/crm/your-crm-id/api2/v2/subscriptions/{subscription_id}` Updates settings for the given subscription. Sibling calls manage autoprolong, hide-posts and price-change hints. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `subscription_id` (string, required) β€” ID of the subscription to update. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X PUT "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/subscriptions/{subscription_id}" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Update subscription bundle (/docs/of-api/subscriptions/update-subscription-bundle) `PUT https://theonlyapi.com/api/crm/your-crm-id/api2/v2/subscriptions/bundles/{bundle_id}` Updates a subscription bundle (discounted multi-month offer) by ID. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `bundle_id` (string, required) β€” ID of the subscription bundle (from body e.id). ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X PUT "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/subscriptions/bundles/{bundle_id}" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # User (/docs/of-api/user) {/* Generated by scripts/gen-api.ts β€” edit that script, not this file. */} Direct proxy to OnlyFans user profile & settings endpoints. **OnlyFans only.** Requires `X-API-Key` + `user-id` headers. | Method | Endpoint | Path | | -------- | -------------------------------------------------------------------------------------------- | -------------------------------------------------- | | `POST` | [Record cookie consent](/docs/of-api/user/record-cookie-consent) | `/api2/v2/accepted-cookies` | | `POST` | [Start age verification](/docs/of-api/user/start-age-verification) | `/api2/v2/age-verifier/start` | | `POST` | [Check account email](/docs/of-api/user/check-account-email) | `/api2/v2/av/email-check` | | `POST` | [Request email address change](/docs/of-api/user/request-email-address-change) | `/api2/v2/emails/change` | | `DELETE` | [Cancel pending email change](/docs/of-api/user/cancel-pending-email-change) | `/api2/v2/emails/change` | | `POST` | [Resend confirmation email](/docs/of-api/user/resend-confirmation-email) | `/api2/v2/emails/resend` | | `POST` | [Postpone face-ID verification](/docs/of-api/user/postpone-face-id-verification) | `/api2/v2/face-id/postpone` | | `POST` | [Start Face ID verification](/docs/of-api/user/start-face-id-verification) | `/api2/v2/face-id/start` | | `DELETE` | [Remove account helper](/docs/of-api/user/remove-account-helper) | `/api2/v2/helpers/{helper_id}` | | `POST` | [Add or update account helper](/docs/of-api/user/add-or-update-account-helper) | `/api2/v2/helpers/{user_id}` | | `POST` | [Report login issue](/docs/of-api/user/report-login-issue) | `/api2/v2/issues/login` | | `POST` | [Start identity verification](/docs/of-api/user/start-identity-verification) | `/api2/v2/iv/start` | | `GET` | [Get Yoti face-ID verification URL](/docs/of-api/user/get-yoti-face-id-verification-url) | `/api2/v2/iv/yoti-face-id-url/{id}/{token}` | | `GET` | [Get Yoti identity verification URL](/docs/of-api/user/get-yoti-identity-verification-url) | `/api2/v2/iv/yoti-redirect-url/{verification_id}` | | `GET` | [List login sessions](/docs/of-api/user/list-login-sessions) | `/api2/v2/logins` | | `DELETE` | [Revoke a login session](/docs/of-api/user/revoke-a-login-session) | `/api2/v2/logins/{login_id}` | | `POST` | [Request phone number change](/docs/of-api/user/request-phone-number-change) | `/api2/v2/phones/change` | | `DELETE` | [Cancel pending phone change](/docs/of-api/user/cancel-pending-phone-change) | `/api2/v2/phones/change` | | `GET` | [List active sessions](/docs/of-api/user/list-active-sessions) | `/api2/v2/sessions` | | `DELETE` | [Revoke all sessions](/docs/of-api/user/revoke-all-sessions) | `/api2/v2/sessions` | | `POST` | [Mark device as trusted](/docs/of-api/user/mark-device-as-trusted) | `/api2/v2/trust` | | `GET` | [Get user public profile](/docs/of-api/user/get-user-public-profile) | `/api2/v2/users/{user_id}` | | `POST` | [Block a user](/docs/of-api/user/block-a-user) | `/api2/v2/users/{user_id}/block` | | `DELETE` | [Unblock a user](/docs/of-api/user/unblock-a-user) | `/api2/v2/users/{user_id}/block` | | `GET` | [Get pinned friends](/docs/of-api/user/get-pinned-friends) | `/api2/v2/users/{user_id}/friends/pinned` | | `GET` | [Get user's links](/docs/of-api/user/get-user-s-links) | `/api2/v2/users/{user_id}/links` | | `POST` | [Restrict a user](/docs/of-api/user/restrict-a-user) | `/api2/v2/users/{user_id}/restrict` | | `GET` | [List user's Shopify stores](/docs/of-api/user/list-user-s-shopify-stores) | `/api2/v2/users/{user_id}/shopify/stores` | | `GET` | [Get user social buttons](/docs/of-api/user/get-user-social-buttons) | `/api2/v2/users/{user_id}/social/buttons` | | `POST` | [Submit account appeal](/docs/of-api/user/submit-account-appeal) | `/api2/v2/users/appeal` | | `GET` | [List blocked users](/docs/of-api/user/list-blocked-users) | `/api2/v2/users/blocked` | | `POST` | [Change password](/docs/of-api/user/change-password) | `/api2/v2/users/change-password` | | `POST` | [Connect a linked account](/docs/of-api/user/connect-a-linked-account) | `/api2/v2/users/connect` | | `DELETE` | [Disconnect a linked account](/docs/of-api/user/disconnect-a-linked-account) | `/api2/v2/users/connect/{account_id}` | | `POST` | [Request account deletion](/docs/of-api/user/request-account-deletion) | `/api2/v2/users/delete/request` | | `DELETE` | [Cancel account deletion request](/docs/of-api/user/cancel-account-deletion-request) | `/api2/v2/users/delete/request` | | `POST` | [Check if username exists](/docs/of-api/user/check-if-username-exists) | `/api2/v2/users/exists` | | `POST` | [Request password reset](/docs/of-api/user/request-password-reset) | `/api2/v2/users/forgot-password` | | `POST` | [Get auth token](/docs/of-api/user/get-auth-token) | `/api2/v2/users/get-auth-token` | | `POST` | [Get OTP token](/docs/of-api/user/get-otp-token) | `/api2/v2/users/get-otp-token` | | `POST` | [Log out helper session](/docs/of-api/user/log-out-helper-session) | `/api2/v2/users/helper-logout` | | `DELETE` | [Dismiss user hint](/docs/of-api/user/dismiss-user-hint) | `/api2/v2/users/hints/{hint_id}` | | `GET` | [Get user links](/docs/of-api/user/get-user-links) | `/api2/v2/users/links` | | `POST` | [Add profile link](/docs/of-api/user/add-profile-link) | `/api2/v2/users/links` | | `PUT` | [Update a user link](/docs/of-api/user/update-a-user-link) | `/api2/v2/users/links` | | `DELETE` | [Delete a user link](/docs/of-api/user/delete-a-user-link) | `/api2/v2/users/links/{link_id}` | | `POST` | [Log in user](/docs/of-api/user/log-in-user) | `/api2/v2/users/login` | | `POST` | [Log in as a helper](/docs/of-api/user/log-in-as-a-helper) | `/api2/v2/users/login-as-helper/{helper_id}` | | `POST` | [Log out current user](/docs/of-api/user/log-out-current-user) | `/api2/v2/users/logout` | | `DELETE` | [Delete mass message hint](/docs/of-api/user/delete-mass-message-hint) | `/api2/v2/users/mass-hints/{hint_id}` | | `GET` | [Get current user profile](/docs/of-api/user/get-current-user-profile) | `/api2/v2/users/me` | | `PATCH` | [Update user profile](/docs/of-api/user/update-user-profile) | `/api2/v2/users/me` | | `GET` | [Get current auth token](/docs/of-api/user/get-current-auth-token) | `/api2/v2/users/me/auth-token` | | `GET` | [Get current user ID](/docs/of-api/user/get-current-user-id) | `/api2/v2/users/me/id` | | `GET` | [Get profile QR code](/docs/of-api/user/get-profile-qr-code) | `/api2/v2/users/me/profile/views/qr` | | `GET` | [Get account settings](/docs/of-api/user/get-account-settings) | `/api2/v2/users/me/settings` | | `PUT` | [Update user settings section](/docs/of-api/user/update-user-settings-section) | `/api2/v2/users/me/settings/{section}` | | `PATCH` | [Update user settings section](/docs/of-api/user/update-user-settings-section-patch) | `/api2/v2/users/me/settings/{settings_section}` | | `PATCH` | [Update message settings](/docs/of-api/user/update-message-settings) | `/api2/v2/users/me/settings/messages` | | `GET` | [Get creator start date](/docs/of-api/user/get-creator-start-date) | `/api2/v2/users/me/start-date-model` | | `GET` | [Get OTP backup codes](/docs/of-api/user/get-otp-backup-codes) | `/api2/v2/users/me/strong_otp_codes` | | `POST` | [Validate current user data](/docs/of-api/user/validate-current-user-data) | `/api2/v2/users/me/validate-data` | | `PUT` | [Set OpenSea NFT profile item](/docs/of-api/user/set-opensea-nft-profile-item) | `/api2/v2/users/opensea/nft` | | `POST` | [Connect OpenSea wallet](/docs/of-api/user/connect-opensea-wallet) | `/api2/v2/users/opensea/wallet` | | `DELETE` | [Disconnect OpenSea wallet](/docs/of-api/user/disconnect-opensea-wallet) | `/api2/v2/users/opensea/wallet` | | `PUT` | [Confirm OTP code](/docs/of-api/user/confirm-otp-code) | `/api2/v2/users/otp` | | `DELETE` | [Disable two-factor OTP](/docs/of-api/user/disable-two-factor-otp) | `/api2/v2/users/otp` | | `PUT` | [Request alternative OTP method](/docs/of-api/user/request-alternative-otp-method) | `/api2/v2/users/otp/alternative` | | `POST` | [Verify OTP code](/docs/of-api/user/verify-otp-code) | `/api2/v2/users/otp/check` | | `GET` | [Request OTP code](/docs/of-api/user/request-otp-code) | `/api2/v2/users/otp/code` | | `PUT` | [Enable phone OTP](/docs/of-api/user/enable-phone-otp) | `/api2/v2/users/otp/phone` | | `DELETE` | [Remove account password](/docs/of-api/user/remove-account-password) | `/api2/v2/users/password` | | `POST` | [Record profile view](/docs/of-api/user/record-profile-view) | `/api2/v2/users/profile/view` | | `POST` | [Record a profile visit](/docs/of-api/user/record-a-profile-visit) | `/api2/v2/users/profile/visit` | | `DELETE` | [Dismiss a recommended user](/docs/of-api/user/dismiss-a-recommended-user) | `/api2/v2/users/recommends/{user_id}` | | `POST` | [Register a new user account](/docs/of-api/user/register-a-new-user-account) | `/api2/v2/users/register` | | `POST` | [Restore account access with code](/docs/of-api/user/restore-account-access-with-code) | `/api2/v2/users/restore-access` | | `PATCH` | [Update notification settings](/docs/of-api/user/update-notification-settings) | `/api2/v2/users/settings/notifications` | | `GET` | [Get notification transport settings](/docs/of-api/user/get-notification-transport-settings) | `/api2/v2/users/settings/notifications/transports` | | `DELETE` | [Disconnect social network](/docs/of-api/user/disconnect-social-network) | `/api2/v2/users/social/{network}` | | `GET` | [Get social buttons](/docs/of-api/user/get-social-buttons) | `/api2/v2/users/social/buttons` | | `POST` | [Add social buttons](/docs/of-api/user/add-social-buttons) | `/api2/v2/users/social/buttons` | | `PUT` | [Update social profile buttons](/docs/of-api/user/update-social-profile-buttons) | `/api2/v2/users/social/buttons` | | `PUT` | [Update a social button](/docs/of-api/user/update-a-social-button) | `/api2/v2/users/social/buttons/{button_id}` | | `DELETE` | [Delete a social button](/docs/of-api/user/delete-a-social-button) | `/api2/v2/users/social/buttons/{button_id}` | | `POST` | [Register social button click](/docs/of-api/user/register-social-button-click) | `/api2/v2/users/social/buttons/{button_id}/click` | | `PUT` | [Set Spotify anthem](/docs/of-api/user/set-spotify-anthem) | `/api2/v2/users/social/spotify/anthem` | | `PUT` | [Set top Spotify artists](/docs/of-api/user/set-top-spotify-artists) | `/api2/v2/users/social/spotify/artists` | | `POST` | [Connect Spring merch account](/docs/of-api/user/connect-spring-merch-account) | `/api2/v2/users/social/spring` | | `DELETE` | [Disconnect Spring integration](/docs/of-api/user/disconnect-spring-integration) | `/api2/v2/users/social/spring` | | `POST` | [Switch to connected account](/docs/of-api/user/switch-to-connected-account) | `/api2/v2/users/switch/{user_id}` | | `GET` | [Get Telegram link info](/docs/of-api/user/get-telegram-link-info) | `/api2/v2/users/telegram-link` | | `GET` | [Get WebSocket auth token](/docs/of-api/user/get-websocket-auth-token) | `/api2/v2/users/ws-auth` | | `GET` | [List WebAuthn credentials](/docs/of-api/user/list-webauthn-credentials) | `/api2/v2/webauthn/credentials` | | `DELETE` | [Delete a WebAuthn credential](/docs/of-api/user/delete-a-webauthn-credential) | `/api2/v2/webauthn/credentials` | --- # Add or update account helper (/docs/of-api/user/add-or-update-account-helper) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/helpers/{user_id}` Grants or updates an account helper (team member) identified by user_id, assigning the given permission set. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `user_id` (string, required) β€” User id of the helper being granted permissions. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` - `permissions` (any[]) β€” List of permission keys to grant the helper (defaults to empty array). ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/helpers/{user_id}" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Add profile link (/docs/of-api/user/add-profile-link) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/links` Adds a custom link to the current user's profile. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/links" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Add social buttons (/docs/of-api/user/add-social-buttons) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/social/buttons` Adds social/link buttons to the user's profile using the provided button IDs. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` - `buttonIds` (any[]) β€” IDs of the social buttons to add. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/social/buttons" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Block a user (/docs/of-api/user/block-a-user) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/{user_id}/block` **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `user_id` (string, required) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” User blocked ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/{user_id}/block" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Cancel account deletion request (/docs/of-api/user/cancel-account-deletion-request) `DELETE https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/delete/request` Cancels a previously submitted account-deletion request. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/delete/request" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Cancel pending email change (/docs/of-api/user/cancel-pending-email-change) `DELETE https://theonlyapi.com/api/crm/your-crm-id/api2/v2/emails/change` Cancels a pending email-change request (POST on the same path initiates one). **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/emails/change" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Cancel pending phone change (/docs/of-api/user/cancel-pending-phone-change) `DELETE https://theonlyapi.com/api/crm/your-crm-id/api2/v2/phones/change` Cancels a pending phone-number change request (POST on the same path initiates one). **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/phones/change" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Change password (/docs/of-api/user/change-password) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/change-password` Changes the current user's account password. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/change-password" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Check account email (/docs/of-api/user/check-account-email) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/av/email-check` Triggers an email check for the account (av module). Called with no arguments. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/av/email-check" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Check if username exists (/docs/of-api/user/check-if-username-exists) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/exists` Checks whether a username is already taken. Body carries the username to check. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` - `username` (string) β€” Username to check for existence. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/exists" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Confirm OTP code (/docs/of-api/user/confirm-otp-code) `PUT https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/otp` Confirms/enables one-time-password (2FA) by submitting the verification code. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` - `code` (string) β€” OTP verification code. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X PUT "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/otp" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Connect a linked account (/docs/of-api/user/connect-a-linked-account) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/connect` Connects/links another account to the current user (used for multi-account switching). Paired with DELETE /users/connect/{id}. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/connect" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Connect OpenSea wallet (/docs/of-api/user/connect-opensea-wallet) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/opensea/wallet` Links an OpenSea (crypto) wallet to the current user account. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/opensea/wallet" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Connect Spring merch account (/docs/of-api/user/connect-spring-merch-account) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/social/spring` Connects/saves the user's Spring (merch) social integration (DELETE unlinks it, GET retrieves it). **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/social/spring" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Delete a social button (/docs/of-api/user/delete-a-social-button) `DELETE https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/social/buttons/{button_id}` Deletes a profile social/link button identified by button_id. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `button_id` (string, required) β€” Id of the social button to delete. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/social/buttons/{button_id}" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Delete a user link (/docs/of-api/user/delete-a-user-link) `DELETE https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/links/{link_id}` Deletes one of the user's profile links by id. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `link_id` (string, required) β€” ID of the link to delete. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/links/{link_id}" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Delete a WebAuthn credential (/docs/of-api/user/delete-a-webauthn-credential) `DELETE https://theonlyapi.com/api/crm/your-crm-id/api2/v2/webauthn/credentials` Removes a registered WebAuthn (passkey/security key) credential for the current user; the credential identifier is sent in the request body. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/webauthn/credentials" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Delete mass message hint (/docs/of-api/user/delete-mass-message-hint) `DELETE https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/mass-hints/{hint_id}` Deletes a mass-message hint for the current user. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `hint_id` (string, required) β€” ID of the mass-message hint to delete. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/mass-hints/{hint_id}" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Disable two-factor OTP (/docs/of-api/user/disable-two-factor-otp) `DELETE https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/otp` Disables two-factor authentication (OTP) for the account using a verification code. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/otp" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Disconnect a linked account (/docs/of-api/user/disconnect-a-linked-account) `DELETE https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/connect/{account_id}` Disconnects a linked/connected account identified by account_id. Enclosing fn is a disconnect helper. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `account_id` (string, required) β€” ID of the connected account to disconnect. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/connect/{account_id}" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Disconnect OpenSea wallet (/docs/of-api/user/disconnect-opensea-wallet) `DELETE https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/opensea/wallet` Removes the connected OpenSea crypto wallet from the current user account. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/opensea/wallet" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Disconnect social network (/docs/of-api/user/disconnect-social-network) `DELETE https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/social/{network}` Disconnects/unlinks a social network account (defaults to twitter) from the profile. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `network` (string, required) β€” Social network name (e.g. twitter); defaults to twitter. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/social/{network}" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Disconnect Spring integration (/docs/of-api/user/disconnect-spring-integration) `DELETE https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/social/spring` Disconnects/removes the user's linked Spring (merch) social integration. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/social/spring" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Dismiss a recommended user (/docs/of-api/user/dismiss-a-recommended-user) `DELETE https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/recommends/{user_id}` Removes/dismisses a suggested (recommended) user identified by user_id. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `user_id` (string, required) β€” ID of the recommended user to dismiss. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/recommends/{user_id}" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Dismiss user hint (/docs/of-api/user/dismiss-user-hint) `DELETE https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/hints/{hint_id}` Dismisses a UI hint/recommendation by ID for the current user. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `hint_id` (string, required) β€” ID of the hint to dismiss. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/hints/{hint_id}" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Enable phone OTP (/docs/of-api/user/enable-phone-otp) `PUT https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/otp/phone` Enables/requests one-time-password (2FA) delivery via phone for the current user. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X PUT "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/otp/phone" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get account settings (/docs/of-api/user/get-account-settings) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/me/settings` Returns account-level settings including banking status, payout eligibility, and verification state. **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Settings object - `needUpdateBanking` (boolean) β€” Whether banking info needs updating. - `canReceiveManualPayout` (boolean) β€” Manual payout eligibility. - `isVerifiedReason` (string) β€” Verification status reason code. - `needVerifyPayoutData` (boolean) β€” Whether payout data verification is needed. ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/me/settings" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get auth token (/docs/of-api/user/get-auth-token) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/get-auth-token` Retrieves an authentication token for the user. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/get-auth-token" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Get creator start date (/docs/of-api/user/get-creator-start-date) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/me/start-date-model` Returns the current user's creator/model start-date information. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. βœ“ **Verified live** against a real OnlyFans account (2026-07-30); the `data` schema below is the real response shape. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response β€” verified live; `data` is the real shape. - `success` (boolean) - `status_code` (integer) - `data` (object) - `startDate` (string) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/me/start-date-model" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get current auth token (/docs/of-api/user/get-current-auth-token) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/me/auth-token` Retrieves an auth token for the current user (used for authenticated sub-flows). **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. βœ“ **Verified live** against a real OnlyFans account (2026-07-30); the `data` schema below is the real response shape. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response β€” verified live; `data` is the real shape. - `success` (boolean) - `status_code` (integer) - `data` (object) - `token` (string) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/me/auth-token" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get current user ID (/docs/of-api/user/get-current-user-id) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/me/id` Returns the ID of the currently authenticated user. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. βœ“ **Verified live** against a real OnlyFans account (2026-07-30); the `data` schema below is the real response shape. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response β€” verified live; `data` is the real shape. - `success` (boolean) - `status_code` (integer) - `data` (object) - `id` (integer) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/me/id" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get current user profile (/docs/of-api/user/get-current-user-profile) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/me` Returns the authenticated user's full profile including stats, subscription info, and settings. Call via the generic proxy endpoint. **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” User profile object - `id` (integer) - `name` (string) - `username` (string) - `about` (string) - `avatar` (string) - `header` (string) - `email` (string) - `isPerformer` (boolean) - `subscribesCount` (integer) - `subscribersCount` (integer) - `postsCount` (integer) - `photosCount` (integer) - `videosCount` (integer) - `audiosCount` (integer) - `tipsEnabled` (boolean) - `subscribePrice` (number) - `canEarn` (boolean) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/me" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get notification transport settings (/docs/of-api/user/get-notification-transport-settings) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/settings/notifications/transports` Returns the available/enabled notification transport channels (email, push, etc.) for the user. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. βœ“ **Verified live** against a real OnlyFans account (2026-07-30); the `data` schema below is the real response shape. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response β€” verified live; `data` is the real shape. - `success` (boolean) - `status_code` (integer) - `data` (string[]) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/settings/notifications/transports" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get OTP backup codes (/docs/of-api/user/get-otp-backup-codes) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/me/strong_otp_codes` Returns the current user's strong OTP (backup/recovery) codes. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/me/strong_otp_codes" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get OTP token (/docs/of-api/user/get-otp-token) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/get-otp-token` Exchanges credentials for a one-time-password token. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/get-otp-token" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Get pinned friends (/docs/of-api/user/get-pinned-friends) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/{user_id}/friends/pinned` Returns a user's pinned friends. Called as getPinnedFriends({userId}). **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `user_id` (string, required) β€” ID of the user whose pinned friends to fetch. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/{user_id}/friends/pinned" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get profile QR code (/docs/of-api/user/get-profile-qr-code) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/me/profile/views/qr` **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” QR code data - `url` (string) β€” QR code image URL. ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/me/profile/views/qr" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get social buttons (/docs/of-api/user/get-social-buttons) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/social/buttons` Retrieves the current user's configured social media buttons/links. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. βœ“ **Verified live** against a real OnlyFans account (2026-07-30); the `data` schema below is the real response shape. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response β€” verified live; `data` is the real shape. - `success` (boolean) - `status_code` (integer) - `data` (any[]) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/social/buttons" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get Telegram link info (/docs/of-api/user/get-telegram-link-info) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/telegram-link` Returns the Telegram linking information/URL for connecting the account to Telegram. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/telegram-link" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get user links (/docs/of-api/user/get-user-links) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/links` Retrieves the current user's configured profile links. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. βœ“ **Verified live** against a real OnlyFans account (2026-07-30); the `data` schema below is the real response shape. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response β€” verified live; `data` is the real shape. - `success` (boolean) - `status_code` (integer) - `data` (any[]) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/links" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get user public profile (/docs/of-api/user/get-user-public-profile) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/{user_id}` **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `user_id` (string, required) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” User profile - `id` (integer) - `name` (string) - `username` (string) - `displayName` (string) - `about` (string) - `avatar` (string) β€” Avatar URL. - `avatarThumbs` (object) - `c50` (string) - `c144` (string) - `header` (string) β€” Profile header/banner URL. - `email` (string) - `isVerified` (boolean) - `isPerformer` (boolean) - `canEarn` (boolean) - `tipsEnabled` (boolean) - `subscribedBy` (boolean) β€” Whether you are subscribed to this user. - `subscribersCount` (integer) - `subscribesCount` (integer) - `postsCount` (integer) - `photosCount` (integer) - `videosCount` (integer) - `audiosCount` (integer) - `friendsCount` (integer) - `joinDate` (string) - `firstPublishedPostDate` (string) - `subscribePrice` (number) - `chatMessagesCount` (integer) β€” Unread chat messages. - `countPriorityChat` (integer) - `countPinnedChat` (integer) - `hasPurchasedPosts` (boolean) - `paidFeed` (boolean) - `openseaInfo` (object) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/{user_id}" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get user's links (/docs/of-api/user/get-user-s-links) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/{user_id}/links` Retrieves the profile links configured by a user. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `user_id` (string, required) β€” ID of the user whose links to fetch. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/{user_id}/links" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get user social buttons (/docs/of-api/user/get-user-social-buttons) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/{user_id}/social/buttons` Retrieves the social/link buttons configured on a user's profile. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `user_id` (string, required) β€” ID of the user whose social buttons to fetch. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/{user_id}/social/buttons" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get WebSocket auth token (/docs/of-api/user/get-websocket-auth-token) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/ws-auth` Returns authentication data/token needed to establish the realtime WebSocket connection. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. βœ“ **Verified live** against a real OnlyFans account (2026-07-30); the `data` schema below is the real response shape. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response β€” verified live; `data` is the real shape. - `success` (boolean) - `status_code` (integer) - `data` (object) - `wsUrl` (string) - `wsAuthToken` (string) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/ws-auth" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get Yoti face-ID verification URL (/docs/of-api/user/get-yoti-face-id-verification-url) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/iv/yoti-face-id-url/{id}/{token}` Returns a Yoti face-ID identity-verification URL for the given identifiers. Part of the /iv identity-verification module (also yoti-redirect-url). **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `id` (string, required) β€” First path identifier (uncertain; likely verification/session id). - `token` (string, required) β€” Second path identifier (uncertain; likely a token/type/hash). ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/iv/yoti-face-id-url/{id}/{token}" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Get Yoti identity verification URL (/docs/of-api/user/get-yoti-identity-verification-url) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/iv/yoti-redirect-url/{verification_id}` Retrieves a Yoti identity-verification redirect URL for the identity verification (iv) flow. Sibling call fetches a Yoti face-ID URL. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `verification_id` (string, required) β€” Identifier for the Yoti identity verification session (exact meaning uncertain). ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/iv/yoti-redirect-url/{verification_id}" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # List active sessions (/docs/of-api/user/list-active-sessions) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/sessions` Retrieves the current user's active login sessions. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. βœ“ **Verified live** against a real OnlyFans account (2026-07-30); the `data` schema below is the real response shape. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response β€” verified live; `data` is the real shape. - `success` (boolean) - `status_code` (integer) - `data` (object[]) - `isCurrent` (boolean) - `lastActivity` (integer) - `ipAddress` (string) - `countryName` (string) - `client` (string) - `os` (string) - `brand` (string) - `loginMessage` (null) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/sessions" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # List blocked users (/docs/of-api/user/list-blocked-users) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/blocked` **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Query parameters - `limit` (integer) β€” Default `10`. - `offset` (integer) β€” Default `0`. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” Blocked users list - `list` (object[]) - `id` (integer) - `name` (string) - `username` (string) - `displayName` (string) - `about` (string) - `avatar` (string) β€” Avatar URL. - `avatarThumbs` (object) - `c50` (string) - `c144` (string) - `header` (string) β€” Profile header/banner URL. - `email` (string) - `isVerified` (boolean) - `isPerformer` (boolean) - `canEarn` (boolean) - `tipsEnabled` (boolean) - `subscribedBy` (boolean) β€” Whether you are subscribed to this user. - `subscribersCount` (integer) - `subscribesCount` (integer) - `postsCount` (integer) - `photosCount` (integer) - `videosCount` (integer) - `audiosCount` (integer) - `friendsCount` (integer) - `joinDate` (string) - `firstPublishedPostDate` (string) - `subscribePrice` (number) - `chatMessagesCount` (integer) β€” Unread chat messages. - `countPriorityChat` (integer) - `countPinnedChat` (integer) - `hasPurchasedPosts` (boolean) - `paidFeed` (boolean) - `openseaInfo` (object) - `hasMore` (boolean) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/blocked" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # List login sessions (/docs/of-api/user/list-login-sessions) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/logins` Returns the account's login sessions/history. Paired with DELETE /logins/{id} to revoke a session. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. βœ“ **Verified live** against a real OnlyFans account (2026-07-30); the `data` schema below is the real response shape. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response β€” verified live; `data` is the real shape. - `success` (boolean) - `status_code` (integer) - `data` (object) - `items` (object[]) - `login` (string) - `date` (string) - `isPersistent` (boolean) - `hasMore` (boolean) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/logins" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # List user's Shopify stores (/docs/of-api/user/list-user-s-shopify-stores) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/{user_id}/shopify/stores` Retrieves the Shopify stores connected to a given user. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `user_id` (string, required) β€” ID of the user whose Shopify stores are listed. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/{user_id}/shopify/stores" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # List WebAuthn credentials (/docs/of-api/user/list-webauthn-credentials) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/webauthn/credentials` Returns the current user's registered WebAuthn (passkey/security key) credentials. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. βœ“ **Verified live** against a real OnlyFans account (2026-07-30); the `data` schema below is the real response shape. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response β€” verified live; `data` is the real shape. - `success` (boolean) - `status_code` (integer) - `data` (any[]) ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/webauthn/credentials" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Log in as a helper (/docs/of-api/user/log-in-as-a-helper) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/login-as-helper/{helper_id}` Impersonates/switches into a helper (team member) account identified by helper id. Paired with POST /users/helper-logout. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `helper_id` (string, required) β€” ID of the helper account to log in as. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/login-as-helper/{helper_id}" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Log in user (/docs/of-api/user/log-in-user) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/login` Authenticates a user and starts a session. Accepts login credentials in the request body. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/login" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Log out current user (/docs/of-api/user/log-out-current-user) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/logout` Logs out the currently authenticated user session. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/logout" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Log out helper session (/docs/of-api/user/log-out-helper-session) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/helper-logout` Ends a helper (login-as-helper) session and returns to the primary account. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/helper-logout" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Mark device as trusted (/docs/of-api/user/mark-device-as-trusted) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/trust` Marks the current session/device as trusted. Found next to webauthn, oauth/confirm and logout auth calls. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/trust" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Postpone face-ID verification (/docs/of-api/user/postpone-face-id-verification) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/face-id/postpone` Postpones the required Face ID identity verification step. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/face-id/postpone" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Record a profile visit (/docs/of-api/user/record-a-profile-visit) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/profile/visit` Records a profile visit event; a sibling POST /users/profile/view records profile views. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/profile/visit" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Record cookie consent (/docs/of-api/user/record-cookie-consent) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/accepted-cookies` Stores the user's accepted cookie/consent preferences. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/accepted-cookies" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Record profile view (/docs/of-api/user/record-profile-view) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/profile/view` Records that the current user viewed a profile (paired with users/profile/visit). Retries once on failure. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/profile/view" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Register a new user account (/docs/of-api/user/register-a-new-user-account) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/register` Registers a new user account. The request body carries the registration form fields. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/register" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Register social button click (/docs/of-api/user/register-social-button-click) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/social/buttons/{button_id}/click` Records a click on a user's social button. Part of the profile social-buttons feature. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `button_id` (string, required) β€” ID of the social button clicked. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/social/buttons/{button_id}/click" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Remove account helper (/docs/of-api/user/remove-account-helper) `DELETE https://theonlyapi.com/api/crm/your-crm-id/api2/v2/helpers/{helper_id}` Removes a helper (delegated team member) from the account. Related calls manage helper permissions and login-as-helper. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `helper_id` (string, required) β€” User ID of the helper to remove. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/helpers/{helper_id}" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Remove account password (/docs/of-api/user/remove-account-password) `DELETE https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/password` Deletes the current user's password (e.g. for social-login-only accounts). **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/password" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Report login issue (/docs/of-api/user/report-login-issue) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/issues/login` Submits a login issue report (support). Called with an optional payload object. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/issues/login" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Request account deletion (/docs/of-api/user/request-account-deletion) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/delete/request` Submits a request to delete the current user's account. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` - `captchaCode` (string) β€” Captcha verification code. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/delete/request" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Request alternative OTP method (/docs/of-api/user/request-alternative-otp-method) `PUT https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/otp/alternative` Requests an alternative one-time-password (2FA) delivery method. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X PUT "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/otp/alternative" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Request email address change (/docs/of-api/user/request-email-address-change) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/emails/change` Initiates a change of the account's email address. A DELETE on the same path cancels a pending change. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/emails/change" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Request OTP code (/docs/of-api/user/request-otp-code) `GET https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/otp/code` Requests/retrieves a one-time password (OTP) code for the current user. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X GET "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/otp/code" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Request password reset (/docs/of-api/user/request-password-reset) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/forgot-password` Initiates a forgot-password / password-reset request. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/forgot-password" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Request phone number change (/docs/of-api/user/request-phone-number-change) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/phones/change` Initiates a change of the account's phone number. A DELETE on the same path cancels a pending change. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/phones/change" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Resend confirmation email (/docs/of-api/user/resend-confirmation-email) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/emails/resend` Resends the account confirmation/verification email. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/emails/resend" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Restore account access with code (/docs/of-api/user/restore-account-access-with-code) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/restore-access` Restores access to a user account using a provided restore/verification code. Sent with a skip429Alert retry config. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` - `code` (string) β€” Restore-access code. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/restore-access" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Restrict a user (/docs/of-api/user/restrict-a-user) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/{user_id}/restrict` **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `user_id` (string, required) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” User restricted ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/{user_id}/restrict" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Revoke a login session (/docs/of-api/user/revoke-a-login-session) `DELETE https://theonlyapi.com/api/crm/your-crm-id/api2/v2/logins/{login_id}` Revokes/removes an active login session identified by login id. Paired with GET /logins which lists active sessions. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `login_id` (string, required) β€” ID of the login/session to revoke. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/logins/{login_id}" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Revoke all sessions (/docs/of-api/user/revoke-all-sessions) `DELETE https://theonlyapi.com/api/crm/your-crm-id/api2/v2/sessions` Terminates the user's active login sessions (used in the sessions settings screen). **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/sessions" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Set OpenSea NFT profile item (/docs/of-api/user/set-opensea-nft-profile-item) `PUT https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/opensea/nft` Updates the OpenSea NFT associated with the user's profile. Sibling calls manage the linked OpenSea wallet and asset listings. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X PUT "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/opensea/nft" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Set Spotify anthem (/docs/of-api/user/set-spotify-anthem) `PUT https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/social/spotify/anthem` Sets the user's Spotify profile anthem track. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` - `anthemId` (string) β€” Spotify track ID to set as the anthem. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X PUT "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/social/spotify/anthem" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Set top Spotify artists (/docs/of-api/user/set-top-spotify-artists) `PUT https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/social/spotify/artists` Sets the user's top Spotify artists shown on their profile. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` - `topArtistsIds` (any[]) β€” IDs of the top Spotify artists. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X PUT "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/social/spotify/artists" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Start age verification (/docs/of-api/user/start-age-verification) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/age-verifier/start` Initiates the age verification flow. Grouped with iv/start and face-id/start identity checks. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/age-verifier/start" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Start Face ID verification (/docs/of-api/user/start-face-id-verification) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/face-id/start` Starts a Face ID (biometric identity) verification session. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/face-id/start" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Start identity verification (/docs/of-api/user/start-identity-verification) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/iv/start` Starts an identity-verification (IV) flow for the user. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/iv/start" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Submit account appeal (/docs/of-api/user/submit-account-appeal) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/appeal` Submits an appeal, e.g. against an account restriction or moderation action. Defined near reports/reasons and unsubscribe/reasons calls. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/appeal" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Switch to connected account (/docs/of-api/user/switch-to-connected-account) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/switch/{user_id}` Switches the active session to a connected/linked user account. Defined near users/connect and users/get-auth-token. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `user_id` (string, required) β€” ID of the connected account to switch to. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/switch/{user_id}" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Unblock a user (/docs/of-api/user/unblock-a-user) `DELETE https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/{user_id}/block` **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `user_id` (string, required) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Responses ### 200 β€” User unblocked ## Example ```bash curl -X DELETE "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/{user_id}/block" \ -H "X-API-Key: " \ -H "user-id: …" ``` --- # Update a social button (/docs/of-api/user/update-a-social-button) `PUT https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/social/buttons/{button_id}` Updates a single social button by id on the user's profile. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `button_id` (string, required) β€” ID of the social button to update. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X PUT "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/social/buttons/{button_id}" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Update a user link (/docs/of-api/user/update-a-user-link) `PUT https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/links` Updates one of the user's external profile links. Sibling calls list, create and delete links. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` - `link` (string|object) β€” The link value to update. ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X PUT "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/links" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Update message settings (/docs/of-api/user/update-message-settings) `PATCH https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/me/settings/messages` Updates the current user's messaging settings. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X PATCH "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/me/settings/messages" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Update notification settings (/docs/of-api/user/update-notification-settings) `PATCH https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/settings/notifications` Updates the account's notification settings. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X PATCH "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/settings/notifications" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Update social profile buttons (/docs/of-api/user/update-social-profile-buttons) `PUT https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/social/buttons` Updates the configuration of the user's social profile buttons. Sibling calls add, reorder, delete and track clicks on these buttons. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X PUT "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/social/buttons" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Update user profile (/docs/of-api/user/update-user-profile) `PATCH https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/me` Update profile fields. Supports display name, about text, subscription price, tip settings, and more. Only include the fields you want to change. **OnlyFans only.** Requests made with a `user-id` belonging to a Fansly account are rejected β€” use the platform-neutral CRM data routes (`/notifications`, `/balances`, `/chats`, `/purchases`, `/subscribers/cached`, ...) which are Fansly-aware. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` - `displayName` (string) β€” Profile display name. e.g. `"My Creator Name"`. - `about` (string) β€” Bio / about text. e.g. `"Welcome to my page! πŸ’•"`. - `subscribePrice` (number) β€” Monthly subscription price in USD. e.g. `9.99`. - `tipsEnabled` (boolean) β€” Whether tips are enabled on the profile. - `tipsMin` (number) β€” Minimum tip amount in USD. - `tipsMax` (number) β€” Maximum tip amount in USD. - `location` (string) β€” Profile location text. - `website` (string) β€” Website URL. - `wishlist` (string) β€” Amazon wishlist URL. - `showPostsTipsSum` (boolean) β€” Show tip totals on posts. - `showMediaCount` (boolean) β€” Show photo/video counts on profile. - `showPostsCount` (boolean) β€” Show total posts count. - `canCommentOnContent` (boolean) β€” Allow comments on posts. - `isPossibleToReply` (boolean) β€” Allow DM replies. ## Responses ### 200 β€” Updated profile ## Example **Update subscription price** ```bash curl -X PATCH "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/me" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{"subscribePrice":14.99}' ``` **Update bio and display name** ```bash curl -X PATCH "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/me" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{"displayName":"My New Name","about":"Welcome to my page! πŸ’• DM me for custom content."}' ``` **Update profile settings** ```bash curl -X PATCH "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/me" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{"tipsEnabled":true,"tipsMin":5,"canCommentOnContent":true}' ``` --- # Update user settings section (/docs/of-api/user/update-user-settings-section) `PUT https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/me/settings/{section}` Replaces the settings for a specific settings section of the current user. The section key is the path param and the settings payload is the body. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `section` (string, required) β€” Settings section/type key (e.g. messages, story, streams). ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X PUT "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/me/settings/{section}" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Update user settings section (/docs/of-api/user/update-user-settings-section-patch) `PATCH https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/me/settings/{settings_section}` Partially updates a named section of the current user's settings. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Path parameters - `settings_section` (string, required) β€” Name of the settings section to update. ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X PATCH "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/me/settings/{settings_section}" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Validate current user data (/docs/of-api/user/validate-current-user-data) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/me/validate-data` Validates submitted profile/account data for the current user. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/me/validate-data" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Verify OTP code (/docs/of-api/user/verify-otp-code) `POST https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/otp/check` Verifies a one-time password code. Grouped with users/otp code/phone/alternative endpoints. **OnlyFans only** β€” Fansly accounts are rejected on `/api2/v2/*`. **Guide:** [The two surfaces](/docs/two-surfaces) ## Authentication - `X-API-Key` header (apiKey) ## Header parameters - `user-id` (string, required) β€” Creator account ID of the account to act as (e.g. `509955039`). **Required** β€” omitting it returns `400 user-id header is required`. Use `GET /accounts` to list your connected accounts. On `/api2/v2/*` the account must be an OnlyFans account; Fansly accounts are rejected there. - `X-Proxy` (string) β€” Proxy URL β€” HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. **Required on the connection routes** (`POST /accounts/login`, `POST /accounts/login/cookies`, `POST /accounts/login/verify-otp`) for OnlyFans accounts; optional for Fansly. ## Request body Content type: `application/json` ## Responses ### 200 β€” OnlyFans response (passthrough envelope) `data` carries OnlyFans' own response body for this endpoint, passed through unchanged. - `success` (boolean, required) β€” True when OnlyFans returned a 2xx status. - `status_code` (integer, required) β€” The upstream OnlyFans HTTP status code. - `data` (any, required) β€” The raw OnlyFans response body (object or array). - `relogin` (boolean) β€” Present and true when the session was refreshed mid-request. ## Example ```bash curl -X POST "https://theonlyapi.com/api/crm/your-crm-id/api2/v2/users/otp/check" \ -H "X-API-Key: " \ -H "user-id: …" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Pagination (/docs/pagination) Three pagination conventions coexist in this API, inherited from the two platforms underneath. Getting these wrong silently loses data β€” usually most of it β€” so this page is worth reading in full before you write a walker. ## 1. Offset + limit, with a total [#1-offset--limit-with-a-total] The `/cached` routes and other server-side reads. ``` GET /accounts/{of_user_id}/subscribers/cached?limit=100&offset=0 ``` ```json { "success": true, "list": [ … ], "count": 100, "total": 412, "limit": 100, "offset": 0, "hasMore": true } ``` Walk until `hasMore` is `false`. This is the only convention where `total` is trustworthy. The high-traffic paginated reads return their rows under a generic `list`, not under a key named after the resource. Getting this wrong yields zero rows silently. | Route | Array key | | ----------------------------------------------------------------------- | ------------------------ | | `/subscribers/cached`, `/subscribers` (live) | `list` | | `/transactions/cached`, `/fans/{id}/transactions/cached` | `list` | | `/claimers/cached` | `list` | | `/subscribers/new` | `subscribers` | | `/fans`, `/campaigns`, `/claimers`, `/purchases`, `/chats`, `/messages` | named after the resource | Per-route limits: `/subscribers/cached` and `/fans` max 500; `/transactions/cached`, `/fans/{id}/transactions/cached` and `/claimers/cached` max 1000; `/subscribers/new` defaults to **50**; `/notifications` defaults to 20, max 100; `/events` defaults to 100, max 500. Exceeding a max is a `400`, not a clamp. ## 2. Offset + limit, no total [#2-offset--limit-no-total] Live reads that proxy a platform which does not report a total β€” `/campaigns`, `/claimers`, `/purchases`, live `/subscribers`. ```json { "success": true, "campaigns": [ … ], "hasMore": true } ``` There is no `total` β€” and these routes do not echo `limit` or `offset` back either. Walk on `hasMore` alone, tracking the offset yourself. `GET /accounts/{of_user_id}/subscribers` returns `nextOffset`. Always pass that back. Do **not** compute `offset + len(list)` there: on Fansly we request an unfiltered page and filter it server-side, so the stream consumed more rows than you received β€” advancing by `len(list)` silently skips every filtered-out subscriber. Only on routes that emit no cursor (`/chats`, `/campaigns`, `/claimers`) do you advance yourself, and there you must use the page length, because a short page does not mean the end: ```python offset += len(page) # NOT offset += limit ``` ## 3. Cursor (`marker` / `id`) [#3-cursor-marker--id] The OnlyFans transactions walker uses an opaque `marker`: ``` GET /accounts/{of_user_id}/purchases?limit=100&marker= ``` ```json { "success": true, "purchases": [ … ], "marker": "eyJ…", "hasMore": true } ``` The response carries both `marker` (the one you sent) and `nextMarker` β€” pass `nextMarker` back on the next request. Do not construct or parse it. Message history uses an `id` cursor β€” but **only on the passthrough**: ``` GET /api/crm/{crm_id}/api2/v2/chats/{fan_id}/messages?id= ``` `GET /accounts/{of_user_id}/chats/{with_user_id}/messages` accepts only `limit` (max 100, default 50) and `offset`; an `id` parameter is silently dropped. Offset paging over this platform endpoint is lossy β€” it both skips and repeats messages. Use the CRM route to read a recent window. To walk a **full** history, go through the passthrough with the `id=` cursor, dedupe on message id, and stop when a page yields nothing new. ## The two traps [#the-two-traps] These are the specific behaviours that break naive walkers. `GET /accounts/{of_user_id}/chats` accepts a `limit` parameter and then largely disregards it β€” a request for 50 typically returns **10 to 14** conversations. Do not treat "fewer than `limit` returned" as the end of the list, and do not size your loop by dividing a total by `limit`. Walk on `hasMore`, advancing `offset` by the number of items you received. `GET /accounts/{of_user_id}/chats/{with_user_id}/messages` needs the `id=` cursor, and it will regularly return a short page β€” sometimes a nearly empty one β€” in the middle of a conversation that has thousands more messages. Terminate on the platform's own `hasMore` signal, or on receiving a genuinely empty page, and never on `len(page) < limit`. A walker that stops at the first short page can lose the overwhelming majority of a message history. ## `hasMore` is camelCase [#hasmore-is-camelcase] Note the casing. Bodies are otherwise snake\_case (`of_user_id`, `created_at`, `api_calls_used`), but `hasMore` is camelCase because it comes straight from OnlyFans. `total`, `limit` and `offset` are lowercase. ## A correct walker [#a-correct-walker] ```python import requests def walk(session, url, key, params=None, item_key="items", page_size=100): """Walk an offset-paginated CRM route without losing short pages.""" offset = 0 while True: r = session.get( url, headers={"X-API-Key": key}, params={**(params or {}), "limit": page_size, "offset": offset}, timeout=60, ) r.raise_for_status() body = r.json() page = body.get(item_key) or [] yield from page # Advance by what we actually received β€” these offsets are per item. offset += len(page) # Trust the platform's own signal, not the page length. if not body.get("hasMore"): return if not page: return # defensive: hasMore true but nothing coming back ``` For cursor routes, carry the `marker` (or `id`) forward instead of an offset, and stop when `hasMore` is false. ## Routes that take only `limit` [#routes-that-take-only-limit] `GET /events` (default 100, max 500) and `GET /accounts/{of_user_id}/notifications` (default **20**, max **100**) accept `limit` with no offset. `/events` is filtered by `types`, `of_user_id`, `since` and `until` instead β€” see [Events](/docs/events). --- # OnlyFans & Fansly (/docs/platforms) Every connected account has a `platform` of either `onlyfans` or `fansly`. All three connection routes accept a `platform` field in the request body (`"onlyfans" | "fansly"`, default `"onlyfans"`). Once connected, the account ID is returned as `of_user_id` **regardless of platform**. That same value is the `{of_user_id}` path parameter and the `user-id` header on the `/api2/v2/*` passthrough β€” the only route that reads it. ## Support matrix [#support-matrix] | Surface | OnlyFans | Fansly | | ------------------------------------------------------------------------------------------------- | -------- | ------------------------------- | | Most CRM data routes (`/accounts/…`, `/fans`, `/events`, `/webhooks`, `/automations`, `/exports`) | yes | yes | | Transparent passthrough (`/api2/v2/*`) | yes | **no β€” 501** | | `POST /accounts/{of_user_id}/payout-requests` | yes | **no β€” 501** | | `GET /accounts/{of_user_id}/campaigns/{campaign_id}/claimers` | yes | **no β€” 501** | | `POST /accounts/{of_user_id}/campaigns` (create) | yes | **no β€” 501** | | `PATCH /accounts/{of_user_id}/subscription-price` | yes | **no β€” 501** (GET works) | | `GET /accounts/{of_user_id}/ppv-stats` | yes | **no β€” 501** | | The three `/referrals` routes | yes | **no β€” 501** | | `POST /accounts/{of_user_id}/request` (raw proxy) | yes | **no β€” 501** | | Real-time WebSocket | yes | **no** β€” Fansly is polling-only | | `POST /accounts/{of_user_id}/messages/mass` (mass DM) | yes | **no β€” 501** | ## What rejection looks like [#what-rejection-looks-like] Nearly every rejection is a `501` from one shared helper, with a lowercase code plus the feature name: ```json { "success": false, "code": "platform_not_supported", "error": "\"referrals\" is not available for fansly accounts yet.", "platform": "fansly", "feature": "referrals" } ``` Mass messaging is the one exception β€” it hand-rolls an **uppercase** code, so compare case-insensitively: ```json { "success": false, "code": "PLATFORM_NOT_SUPPORTED", "error": "mass messaging is OnlyFans-only for now" } ``` ## Write platform-agnostic code [#write-platform-agnostic-code] Prefer the **normalized CRM routes**. They are Fansly-aware, they project both platforms' rows to the same shape, and several of them are server-side aggregations with no platform equivalent at all: ``` /accounts/{of_user_id}/notifications /accounts/{of_user_id}/balances /accounts/{of_user_id}/chats /accounts/{of_user_id}/purchases /accounts/{of_user_id}/subscribers/cached /accounts/{of_user_id}/transactions/cached /earnings/summary /fans ``` Reach for the passthrough only when you need an OnlyFans capability the CRM layer does not expose β€” and branch before you do. `GET /accounts` returns a per-account `capabilities` object, which is the authoritative matrix; prefer it over hard-coding this table. do. Fansly reports monetary amounts at a different scale than OnlyFans. The normalized CRM routes handle the conversion for you; raw passthrough responses do not, because they are OnlyFans' own bytes. See [Earnings & transactions](/docs/earnings). ## Fansly-specific helpers [#fansly-specific-helpers] ``` GET /accounts/{of_user_id}/fansly-credentials ``` Returns the stored Fansly credential block for a connected account. --- # Posting & scheduling (/docs/posting) Posting media is two calls: upload the file, then create the post referencing what you got back. ```bash # 1. upload curl -X POST "$BASE/api/crm/$CRM/accounts/$OFUID/media" \ -H "X-API-Key: $KEY" -F "file=@photo.jpg" # -> {"success":true,"media":{"processId":"…","host":"…","thumbId":1,"name":"photo.jpg","extra":"…"}} # 2. post it, passing that object through whole curl -X POST "$BASE/api/crm/$CRM/api2/v2/posts" \ -H "X-API-Key: $KEY" -H "user-id: $OFUID" -H "Content-Type: application/json" \ -d '{"text":"new set πŸ”₯","mediaFiles":[{"processId":"…","host":"…","thumbId":1,"name":"photo.jpg","extra":"…"}]}' ``` A runnable Python client covering upload, immediate posting, scheduling and every trap on this page: [theonlyapi-posting-example.zip](/theonlyapi-posting-example.zip). ## Uploading [#uploading] Two ways in β€” raw bytes, or a URL we fetch for you. ```bash curl -X POST "$BASE/api/crm/$CRM/accounts/$OFUID/media" \ -H "X-API-Key: $KEY" \ -F "file=@photo.jpg" ``` Any format OnlyFans accepts, including **HEIC** straight off an iPhone. Up to 512 MB. ```bash curl -X POST "$BASE/api/crm/$CRM/accounts/$OFUID/media" \ -H "X-API-Key: $KEY" -H "Content-Type: application/json" \ -d '{"source_url":"https://drive.google.com/uc?export=download&id=FILE_ID"}' ``` The URL must return the **file bytes**, not a viewer page. For Google Drive that means sharing as "Anyone with the link" and using the `uc?export=download&id=` form β€” a `/file/d/…/view` link returns HTML and is rejected at `stage: "fetch"`. Large Drive files return a virus-scan interstitial and can't be fetched this way. OnlyFans has no single upload endpoint of its own β€” internally it's a signed S3 create, a direct `PUT` of the bytes (5 MiB parts above 5 MiB), a multipart finish, then a handoff to a converter host. `POST /accounts/{of_user_id}/media` runs all four server-side so you make one call. On failure the response carries a `stage` β€” `fetch`, `create`, `put` or `convert` β€” telling you which part broke. ## Scheduling [#scheduling] Send `isScheduled` **and** `scheduledDate`: ```bash curl -X POST "$BASE/api/crm/$CRM/api2/v2/posts" \ -H "X-API-Key: $KEY" -H "user-id: $OFUID" -H "Content-Type: application/json" \ -d '{ "text": "going live tomorrow", "mediaFiles": [ { "processId": "…", "host": "…", "thumbId": 1, "name": "photo.jpg", "extra": "…" } ], "isScheduled": 1, "scheduledDate": "2026-08-20T12:00:00+00:00" }' ``` Confirm it actually queued β€” `GET /api2/v2/schedules` should list the post id: ```bash curl "$BASE/api/crm/$CRM/api2/v2/schedules" -H "X-API-Key: $KEY" -H "user-id: $OFUID" ``` Delete a queued post the same way as a published one: `DELETE /api2/v2/posts/{post_id}`. ## Four ways this fails silently [#four-ways-this-fails-silently] Each of these returns **HTTP 200** while doing nothing you wanted. `postedAt` is ignored on create. In **either** format (`…Z` or `…+00:00`) the post publishes immediately. If you have been scheduling with `postedAt`, those posts went out the moment you created them. Use `isScheduled` + `scheduledDate`, and verify against `/api2/v2/schedules`. | body | result | | ------------------------------------------------------- | ------------------------- | | `mediaFiles: [{processId, host, thumbId, name, extra}]` | attached | | `media: [{…same object…}]` | post created, **0 media** | | `mediaFiles: [{processId}]` alone | post created, **0 media** | Pass the upload result through **whole**. Dropping `thumbId` or `name` loses the attachment with no error. Check `media.length` on the response. OnlyFans creates the vault row when a post **consumes** the media β€” roughly 10–15 seconds after posting, not at upload time. A fresh upload will not appear in `GET /api2/v2/vault/media`, nor in `/vault/media/processing`, nor under `/vault/media/hash`. This is OnlyFans' own behaviour: it has no upload-to-vault operation, and its web client's vault page is browse/organise only. Don't poll the vault for a new upload's id β€” use the returned object. Integer vault IDs are only for re-using media that has already been posted. Two posts inside ten seconds returns `400 "Please allow 10 seconds"`. Space them by 12s when publishing in a loop. ## Write actions are off by default [#write-actions-are-off-by-default] Uploading and posting act as the creator, so both are gated per account. Enable once: ```bash curl -X PATCH "$BASE/api/crm/$CRM/accounts/$OFUID/polling" \ -H "X-API-Key: $KEY" -H "Content-Type: application/json" \ -d '{"allow_of_write_actions": true}' ``` Without it you get `403` with `code: "WRITES_DISABLED"` β€” match on the code, not the message. Check current state with `GET /accounts/{of_user_id}/polling`. The account capability `send_attachments` refers to **DM** attachments, which are not wired yet. Upload support is reported by `media_upload`. ## Re-using media already in the vault [#re-using-media-already-in-the-vault] Media that has been posted before is referenced by plain integer id: ```bash curl "$BASE/api/crm/$CRM/api2/v2/vault/media?field=recent&sort=desc&limit=24" \ -H "X-API-Key: $KEY" -H "user-id: $OFUID" ``` Both forms can go in the same `mediaFiles` array β€” integers for existing vault media, whole objects for fresh uploads. To match a local file against something already uploaded, use `GET /api2/v2/vault/media/hash?h={md5}&size={bytes}` (note `h`, not `hash`). The MD5 must be of the **original** bytes; a re-encoded or CDN-downloaded copy will not match. ## Stories and messages [#stories-and-messages] The same uploaded object attaches to stories (`POST /api2/v2/stories`) and DMs (`POST /api2/v2/chats/{fan_id}/messages`) through the same `mediaFiles` field. See [Messaging & mass DM](/docs/messaging) for the send flow and the PPV pricing rules. ## Platform support [#platform-support] OnlyFans only. Fansly accounts return `501` from the upload endpoint β€” its upload pipeline is not wired yet. See [Platforms](/docs/platforms). --- # Proxies (/docs/proxies) OnlyFans ties a session to the network it was created from. If requests for that session start arriving from a different IP, the session gets invalidated. So every OnlyFans account is bound to a proxy at connect time, and we route all of its subsequent traffic through the same one. | Platform | `X-Proxy` on connect | On later requests | | -------- | -------------------------------------- | ------------------------------------ | | OnlyFans | not enforced, but strongly recommended | optional β€” overrides the saved proxy | | Fansly | optional | optional | ## Supplying one [#supplying-one] Pass it as a header on the connection routes: ```bash curl -X POST "$BASE/api/crm/$CRM/accounts/login/cookies" \ -H "X-API-Key: $KEY" \ -H "X-Proxy: http://user:pass@host:port" \ … ``` It is saved with the account. You do not send it again unless you want to override it for a single request. ## Accepted formats [#accepted-formats] ``` http://user:pass@host:port https://user:pass@host:port http://host:port socks5://user:pass@host:port socks5h://user:pass@host:port # DNS resolved proxy-side host:port:user:pass # compact form, converted to http:// ``` The compact form splits on the first three colons, so a password containing a colon survives. `socks5h://` resolves hostnames at the proxy rather than locally, which is usually what you want with SOCKS. ## Test before you connect [#test-before-you-connect] ```bash curl -X POST "$BASE/api/crm/$CRM/proxy/test" \ -H "X-API-Key: $KEY" \ -H "Content-Type: application/json" \ -d '{"proxy": "http://user:pass@host:port"}' ``` Worth doing first β€” a bad proxy during login looks like a login failure, and login routes are limited to 100 requests/minute. `/proxy/test` blocks loopback, private and link-local addresses as an SSRF guard, so a proxy on your own machine reports as a failure rather than a pass. ## Changing an account's proxy [#changing-an-accounts-proxy] ```bash curl -X PATCH "$BASE/api/crm/$CRM/accounts/$OFUID/proxy" \ -H "X-API-Key: $KEY" \ -H "Content-Type: application/json" \ -d '{"proxy": "http://user:pass@newhost:port"}' ``` `GET` the same path to read the current one. Swapping to a proxy that exits from a noticeably different city or country tends to invalidate the session, because it looks exactly like an account takeover. Expect to reconnect the account. Rotate within the same region if you must rotate. ## Choosing proxies [#choosing-proxies] * **One proxy per account.** Sharing an IP across many creator accounts is a reliable way to get all of them flagged together. * **Residential or ISP proxies** behave better than datacenter ranges, which OnlyFans is more aggressive about. * **Sticky sessions**, not per-request rotation. A rotating proxy that changes IP mid-session defeats the entire point. ## Credentials in logs [#credentials-in-logs] Proxy URLs contain credentials. They are stored server-side with the account and never reflected back except through `GET /accounts?include_session=true` and `GET /accounts/{of_user_id}/proxy`, both of which need your API key. Server errors are deliberately opaque so a proxy URL cannot leak through a stack trace β€” see [Responses & errors](/docs/responses). --- # Quickstart (/docs/quickstart) You need two things before any call works: an **API key** and a **connected creator account**. ## Get an API key [#get-an-api-key] Sign up at [theonlyapi.com](https://theonlyapi.com/pricing) and copy your key from **Dashboard β†’ Settings β†’ API Credentials** (or **Dashboard β†’ API Keys**). The same screen shows your `crm_id`. Keys look like a 43-character URL-safe string. Treat one like a password β€” it grants full access to the panel. Signing up provisions the panel and its first key together, so there is nothing else to create. See [Get an API key](/docs/get-an-api-key). ## Set up your environment [#set-up-your-environment] ```bash export BASE="https://theonlyapi.com" export CRM="crm_xxxxxxxxxxxxxxxx" # your panel id export KEY="YOUR_API_KEY" # your API key export OFUID="482687148" # an of_user_id from GET /accounts (step 4) ``` ## Connect a creator account [#connect-a-creator-account] The recommended way is to paste session cookies once. Grab `sess` and `auth_id` from a browser logged into OnlyFans (**DevTools β†’ Application β†’ Cookies β†’ onlyfans.com**) and send them with a proxy: ```bash curl -X POST "$BASE/api/crm/$CRM/accounts/login/cookies" \ -H "X-API-Key: $KEY" \ -H "X-Proxy: http://user:pass@host:port" \ -H "Content-Type: application/json" \ -d '{ "platform": "onlyfans", "sess": "", "auth_id": "" }' ``` We store the session server-side. You never send cookies again. For Fansly, paste an auth token instead and the proxy is optional: ```bash curl -X POST "$BASE/api/crm/$CRM/accounts/login/cookies" \ -H "X-API-Key: $KEY" \ -H "Content-Type: application/json" \ -d '{ "platform": "fansly", "auth_token": "", "fansly_session_id": "" }' ``` This is the short version. [Connect an account](/docs/connect-an-account) covers the rest: * **Credentials login** β€” email/username + password, with Cloudflare and Turnstile handled for you * **Two-factor** β€” what `requires_2fa` looks like and how to submit the code (the field is `otp_code`, not `code`) * **Proxies** β€” why OnlyFans needs one and what happens if you omit it * **Connecting many accounts at once** via [bulk import](/docs/bulk-import) * **Enabling write actions**, which are off until you turn them on * **Disconnecting** and freeing the slot ## List your connected accounts [#list-your-connected-accounts] ```bash curl "$BASE/api/crm/$CRM/accounts" \ -H "X-API-Key: $KEY" ``` Each entry carries an `of_user_id`. Despite the name it identifies an account on **either** platform, and it is the `{of_user_id}` path parameter on every CRM route. It is also the `user-id` **header** on the `/api2/v2/*` passthrough β€” the only route in the API that reads that header β€” but that surface is OnlyFans-only: a `user-id` belonging to a Fansly account returns `501 platform_not_supported`. Each row also reports its `platform` and a `capabilities` object β€” the authoritative per-account answer to "does this work on Fansly?". See [OnlyFans & Fansly](/docs/platforms). ## Make a real call [#make-a-real-call] A normalized CRM read β€” works for OnlyFans and Fansly: ```bash curl "$BASE/api/crm/$CRM/accounts/$OFUID/balances" \ -H "X-API-Key: $KEY" ``` Or go straight through to OnlyFans, signed for you: ```bash curl "$BASE/api/crm/$CRM/api2/v2/users/me" \ -H "X-API-Key: $KEY" \ -H "user-id: $OFUID" ``` No cookie header, no signing, no proxy rotation β€” the saved session does the work. OnlyFans' own body comes back under `data`, inside a `{ success, status_code, data }` envelope. Those two calls are the two halves of the API, and they behave differently β€” different response envelopes, different platform support. Read [The two surfaces](/docs/two-surfaces) before you build on either. ## Where to go next [#where-to-go-next] When to use the passthrough and when to use the CRM layer. The `/cached` routes cost zero platform requests. Use them. Get pushed new tips, subscribers and messages instead of polling. What you can send, and the platform-side limits we do not enforce for you. --- # Rate limits & quotas (/docs/rate-limits) Three separate limits apply, and they are independent of each other. ## 1. Per-minute HTTP rate limits [#1-per-minute-http-rate-limits] Anti-flood protection, applied on every plan. Keyed on your API key (falling back to client IP when no key is present). | Scope | Limit | | ------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | | Default β€” most reads, and the passthrough | **1000 / minute** | | Sensitive β€” writes, key management, mass DMs, exports | **100 / minute** | | Login β€” the three connection routes **and** all four `/api/auth/*` routes | **20 / minute** | | `POST /api/auth/login` | additionally **6 / minute per email address**, stacked on the 20/minute above so an IP-rotating botnet still cannot brute-force one account | | `GET /health`, `GET /events/stream` | exempt | Exceeding one returns: ```json { "error": "Rate limit exceeded", "retry_after": "1000 per 1 minute" } ``` with HTTP `429`. Current state is exposed on `X-RateLimit-*` response headers, so you can back off before hitting the wall. Limits use a fixed window, so a burst that straddles a minute boundary can briefly appear to allow double the nominal rate. Do not rely on that. ## 2. Monthly call quota [#2-monthly-call-quota] Every counted request increments a per-panel monthly counter. | Plan | Connected accounts | API calls / month | | -------------------------------- | ------------------ | ----------------- | | Free | 10 | 1,000 | | Slots β€” $20/slot/mo ($15 at 15+) | 1 per slot | unlimited | | Enterprise | custom | custom | Check consumption: ```bash curl "$BASE/api/crm/$CRM/usage" -H "X-API-Key: $KEY" ``` ```json { "plan": "slots", "api_calls_used": 18432, "api_calls_limit": -1, "accounts_used": 3, "accounts_limit": 15 } ``` `GET /api/crm/{crm_id}/usage` is authoritative for your panel β€” read it rather than assuming plan defaults. An `api_calls_limit` of `-1` means unlimited. Exhausting a finite quota returns `429`. Quota is not charged on every request: only calls that actually reach the platform count. Cached reads, async-job status polls and background polling are free. Adding an account beyond your slot count returns `403` (not 429): ```json { "error": "Account limit reached (1). Buy a slot to add another account.", "accounts_limit": 1 } ``` ## 3. Platform-side limits β€” your responsibility [#3-platform-side-limits--your-responsibility] This is the one that actually gets accounts banned, and **we do not enforce it for you.** OnlyFans and Fansly rate-limit per account. Bursts of roughly 1 request/second are fine; sustained traffic above about **5 requests/second** will get an account flagged. Every `/api2/v2/*` call and every live (non-cached) CRM read reaches the platform. Prefer the `/cached` routes, which serve from our own store and cost **zero** platform requests: `/subscribers/cached` Β· `/subscribers/new` Β· `/subscribers/stats` Β· `/transactions/cached` Β· `/fans/{fan_id}/transactions/cached` Β· `/campaigns/{campaign_id}/claimers/cached` Refresh them on a schedule with the async [refresh jobs](/docs/async-jobs) rather than reading live in a loop. See [Cached reads](/docs/cached-reads). ## Handling 429 correctly [#handling-429-correctly] ```python import time, requests def call(session, method, url, key, **kw): for attempt in range(6): r = session.request(method, url, headers={"X-API-Key": key}, timeout=60, **kw) if r.status_code != 429: return r # Prefer the server's hint; otherwise back off exponentially. wait = float(r.headers.get("Retry-After") or 2 ** attempt) time.sleep(min(wait, 60)) return r ``` Distinguish the two `429` causes before retrying: a per-minute limit clears within the minute, but an exhausted **monthly quota** will not clear by retrying at all. Check the `error` string, or call `/usage`. ## Exemptions [#exemptions] Panels can be granted a rate-limit exemption or a quota override. Both are set server-side by us, not through the API β€” contact support if your workload needs one. --- # Responses & errors (/docs/responses) ## Two envelopes [#two-envelopes] Which envelope you get depends on which [surface](/docs/two-surfaces) you are on. Data is a **sibling key** alongside `success`, named after the resource: ```json { "success": true, "list": [ … ], "total": 412, "limit": 100, "offset": 0, "hasMore": true } ``` This is the convention, not a guarantee. Some CRM routes return a bare object or a bare array with no `success` field. Do not write a client that requires `success` to be present on every CRM response β€” check the individual endpoint page. Always wrapped, always the same three keys: ```json { "success": true, "status_code": 200, "data": { "…OnlyFans' own payload…" } } ``` `data` holds OnlyFans' response verbatim, including its own `list` / `hasMore` pagination fields. A `relogin: true` key is added when the session had to be refreshed to serve the request. On failure: ```json { "success": false, "status_code": 401, "data": { "error": { "code": 401, "message": "Unauthorized" } } } ``` ## Error shapes [#error-shapes] There is **no single error envelope**. In practice you will see three shapes: ```json // Most handlers β€” a bare error string { "error": "Invalid API key" } // Validation failures { "error": "limit must be at most 500" } // Uncaught server errors { "error": "Internal server error", "correlation_id": "a1b2c3d4" } ``` Some routes additionally include `success: false`, and some include a machine `code`: ```json // Mass messaging β€” the one route using an UPPERCASE code { "success": false, "code": "PLATFORM_NOT_SUPPORTED", "error": "mass messaging is OnlyFans-only for now" } // Every other 501 β€” lowercase, with `platform` and `feature` { "success": false, "code": "platform_not_supported", "error": "\"referrals\" is not available for fansly accounts yet.", "platform": "fansly", "feature": "referrals" } ``` Compare that code case-insensitively β€” branching on the uppercase spelling alone misses every 501 except mass DMs. Read `error` as the human message, and treat `success`, `code` and `correlation_id` as optional. Do not branch on `success` being present. Rate limiting and quota errors carry extra fields: ```json { "error": "Rate limit exceeded", "retry_after": "1000 per 1 minute" } { "error": "API call limit reached", "plan": "only-api-free", "limit": 1000, "used": 1000, "upgrade_url": "…" } // 403, not 429 { "error": "Account limit reached (10). Buy a slot to add another account.", "code": "SLOT_LIMIT", "plan": "only-api-free", "accounts_used": 10, "accounts_limit": 10, "slot_purchase_url": "…" } ``` `500` responses are deliberately opaque β€” the full traceback is logged server-side only, so SQL fragments, file paths, proxy credentials and session tokens never reflect back to you. Quote the `correlation_id` when reporting one. ## Status codes [#status-codes] | Code | Meaning | | ----- | ---------------------------------------------------------------------------------------------------------------- | | `200` | Success | | `202` | Async job accepted β€” poll its status route. See [Async jobs](/docs/async-jobs) | | `400` | Validation error, or a missing required header | | `401` | No `X-API-Key` sent, bad dashboard credentials, or a session that could not be re-established (`relogin_failed`) | | `403` | **Invalid** key, wrong panel, primary-key-only route, write actions disabled, or the account slot limit | | `404` | Unknown job or, on a few account routes, an account that is not yours | | `409` | An async job of that kind is already running for this account | | `429` | Per-minute rate limit or monthly quota | | `500` | Server error β€” includes a `correlation_id` | | `501` | The operation is not supported for that account's platform | ## The `_notice` wrapper means you are on a decoy path [#the-_notice-wrapper-means-you-are-on-a-decoy-path] Some URLs on this domain are honeypot bait rather than API routes β€” notably `/api/health`, `/api/v1/*`, `/api/internal/*`, and paths like `/.env` and `/.git/config`. Those return **procedurally-generated fake data** with a `_notice` string prepended (and a top-level array reshaped into `{_notice, data: […]}`), plus `X-Honeypot-*` and `X-AI-Notice` headers. The decoy is selected by **path**, not by authentication. `GET /api/health` is bait and reports a fabricated version and service list; the real health check is `GET /health` on `api.theonlyapi.com`. The real API is panel-scoped: `https://theonlyapi.com/api/crm/{crm_id}/…`. A missing or wrong key there gives you a plain `401`/`403` JSON error with no `_notice`. There is **no User-Agent check** on the API. Testing with `curl` needs no `-A` flag β€” the User-Agent only appears echoed inside a decoy notice, and never changes which response you get. ## Other headers [#other-headers] Every response carries `Cache-Control: no-store` plus a standard security header set (HSTS, `X-Content-Type-Options: nosniff`, `X-Frame-Options: DENY`, `Referrer-Policy`). Rate-limit state is exposed via `X-RateLimit-*` headers. CORS is restricted for `/api/*`; allowed request headers are `Content-Type`, `X-API-Key`, `X-Proxy` and `Authorization`. If you are calling from a browser origin, proxy through your own backend instead. --- # Sessions & re-login (/docs/sessions) A connected account's session lives on our side, scoped to your panel. You send an `of_user_id`; we load the cookies, `x-bc` and `x-hash`, route through the account's proxy, sign the request, and forward it. ## What we store [#what-we-store] | Stored | Used for | | ---------------------------------------------------------------- | ------------------------------- | | Session cookies (`sess`, `auth_id`, `fp`) or a Fansly auth token | Authenticating as the account | | `x-bc`, `x-hash` | OnlyFans request signing | | The proxy supplied at connect time | Keeping the session's IP stable | | Credentials, when you connected with them | Automatic re-login | Retrieve the session block for an account with `GET /accounts?include_session=true`. You rarely need to β€” the point of the API is that you do not handle these values. ## Automatic re-login [#automatic-re-login] Platforms invalidate sessions for all sorts of reasons: a password change, a suspicious-activity lockout, a login from elsewhere, or simple expiry. When we detect an invalidated session mid-request, we re-login using the stored credentials and retry the request transparently. When that happens on the passthrough, the response carries an extra flag: ```json { "success": true, "status_code": 200, "relogin": true, "data": { … } } ``` `relogin: true` means the call succeeded, but the session behind it was rebuilt. Nothing is required of you β€” it is a signal, not an error. ## When re-login fails [#when-re-login-fails] If we cannot recover the session β€” no stored credentials, credentials no longer valid, or 2FA now required β€” the endpoint returns `401` with `relogin_failed`. Once the credential circuit-breaker trips it also carries `needs_reconnect: true` and `reason: "invalid_credentials"`. `needs_reconnect` is the actionable flag, and it is also surfaced per account on `GET /accounts` β€” poll that rather than waiting for a call to fail. The account needs reconnecting: ```bash curl -X POST "$BASE/api/crm/$CRM/accounts/login/cookies" \ -H "X-API-Key: $KEY" \ -H "X-Proxy: http://user:pass@host:port" \ -H "Content-Type: application/json" \ -d '{"platform":"onlyfans","sess":"","auth_id":""}' ``` After five consecutive failures, background polling for that account is paused automatically and a `polling_paused` event is emitted with a `reason` and a `failures` count. Subscribe to it β€” it is the earliest reliable signal that an account needs attention. See [Events](/docs/events). Reconnecting clears the **re-login block**, but **not** the polling pause. Re-enable it explicitly: ```bash curl -X PATCH "$BASE/api/crm/$CRM/accounts/$OFUID/polling" \ -H "X-API-Key: $KEY" -H "Content-Type: application/json" \ -d '{"enabled": true}' ``` The failure counter only resets on a *successful* poll, so if the underlying problem is still there the first failure after re-enabling re-trips the threshold and pauses it again. ## Detecting it before your users do [#detecting-it-before-your-users-do] Two approaches, in order of preference: 1. **Subscribe to** `polling_paused` via [webhooks](/docs/webhooks) or [SSE](/docs/streaming). You find out within a poll cycle. 2. **Watch for** `relogin_failed` on your own calls, and surface it as a reconnect prompt rather than a generic error. ## Why the proxy matters [#why-the-proxy-matters] OnlyFans associates a session with the network it was created from. If requests for that session start arriving from a different IP, it gets invalidated β€” which is why `X-Proxy` is required when connecting an OnlyFans account, and why we route every subsequent request for that account through the same proxy. Changing an account's proxy after the fact is supported: ```bash curl -X PATCH "$BASE/api/crm/$CRM/accounts/$OFUID/proxy" \ -H "X-API-Key: $KEY" \ -H "Content-Type: application/json" \ -d '{"proxy": "http://user:pass@newhost:port"}' ``` Expect the session to need re-establishing if the new proxy exits from a noticeably different location. See [Proxies](/docs/proxies). --- # Server-sent events (/docs/streaming) ``` GET /api/crm/{crm_id}/events/stream ``` A long-lived `text/event-stream` connection carrying [events](/docs/events) for your panel as they are emitted, plus `export.progress` and `export.complete` for running [exports](/docs/exports). This endpoint is **exempt from rate limiting** β€” a persistent connection would otherwise burn your per-minute budget immediately. ## Connecting [#connecting] ```bash curl -N "$BASE/api/crm/$CRM/events/stream" \ -H "X-API-Key: $KEY" ``` ``` : connected id: 12345 event: new_tip data: {"id":12345,"event_type":"new_tip","crm_id":"crm_…","of_user_id":"1234567","occurred_at":"…","created_at":"…","source_event_id":"tx:99","payload":{…}} event: export.progress data: {"event_type":"export.progress","payload":{"job_id":"f01152d3…","status":"running","phase":"messages","phase_index":6,"phase_total":7,"counts":{…}}} : keep-alive ``` Lines beginning with `:` are comments β€” one `: connected` on open, then `: keep-alive` every 15 seconds. Ignore them. Account events are the flat [event envelope](/docs/events) and carry an `id:` line. **Progress frames (`export.*`, `import.*`, `refresh.*`) nest everything under `payload`** and have no `id`, `crm_id` or `occurred_at`. A client that assumes the envelope will crash on them. ## Filtering server-side [#filtering-server-side] ``` GET /events/stream?types=new_tip,import.progress ``` An unknown type is a `400`; omitting it (or `*`) means everything. This is the only way to subscribe to just the job-progress events. ```python import json, requests with requests.get( f"{BASE}/api/crm/{CRM}/events/stream", headers={"X-API-Key": KEY, "Accept": "text/event-stream"}, stream=True, timeout=None, ) as r: r.raise_for_status() event_type = None for line in r.iter_lines(decode_unicode=True): if not line: # blank line terminates an event event_type = None elif line.startswith(":"): # keep-alive continue elif line.startswith("event:"): event_type = line[6:].strip() elif line.startswith("data:"): handle(event_type, json.loads(line[5:].strip())) ``` ```js // Node's global fetch streams fine and lets you set headers, // which EventSource cannot do. const res = await fetch(`${BASE}/api/crm/${CRM}/events/stream`, { headers: { 'X-API-Key': KEY, Accept: 'text/event-stream' }, }); const reader = res.body.pipeThrough(new TextDecoderStream()).getReader(); let buffer = ''; for (;;) { const { value, done } = await reader.read(); if (done) break; buffer += value; let split; while ((split = buffer.indexOf('\n\n')) !== -1) { const chunk = buffer.slice(0, split); buffer = buffer.slice(split + 2); let type, data; for (const line of chunk.split('\n')) { if (line.startsWith('event:')) type = line.slice(6).trim(); else if (line.startsWith('data:')) data = line.slice(5).trim(); } if (data) handle(type, JSON.parse(data)); } } ``` The browser `EventSource` API **cannot set request headers**, so it cannot send `X-API-Key`. Never put your key in a query string or in client-side JavaScript either β€” it grants full access to your panel. Proxy the stream through your own backend, attaching the key server-side: ```ts // app/api/events/stream/route.ts (Next.js) export async function GET() { const upstream = await fetch( `${process.env.CRM_API_BASE}/api/crm/${process.env.CRM_ID}/events/stream`, { headers: { 'X-API-Key': process.env.CRM_API_KEY! } }, ); return new Response(upstream.body, { headers: { 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache, no-transform', Connection: 'keep-alive', }, }); } ``` Then in the browser: ```js const es = new EventSource('/api/events/stream'); es.addEventListener('new_tip', (e) => handle(JSON.parse(e.data))); ``` ## Reconnecting [#reconnecting] Unlike [webhooks](/docs/webhooks), the stream does not retry or replay. Anything emitted while you were disconnected is gone from your point of view. There is also a bounded **200-event queue per connection**: if you read more slowly than we emit, the overflow is dropped silently. A client that must not miss events should reconcile against `GET /events`, not rely on the stream alone. Reconnect with exponential backoff and backfill from `GET /events?since=`. Track `created_at` β€” `since` is an exclusive bound on our insert time, whereas `occurred_at` is the platform's own timestamp and can be much older. ## SSE or webhooks? [#sse-or-webhooks] | | SSE | Webhooks | | --------------------- | --------------------------------------- | -------------------------------------------------------- | | Needs a public URL | no | yes | | Retries | no | `5s β†’ 30s β†’ 5m β†’ 30m β†’ 2h` | | Survives your restart | no | yes | | Latency | lowest | low | | Good for | dashboards, live UI, watching an export | server-side automation, anything that must not be missed | Use SSE for anything a human is watching. Use webhooks for anything that has to be reliable. Using both is reasonable: SSE to update the UI instantly, webhooks as the durable path. ## Behind a proxy [#behind-a-proxy] The response already sets `X-Accel-Buffering: no`, which nginx honours. For other proxies or CDNs, disable response buffering for this route or events arrive in batches. Cloudflare buffers `text/event-stream` on some plans; keep-alive comments mitigate but do not eliminate this. --- # Subscribers & fans (/docs/subscribers) Two related resources. **Subscribers** are per-account subscription records. **Fans** are the panel-wide CRM view of people, with tags, notes and spend. ## Subscribers [#subscribers] ```bash # Cached β€” zero platform requests, reliable total curl "$BASE/api/crm/$CRM/accounts/$OFUID/subscribers/cached?limit=100&offset=0" \ -H "X-API-Key: $KEY" # Live β€” hits the platform curl "$BASE/api/crm/$CRM/accounts/$OFUID/subscribers" -H "X-API-Key: $KEY" ``` Default to cached. See [Cached reads](/docs/cached-reads). ### Newly seen subscribers [#newly-seen-subscribers] ```bash curl "$BASE/api/crm/$CRM/accounts/$OFUID/subscribers/new" -H "X-API-Key: $KEY" ``` Every incoming subscription β€” new subs **and renewals**, because a renewal moves the fan's `subscribed_at` forward β€” newest first, from cache at zero platform cost. There is no sync cursor. Without `since`/`until` you get the newest **50** of the entire cache. Accepts `since`, `until` (inclusive ISO bounds on `subscribed_at`), `limit` (1–500, default 50), `offset`, and `type` (`all`|`active`|`expired`). For a genuine "what is new since I last looked" cursor, use `GET /events?types=new_subscriber&since=…` instead. ### Statistics [#statistics] ```bash curl "$BASE/api/crm/$CRM/accounts/$OFUID/subscribers/stats?granularity=day" \ -H "X-API-Key: $KEY" ``` `granularity` is `hour`, `day`, `week` or `month`. Aggregated server-side, so this is one cheap request rather than bucketing thousands of rows yourself. ### Keeping it fresh [#keeping-it-fresh] ```bash curl -X POST "$BASE/api/crm/$CRM/accounts/$OFUID/subscribers/refresh" -H "X-API-Key: $KEY" # 202 β†’ poll .../subscribers/refresh/status ``` A delta sync, so it is cheap enough to schedule. See [Async jobs](/docs/async-jobs). The `expired_subscriber` event has no fan identity β€” only `previous_total`, `new_total` and a **negative** `delta`, sampled every 10th poll. But you do not need to diff snapshots to recover the *who*: `GET /subscribers/cached?type=expired` returns them directly with each row's `expired_at`, because `is_active` is recomputed from `expired_at` on every read rather than frozen at sync time. ## Fans [#fans] Panel-wide, across every connected account: ```bash curl "$BASE/api/crm/$CRM/fans?limit=100&offset=0" -H "X-API-Key: $KEY" ``` Each fan carries identity, tags, notes and `total_spend`. That figure is `MAX(platform lifetime total, sum of captured tip/purchase events)` β€” **not** the chargeback-corrected signed sum. Check `spend_known`: when it is `0`, spend is unknown rather than zero. See [Earnings & transactions](/docs/earnings). ### Tags [#tags] ```bash # Add β€” of_user_id is REQUIRED in the body curl -X POST "$BASE/api/crm/$CRM/fans/$FANID/tags" \ -H "X-API-Key: $KEY" -H "Content-Type: application/json" \ -d '{"tag": "vip", "of_user_id": "'$OFUID'"}' # Remove β€” of_user_id in the body or the query string curl -X DELETE "$BASE/api/crm/$CRM/fans/$FANID/tags/vip?of_user_id=$OFUID" \ -H "X-API-Key: $KEY" ``` Tags are how you segment, and they can be applied automatically β€” a `tag_fan` [automation](/docs/automations) on `new_purchase` with an amount condition builds a VIP list with no code. Tags are **not** a mass-DM audience filter. To message a tagged segment, read the ids from `GET /fans` and pass them as `audience.fan_ids` β€” see [Messaging](/docs/messaging). ### Notes [#notes] ```bash curl -X PUT "$BASE/api/crm/$CRM/fans/$FANID/note" \ -H "X-API-Key: $KEY" -H "Content-Type: application/json" \ -d '{"note": "Prefers video content.", "of_user_id": "'$OFUID'"}' ``` One free-text note per fan, replaced on write; max 2000 characters, and an empty string clears it. The `fans` table is unique on `(crm_id, of_user_id, fan_of_user_id)`, so the panel-wide path alone cannot identify a row. All three of these routes return `400` without `of_user_id`. Tags cap at 40 characters. ### Refreshing one fan's profile [#refreshing-one-fans-profile] ```bash curl -X POST "$BASE/api/crm/$CRM/accounts/$OFUID/fans/$FANID/refresh-profile" \ -H "X-API-Key: $KEY" ``` Pulls that fan's current profile from the platform. Targeted, so it costs one platform request rather than a full re-walk β€” good for a "refresh" button in a UI. ### Per-fan transactions [#per-fan-transactions] ```bash curl "$BASE/api/crm/$CRM/accounts/$OFUID/fans/$FANID/transactions/cached" \ -H "X-API-Key: $KEY" ``` ## A common workflow [#a-common-workflow] ### Refresh, then read [#refresh-then-read] Kick off `subscribers/refresh` and `transactions/refresh`, then read from the cached routes. Do not block on the refresh β€” the cache always answers. ### Tag automatically [#tag-automatically] An automation on `new_purchase` with `payload.amount >= 100` and a `tag_fan` action keeps a `vip` segment current without any code. ### Segment and act [#segment-and-act] Read `GET /fans`, filter by tag and spend, then send a targeted [mass DM](/docs/messaging) β€” with `dry_run: true` first to check the reach. --- # The two surfaces (/docs/two-surfaces) The API has two surfaces with genuinely different contracts. Picking the wrong one is the most common source of confusion. ## 1. Transparent passthrough β€” `/api2/v2/*` [#1-transparent-passthrough--api2v2] **OnlyFans only.** A thin, signed proxy. OnlyFans' own response body is passed through unchanged, but always wrapped in a small envelope: ```json { "success": true, "status_code": 200, "data": { "…OnlyFans' actual payload…" } } ``` Check `success` first, then read the OnlyFans payload β€” including `list` and `hasMore` on paginated endpoints β€” from `data`. On error, `success` is `false`, `status_code` carries the upstream HTTP status, and `data` holds an `error` object with `code` and `message`. A `relogin: true` field appears when the session was refreshed mid-request. Each request needs: | Header | Required | Purpose | | ----------- | -------- | --------------------------------------------------------------------------------------- | | `X-API-Key` | yes | Your panel key | | `user-id` | yes | Which connected account to act as. Omitting it returns `400 user-id header is required` | | `X-Proxy` | no | Overrides the proxy saved at login time | ```bash curl "$BASE/api/crm/$CRM/api2/v2/users/me" \ -H "X-API-Key: $KEY" \ -H "user-id: 482687148" ``` ### What we do for you [#what-we-do-for-you] 1. Load the saved session for that account (cookies, `x-bc`, `x-hash`) 2. Route the request through the account's proxy, so OnlyFans sees the same IP that logged in 3. Generate fresh signed headers server-side using the current OnlyFans signing algorithm 4. Forward to `onlyfans.com/api2/v2/…` 5. Return the JSON response Two different failures are worth telling apart: | Code | Meaning | | -------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------- | | `403 Account not found or does not belong to this CRM panel` | The `of_user_id` is not connected to your panel | | `401 No session found. Provide sess and auth_id cookies (-b) on first request, or login via /accounts/login/cookies` | It *is* your account, but there is no stored session | The passthrough does have a cookie bootstrap for that second case β€” send `sess` and `auth_id` as cookies on the first request and a session is created. Prefer `POST /accounts/login/cookies`, which stores it once and properly. ## 2. Normalized CRM layer [#2-normalized-crm-layer] **OnlyFans + Fansly.** Here responses *are* normalized: both platforms' rows are projected to the same shape, and several routes are server-side aggregations with no platform equivalent. * **Cached reads that cost zero platform requests** β€” `/subscribers/cached`, `/subscribers/new`, `/subscribers/stats`, `/transactions/cached`, `/fans/{fan_id}/transactions/cached`, `/campaigns/{campaign_id}/claimers/cached` * **Async refresh and backfill jobs** β€” `POST /subscribers/refresh`, `/transactions/refresh`, `/campaigns/refresh`, `/backfill`. Each returns `202`; poll the matching `/refresh/status` route or listen on `/events/stream` * **Cross-account aggregation** β€” `GET /earnings/summary`, `GET /balances/summary` * **Fan CRM** β€” `GET /fans` with tags, notes and per-fan cached transactions * **Messaging** β€” `/chats`, `/chats/{with_user_id}/messages`, `POST /messages/mass`, `/ppv-stats` * **Data exports** β€” `/exports`, producing a downloadable ZIP * **Webhooks** β€” `/webhooks` with a delivery log and test fire * **Automations** β€” event-triggered actions, `/run-now`, run history * **Realtime** β€” `GET /events` (poll) and `GET /events/stream` (SSE) The response envelope is different: data is a **sibling key**, not nested under `data`. ```json { "success": true, "list": [ … ], "total": 412, "limit": 100, "offset": 0, "hasMore": true } ``` See [Responses & errors](/docs/responses) for the full picture, including the routes that return a bare object with no envelope at all. ## Which should I use? [#which-should-i-use] Default choice. Works on both platforms, cheaper (cached reads cost no platform requests), stable shapes, and it is where events, webhooks, automations and exports live. When you need an OnlyFans capability the CRM layer does not expose β€” vault media, stories, streams, promotions, granular post management. GET is always allowed. Any other method through `/api2/v2/*` is a write performed as the creator, so it requires `allow_of_write_actions` on that account and otherwise returns `403` with `code: "WRITES_DISABLED"` β€” the same gate as the CRM write routes. See [Connect an account](/docs/connect-an-account). Passthrough calls hit OnlyFans directly and count against *their* rate limits, which we do not enforce for you. Roughly 1 request/second in bursts is fine; sustained traffic above \~5 req/s risks getting the account flagged. Prefer the `/cached` routes. See [Rate limits & quotas](/docs/rate-limits). --- # Webhooks (/docs/webhooks) Subscribe an HTTPS endpoint and we will POST events to it as they happen. ## Create one [#create-one] ```bash curl -X POST "$BASE/api/crm/$CRM/webhooks" \ -H "X-API-Key: $KEY" \ -H "Content-Type: application/json" \ -d '{ "url": "https://example.com/hooks/theonlyapi", "event_types": ["new_subscriber", "new_tip"], "description": "production worker" }' ``` | Field | Required | Notes | | ------------- | -------- | ----------------------------------------------------- | | `url` | yes | `http://` is accepted, but see the HTTPS note below | | `event_types` | **yes** | Must be a non-empty array. Use `["*"]` for every type | | `description` | no | Free-text label, max 200 characters | The field is `event_types` β€” not `events`. A body using `events` is silently ignored, which then fails the non-empty check and returns `400 event_types must be a non-empty list`. There is also **no `of_user_id` field** and no `enabled` field on create. See below. The response includes the generated signing `secret` β€” store it, it is what you verify deliveries with. It is also returned by `GET /webhooks` and `GET /webhooks/{id}`. ## Approval β€” a new webhook may deliver nothing [#approval--a-new-webhook-may-deliver-nothing] This is the first thing to check when a webhook seems dead. A webhook is created with a `status` of either `approved` or `pending`, returned in the create response. **A `pending` webhook receives no deliveries at all.** These hosts are approved immediately: ``` discord.com discordapp.com hooks.slack.com api.telegram.org ``` So is any host an admin has already approved for your panel. **Every other host starts as** `pending` β€” including your own domain, the first time. | Symptom | Cause | | ----------------------------------------------------------------------------------------------- | ---------------------------- | | `POST /webhooks/{id}/test` returns `403 Webhook is awaiting admin approval and cannot send yet` | `status: "pending"` | | Events appear in `GET /events` but never arrive at your URL | `status: "pending"` | | `status: "rejected"` with a `reject_reason` | An admin declined the domain | Check `status` on `GET /webhooks/{id}`. If it is `pending`, [contact support](https://theonlyapi.com/contact) to get the domain reviewed. Once a host is approved for your panel, further webhooks on that same host are approved automatically. Repointing a webhook at a **different** host puts it back into review; changing only the path does not. ## Webhooks are panel-wide [#webhooks-are-panel-wide] Every connected account's events go to every matching webhook. There is no per-webhook account filter β€” the `webhooks` table has no `of_user_id` column. If you need per-account routing, either filter on `of_user_id` in your handler, or use an [automation](/docs/automations), which *does* accept `of_user_id`. ## Delivery format [#delivery-format] Every delivery is a `POST` with these headers: | Header | Value | | ----------------------- | --------------------------------------------- | | `Content-Type` | `application/json` | | `User-Agent` | `TheOnlyAPI-Webhook/1.0` | | `X-OnlyAPI-Signature` | `sha256=` | | `X-OnlyAPI-Timestamp` | Unix seconds β€” the same value that was signed | | `X-OnlyAPI-Event` | The event type, e.g. `new_tip` | | `X-OnlyAPI-Delivery-Id` | Unique per attempt | The body is exactly six keys β€” `id`, `event_type`, `crm_id`, `of_user_id`, `occurred_at`, `payload`. (The SSE stream and `GET /events` add `source_event_id` and `created_at`; the webhook body is trimmed to these six.) See [Events](/docs/events) for payload shapes. ## Verifying the signature [#verifying-the-signature] The signed message is **not** the body alone. It is the timestamp, a literal `.`, then the raw request body: ``` message = "{X-OnlyAPI-Timestamp}." + raw_body signature = "sha256=" + HMAC_SHA256(webhook_secret, message).hexdigest() ``` We serialise with compact separators (`,` and `:`, no spaces). Re-serialising parsed JSON will not reproduce those bytes and the signature will not match. Capture the body as bytes first, verify, then parse. ```python import hmac, hashlib def verify(secret: str, timestamp: str, raw_body: bytes, received: str) -> bool: message = f"{timestamp}.".encode() + raw_body expected = "sha256=" + hmac.new(secret.encode(), message, hashlib.sha256).hexdigest() return hmac.compare_digest(expected, received) # Flask @app.post("/hooks/theonlyapi") def hook(): raw = request.get_data() # bytes, before parsing ok = verify(SECRET, request.headers["X-OnlyAPI-Timestamp"], raw, request.headers["X-OnlyAPI-Signature"]) if not ok: return "", 401 event = request.get_json() ... return "", 200 ``` ```js import crypto from 'node:crypto'; function verify(secret, timestamp, rawBody, received) { const message = Buffer.concat([Buffer.from(`${timestamp}.`), rawBody]); const expected = 'sha256=' + crypto.createHmac('sha256', secret).update(message).digest('hex'); const a = Buffer.from(expected); const b = Buffer.from(received ?? ''); return a.length === b.length && crypto.timingSafeEqual(a, b); } // Express β€” note express.raw(), NOT express.json() app.post( '/hooks/theonlyapi', express.raw({ type: 'application/json' }), (req, res) => { if (!verify(SECRET, req.get('X-OnlyAPI-Timestamp'), req.body, req.get('X-OnlyAPI-Signature'))) { return res.sendStatus(401); } const event = JSON.parse(req.body.toString('utf8')); res.sendStatus(200); }, ); ``` ```go func verify(secret, timestamp string, rawBody []byte, received string) bool { mac := hmac.New(sha256.New, []byte(secret)) mac.Write([]byte(timestamp + ".")) mac.Write(rawBody) expected := "sha256=" + hex.EncodeToString(mac.Sum(nil)) return hmac.Equal([]byte(expected), []byte(received)) } ``` Always use a constant-time comparison (`hmac.compare_digest`, `crypto.timingSafeEqual`, `hmac.Equal`) rather than `==`. ## Retries and auto-deactivation [#retries-and-auto-deactivation] A delivery is retried on this ladder, up to 6 attempts total: ``` 5s β†’ 30s β†’ 5m β†’ 30m β†’ 2h ``` Those are **lower bounds** β€” a scheduler job sweeps due retries every 10 seconds and processes at most 50 per pass. A delivery only counts as a *failure* once it has exhausted the whole ladder, or hit a non-retryable error. After **five such consecutive failures** the webhook is set inactive and stays that way until you re-enable it: ```bash curl -X PATCH "$BASE/api/crm/$CRM/webhooks/$WEBHOOK_ID" \ -H "X-API-Key: $KEY" -H "Content-Type: application/json" \ -d '{"is_active": true}' ``` Setting `is_active: true` also resets the failure counter. Because each failure must walk the full \~2h ladder first, auto-deactivation takes well over half a day of sustained downtime β€” but it also means a webhook can be quietly failing for hours before anything gives up. Watch `GET /webhooks/{id}/deliveries?limit=50` (max 200), or reconcile against [`GET /events`](/docs/events). Retried rows appear in the log with status `superseded` β€” that is bookkeeping, not a failure. ### Non-retryable failures [#non-retryable-failures] | Response | Behaviour | | ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | | `3xx` | **Terminal, never retried.** We send with redirects disabled and refuse to carry a signed payload to a `Location` we did not validate (`redirect refused`) | | Private / loopback target | Blocked *before* the request is made β€” logged as `blocked: ` | | Any other non-2xx | Retried on the ladder | ## Writing a good handler [#writing-a-good-handler] * **Return 2xx fast, and never 3xx.** Acknowledge, enqueue, process asynchronously. * **Be idempotent.** Retries mean the same event can arrive more than once. Dedupe on the event `id`. * **Verify before you trust.** The URL is public; the signature is what makes the payload yours. * **Use HTTPS.** `http://` is accepted, but the payload carries fan PII and the signature authenticates it without encrypting it. ## Testing locally [#testing-locally] ```bash curl -X POST "$BASE/api/crm/$CRM/webhooks/$WEBHOOK_ID/test" -H "X-API-Key: $KEY" ``` Fires a real, signed delivery so you can validate the whole path including signature verification. It returns `403` if the webhook is still `pending`. Deliveries to `localhost`, `127.0.0.1` and any private or link-local address are blocked before the request is made, and DNS failures fail closed. Use `ngrok` or `cloudflared` while developing β€” and remember the tunnel host will start as `pending` unless it has been approved for your panel. ## Routes [#routes] ``` GET /webhooks # list, each with its secret and status POST /webhooks # create GET /webhooks/{webhook_id} # read one PATCH /webhooks/{webhook_id} # url, event_types, description, is_active DELETE /webhooks/{webhook_id} POST /webhooks/{webhook_id}/test # fire a real signed delivery GET /webhooks/{webhook_id}/deliveries?limit=50 # delivery log, max 200 ```