Authentication
Auth
Authenticate API requests with an API key. Keys are scoped to an organization and carry a per-route permission set.
Passing the key
Send your API key with every request in one of two headers. Both behave the same way; the bearer form is recommended for tooling that already supports OAuth-style headers.
Authorization: Bearer fm_api_...X-API-Key: fm_api_...
Permissions
Each API key has a role, and each role has a set of per-route permissions. If a key doesn't have the permission required by an endpoint, the request returns 403.
Permissions are named like api_chats_list, api_messages_send, api_tracking_links_create. Each endpoint reference page calls out the permission it requires.
Rate limits
Limits are enforced per organization — every key in an org shares the same window. Two windows are tracked independently: per-minute (default 1,000) and per-day (default 50,000). Either limit can trigger a 429.
Headroom is reported on every successful response inside _meta._rate_limits (remaining_minute, remaining_day).
Errors
Error responses use a flat { "error": "..." } body — no data and no _meta. The HTTP status reflects the failure class.
400— malformed request: bad query params, invalid body, unknown enum value401— auth failed: missing, invalid, revoked, or expired API key. Does not consume a credit402— your FansMetric organization has no active subscription (or is past due). Connect / repair billing in the FansMetric app403— your API key role does not grant the per-route permission required by this endpoint404— resource not found on OnlyFans or in FansMetric (depending on the route)413— request body exceeds the 1 MiB limit applied to every authenticated route424— the connected OnlyFans account is insync_lostand cannot proxy upstream calls until the session is restored429— per-organization rate limit exceeded (per-minute or per-day window). Back off until_meta._rate_limits.remaining_*recovers. Does not consume a credit5xx— upstream OnlyFans error, OF proxy error, or unhandled exception (5xx errors are captured by our error tracking)