Changelog
Resources

Changelog

Dated, additive changes to the API and these docs.

View as MarkdownUpdated Oct 26, 2026

Changes to the API are additive — new fields, new endpoints — and land here with a date. A breaking change would get its own dated entry and advance warning before it happens. Check this page (or its Markdown twin) when something looks new.

2026-11-01 — API v1 for OAuth apps at api.dropfans.io#

  • New: OAuth 2.0 / OpenID Connect at auth.dropfans.io (authorization code with PKCE S256, client_secret_basic, rotating refresh tokens with reuse detection, revoke, userinfo, discovery). Ask us for a client id and secret for your approved app. See /developers/api-v1/oauth-apps.
  • New: API v1 at https://api.dropfans.io with OAuth access tokens: account and audience, insights, agencies and their creators (/creators/{creatorUserUuid}/…), vault media and uploads, posts, media links, tracking links and webhooks. /v1 pages with a cursor ({data, nextCursor}); /v0 and unprefixed paths page with page and size ({data, pagination}). See /developers/api-v1/overview and the generated /developers/api-v1/resources.
  • New: per-account webhook subscriptions for OAuth apps (POST /v1/webhooks/subscriptions), signed t=…,v0=HMAC-SHA256(secret, "t.body"), with POST /v1/webhooks/test. See /developers/api-v1/webhooks.
  • Chat operations and chat webhook topics are part of API v1 and become available once chat is enabled for your app; until then they answer 404.
  • The API-key endpoints under /api/external are unchanged.

2026-11-01 — Act for a creator with /v1/creators/{creatorId}/…; creator roster; invite list and revoke#

  • Every creator endpoint is now also served at /api/external/v1/creators/{creatorId}/<path> (for example GET /api/external/v1/creators/{creatorId}/drops). An agency’s own key can use it for every creator and AI persona it manages (same permissions as before); your app owner’s own key can use it for every account your app onboarded with POST /accounts, while that account still holds the key bound to your app.
  • The X-Dropfans-Account header keeps working but is deprecated: responses to calls that send it carry Deprecation: true and a Link: rel="successor-version" header with the path form. A path and a header naming different accounts is 400 account_mismatch; a creator path on an endpoint that acts as your own account, agency or app (agency, accounts, webhooks, crm, payout writes, splits) is 400 creator_scope_not_allowed. Endpoints that act as your app (accounts, webhooks) now refuse X-Dropfans-Account too (400 account_header_not_allowed).
  • New GET /api/external/v1/creators and GET /api/external/v1/creators/{id}: the accounts your key can act for, with relationship (managed, ai_persona, onboarded), permissions, active and creatorPath, paged with {data, nextCursor}.
  • New GET /api/external/v1/agency/invites (the agency’s invites with status pending, accepted, expired or revoked) and DELETE /api/external/v1/agency/invites/{id} (revoke a pending invite).
  • GET /me adds key.via: self, agency or app. Links generated by an app owner for an account it onboarded are no longer recorded as an agency’s.
  • openapi.json lists each creator endpoint a second time as a …ForCreator operation under /api/external/v1/creators/{creatorId}/…, and marks the X-Dropfans-Account parameter deprecated.

2026-11-01 — Versioned paths: /api/external/v1#

  • Every endpoint is now also served under /api/external/v1/ (for example GET /api/external/v1/me), and the docs, the OpenAPI spec and the Markdown editions show the /v1 paths. The unversioned /api/external/ paths stay as permanent aliases: same handlers, same responses, nothing to change.

2026-11-01 — API categories: a switch per app; Payouts off by default#

  • Every endpoint now belongs to one API category (account, onboarding, agency, vault, drops, posts, links, earnings, payouts, splits, notifications, webhooks, crm), and every app has a switch per category. A call to a category that is off returns 403 api_category_disabled with a category field. See /developers/concepts/api-categories.
  • Payouts are off for every app, including Dropfans-operated ones, until we switch them on for that app; Onboarding (POST /api/external/accounts) is off for new apps, as creator sign-up was before. Everything else stays on, so other integrations see no change. GET /balance is in the earnings category and keeps working.
  • Payout requests, payout methods and the MassPay wallet setup are no longer limited to Dropfans-operated integrations: any app with Payouts on can use them, with the same rules as before (the key’s own account only, no agency-minted keys, after the ID check). Personal keys can read payouts but get 403 app_key_required on these writes. The first_party_only answer on them is gone.
  • Creator sign-up no longer answers 403 capability_missing: an app without Onboarding gets 403 api_category_disabled instead.
  • GET /api/external/crm/app adds apiCategories, and GET /api/external/me adds key.apiCategories (null for a personal key): each category with enabled and locked.

2026-10-31 — Subscription webhooks#

  • New webhook events subscription.paid (every charge — first charge and renewals — plus a $0 trial start with trial: true), subscription.canceled (renewal turned off, access continues until accessUntil) and subscription.ended (access over). subscription.paid carries a per-charge transactionId to dedupe on. See /developers/webhooks/overview.
  • Apps whose webhook has no event filter (the default: everything) receive them automatically — ignore types you do not handle. PUT /api/external/webhooks accepts them in events.

2026-10-31 — Earnings summary, daily agency earnings, media upload sessions#

  • New GET /api/external/earnings/summary: totals for all time, this month and your window, a breakdown by source (drop, tip, subscription) and a zero-filled day or Monday-start week series, in integer cents and any IANA timezone (an unknown zone is a 400). The series always adds up to the window total, which equals GET /api/external/earnings for the same window and timezone. An agency with canViewStats can read a managed account with X-Dropfans-Account.
  • New GET /api/external/agency/earnings (the agency’s own key): one row per managed creator per day with revenue — creatorId, date, grossCents, netCents, count — across every account the agency may see stats for, paged with a cursor ({data, nextCursor}).
  • New media upload sessions: POST /api/external/media/uploads {kind, filename, sizeBytes, contentType, folderId?} returns tus credentials for a video, or 3 MB part URLs for an image or audio file (PUT /api/external/media/uploads/{id}/parts/{n}). POST /api/external/media/uploads/{id}/complete creates the vault item and starts moderation (idempotent; 409 missing_parts lists what is missing) and GET /api/external/media/uploads/{id} shows the parts, the vault item and its moderation status. Up to 30 MB per image and 20 MB per audio file — more than the 4 MB a single POST /api/external/vault takes. The existing /vault and /vault/video-upload endpoints are unchanged.
  • Fix: GET /api/external/earnings no longer counts the first hour of the next day (or drops the last hour) when endDate is a daylight-saving switch day in tz.

2026-10-30 — Payouts API; GET /balance adds total and sides#

  • New Payouts endpoints (any key; an agency with canViewStats can read a managed account with X-Dropfans-Account): GET /api/external/payouts/summary (balance per bucket and side in cents, minimum, masked default method, open request, in-flight payout, upcoming releases, eligible + ineligibleReasons), GET /api/external/payouts (the payout history — payouts, manual payouts and open requests — paginated with a cursor, filters since, until, status, kind, includeReversed), GET /api/external/payouts/{id} and GET /api/external/payouts/methods (masked: Paxum e-mail as j***@example.com, bank last 4 only, no tokens). All money in integer cents.
  • New POST /api/external/payouts/requests (Idempotency-Key header required) requests a payout of the full available balance, one request per side, with the same gates as the dashboard plus the ID check, wallet activation and in-flight checks, each with its own code. Idempotency keys are scoped to the account and your app (a personal key: that key); a concurrent call with the same key gets 409 payout_busy and a retry replays. POST /api/external/payouts/requests/{id}/cancel cancels a request while it is still requested (approved and processing requests are on their way: 409 request_not_cancellable). Both act for the key’s own account only (X-Dropfans-Account is refused, and agency-minted keys get 403 agency_key_not_allowed — agencies cannot request payouts for managed creators) and are limited to Dropfans-operated integrations at launch (403 first_party_only).
  • GET /api/external/balance adds total (the full payable balance — creator side + agency side + referral commission + partner shares, the same numbers as the Payouts page and a payout request) and sides (total broken down per side). The existing top-level fields are unchanged (creator side, USD dollars), so current integrations keep working.
  • New payout-method writes, with the same rules as payout requests (the key’s own account only, no agency-minted keys, after the ID check, Dropfans-operated integrations only at launch): POST /api/external/payouts/methods adds a Paxum method (the e-mail must be an active Paxum account, else 422 paxum_account_not_active; repeating an e-mail returns the existing method with Idempotent-Replayed: true), PATCH /api/external/payouts/methods/{id} changes nickname, isDefault or paxumEmail (other fields: 400 unknown_field), DELETE /api/external/payouts/methods/{id} removes one (409 method_in_use while a payout to it is in flight).
  • New MassPay wallet setup: GET /api/external/payouts/masspay/profile (the live profile + missingFields), POST /api/external/payouts/masspay/profile (creates the payee from the same profile as the dashboard form — or fills in what an existing payee lacks — and attaches the wallet as the default method; returns activationUrl) and GET /api/external/payouts/masspay/activation (activated, plus a fresh activationUrl). Address line 1, city, state / province and postal code are now required, as MassPay needs them to pay out; middle name, mobile number, language, date of birth and address line 2 stay optional.
  • New webhook events: payout.requested, payout.processing, payout.paid and payout.failed, with the GET /payouts/{id} row plus accountId as data. Apps whose webhook has no event filter (the default) start receiving them now — ignore types you do not handle, or set events with PUT /api/external/webhooks.

2026-10-30 — Your integration dashboard, as an API#

  • New CRM endpoints for the app owner’s keys, with the same numbers as Dashboard → Developer: GET /api/external/crm/app, GET /api/external/crm/stats (totals + zero-filled hour / day / week / month buckets, any IANA tz), GET /api/external/crm/transactions (every sale through your app, paginated) and GET /api/external/crm/accounts (connected accounts, all-time). Amounts are integer US cents, excl. tax, before our platform fee.
  • An account that moved to another CRM shows movedAway (when), never which CRM — in the API and in your dashboard.
  • New: link ids. POST /api/external/links creates a link for a drop, a tip (fixed amount or the fan picks), a subscription or the profile, with your externalRef. The link is just https://www.dropfans.io/buy/{id} (startapp={id} in Telegram); everything else is stored with the id. GET /api/external/links adds links.profile / links.tip / links.subscribe.
  • A drop bought, a tip sent or a subscription started through your app’s links earns your app owner commission for life (every renewal of that subscription too), by default 5%. Generating links makes your app the account’s connected CRM.
  • Orders, tips, the earnings ledger and the drop.paid / tip.paid webhooks gain linkId.
  • Called with an app key, POST /drops returns buyUrl as your app’s link id (/buy/{linkId}, plus linkId); the read endpoints return that link when it exists and never create one. Personal keys still get /buy/{productId}.
  • A drop your app created with its key counts as yours however it is bought: its plain /buy/{productId} and b_{productId} links are links your app generated.
  • No commission when your app’s owner is the managing agency of the selling creator — the agency share already pays for that sale.
  • The web / telegram templates are deprecated but unchanged and keep working. A template sale with an externalRef counts for a CRM only when it is the only app that has ever generated links for the account, its own key works the account (directly or through its agency), and the account has no personal key. Links created with a personal key never earn commission.

2026-10-28 — Referral commission is CRM-only; subscription period cards; paginated earnings ledger#

  • New GET /api/external/earnings/transactions: every drop sale, tip and subscription payment, paginated with a cursor (limit up to 200, no total cap), with netAmountCents, grossAmountCents, platformFeeCents, taxCents and totalChargedCents per transaction. Filters: since, until, type, includeReversed. GET /api/external/earnings is unchanged (its transactions stay the newest 50).
  • Orders (GET /api/external/orders, check-status, drop.paid / drop.refunded) and tips (GET /api/external/tips, tip.paid / tip.refunded) now also carry netAmountCents, platformFeeCents and taxCents. Additive — existing fields are unchanged.
  • Referral commission is now only for CRM apps: accounts created through POST /api/external/accounts earn the app owner 5% of their sales for their first 12 months, and drops created with a CRM app’s keys keep earning 5% on every sale. The creator referral link program has ended. Nothing changes in the API (referralCredited is unchanged).
  • GET /api/external/subscription now returns plans (the subscription period cards, left to right), and PUT accepts plans: [{ period: WEEK|MONTH|MONTH_3|MONTH_6|LIFETIME, priceUsd, promoPriceUsd?, trialDays? }]. The single priceUsd + interval form still works and saves one card.

2026-10-27 — Lucky Wheel retired#

  • The Lucky Wheel feature has been removed. GET /api/external/links no longer returns telegram.spin, and POST /api/external/wheel/grant now returns 404. Old t.me w_<username> links open the creator’s profile.

2026-10-26 — Agencies: one key for every creator#

  • Account targeting: a verified agency’s own key can act for any creator or AI persona it manages by sending X-Dropfans-Account: <account id> on any creator endpoint. Checked on every request (accepted management, nobody suspended, banned or deleted, plus the endpoint’s permission). New errors: 400 invalid_account_header, 403 account_not_managed, 403 permission_denied. Without the header nothing changes.
  • Every response now carries an X-Dropfans-Account header with the id of the account the request acted on. GET /me adds key.viaAgency, and key.managedBy names the agency when the header is used. Rate limits stay per key.
  • New Agencies endpoints (the agency’s own key, without the header): GET /api/external/agency/creators, POST /api/external/agency/personas, PATCH and DELETE /api/external/agency/personas/{id}, POST /api/external/agency/personas/{id}/reactivate, POST /api/external/agency/invites, DELETE /api/external/agency/creators/{id} and GET /api/external/agency/stats.
  • New creator endpoints (own key or with the header): GET/PATCH /api/external/profile, GET /api/external/drops (list), PATCH and DELETE /api/external/drops/{id} and GET/PUT /api/external/subscription.
  • Webhooks: an app holding an agency’s own key also receives events for every creator that agency manages; those payloads carry data.agencyId next to data.accountId. An app never gets the same event twice.

2026-10-23 — Referral commission on drops a CRM app creates#

  • Drops created with a CRM app’s keys (apps with CRM sign-up enabled) earn the app owner the 5% referral commission on every sale of that drop, with no time limit. On those sales it replaces the creator’s own referrer.

2026-10-23 — Per-fan references on tips#

  • Tip links can carry your per-fan reference: ?tip={usd}&m={externalRef} on the web, startapp=tm_{cents}{externalRef}{username} in Telegram ({cents} 0 = the fan picks; there the reference is 1–20 of A-Z a-z 0-9 - with no underscore). GET /links returns tipWithRefTemplate for both.
  • New webhook events: tip.paid and tip.refunded, with externalRef and the fan’s message.
  • New endpoint: GET /api/external/tips — paid tips with externalRef, message, tipper and status; filter by externalRef or since.

2026-10-17 — Per-fan references, webhooks and creator sign-up#

  • Per-fan checkout references: share ONE drop with many fans. Add ?m={externalRef} to the buy link (Telegram: startapp=b_{productId}_{externalRef}); the reference comes back on every paid order. GET /links returns buyWithRefTemplate for both.
  • New endpoint: GET /api/external/orders — paid drop orders with externalRef, buyer and status; filter by productId, externalRef or since.
  • POST /drops/check-status now also returns orders — every paid order per product (the existing sales map is unchanged).
  • Webhooks are live: drop.paid, drop.refunded and account.kyc_updated, HMAC-signed (DropFans-Signature) with retries. Configure with PUT /api/external/webhooks using a key the app owner holds.
  • Creator sign-up for approved CRM apps: POST /api/external/accounts creates a creator account with profile, residency, images and subscription price, returns the ID-check link and a key for the account, and credits the referral commission to the app owner.

2026-08-19 — Public launch#

  • Apps & approval: third-party integrations can now apply for API access at /developers/apply. Approved apps appear in the key picker under Vault → API Connect.
  • Rate limits: every response now carries X-RateLimit-* headers (minute and day windows, per tier). Dropfans-operated integrations are exempt.
  • New endpoint: GET /api/external/drops/{id} — read back a drop you created, including per-item moderation status and sales count.
  • New endpoint: GET /api/external/links — canonical web and Telegram Mini App links (profile, tip, subscribe, buy) for the creator behind the key.
  • Web tip links: /u/<username>?tip=1 opens the tip sheet; ?tip=<usd> opens it prefilled.
  • Malformed JSON on PUT /timezone, PUT /notifications and POST /register-telegram-chat now returns 400 {"error":"Invalid JSON body"} instead of an unstructured 500.
  • POST /api/external/posts now builds the returned url from the configured app URL instead of a hardcoded host.
  • Drops created through the API now carry the correct moderation status at creation — a drop built from approved vault items is born APPROVED and can be attached to a post immediately.
  • Full documentation: every endpoint is now documented at /developers, with an OpenAPI 3.1 spec, llms.txt / llms-full.txt editions and a Markdown twin of every page.

Next: API terms & acceptable use or API reference.

Questions? support@dropfans.io