Set up the MassPay wallet
Set up the account's MassPay payout wallet from the same profile the dashboard's setup form collects, and make it the default payout method.
/api/external/v1/payouts/masspay/profilealso served at /api/external/payouts/masspay/profileNewSet up the account's MassPay payout wallet from the same profile the dashboard's setup form collects, and make it the default payout method.
Required: firstName, lastName, email, country, address1, city, stateProvince, postalCode, plus businessName when accountType is BUSINESS. Optional: middleName, mobileNumber, language, dateOfBirth, address2. Enter everything as on the payee's government-issued ID. Every field is checked before anything is sent to MassPay; a refused profile answers 400 invalid_profile naming the first bad field, with all of them in errors.
- No payee yet → the payee is created at MassPay with the full profile (201).
- Payee exists but lacks required details (see
missingFieldson GET /payouts/masspay/profile) → the fields you send fill them in.country,emailandbusinessNamestay as MassPay has them; send at least the missing fields. - Payee complete → the body is not needed; the wallet is (re)attached.
Activation: before the first payout to the wallet, the payee must open activationUrl once in a browser (a MassPay requirement). The link expires — get a fresh one from GET /payouts/masspay/activation when you send the payee there. Payout requests to a wallet that is not activated are refused (masspay_not_activated).
Safe to retry: there is one MassPay payee and one wallet per account. The key's own account only, after the ID check.
Payouts are an API category that is off for every app until we switch it on — ask support. Personal keys can read payouts but get 403 app_key_required here.
Authentication
Send the creator's API key as a bearer token: Authorization: Bearer dpfn_…. See Authentication & API keys.
Request body
Content type: application/json — The payout profile. Optional when the payee already exists and is complete.
| Name | Type | Required | Description |
|---|---|---|---|
accountType | string | Optional | Who the payee is. BUSINESS makes businessName required; the person fields are then the authorized representative’s.One of: INDIVIDUAL, BUSINESSDefault: "INDIVIDUAL" |
businessName | string | Optional | **Required when accountType is BUSINESS.** The company’s registered legal name. Its presence is what makes the payee a business account at MassPay; the person fields are then the authorized representative’s. Cannot be changed once set.Max length: 150 |
firstName | string | Required | As on the government-issued ID. Max length: 100 |
middleName | string | Optional | Optional. As on the ID. Max length: 100 |
lastName | string | Required | As on the ID. Max length: 100 |
email | string | Required | Must not be used by another MassPay account. Format: email Max length: 254 |
mobileNumber | string | Optional | Optional. With country code; 7–15 digits once spaces and symbols are removed. Max length: 32 |
language | string | Optional | Optional. ISO 639-1 code for MassPay’s e-mails and portal (default "en"). Max length: 2 |
dateOfBirth | string | Optional | Optional. YYYY-MM-DD, a real date; the payee must be at least 18. Format: date Max length: 10 |
country | string | Required | ISO 3166-1 alpha-3 country of residence. Max length: 3 |
address1 | string | Required | Street address. Max length: 150 |
address2 | string | Optional | Optional. Apartment, suite, c/o. Max length: 150 |
city | string | Required | City. Max length: 100 |
stateProvince | string | Required | State, province, county or region. Max length: 100 |
postalCode | string | Required | Postal / ZIP code. Max length: 20 |
{
"accountType": "INDIVIDUAL",
"firstName": "Jane",
"lastName": "Doe",
"email": "jane@example.com",
"country": "SWE",
"address1": "Storgatan 1",
"city": "Stockholm",
"stateProvince": "Stockholm County",
"postalCode": "111 22",
"dateOfBirth": "1994-05-17",
"language": "sv"
}{
"address1": "Storgatan 1",
"city": "Stockholm",
"stateProvince": "Stockholm County",
"postalCode": "111 22"
}Responses
| Name | Type | Description | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
method | PayoutMethodSummary | The wallet method, now the default.Show child attributes
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
activationUrl | string | null | Where the payee activates the wallet (once, in a browser). Null when already activated. Expires. Format: uri | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
created | boolean | True when the MassPay payee was created by this call. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
completed | boolean | True when missing profile fields were filled in at MassPay by this call. |
{
"method": {
"id": "clxpm0001method",
"type": "MASSPAY",
"isDefault": true,
"nickname": null,
"label": "Payout wallet · SWE",
"holderType": "INDIVIDUAL",
"createdAt": "2026-10-30T10:00:00.000Z",
"paxum": null,
"masspay": {
"country": "SWE",
"currency": null,
"payerName": null,
"activated": false
},
"bank": null
},
"activationUrl": "https://payee.masspay.io/activate/…",
"created": true,
"completed": false
}Errors
| Status | Body | When |
|---|---|---|
| 400 | {"error":"City is required.","code":"invalid_profile","field":"city","errors":[{"field":"city","code":"required","message":"City is required."}]} | A field is missing or invalid. Codes in `errors`: required, too_long, invalid_type, invalid_account_type, invalid_email, invalid_country, invalid_date_of_birth, under_18, invalid_mobile_number, invalid_language. |
| 400 | {"error":"Invalid JSON body"} | The body is not valid JSON (`invalid_body` when it is not an object). |
| 401 | {"error":"Unauthorized","code":"unauthorized"} | Missing or invalid API key. |
| 403 | {"error":"Verify your identity (KYC) before setting up payouts.","code":"kyc_required"} | The account has not passed the ID check. |
| 403 | {"error":"Payout methods need the account’s own key — a key an agency minted for a managed account cannot read or change where payouts go.","code":"agency_key_not_allowed"} | The key was minted by an agency for an account it manages. |
| 403 | {"error":"This endpoint needs a key bound to an app with the payouts API category enabled — personal keys cannot use it.","code":"app_key_required","category":"payouts"} | A personal key (not bound to an app). Personal keys may read payouts, but not change them. |
| 409 | {"error":"Could not determine your payout country. Contact support.","code":"no_country"} | An existing payee has no usable country. Contact support. |
| 422 | {"error":"This email is already used by another MassPay account. Enter a different email.","code":"masspay_email_in_use"} | MassPay refused the profile (`masspay_rejected` with MassPay’s reason for other refusals). |
| 502 | {"error":"Could not read your MassPay profile. Try again in a moment.","code":"masspay_unavailable"} | MassPay did not answer. Retry. |
| 503 | {"error":"MassPay is not available right now.","code":"not_configured"} | MassPay payouts are switched off on this environment. |
| 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` names another account. An agency can never change where a creator it manages is paid. |
| 400 | {"error":"This endpoint acts as the key’s own account or app — call it without /creators/{creatorId}.","code":"creator_scope_not_allowed"} | Called under /api/external/v1/creators/{creatorId}/ — this endpoint always acts as the key’s own account, agency or app. |
| 403 | {"error":"This app does not have the payouts API category enabled. Contact support to enable it.","code":"api_category_disabled","category":"payouts"} | Your app has the Payouts [API category](/developers/concepts/api-categories) switched off (the default for new apps). |
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 -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",
"dateOfBirth": "1994-05-17",
"language": "sv"
}'const 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",
"dateOfBirth": "1994-05-17",
"language": "sv"
}),
});
console.log(await res.json());import os
import 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",
"dateOfBirth": "1994-05-17",
"language": "sv",
},
)
print(res.json())Questions? support@dropfans.io
