Payouts
Payouts move available balance to a financial account. You choose a destination, maximum amount, and earliest execution time; the payout response exposes its current status, public error details, linked balance transactions, and lifecycle timestamps.
Schedule, cancel, set destinations, enable automatic payouts, disable automatic payouts, enable FX, and disable FX support idempotency. A successful response can be replayed with the same idempotency key and request body for 24 hours. Lookup, settings, and page do not opt in to idempotent replay.
The Payout object
Optional payout fields are omitted until they have values. The public object does not include execution-attempt records or attempt counters.
Properties
Schedule a payout
Create and schedule a payout to move funds from your available balance to a financial account. The destination must exist and cannot already have an open payout. The requested maximum cannot exceed your configured ceiling.
You'll typically call this endpoint when hitting a payout threshold (weekly settlements, minimum balance triggers), fulfilling vendor payments, or implementing scheduled disbursement runs. The payout executes at or after execute_after—set it to "now" for immediate transfers or schedule future disbursements for specific times.
The response includes the payout ID and initial status. Use the ID with the lookup endpoint to monitor status, public error details, and the final transferred amount.
This operation supports idempotency. A successful response can be replayed with the same idempotency key and request body for 24 hours.
Request attributes
- Name
execute_after- Type
- timestamp
- Description
Optional. Earliest time we'll start processing this payout—ISO 8601 format in UTC. Defaults to "now" if omitted, meaning the payout executes immediately. Set this to schedule future disbursements:
"2025-04-15T09:00:00Z"for a specific time, or calculate relative times in your application for recurring schedules.
Request
curl https://api.zebo.dev/payouts/schedule \
-H "Authorization: Bearer $COMMERCE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"destination_id": "fa_Q90wZdd2P7W8hJ1cN9Mx4Rk5sVWBvY3L6pTz8q0",
"reference": "PAYOUT-APR-15",
"max_amount": 250000,
"execute_after": "2025-04-15T09:00:00Z"
}'
{
"payout": {
"id": "po_yQ2wXm5Dc7Pk9Ls1Vn0RgHaB",
"destination_id": "fa_Q90wZdd2P7W8hJ1cN9Mx4Rk5sVWBvY3L6pTz8q0",
"reference": "PAYOUT-APR-15",
"status": "scheduled",
"max_amount": { "currency": "ghs", "value": 250000 },
"execute_after": "2025-04-15T09:00:00Z",
"scheduled_at": "2025-04-14T18:32:11.000Z",
"initiated_at": "2025-04-14T18:32:10.000Z"
}
}
Lookup a payout
Fetch the current state of a payout to monitor execution progress and retrieve the final transferred amount. You'll typically use this after scheduling a payout to poll for completion or during reconciliation.
Optional lifecycle timestamps, error, and balance_transactions are omitted until they have values.
Request attributes
Request
curl https://api.zebo.dev/payouts/lookup \
-H "Authorization: Bearer $COMMERCE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"payout_id": "po_yQ2wXm5Dc7Pk9Ls1Vn0RgHaB"
}'
{
"payout": {
"id": "po_yQ2wXm5Dc7Pk9Ls1Vn0RgHaB",
"status": "executing",
"destination_id": "fa_Q90wZdd2P7W8hJ1cN9Mx4Rk5sVWBvY3L6pTz8q0",
"amount": { "currency": "ghs", "value": 240000 },
"initiated_at": "2025-04-14T18:32:10.000Z",
"sent_at": "2025-04-15T09:01:05.000Z",
"balance_transactions": [
"bt_Za2bL9kPxV1c4Gs7Ju0DrQhn",
"bt_Ps8wC1nDf5m9Qh2Vt6YkRgLb"
]
}
}
Cancel a payout
Cancel a scheduled payout before it executes. This is the escape hatch for payouts scheduled in error, amounts that need adjustment, or disbursements that must be blocked due to compliance holds. Once canceled, the payout is permanently stopped—balance transactions that would have been bundled into it remain in your available balance for future payouts.
Cancellation is only possible when the payout is in scheduled status and its execute_after time is still in the future. A payout that has already started executing—or whose execution window has passed—cannot be canceled. If you need to reverse a completed payout, use a refund or manual balance adjustment instead.
The response returns the updated payout object with status: "canceled" and canceled_at set to the cancellation timestamp.
Request attributes
Request
curl https://api.zebo.dev/payouts/cancel \
-H "Authorization: Bearer $COMMERCE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"payout_id": "po_yQ2wXm5Dc7Pk9Ls1Vn0RgHaB"
}'
{
"payout": {
"id": "po_yQ2wXm5Dc7Pk9Ls1Vn0RgHaB",
"destination_id": "fa_Q90wZdd2P7W8hJ1cN9Mx4Rk5sVWBvY3L6pTz8q0",
"status": "canceled",
"initiated_by": "manual",
"initiated_at": "2025-04-14T18:32:10.000Z",
"execute_after": "2025-04-15T09:00:00Z",
"scheduled_at": "2025-04-14T18:32:11.000Z",
"canceled_at": "2025-04-14T20:15:44.000Z",
"max_amount": { "currency": "ghs", "value": 250000 },
"amount": null
}
}
Get payout settings
Check your current payout configuration to understand when automatic settlements run and where funds land for each currency. This endpoint returns your payout schedule (how often settlements happen, which day of the week, aging specifications) and your destinations map (which financial account receives funds for each supported currency).
Use this when building dashboards that show payout timing, when onboarding new team members who need to understand your settlement flow, or before scheduling manual payouts to confirm destination accounts are configured correctly. No request body needed—just authenticate and call.
The response includes complete schedule details (interval, timing, aging specifications, settlement rules) and a destinations object mapping currency codes to financial account IDs. If you haven't configured a destination for a currency yet, it won't appear in the map—you'll need to set one with /payouts/set_destinations before automatic payouts can run for that currency.
For a deep dive into what each field means and how to use them, see the Understand payout settings guide.
Request
curl https://api.zebo.dev/payouts/settings \
-H "Authorization: Bearer $COMMERCE_API_KEY"
{
"settings": {
"fx_enabled": false,
"schedule": {
"name": "weekly",
"type": "automatic",
"interval": "weekly",
"schedule_on": "sunday",
"aging_spec": {
"t_plus": "168h",
"label": "168_hours",
"abide": "strictly"
},
"description": "Automatic weekly payout. Default."
},
"destinations": {
"ghs": "fa_Q90wZdd2P7W8hJ1cN9Mx4Rk5sVWBvY3L6pTz8q0"
}
}
}
Set payout destinations
Configure where automatic payouts land for each currency. Map GHS to your mobile money wallet, USD to your bank account, and so on—each currency routes to its own destination.
Call this when setting up payouts for the first time, switching settlement accounts, or adding new currencies. To remove a currency's destination, send an empty string. Currencies you omit keep their existing values.
Rules
- Each currency key must be supported (currently
ghs—see studio.zebo.dev/specs/currencies for the complete list). - Each financial account must exist in your Commerce account and belong to you.
- Each financial account must not be disconnected—only active accounts can receive payouts.
- Each financial account's currency must match its map key. You can't send GHS payouts to a USD account.
- Each financial account must have push operations enabled—accounts without push configuration can't receive payouts.
Request attributes
Request
curl https://api.zebo.dev/payouts/set_destinations \
-H "Authorization: Bearer $COMMERCE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"destinations": {
"ghs": "fa_H3cNv7pQf9WbLt2mJs6yXrPq4Kz1Vd5G0aEiUo"
}
}'
{
"settings": {
"fx_enabled": false,
"schedule": {
"name": "weekly",
"type": "automatic",
"interval": "weekly",
"schedule_on": "sunday",
"aging_spec": {
"t_plus": "168h",
"label": "168_hours",
"abide": "strictly"
},
"description": "Automatic weekly payout. Default."
},
"destinations": {
"ghs": "fa_H3cNv7pQf9WbLt2mJs6yXrPq4Kz1Vd5G0aEiUo"
}
}
}
Disable automatic payouts
Switch your payout schedule from automatic to manual mode. This stops scheduled automatic settlements—Commerce won't create new payouts until you manually call /payouts/schedule or re-enable automatic payouts.
Use this when you need temporary control over payout timing: during financial audits, when coordinating with accounting periods, or when testing new settlement flows. Your existing scheduled payouts continue executing normally—this only prevents new automatic payouts from being created.
The response includes your updated settings with the schedule switched to manual mode. Your destination mappings remain unchanged—when you re-enable automatic payouts, funds will continue routing to the same financial accounts.
Request
curl https://api.zebo.dev/payouts/disable \
-H "Authorization: Bearer $COMMERCE_API_KEY"
{
"settings": {
"schedule": {
"name": "manual",
"type": "manual",
"description": "Manual payout",
"interval": "never",
"schedule_on": "never"
},
"destinations": {
"ghs": "fa_Q90wZdd2P7W8hJ1cN9Mx4Rk5sVWBvY3L6pTz8q0"
}
}
}
Enable automatic payouts
Switch your payout schedule from manual to automatic mode. This resumes scheduled automatic settlements on the default weekly cadence—Commerce will create payouts automatically every Sunday for funds that have aged at least 7 days.
Use this when you're ready to resume predictable settlement flows after a period of manual control. Your payout destinations remain unchanged—GHS payouts route to your configured GHS account, USD to your USD account, and so on.
The response includes your updated settings with the schedule switched back to the default weekly automatic mode. Any manual payouts you've already scheduled complete normally—enabling automatic mode doesn't affect existing in-flight transfers.
Request
curl https://api.zebo.dev/payouts/enable \
-H "Authorization: Bearer $COMMERCE_API_KEY"
{
"settings": {
"fx_enabled": false,
"schedule": {
"name": "weekly",
"type": "automatic",
"interval": "weekly",
"schedule_on": "sunday",
"aging_spec": {
"t_plus": "168h",
"label": "168_hours",
"abide": "strictly"
},
"description": "Automatic weekly payout. Default."
},
"destinations": {
"ghs": "fa_Q90wZdd2P7W8hJ1cN9Mx4Rk5sVWBvY3L6pTz8q0"
}
}
}
Enable FX conversion
Enable automatic foreign-exchange conversion for payouts. When FX is enabled, Commerce converts payout amounts from your balance currency into the destination financial account's local currency at the prevailing exchange rate before transfer.
This endpoint takes no request body—it toggles fx_enabled to true on your payout settings and saves immediately. The updated settings object is returned so you can confirm the change and inspect your current schedule and destination configuration.
Use this when you collect revenue in one currency (e.g. USD) but your financial account operates in a local currency (e.g. UGX or GHS). Commerce handles the conversion and records the applied rate in each payout's balance transactions for reconciliation.
Request
curl https://api.zebo.dev/payouts/enable_fx \
-H "Authorization: Bearer $COMMERCE_API_KEY"
{
"settings": {
"fx_enabled": true,
"schedule": {
"name": "weekly",
"type": "automatic",
"description": "Weekly automatic payout",
"interval": "weekly",
"schedule_on": "sunday"
},
"destinations": {
"ghs": "fa_Q90wZdd2P7W8hJ1cN9Mx4Rk5sVWBvY3L6pTz8q0"
}
}
}
Disable FX conversion
Disable automatic foreign-exchange conversion for payouts. When FX is disabled, Commerce disburses payout amounts in your balance currency without conversion—the destination account must accept that currency directly.
This endpoint takes no request body—it toggles fx_enabled to false on your payout settings and saves immediately. The updated settings object is returned so you can confirm the change.
Disable FX when your balance currency matches your destination currency, when you want to handle conversion externally through your financial institution, or when you need precise control over exchange rates and timing for compliance or financial reporting purposes.
Request
curl https://api.zebo.dev/payouts/disable_fx \
-H "Authorization: Bearer $COMMERCE_API_KEY"
{
"settings": {
"fx_enabled": false,
"schedule": {
"name": "weekly",
"type": "automatic",
"description": "Weekly automatic payout",
"interval": "weekly",
"schedule_on": "sunday"
},
"destinations": {
"ghs": "fa_Q90wZdd2P7W8hJ1cN9Mx4Rk5sVWBvY3L6pTz8q0"
}
}
}
Page through payouts
Retrieve a paginated list of the most recent payouts for the authenticated application. Payouts are sorted by initiated_at in descending order, so page 1 always contains the freshest activity and subsequent pages step back in time.
Request attributes
Response shape
- Top level
pageobject includesnumber,size, and apayoutsarray. - Every entry uses the same payout shape documented above.
- Optional fields such as
amount,error, lifecycle timestamps, andbalance_transactionsare omitted until available.
Request
curl https://api.zebo.dev/payouts/page \
-H "Authorization: Bearer $COMMERCE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"page_number": 1,
"page_size": 25
}'
{
"page": {
"number": 1,
"size": 2,
"payouts": [
{
"id": "po_abc123def456",
"destination_id": "fa_dest001",
"amount": {
"value": 50000,
"currency": "ghs"
},
"status": "succeeded",
"initiated_by": "automatic",
"initiated_at": "2025-12-15T10:30:00Z",
"sent_at": "2025-12-15T10:35:00Z",
"succeeded_at": "2025-12-15T10:35:30Z",
"balance_transactions": [
"btx_001",
"btx_002",
"btx_003"
]
},
{
"id": "po_def456ghi789",
"destination_id": "fa_dest002",
"amount": {
"value": 75000,
"currency": "ghs"
},
"status": "invalid",
"initiated_by": "manual",
"error": {
"type": "destination_error",
"message": "Insufficient funds in destination account",
"cause": "Account balance too low",
"occurred_at": "2025-12-14T15:20:00Z"
},
"initiated_at": "2025-12-14T15:00:00Z",
"failed_at": "2025-12-14T15:20:00Z",
"expected_at": "2025-12-14T15:00:00Z",
"balance_transactions": [
"btx_004",
"btx_005"
]
}
]
}
}