2fansAPI docs

Earnings, balances and payouts

View as Markdown

Show 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.

  1. 1Read earnings

    startDate and endDate are required. stats.totalEarningsCents is what the creator keeps, stats.grossEarningsCents is what buyers paid, and refunds and chargebacks are left out.

    curl
    curl "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"
    Node
    const 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();
    Python
    import 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()
  2. 2Read the balance

    GET /balance shows where the money sits: pending (in the release hold), available (payable), processing (in a payout run) and paidOut (lifetime). GET /payouts/summary adds the minimum, the payout method and whether a request would be accepted right now.

    curl
    curl "https://www.dropfans.io/api/external/v1/payouts/summary" \
      -H "Authorization: Bearer $DROPFANS_API_KEY"
    Node
    const 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());
    Python
    import 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())
  3. 3Add Paxum

    The email has to belong to an active Paxum account. isDefault makes it the method payouts go to. The account has to have passed the ID check.

    curl
    curl -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
        }'
    Node
    const 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());
    Python
    import 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())
  4. 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. country is a three-letter code, and dateOfBirth is optional.

    curl
    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"
        }'
    Node
    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"
      }),
    });
    console.log(await res.json());
    Python
    import 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())
  5. 5Have the creator activate the wallet once

    This is the one step a person has to do. Before the first payout, the creator opens activationUrl once 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.

    curl
    curl "https://www.dropfans.io/api/external/v1/payouts/masspay/activation" \
      -H "Authorization: Bearer $DROPFANS_API_KEY"
    Node
    const 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());
    Python
    import 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/…"
    }
  6. 6Request the payout

    This requests the full available balance; partial payouts aren’t possible. The Idempotency-Key header is required, so a retry can’t pay twice. We review each request and send it, and payout.* webhooks report each stage.

    curl
    curl -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" }'
    Node
    const 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();
    Python
    import 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