Earnings, balances and payouts
View as MarkdownShow earnings and balances in your product, set up crypto, bank or Paxum payouts, and request them through the API without sending creators to 2fans.
Earnings and balance reads are on by default. Setting up methods and requesting payouts needs an app key with the Payouts category, which starts switched off, so ask us to enable it. A personal key can read payouts but not change them; those creators request payouts in the 2fans dashboard. All money is in USD cents.
1Read earnings
startDateandendDateare required.stats.totalEarningsCentsis what the creator keeps,stats.grossEarningsCentsis what buyers paid, and refunds and chargebacks are left out.curlcurl "https://www.dropfans.io/api/external/v1/earnings?startDate=2026-08-01&endDate=2026-08-19&tz=Europe/Stockholm" \ -H "Authorization: Bearer $DROPFANS_API_KEY"Nodeconst res = await fetch('https://www.dropfans.io/api/external/v1/earnings?startDate=2026-08-01&endDate=2026-08-19&tz=Europe/Stockholm', { headers: { Authorization: 'Bearer ' + process.env.DROPFANS_API_KEY }, }); const { stats, chart, transactions } = await res.json();Pythonimport os, requests HEADERS = {"Authorization": f"Bearer {os.environ['DROPFANS_API_KEY']}"} res = requests.get("https://www.dropfans.io/api/external/v1/earnings?startDate=2026-08-01&endDate=2026-08-19&tz=Europe/Stockholm", headers=HEADERS) data = res.json()2Read the balance
GET /balanceshows where the money sits:pending(in the release hold),available(payable),processing(in a payout run) andpaidOut(lifetime).GET /payouts/summaryadds the minimum, the payout method and whether a request would be accepted right now.curlcurl "https://www.dropfans.io/api/external/v1/payouts/summary" \ -H "Authorization: Bearer $DROPFANS_API_KEY"Nodeconst res = await fetch('https://www.dropfans.io/api/external/v1/payouts/summary', { headers: { Authorization: 'Bearer ' + process.env.DROPFANS_API_KEY }, }); console.log(await res.json());Pythonimport os, requests HEADERS = {"Authorization": f"Bearer {os.environ['DROPFANS_API_KEY']}"} res = requests.get("https://www.dropfans.io/api/external/v1/payouts/summary", headers=HEADERS) print(res.json())3Add Paxum
The email has to belong to an active Paxum account.
isDefaultmakes it the method payouts go to. The account has to have passed the ID check.curlcurl -X POST "https://www.dropfans.io/api/external/v1/payouts/methods" \ -H "Authorization: Bearer $DROPFANS_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "type": "PAXUM_P2P", "paxumEmail": "jane@example.com", "nickname": "Main Paxum", "isDefault": true }'Nodeconst res = await fetch('https://www.dropfans.io/api/external/v1/payouts/methods', { method: 'POST', headers: { Authorization: 'Bearer ' + process.env.DROPFANS_API_KEY, 'Content-Type': 'application/json', }, body: JSON.stringify({ "type": "PAXUM_P2P", "paxumEmail": "jane@example.com", "nickname": "Main Paxum", "isDefault": true }), }); console.log(await res.json());Pythonimport os, requests res = requests.post( "https://www.dropfans.io/api/external/v1/payouts/methods", headers={"Authorization": f"Bearer {os.environ['DROPFANS_API_KEY']}"}, json={ "type": "PAXUM_P2P", "paxumEmail": "jane@example.com", "nickname": "Main Paxum", "isDefault": True }, ) print(res.json())4Or set up the wallet for crypto, bank and card
Crypto, bank transfer and card are cash-out options inside a MassPay wallet, chosen by the creator when they cash out. Send the profile to create the wallet.
countryis a three-letter code, anddateOfBirthis optional.curlcurl -X POST "https://www.dropfans.io/api/external/v1/payouts/masspay/profile" \ -H "Authorization: Bearer $DROPFANS_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "accountType": "INDIVIDUAL", "firstName": "Jane", "lastName": "Doe", "email": "jane@example.com", "country": "SWE", "address1": "Storgatan 1", "city": "Stockholm", "stateProvince": "Stockholm County", "postalCode": "111 22" }'Nodeconst res = await fetch('https://www.dropfans.io/api/external/v1/payouts/masspay/profile', { method: 'POST', headers: { Authorization: 'Bearer ' + process.env.DROPFANS_API_KEY, 'Content-Type': 'application/json', }, body: JSON.stringify({ "accountType": "INDIVIDUAL", "firstName": "Jane", "lastName": "Doe", "email": "jane@example.com", "country": "SWE", "address1": "Storgatan 1", "city": "Stockholm", "stateProvince": "Stockholm County", "postalCode": "111 22" }), }); console.log(await res.json());Pythonimport os, requests res = requests.post( "https://www.dropfans.io/api/external/v1/payouts/masspay/profile", headers={"Authorization": f"Bearer {os.environ['DROPFANS_API_KEY']}"}, json={ "accountType": "INDIVIDUAL", "firstName": "Jane", "lastName": "Doe", "email": "jane@example.com", "country": "SWE", "address1": "Storgatan 1", "city": "Stockholm", "stateProvince": "Stockholm County", "postalCode": "111 22" }, ) print(res.json())5Have the creator activate the wallet once
This is the one step a person has to do. Before the first payout, the creator opens
activationUrlonce in a browser, which is a MassPay requirement. It’s a MassPay page, not 2fans. The link expires, so fetch it right before you show it and never store it.curlcurl "https://www.dropfans.io/api/external/v1/payouts/masspay/activation" \ -H "Authorization: Bearer $DROPFANS_API_KEY"Nodeconst res = await fetch('https://www.dropfans.io/api/external/v1/payouts/masspay/activation', { headers: { Authorization: 'Bearer ' + process.env.DROPFANS_API_KEY }, }); console.log(await res.json());Pythonimport os, requests HEADERS = {"Authorization": f"Bearer {os.environ['DROPFANS_API_KEY']}"} res = requests.get("https://www.dropfans.io/api/external/v1/payouts/masspay/activation", headers=HEADERS) print(res.json())Response{ "provisioned": true, "activated": false, "activationUrl": "https://payee.masspay.io/activate/…" }6Request the payout
This requests the full available balance; partial payouts aren’t possible. The
Idempotency-Keyheader is required, so a retry can’t pay twice. We review each request and send it, andpayout.*webhooks report each stage.curlcurl -X POST "https://www.dropfans.io/api/external/v1/payouts/requests" \ -H "Authorization: Bearer $DROPFANS_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{ "note": "October" }'Nodeconst res = await fetch('https://www.dropfans.io/api/external/v1/payouts/requests', { method: 'POST', headers: { Authorization: 'Bearer ' + process.env.DROPFANS_API_KEY, 'Idempotency-Key': crypto.randomUUID(), 'Content-Type': 'application/json', }, body: JSON.stringify({ note: 'October' }), }); const { requests } = await res.json();Pythonimport os, uuid, requests res = requests.post( "https://www.dropfans.io/api/external/v1/payouts/requests", headers={ "Authorization": f"Bearer {os.environ['DROPFANS_API_KEY']}", "Idempotency-Key": str(uuid.uuid4()), }, json={"note": "October"}, ) print(res.json()["requests"])
Who can do what
| Personal key | App key with the Payouts category | |
|---|---|---|
| Read balances and history | Yes | Yes |
| Add payout methods | No, use the dashboard | Yes |
| Request a payout | No, use the dashboard | Yes |
A payout request acts for the key's own account, so use the key made for that creator. An agency can read a managed creator's payouts but can't request a payout for them.
Next
Last updated 2026-11-02