<!-- Generated by scripts/gen-docs.ts from @bfl/contract. Do not edit. -->

# REST routes

Base URL `https://app.betterfans.link/v1`. Send `Authorization: Bearer <key>`. Full reference: https://app.betterfans.link/docs/api

Every account route takes `accountId`, the creator's OnlyFans user id from `GET /v1/accounts`. Lists take `cursor` and `limit` (default 25; a larger value than 100 counts as 100) and return `hasMore` and `nextCursor`.

## Workspace

### Who am I

`GET /v1/me`, scope `read`. Returns Me.

The workspace, key and rate limit behind the key you sent. Call it to check that a key works.

## Accounts

### List accounts

`GET /v1/accounts`, scope `read`. Returns list of Account.

The OnlyFans accounts your key can use, with their status. A key limited to some accounts sees only those. In test mode this lists the sandbox creators.

### Create link

`POST /v1/links`, scope `read`. Returns HostedLink.

Creates a hosted link. Send its `url` to the creator: they open it, sign in to OnlyFans and the account is linked to your workspace. The link works for 24 hours.

### Get link

`GET /v1/links/{linkId}`, scope `read`. Returns HostedLink.

The progress of a hosted link, with the current step in plain words. Once `status` is `connected`, `accountId` holds the new account.

### Get account

`GET /v1/accounts/{accountId}`, scope `read`. Returns AccountDetail.

One account with its counts, 30 day revenue and last sync. Read it before a long task, or after a call fails with `account_unavailable`.

## Fans

### List fans

`GET /v1/accounts/{accountId}/fans`, scope `read`. Returns list of Fan.

An account's fans, ranked by lifetime spend unless you pick another sort. `search` matches username or display name.

- `search`: Match username or display name.
- `status`: Subscription status. Default active. One of `active`, `expired`, `all`; default `active`.
- `sort`: spend = lifetime spend, recent = last message, subscribed = newest subscription. One of `spend`, `recent`, `subscribed`; default `spend`.

### Get fan

`GET /v1/accounts/{accountId}/fans/{fanId}`, scope `read`, supports `fresh=true`. Returns FanDetail.

Everything about one fan: subscription, lifetime spend by type, lists, notes and presence. Spend comes from transactions.

- `fresh`: true reads live from OnlyFans instead of synced data. Slower. Use it when the answer must be current.

### Fan lists

`GET /v1/accounts/{accountId}/lists`, scope `read`. Returns list of FanList.

The account's fan lists with ids and sizes. Use a list id in a mass message audience or a list action.

### Online fans

`GET /v1/accounts/{accountId}/online-fans`, scope `read`, supports `fresh=true`. Returns OnlineFans.

Fans online right now, with their lifetime spend. A fan missing from the list is not known to be offline.

- `fresh`: true reads live from OnlyFans instead of synced data. Slower. Use it when the answer must be current.

## Chats

### List chats

`GET /v1/accounts/{accountId}/chats`, scope `read`. Returns list of Chat.

Chats for an account with the newest message, the unread count and what the fan has spent. `filter=unread` shows the chats waiting on the creator.

- `filter`: unread = waiting on the creator; paying = fans who have spent. One of `all`, `unread`, `paying`; default `all`.

### List messages

`GET /v1/accounts/{accountId}/chats/{fanId}/messages`, scope `read`, supports `fresh=true`. Returns list of Message.

Messages in one chat, newest first. The chat id is the fan's id.

- `fresh`: true reads live from OnlyFans instead of synced data. Slower. Use it when the answer must be current.

### Search messages

`GET /v1/accounts/{accountId}/messages/search`, scope `read`. Returns list of Message.

Full text search over an account's messages, for one fan or a date range if you like.

- `q` (required): Words to find in message text.
- `fanId`: Only this fan's chat.
- `from`: Start, ISO 8601 date or timestamp (UTC). Default 30 days ago.
- `to`: End, ISO 8601 date or timestamp (UTC). Default now.

## Money

### Revenue summary

`GET /v1/accounts/{accountId}/revenue`, scope `read`. Returns RevenueSummary.

Gross and net revenue for a period, split by type and as a time series, with the top fans and the previous period for comparison.

- `from`: Start, ISO 8601 date or timestamp (UTC). Default 30 days ago.
- `to`: End, ISO 8601 date or timestamp (UTC). Default now.
- `interval`: Bucket size for the series. One of `day`, `week`, `month`; default `day`.

### List transactions

`GET /v1/accounts/{accountId}/transactions`, scope `read`. Returns list of Transaction.

Single transactions, each with the fan, gross, net and fee: subscriptions, tips, paid messages, posts and more.

- `from`: Start, ISO 8601 date or timestamp (UTC). Default 30 days ago.
- `to`: End, ISO 8601 date or timestamp (UTC). Default now.
- `type`: Only this kind of earning. One of `all`, `subscription`, `tip`, `message`, `post`, `stream`, `referral`, `other`; default `all`.
- `fanId`: Only this fan's transactions.

## Content

### Mass messages

`GET /v1/accounts/{accountId}/mass-messages`, scope `read`. Returns list of MassMessage.

Mass messages with how many fans got, opened and bought each one, and what each earned.

- `from`: Start, ISO 8601 date or timestamp (UTC). Default 30 days ago.
- `to`: End, ISO 8601 date or timestamp (UTC). Default now.
- `sort`: recent = newest first. One of `recent`, `revenue`; default `recent`.

### Top content

`GET /v1/accounts/{accountId}/posts`, scope `read`. Returns list of Post.

Posts with price, likes and comments, sorted by `recent` or `likes`. `tips` and `revenue` are null: OnlyFans does not say which post a payment was for.

- `from`: Start, ISO 8601 date or timestamp (UTC). Default 30 days ago.
- `to`: End, ISO 8601 date or timestamp (UTC). Default now.
- `sort`: recent = newest first, likes = most liked first. One of `recent`, `likes`; default `recent`.

### Tracking links

`GET /v1/accounts/{accountId}/links`, scope `read`. Returns list of TrackingLink.

Tracking and free trial links with clicks, subscribers and revenue.

- `sort`: revenue = most earned first. One of `revenue`, `subscribers`, `recent`; default `revenue`.

### Vault

`GET /v1/accounts/{accountId}/vault`, scope `read`. Returns list of VaultItem.

Media in the account's vault, with the vault lists each item is in. Put a media id in `mediaIds` to attach it to a message.

- `folder`: Vault list id. Leave out for all media.
- `type`: Media type. One of `all`, `photo`, `video`, `audio`, `gif`; default `all`.

## Call OnlyFans

### Call OnlyFans

`GET /v1/accounts/{accountId}/onlyfans/{path}`, scope `read`. Returns raw OnlyFans JSON.

Runs a read-only OnlyFans API `GET` for an account, with the account's session. Use it for data the other routes do not cover.

## Actions

### Create action

`POST /v1/accounts/{accountId}/actions`, scope `write`. Returns Action.

Asks for a write on OnlyFans. BetterFans Link stores it as a pending action and returns its `approvalUrl`. Nothing reaches OnlyFans until a person approves it in the dashboard. Pending actions expire after 24 hours.

### Get action

`GET /v1/actions/{actionId}`, scope `read`. Returns Action.

One action with its status, who decided and the result. Poll it after creating an action, or listen for the `action.executed`, `action.rejected` and `action.failed` webhook events.

### List actions

`GET /v1/actions`, scope `read`. Returns list of Action.

Actions in your workspace, filtered by status or account. `status=pending` lists what is waiting for a person.

- `status`: Only actions in this state. One of `all`, `pending`, `approved`, `rejected`, `expired`, `executing`, `executed`, `failed`; default `all`.
- `accountId`: Only this account's actions.
