The Only API docs

The two surfaces

A thin signed passthrough and a normalized CRM layer, with different response shapes.

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/*

OnlyFans only. A thin, signed proxy. OnlyFans' own response body is passed through unchanged, but always wrapped in a small envelope:

{
  "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:

HeaderRequiredPurpose
X-API-KeyyesYour panel key
user-idyesWhich connected account to act as. Omitting it returns 400 user-id header is required
X-ProxynoOverrides the proxy saved at login time
curl "$BASE/api/crm/$CRM/api2/v2/users/me" \
  -H "X-API-Key: $KEY" \
  -H "user-id: 482687148"

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:

CodeMeaning
403 Account not found or does not belong to this CRM panelThe 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/cookiesIt 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

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 jobsPOST /subscribers/refresh, /transactions/refresh, /campaigns/refresh, /backfill. Each returns 202; poll the matching /refresh/status route or listen on /events/stream
  • Cross-account aggregationGET /earnings/summary, GET /balances/summary
  • Fan CRMGET /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
  • RealtimeGET /events (poll) and GET /events/stream (SSE)

The response envelope is different: data is a sibling key, not nested under data.

{
  "success": true,
  "list": [  ],
  "total": 412,
  "limit": 100,
  "offset": 0,
  "hasMore": true
}

See Responses & errors for the full picture, including the routes that return a bare object with no envelope at all.

Which should I use?

Non-GET passthrough requests need write actions enabled

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.

Pace the passthrough yourself

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.

On this page