coal
coal

Revenue Splits API

Revenue splits let you automatically divide each incoming payment between multiple wallet addresses. When a checkout session is confirmed, Coal applies the split configuration and routes funds to each recipient according to their defined percentage.

Use splits for marketplace payouts, affiliate commissions, co-creator revenue sharing, or distributing fees between a platform and its vendors.

This page covers the console-managed split configuration surface. Public checkout creation still uses x-api-key on /api/checkouts; split CRUD under /api/console/* is Privy-authenticated.

Base URL: https://api.usecoal.xyz


Create a Split

POST /api/console/splits

Creates a new split configuration. Splits can be attached to products or payment links at creation time.

Authentication

HeaderRequiredDescription
AuthorizationYesBearer <privy_access_token> from an authenticated console session

Request Body

FieldTypeRequiredDescription
namestringYesA human-readable name for this split (e.g. "Marketplace Fee Split").
recipientsSplitRecipient[]YesArray of recipients. Must have at least 2 entries. Percentages must sum to exactly 100.
descriptionstringNoOptional notes about what this split is for.

SplitRecipient

FieldTypeRequiredDescription
addressstringYesEVM wallet address of the recipient on Base.
percentnumberYesPercentage of each payment to send here (e.g. 30 for 30%).
labelstringNoHuman-readable label (e.g. "Platform Fee", "Creator").

Percentages must sum to exactly 100. Coal will reject the request with 400 INVALID_SPLIT if the sum differs.

cURL Example

bash
1curl -X POST https://api.usecoal.xyz/api/console/splits \
2 -H "Content-Type: application/json" \
3 -H "Authorization: Bearer <privy_access_token>" \
4 -d '{
5 "name": "Marketplace Fee Split",
6 "description": "10% platform fee, 90% to creator.",
7 "recipients": [
8 {
9 "address": "0xPlatformWalletAddress000000000000000000",
10 "percent": 10,
11 "label": "Platform Fee"
12 },
13 {
14 "address": "0xCreatorWalletAddress0000000000000000000",
15 "percent": 90,
16 "label": "Creator"
17 }
18 ]
19 }'

Response Example

json
1{
2 "id": "spl_cm9x4k2j00003lb08n5qz7v1r",
3 "name": "Marketplace Fee Split",
4 "description": "10% platform fee, 90% to creator.",
5 "recipients": [
6 {
7 "address": "0xPlatformWalletAddress000000000000000000",
8 "percent": 10,
9 "label": "Platform Fee"
10 },
11 {
12 "address": "0xCreatorWalletAddress0000000000000000000",
13 "percent": 90,
14 "label": "Creator"
15 }
16 ],
17 "createdAt": "2026-03-22T10:00:00.000Z"
18}

List Splits

GET /api/console/splits

Returns all split configurations for the authenticated merchant, sorted by creation date descending.

Authentication

HeaderRequiredDescription
AuthorizationYesBearer <privy_access_token> from an authenticated console session

cURL Example

bash
1curl https://api.usecoal.xyz/api/console/splits \
2 -H "Authorization: Bearer <privy_access_token>"

Response Example

json
1{
2 "data": [
3 {
4 "id": "spl_cm9x4k2j00003lb08n5qz7v1r",
5 "name": "Marketplace Fee Split",
6 "recipients": [
7 { "address": "0xPlatformWalletAddress000000000000000000", "percent": 10, "label": "Platform Fee" },
8 { "address": "0xCreatorWalletAddress0000000000000000000", "percent": 90, "label": "Creator" }
9 ],
10 "createdAt": "2026-03-22T10:00:00.000Z"
11 },
12 {
13 "id": "spl_cm9x1a2b00001lb08m3pz5y0q",
14 "name": "Three-Way Split",
15 "recipients": [
16 { "address": "0xAddress1000000000000000000000000000000000", "percent": 33, "label": "Partner A" },
17 { "address": "0xAddress2000000000000000000000000000000000", "percent": 33, "label": "Partner B" },
18 { "address": "0xAddress3000000000000000000000000000000000", "percent": 34, "label": "Partner C" }
19 ],
20 "createdAt": "2026-03-20T08:30:00.000Z"
21 }
22 ],
23 "total": 2
24}

Update a Split

PUT /api/console/splits/:id

Updates an existing split. You can change the name, description, or recipients. If you update recipients, the new array replaces the old one entirely — you cannot patch individual recipients.

Changes apply to future payments only. Payments that have already been disbursed are not affected.

Authentication

HeaderRequiredDescription
AuthorizationYesBearer <privy_access_token> from an authenticated console session

Path Parameters

ParameterTypeDescription
idstringThe split ID (spl_…).

Request Body

FieldTypeDescription
namestringNew name for the split.
descriptionstringUpdated description.
recipientsSplitRecipient[]Full replacement recipient list. Percentages must still sum to 100.

cURL Example

bash
1curl -X PUT https://api.usecoal.xyz/api/console/splits/spl_cm9x4k2j00003lb08n5qz7v1r \
2 -H "Content-Type: application/json" \
3 -H "Authorization: Bearer <privy_access_token>" \
4 -d '{
5 "name": "Updated Fee Split",
6 "recipients": [
7 {
8 "address": "0xPlatformWalletAddress000000000000000000",
9 "percent": 15,
10 "label": "Platform Fee"
11 },
12 {
13 "address": "0xCreatorWalletAddress0000000000000000000",
14 "percent": 85,
15 "label": "Creator"
16 }
17 ]
18 }'

Response Example

json
1{
2 "id": "spl_cm9x4k2j00003lb08n5qz7v1r",
3 "name": "Updated Fee Split",
4 "recipients": [
5 { "address": "0xPlatformWalletAddress000000000000000000", "percent": 15, "label": "Platform Fee" },
6 { "address": "0xCreatorWalletAddress0000000000000000000", "percent": 85, "label": "Creator" }
7 ],
8 "updatedAt": "2026-03-22T12:00:00.000Z"
9}

Delete a Split

DELETE /api/console/splits/:id

Permanently deletes a split. Any payment links or products attached to this split will retain the split data on historical payments, but will no longer use split routing for new payments.

Authentication

HeaderRequiredDescription
AuthorizationYesBearer <privy_access_token> from an authenticated console session

Path Parameters

ParameterTypeDescription
idstringThe split ID (spl_…).

cURL Example

bash
1curl -X DELETE https://api.usecoal.xyz/api/console/splits/spl_cm9x4k2j00003lb08n5qz7v1r \
2 -H "Authorization: Bearer <privy_access_token>"

Response Example

json
1{
2 "deleted": true,
3 "id": "spl_cm9x4k2j00003lb08n5qz7v1r"
4}

Error Responses

StatusCodeDescription
400INVALID_SPLITRecipient percentages do not sum to 100.
401UNAUTHORIZEDMissing or invalid Bearer token.
403FORBIDDENThe split belongs to a different merchant.
404NOT_FOUNDNo split found with the given ID.

Node.js Example

typescript
1const COAL_API = 'https://api.usecoal.xyz';
2const consoleToken = '<privy_access_token>';
3
4interface SplitRecipient {
5 address: string;
6 percent: number;
7 label?: string;
8}
9
10async function createSplit(name: string, recipients: SplitRecipient[]) {
11 const total = recipients.reduce((sum, r) => sum + r.percent, 0);
12 if (total !== 100) {
13 throw new Error(`Recipient percentages must sum to 100 (got ${total})`);
14 }
15
16 const res = await fetch(`${COAL_API}/api/console/splits`, {
17 method: 'POST',
18 headers: {
19 'Content-Type': 'application/json',
20 Authorization: `Bearer ${consoleToken}`,
21 },
22 body: JSON.stringify({ name, recipients }),
23 });
24
25 if (!res.ok) {
26 const err = await res.json();
27 throw new Error(`Failed to create split: ${err.error}`);
28 }
29
30 return res.json();
31}
32
33// Example: 5% platform, 95% seller
34const split = await createSplit('Standard Marketplace Split', [
35 { address: '0xYourPlatformAddress', percent: 5, label: 'Platform' },
36 { address: '0xSellerAddress', percent: 95, label: 'Seller' },
37]);
38
39console.log('Split created:', split.id);

How Splits Are Applied

When a payment is confirmed for a checkout session that has an associated split:

  1. Coal calculates each recipient's share by multiplying the total payment amount by their percentage.
  2. The amounts are rounded down to the settlement token precision.
  3. Any rounding remainder is added to the last recipient in the array.
  4. Each transfer is dispatched as an on-chain settlement-token transfer on Base.
  5. The webhook payload includes a splits array showing each disbursement's txHash.
json
1{
2 "event": "checkout.session.completed",
3 "data": {
4 "id": "cm9x4k2j00003lb08n5qz7v1r",
5 "amount": 100,
6 "splits": [
7 {
8 "address": "0xPlatformWalletAddress000000000000000000",
9 "amount": 10,
10 "percent": 10,
11 "txHash": "0xabc111..."
12 },
13 {
14 "address": "0xCreatorWalletAddress0000000000000000000",
15 "amount": 90,
16 "percent": 90,
17 "txHash": "0xabc222..."
18 }
19 ]
20 }
21}