BetterFans Link: the OnlyFans APIBetterFans Link

Money

Revenue summaries and single transactions.

Revenue summaries and single transactions. Amounts are integer cents; read money before you add anything up. Every route can also return the authentication errors, rate_limited and internal_error.

RouteMethod and path
Revenue summaryGET /v1/accounts/{accountId}/revenue
List transactionsGET /v1/accounts/{accountId}/transactions

Revenue summary

GET /v1/accounts/{accountId}/revenue

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.

Needs the read scope. Reads synced data.

Gross is what fans paid. Net is what the creator keeps, about 80% of gross. Never add them together. See money.

Path parameters

NameDescription
accountIdThe account's id, which is the creator's OnlyFans user id. Get it from GET /v1/accounts.

Query parameters

NameTypeDefaultDescription
fromdate or timestamp30 days agoStart, ISO 8601 date or timestamp (UTC).
todate or timestampnowEnd, ISO 8601 date or timestamp (UTC).
intervalenumdayBucket size for the series. One of day, week or month.

Returns

200 with a RevenueSummary object in data.

Example request

curl "https://app.betterfans.link/v1/accounts/412345678/revenue?from=2026-09-01&to=2026-09-28&interval=week" \
  -H "Authorization: Bearer $BFL_KEY"

Example response

{
  "data": {
    "from": "2026-09-01T00:00:00Z",
    "to": "2026-09-28T00:00:00Z",
    "interval": "week",
    "gross": {
      "amount": 2045000,
      "currency": "USD"
    },
    "net": {
      "amount": 1636000,
      "currency": "USD"
    },
    "byType": {
      "subscription": {
        "gross": {
          "amount": 612000,
          "currency": "USD"
        },
        "net": {
          "amount": 489600,
          "currency": "USD"
        },
        "count": 612
      },
      "tip": {
        "gross": {
          "amount": 402500,
          "currency": "USD"
        },
        "net": {
          "amount": 322000,
          "currency": "USD"
        },
        "count": 190
      },
      "message": {
        "gross": {
          "amount": 918000,
          "currency": "USD"
        },
        "net": {
          "amount": 734400,
          "currency": "USD"
        },
        "count": 804
      },
      "post": {
        "gross": {
          "amount": 98500,
          "currency": "USD"
        },
        "net": {
          "amount": 78800,
          "currency": "USD"
        },
        "count": 51
      },
      "stream": {
        "gross": {
          "amount": 14000,
          "currency": "USD"
        },
        "net": {
          "amount": 11200,
          "currency": "USD"
        },
        "count": 6
      },
      "referral": {
        "gross": {
          "amount": 0,
          "currency": "USD"
        },
        "net": {
          "amount": 0,
          "currency": "USD"
        },
        "count": 0
      },
      "other": {
        "gross": {
          "amount": 0,
          "currency": "USD"
        },
        "net": {
          "amount": 0,
          "currency": "USD"
        },
        "count": 0
      }
    },
    "series": [
      {
        "start": "2026-09-01T00:00:00Z",
        "gross": {
          "amount": 498000,
          "currency": "USD"
        },
        "net": {
          "amount": 398400,
          "currency": "USD"
        },
        "count": 402
      },
      {
        "start": "2026-09-08T00:00:00Z",
        "gross": {
          "amount": 521500,
          "currency": "USD"
        },
        "net": {
          "amount": 417200,
          "currency": "USD"
        },
        "count": 418
      },
      {
        "start": "2026-09-15T00:00:00Z",
        "gross": {
          "amount": 470250,
          "currency": "USD"
        },
        "net": {
          "amount": 376200,
          "currency": "USD"
        },
        "count": 390
      },
      {
        "start": "2026-09-22T00:00:00Z",
        "gross": {
          "amount": 555250,
          "currency": "USD"
        },
        "net": {
          "amount": 444200,
          "currency": "USD"
        },
        "count": 453
      }
    ],
    "topFans": [
      {
        "fan": {
          "id": "38291045",
          "username": "mike_travels",
          "name": "Mike",
          "avatarUrl": null
        },
        "gross": {
          "amount": 96500,
          "currency": "USD"
        }
      },
      {
        "fan": {
          "id": "51820377",
          "username": "danny.k",
          "name": "Danny",
          "avatarUrl": null
        },
        "gross": {
          "amount": 61200,
          "currency": "USD"
        }
      }
    ],
    "previousPeriod": {
      "gross": {
        "amount": 1872500,
        "currency": "USD"
      },
      "net": {
        "amount": 1498000,
        "currency": "USD"
      }
    }
  },
  "meta": {
    "source": "synced",
    "asOf": "2026-09-28T13:58:40Z",
    "requestId": "req_7Hq2LmX9pRt4VbN8cKe3WzYa"
  }
}

Errors

CodeStatusWhen
account_not_found404The account is not linked to your workspace, your key's account list leaves it out, or, with a test key, it is not a sandbox creator.
invalid_parameter400A query parameter has a value this route does not accept, or a required one is missing. error.param names it.

List transactions

GET /v1/accounts/{accountId}/transactions

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

Needs the read scope. Reads synced data.

Only sales are listed. Refunds and chargebacks are not in v1.

messageId and postId are not filled yet and are always null for now.

Path parameters

NameDescription
accountIdThe account's id, which is the creator's OnlyFans user id. Get it from GET /v1/accounts.

Query parameters

NameTypeDefaultDescription
fromdate or timestamp30 days agoStart, ISO 8601 date or timestamp (UTC).
todate or timestampnowEnd, ISO 8601 date or timestamp (UTC).
typeenumallOnly this kind of earning. One of all, subscription, tip, message, post, stream, referral or other.
fanIdstringNoneOnly this fan's transactions.
cursorstringNonenextCursor from the previous page. Leave out for the first page.
limitinteger25Page size, 1 to 100.

Returns

200 with a list of Transaction objects in data. See pagination.

Example request

curl "https://app.betterfans.link/v1/accounts/412345678/transactions?type=tip&limit=10" \
  -H "Authorization: Bearer $BFL_KEY"

Example response

{
  "data": [
    {
      "id": "7730021596",
      "type": "tip",
      "fan": {
        "id": "51820377",
        "username": "danny.k",
        "name": "Danny",
        "avatarUrl": null
      },
      "gross": {
        "amount": 2000,
        "currency": "USD"
      },
      "net": {
        "amount": 1600,
        "currency": "USD"
      },
      "fee": {
        "amount": 400,
        "currency": "USD"
      },
      "createdAt": "2026-09-28T09:12:44Z",
      "messageId": null,
      "postId": null,
      "description": "Tip from Danny"
    },
    {
      "id": "7729988120",
      "type": "tip",
      "fan": {
        "id": "38291045",
        "username": "mike_travels",
        "name": "Mike",
        "avatarUrl": null
      },
      "gross": {
        "amount": 5000,
        "currency": "USD"
      },
      "net": {
        "amount": 4000,
        "currency": "USD"
      },
      "fee": {
        "amount": 1000,
        "currency": "USD"
      },
      "createdAt": "2026-09-27T23:40:02Z",
      "messageId": null,
      "postId": null,
      "description": "Tip from Mike on a post"
    }
  ],
  "hasMore": true,
  "nextCursor": "q8ZtR2vN5xWcL7mK4pBd",
  "meta": {
    "source": "synced",
    "asOf": "2026-09-28T13:58:40Z",
    "requestId": "req_7Hq2LmX9pRt4VbN8cKe3WzYa"
  }
}

Errors

CodeStatusWhen
account_not_found404The account is not linked to your workspace, your key's account list leaves it out, or, with a test key, it is not a sandbox creator.
invalid_parameter400A query parameter has a value this route does not accept, or a required one is missing. error.param names it.
invalid_cursor400cursor is not a nextCursor this list returned.

The RevenueSummary object

Revenue for a period.

FieldTypeDescription
fromtimestampStart of the period.
totimestampEnd of the period.
intervalenumBucket size of series. One of day, week or month.
grossMoneyWhat fans paid in the period.
netMoneyWhat the creator keeps, about 80% of gross.
byTypeobjectTotals per transaction type. One entry for each of subscription, tip, message, post, stream, referral and other.
byType.<type>.grossMoneyGross for this type.
byType.<type>.netMoneyNet for this type.
byType.<type>.countintegerNumber of transactions.
seriesarray of objectsOne point per bucket.
series[].starttimestampStart of the bucket.
series[].grossMoneyGross in the bucket.
series[].netMoneyNet in the bucket.
series[].countintegerTransactions in the bucket.
topFansarray of objectsThe fans who paid the most in the period.
topFans[].fanFanSummaryThe fan.
topFans[].grossMoneyWhat the fan paid in the period.
previousPeriodobjectThe same length of time just before from, for comparison.
previousPeriod.grossMoneyGross in the previous period.
previousPeriod.netMoneyNet in the previous period.

The Transaction object

One payment from a fan.

FieldTypeDescription
idstringTransaction id.
typeenumWhat the fan paid for. One of subscription, tip, message, post, stream, referral or other.
fanFanSummary or nullThe fan who paid.
grossMoneyWhat the fan paid.
netMoneyWhat the creator keeps.
feeMoneyThe OnlyFans fee, gross minus net.
createdAttimestampWhen it happened.
messageIdstring or nullThe paid message, or the message a tip came with. Not filled yet, so it is always null for now.
postIdstring or nullThe post the payment was for. Not filled yet, so it is always null for now.
descriptionstring or nullOnlyFans' own description of the transaction.

On this page