List sales through your app
API reference

List sales through your app

Your integration dashboard’s Transactions tab: every sale through your app’s links across all your accounts, newest first, with the commission booked on each.

View as MarkdownUpdated Oct 30, 2026
GET/api/external/crm/transactionsNew

Your integration dashboard’s Transactions tab: every sale through your app’s links across all your accounts, newest first, with the commission booked on each.

Drop sales, tips and subscription payments are all included. Refunded and charged-back sales are included by default with their status (like the dashboard); pass includeReversed=false to leave them out. Window by exact instants (since / until) or by calendar days (startDate / endDate in tz), not both. Page with cursor.

Authentication

Send the creator's API key as a bearer token: Authorization: Bearer dpfn_…. See Authentication & API keys.

Query parameters

NameTypeRequiredDescription
sincestringOptionalOnly sales paid at or after this instant (ISO 8601).
Format: date-time
untilstringOptionalOnly sales paid at or before this instant (ISO 8601).
Format: date-time
startDatestringOptionalInstead of since/until: first day, YYYY-MM-DD, in tz. Needs endDate.
Format: date
endDatestringOptionalLast day, YYYY-MM-DD, in tz (at most 366 days).
Format: date
tzstringOptionalIANA time zone the calendar days (and buckets) are cut in. Defaults to Europe/Stockholm, like your dashboard.
Default: "Europe/Stockholm"
Format: iana-timezone
typestringOptionalComma-separated subset of drop,tip,subscription. Default: all.
includeReversedbooleanOptionalfalse leaves refunded and charged-back sales out.
Default: true
limitintegerOptionalPage size (clamped to the range).
Default: 50
Min: 1
Max: 100
cursorstringOptionalnextCursor from the previous page, unchanged. Keep the other parameters the same.

Responses

200A page of sales.
NameTypeDescription
currencystringCurrency of every *Cents field.
One of: USD
transactionsCrmTransaction[]Newest first.
Show child attributes
idstringOur id of the sale (order, tip or subscription payment).
typestringWhat was sold. subscription is one payment (the first or a renewal).
One of: drop, tip, subscription
paidAtstringWhen it was paid (UTC).
Format: date-time
transactionIdstringThe payment processor’s transaction id when known, else our id.
linkIdstring | nullThe link id (POST /api/external/links) the drop or tip was bought through; null for subscription payments and older template links.
amountCentsintegerSale amount, US cents, excl. tax, before our platform fee.
crmEarnedCentsintegerCommission booked for your app owner on this sale, US cents. 0 when the commission was reversed (refund or chargeback).
statusstringCurrent state of the sale.
One of: paid, refunded, charged_back
creatorobjectThe account that made the sale.
Show child attributes
idstringAccount id.
usernamestring | null@handle without the @.
namestring | nullDisplay name.
nextCursorstring | nullPass as cursor for the next page; null on the last page.
Example response
{
  "currency": "USD",
  "transactions": [
    {
      "id": "clxor0001ord",
      "type": "drop",
      "paidAt": "2026-10-29T18:42:11.000Z",
      "transactionId": "cb_8812734",
      "linkId": "k3v9x2m1qa",
      "amountCents": 1500,
      "crmEarnedCents": 75,
      "status": "paid",
      "creator": {
        "id": "clxac0001acct",
        "username": "valeria",
        "name": "Valeria"
      }
    }
  ],
  "nextCursor": "MjAyNi0xMC0yOVQxODo0MjoxMS4wMDBafGNseG9yMDAwMW9yZA"
}

Errors

StatusBodyWhen
400{"error":"Use since/until or startDate/endDate, not both.","code":"invalid_input","field":"since"}Both windows were sent.
400{"error":"since must be an ISO 8601 date or date-time.","code":"invalid_input","field":"since"}Unparseable `since` / `until`, or `until` before `since`.
400{"error":"startDate must be a real calendar day, YYYY-MM-DD.","code":"invalid_input","field":"startDate"}`startDate` / `endDate` missing (stats) or not a YYYY-MM-DD day.
400{"error":"endDate must be on or after startDate.","code":"invalid_input","field":"endDate"}`endDate` is before `startDate`.
400{"error":"The range can be at most 366 days.","code":"invalid_input","field":"endDate"}More than 366 days.
400{"error":"tz must be an IANA time zone, e.g. Europe/Stockholm or America/New_York.","code":"invalid_input","field":"tz"}Unknown `tz`.
400{"error":"type must be a comma-separated subset of drop,tip,subscription.","code":"invalid_input","field":"type"}Unknown `type`.
400{"error":"includeReversed must be true or false.","code":"invalid_input","field":"includeReversed"}Anything else.
400{"error":"Invalid cursor. Pass nextCursor from the previous page unchanged.","code":"invalid_input","field":"cursor"}Malformed `cursor`.
401{"error":"Unauthorized","code":"unauthorized"}Missing or invalid API key.
403{"error":"This endpoint needs a key bound to an approved app.","code":"app_key_required"}A Personal key was used.
403{"error":"Use the app owner's key for this endpoint.","code":"owner_key_required"}The key was minted by a creator for themselves. App-level calls need a key held by your app owner: their own, or one their agency minted for its personas or managed creators.
400{"error":"This endpoint only acts as the key’s own account — send it without X-Dropfans-Account.","code":"account_header_not_allowed"}`X-Dropfans-Account` was sent. These endpoints always answer for the key’s app.

Rate limiting

Every response carries the X-RateLimit-Tier header and, on limited tiers, the per-minute and per-day trios — read X-RateLimit-Remaining and X-RateLimit-Reset instead of hardcoding limits. Details in Rate limits.

Code samples

curl "https://www.dropfans.io/api/external/crm/transactions?tz=America%2FNew_York&type=drop%2Ctip" \
  -H "Authorization: Bearer $DROPFANS_API_KEY"

Questions? [email protected]