Platform Features
The complete developer platform for F2F
A consistent REST surface over fans, messages, vault, earnings and tracking links, with request logs, signed webhooks and predictable rate limits built in.
Built for production workloads
200+ endpoint directory
Creators, fans, chats, mass messages, vault media, earnings, payouts, tracking links, promotions and statistics, all versioned under /v1.
Observability logs
Every request is logged with request_id, latency, status and payload preview. Filter by key, creator or endpoint and replay failed calls.
Webhook engine
Subscribe to subscriptions, tips, PPV unlocks, renewals, cancellations and link clicks. HMAC-SHA256 signatures and 24-hour retry backoff.
Rate limits
120 requests per minute per key by default with Retry-After headers. Enterprise plans unlock custom concurrency.
Idempotency keys
Send an Idempotency-Key header on any POST to make retries safe. Conflicting payloads return 409 idempotency_conflict.
Cursor pagination
Every list endpoint returns has_more and next_cursor so you can stream large fan lists without offsets drifting.
List fans with spend data
Pull a creator's fan list sorted by lifetime spend. The same request works in every supported language.
- Base URL: https://api.apif2f.com/v1
- Auth: Authorization: Bearer sk_live_...
- Env var: F2F_API_KEY
curl -X GET "https://api.apif2f.com/v1/fans?creator_id=crt_8f2a91&sort=-lifetime_spend&limit=100" \
-H "Authorization: Bearer $F2F_API_KEY"Endpoint directory
200+ endpoints across 12 resources
A sample of each resource group. Every endpoint shares authentication, pagination and error conventions.
| Resource | Example endpoints | Count |
|---|---|---|
| Creators | GET /v1/creators, GET /v1/creators/{id}, GET /v1/creators/{id}/stats | 18 |
| Fans | GET /v1/fans, GET /v1/fans/{id}, POST /v1/fans/{id}/tags, GET /v1/fans/lifetime-value | 34 |
| Messages | GET /v1/chats, POST /v1/messages, POST /v1/messages/mass-dm, GET /v1/messages/{id}/stats | 29 |
| Vault & Media | GET /v1/vault/media, POST /v1/vault/upload, PATCH /v1/vault/media/{id} | 21 |
| Earnings & Payouts | GET /v1/earnings, GET /v1/earnings/daily, GET /v1/payouts | 17 |
| Tracking Links | POST /v1/tracking-links, GET /v1/tracking-links/{id}/clicks | 14 |
| Ads Tracking (CAPI) | POST /v1/capi/conversions, GET /v1/capi/events, POST /v1/capi/test | 16 |
| Auth & Sessions | POST /v1/auth/session, POST /v1/auth/session/refresh, POST /v1/auth/2fa | 11 |
| Webhooks | POST /v1/webhooks, GET /v1/webhooks/{id}/deliveries, POST /v1/webhooks/{id}/replay | 12 |
| Automation & Housekeeping | POST /v1/jobs, POST /v1/housekeeping/prune, POST /v1/housekeeping/ppv-pricing | 19 |
| Exports | POST /v1/exports, GET /v1/exports/{id} | 9 |
| MCP | GET /v1/mcp/tools, POST /v1/mcp/tools/call | 4 |
Error reference
Standardized error envelopes
Every REST endpoint and webhook dispatch returns the same JSON error shape, so a single handler covers your whole integration.
{
"error": {
"type": "invalid_request_error",
"code": "parameter_missing",
"message": "The required parameter 'creator_id' was not provided in the request body.",
"param": "creator_id",
"doc_url": "https://apif2f.com/docs/errors#parameter_missing",
"request_id": "req_f2f_9b8a7c6d5e"
}
}| Status | Error Code | Category | Cause & Explanation | Recovery Step |
|---|---|---|---|---|
| 400 | parameter_missing | invalid_request_error | Required JSON field or query string omitted from payload | Inspect payload schema; ensure all mandatory parameters are supplied |
| 400 | invalid_parameter_format | invalid_request_error | Parameter provided with invalid syntax (e.g. malformed email or ISO date) | Ensure dates are ISO 8601 strings and emails pass RFC 5322 validation |
| 401 | invalid_api_key | authentication_error | Provided API key does not exist or has been revoked | Verify Authorization: Bearer sk_live_... header matches active key in dashboard |
| 401 | expired_session_token | authentication_error | F2F account session vault token has expired | Trigger automated headless token refresh via POST /api/v1/auth/session/refresh |
| 402 | quota_exceeded | billing_error | Monthly request limit exhausted on Trial or Scale plan | Upgrade plan tier or purchase supplementary request quota in account settings |
| 403 | insufficient_scope | authorization_error | API key lacks permission to access specified resource or creator account | Generate a new scoped key with required permissions (e.g. messages:write) |
| 403 | account_disconnected | authorization_error | Creator revoked F2F access or changed password directly on F2F.com | Prompt agency manager to re-authenticate creator via the Auth Module flow |
| 404 | resource_not_found | invalid_request_error | Requested creator ID, fan ID, or message ID does not exist | Verify resource ID matches active database records; confirm tenant ownership |
| 409 | idempotency_conflict | idempotency_error | Duplicate request detected with an identical Idempotency-Key header | If payload changed, issue request with a new UUID v4 Idempotency-Key header |
| 422 | two_factor_required | auth_challenge_error | F2F security challenge requires SMS, TOTP, or email OTP validation | Retrieve auth_challenge_id and submit user code via /api/v1/auth/2fa |
| 422 | vault_upload_rejected | media_error | Media upload exceeds maximum file size (500MB) or unsupported codec | Encode video to H.264/AAC MP4 or image to JPG/PNG before re-uploading |
| 429 | rate_limit_exceeded | rate_limit_error | Exceeded 120 requests/minute concurrency limit | Honor the returned Retry-After: {seconds} header; implement exponential backoff |
| 500 | internal_server_error | api_error | Unhandled error within the F2F API platform infrastructure | Retry with exponential backoff; if persistent, contact hello@apif2f.com with request_id |
| 502 | upstream_f2f_timeout | gateway_error | Underlying F2F.com servers took > 15,000ms to respond | Implement automated retry queue (F2F API queues webhook retry automatically for 24h) |
| 503 | service_maintenance | api_error | Platform undergoing scheduled zero-downtime database maintenance | Check status indicators; requests should be queued and retried after maintenance window |
Simulating errors in the sandbox
Trial keys can force any error by sending the header F2F-Simulate-Error: rate_limit_exceeded (or any code above). The sandbox returns the exact envelope, status and headers, including Retry-After for 429 responses, so you can test retry and backoff logic before going live.
Platform FAQ
Start building on F2F today.
Free sandbox access, 1,000 monthly requests, no credit card. API automation and server-side ads tracking in one key.
Prefer email? hello@apif2f.com