> ## Documentation Index
> Fetch the complete documentation index at: https://www.dropfans.io/developers/llms.txt
> Use this file to discover all available pages before exploring further.

# API v1 overview

> Base URL, versions, cursor and page paging, acting for a creator as an agency, error shapes, rate limits, money and ids for API v1 with OAuth tokens.

- Source: https://www.dropfans.io/developers/api-v1/overview
- Section: API v1 (OAuth apps)
- OpenAPI: https://www.dropfans.io/developers/openapi.json

API v1 serves creators’ accounts, audience, insights, vault media, posts, tracking links, webhooks and chat to [OAuth apps](https://www.dropfans.io/developers/api-v1/oauth-apps.md). Every request carries `Authorization: Bearer <access token>`. The base URL is `https://api.dropfans.io`.

## Paths and paging

| Prefix | Paging | List response |
| --- | --- | --- |
| `/v1/…` | `cursor` + `limit` | `{"data": […], "nextCursor": "…" \| null}` |
| `/v0/…` and unprefixed (`/users/me`) | `page` (from 1) + `size` | `{"data": […], "pagination": {"page": 1, "size": 20, "hasMore": true}}` |

The three prefixes serve the same operations; pick one style and keep it. On `/v1`, pass `nextCursor` back as `cursor` until it is `null`. A cursor is opaque: do not build or edit one.

## Version header

Send the API version in a request header whose name ends in `-API-Version`, for example `X-Dropfans-API-Version: 2025-06-26`. Without one you get `2025-06-26`, the current version. An unknown version is `400 {"error": "Unsupported API version", "message": "…"}`.

## Acting for a creator (agencies)

A token acts for the account that authorized it. An agency’s token can also act for each creator it manages: prefix the path with `/creators/{creatorUserUuid}`, for example `GET /v1/creators/{creatorUserUuid}/posts`. Which operations have this form, and the extra scopes it needs (usually `read:creator`), is in the [resource list](https://www.dropfans.io/developers/api-v1/resources.md). The agency needs the matching permission on that creator; otherwise the call is `403 {"message": "Forbidden"}`. `GET /v1/creators` lists the creators your token can act for.

## Errors

| Status | Body | When |
| --- | --- | --- |
| 400 | `{"errors": ["…"]}` | Validation failed (one message per problem) |
| 400 | `{"message": "Invalid UUID format …"}` | A path parameter is not a UUID |
| 401 | `{"error": "Unauthorized"}` | Token missing, expired or revoked |
| 403 | `{"error": "Insufficient scopes"}` | The token lacks a scope the operation needs |
| 403 | `{"message": "Forbidden"}` | A creator path you cannot act for |
| 404 | `{"message": "Resource not found"}` | Unknown path, an id that is not yours, or a category that is off for your app |
| 429 | `{"error": "Too many requests"}` + `Retry-After` | Rate limit reached |

## Rate limits

200 requests per 60 seconds per (account, app); a call in the `/creators/{creatorUserUuid}` form counts against that creator’s own budget as well, so one busy creator does not starve the rest of a roster. Every response carries `X-RateLimit-Limit`, `X-RateLimit-Remaining` and `X-RateLimit-Reset`.

## Money, ids and times

- **Money** is an integer number of USD cents (`1999` = $19.99).
- **Ids** are UUIDs: accounts, posts, media, chats and every other object. Internal ids never appear.
- **Times** are ISO 8601 in UTC.

## Onboarding creators

There are two ways to bring a creator to your app.

**Sign in with Dropfans.** For creators who already have an account, or who sign up themselves: send them through [OAuth](https://www.dropfans.io/developers/api-v1/oauth-apps.md). They sign in or sign up, then approve your app.

**Onboard them yourself.** `POST /v1/onboarding/creators` creates the account and returns `kycUrl`, the ID-check link to send the creator to in their own browser. Your app then acts for the creator at `/v1/creators/{creatorUserUuid}/…`, so they never need to sign in to Dropfans. Three optional fields go beyond the basic request:

| Field | Meaning |
| --- | --- |
| `acceptedFromIp` | IP address of the creator’s browser when they accepted the Dropfans Terms of Service in your app |
| `acceptedUserAgent` | That browser’s user agent |
| `kycReturnUrl` | `https` URL the creator returns to after the ID check (default: your app’s website) |

With `acceptedFromIp` and `acceptedUserAgent`, the acceptance is recorded at once and `kycUrl` is the verification provider’s own hosted link: the creator goes straight to the ID check and back to `kycReturnUrl`, without visiting a Dropfans page. Without them, `kycUrl` first shows a short page where the creator accepts the Terms in their own browser; it carries your app’s branding when white label is on (below). Either way, the acceptance is recorded with the creator’s IP address and user agent, never your server’s.

`POST /v1/onboarding/creators/{uuid}/kyc-session` returns a fresh `kycUrl`, for example after a declined check, with the same three optional fields. A link that is still valid is returned again rather than replaced, unless your app asks for a different `kycReturnUrl`; new links are limited per creator per day (`429` beyond that).

## White label for the creators you onboard

For the creators your app onboarded, we can show your app instead of Dropfans. Ask us to set it up; it needs your app’s logo.

- **Emails**, one of three modes:
  - **Dropfans** (default): emails as today.
  - **Your app**: the same emails with your logo and name, sent by us.
  - **Webhooks**: we send no notification email and deliver a `seller.notification` event to your webhook endpoint (and `creator.notification` to API v1 webhook subscriptions) instead.
- **Pages**: the Terms, password, sign-in, sign-up, consent and verification pages show your logo, name and colour, with a small “Powered by Dropfans” line.

A `seller.notification` / `creator.notification` event carries `kind` (for example `kyc_approved`, `payout_sent`, `sale`), `seller` (`uuid`, `handle`, `email`), `data` (the facts the email would show, money in cents) and `email` (`subject`, `html`, `text`), the email already rendered with your branding so you can forward it as it is. A kind only reaches you when your app has the matching category switched on and, for API v1 subscriptions, the matching scope; otherwise the creator gets the email with your branding instead. Security emails (password reset, sign-in and verification codes) are always sent by email, never as events.

## Chat

The chat operations (`/chats/**`, `/agencies/chats/**`, online subscribers) and the chat webhook topics are available once chat is enabled for your app. Until then they answer `404 {"message": "Resource not found"}`, like any path that does not exist.

Next: [Resource list](https://www.dropfans.io/developers/api-v1/resources.md) · [Webhooks](https://www.dropfans.io/developers/api-v1/webhooks.md).

---

Previous: [OAuth apps](https://www.dropfans.io/developers/api-v1/oauth-apps.md) · Next: [API v1 resource list](https://www.dropfans.io/developers/api-v1/resources.md) · All pages: [llms.txt](https://www.dropfans.io/developers/llms.txt)
