The FanOptik API
Read the money and connection health of every creator in your agency workspace — the same figures the app shows — over a clean REST API with signed webhooks.
Base URL https://app.fanoptik.com
Authentication
Every request carries an API key as a Bearer token. Create and revoke keys in the app under Settings → Integrations (owner only). A key is shown in full exactly once, at creation — store it then. A key can only ever read the one workspace it was minted in.
Authorization: Bearer fo_live_xxxxxxxxxxxxxxxxxxxxxxxx
Requests are rate-limited per key, per minute (over the limit returns 429); a missing or invalid key returns 401.
Endpoints
/api/v1/creatorsList the creators in your workspace.
{
"creators": [
{ "id": "cl_...", "name": "Creator Name", "status": "active", "lastSyncAt": "2026-09-16T03:12:00Z" }
]
}
/api/v1/creators/{id}/earnings?days=30Earnings for one creator over a window (days: 1–365, default 30) — net (the Statements value) and gross, split by type, from FanOptik’s own reconciled transactions.
{
"creatorId": "cl_...",
"windowDays": 30,
"totals": { "count": 194, "gross": 3666.04, "net": 2932.64 },
"byType": {
"subscription": { "count": 126, "gross": 2519.74, "net": 2015.79 },
"custom": { "count": 61, "gross": 1100.30, "net": 880.24 },
"tip": { "count": 1, "gross": 46.00, "net": 36.61 }
}
}
/api/v1/creators/needs-relinkThe creators that need a human to re-link them — the operational signal most worth alerting on.
Webhooks
Register https:// endpoints under Settings → Integrations. FanOptik POSTs a JSON body for each event:
sync.completeda creator’s data pull finishedalert.firedan account alert triggeredclient.needs_relinka creator’s session lapsed and needs re-linkingEvery delivery is signed. The raw body is HMAC-SHA256’d under the webhook’s signing secret (shown once, at creation) and sent as:
X-FanOptik-Signature: sha256=<hex digest of the raw request body>
Verify by recomputing the HMAC over the raw body and comparing in constant time. Reject any request whose signature does not match.
import { createHmac, timingSafeEqual } from "node:crypto";
function verify(rawBody, header, secret) {
const expected = "sha256=" + createHmac("sha256", secret).update(rawBody).digest("hex");
const a = Buffer.from(header || ""); const b = Buffer.from(expected);
return a.length === b.length && timingSafeEqual(a, b);
}
Notes
Read-only by construction — there is no write endpoint.
Privacy — no raw fan handles or fan identifiers are ever returned.
Stability — FanOptik signs OnlyFans requests in-house, so the API is not subject to the public signing-rule drift that breaks scraped integrations.
The complete CRM for OnlyFans agencies and independent creators. From the inbox to the payout, numbers you can defend.
API reference
Free tools
System status
References
How fan data is handled
Privacy policy
Terms of service
© 2026 FanOptik. All rights reserved. · Built for people who pay their team from records, not memory.