Skip to main content
Pilot keys are live — step 4 moves real money. Walk this guide with Jenzy on your onboarding call, with a small amount, to a destination you control.
1

Check your key works

You received a jz_live_… API key from Jenzy at onboarding. It goes in the Authorization header of every request. GET /ping exercises the whole auth chain and echoes who you are:
curl https://api.jenzy.com/v1/ping \
  -H "Authorization: Bearer $JENZY_API_KEY"
{
  "org": "Acme Remittances Ltd",
  "mode": "live",
  "key_prefix": "jz_live_AbC123Xy"
}
2

Check your balance

Payouts draw down your prefunded balance. available is what you can spend now; held is reserved by payouts still in flight.
curl https://api.jenzy.com/v1/balance \
  -H "Authorization: Bearer $JENZY_API_KEY"
{ "available": 1250000, "held": 50000, "currency": "MWK" }
Amounts are integer kwacha. If available is short, book a trade with Jenzy — funding lands as a trade.settled webhook and a credit here.
3

Look up the destination

Destinations are validated when you create the payout — there is no separate validation call. What you need first is the identifier for where the money goes: an operator_ref_id for mobile money, or a bank_uuid for banks.
curl https://api.jenzy.com/v1/operators \
  -H "Authorization: Bearer $JENZY_API_KEY"
{
  "operators": [
    { "ref_id": "20be6c20-adeb-4b5b-a7ba-0769820df4fb", "name": "Airtel Money" },
    { "ref_id": "27494cb5-ba9e-437f-a114-4e7a7686bcca", "name": "TNM Mpamba" }
  ],
  "fetched_at": "2026-07-08T06:00:11.000Z"
}
Banks work the same way via GET /banks. Cache these lists — they change rarely — and re-fetch if a create comes back unknown_bank / unknown_operator.
4

Create the payout

The endpoint is the rail: /payouts/momo for mobile money, /payouts/bank for banks — no rail field in the body. Every create requires an Idempotency-Key header you mint per payout intent (a UUID is perfect): retries with the same key and body return the original response byte-for-byte, so a network timeout can never double-pay.
curl -X POST https://api.jenzy.com/v1/payouts/momo \
  -H "Authorization: Bearer $JENZY_API_KEY" \
  -H "Idempotency-Key: 9f1c7a58-6f2d-4b0e-9d2e-3f8a1c5b7e42" \
  -H "Content-Type: application/json" \
  -d '{
    "amount_mwk": 5000,
    "operator_ref_id": "20be6c20-adeb-4b5b-a7ba-0769820df4fb",
    "mobile_number": "+265991234567"
  }'
A 202 means accepted: the amount is now held and the payout is queued.
{
  "id": "0d5e63b2-59f3-4d2a-8f57-2f14a3c14f6d",
  "amount_mwk": 5000,
  "rail": "momo",
  "status": "held",
  "destination": {
    "operator_ref_id": "20be6c20-adeb-4b5b-a7ba-0769820df4fb",
    "mobile_number": "+265991234567"
  },
  "failure": null,
  "created_at": "2026-07-08T09:14:02.000Z",
  "terminal_at": null
}
A 4xx here means no payout was created and nothing was held — see Errors for every code. For a bank payout the body is { amount_mwk, bank_uuid, account_number, account_name } — all four required.
5

Learn the outcome

A payout is terminal when status is succeeded or failed — nothing else is final. Two ways to find out:Webhooks (recommended) — register an endpoint in your Jenzy portal and you’ll receive payout.succeeded / payout.failed events within seconds of the outcome. See Webhooks.Polling — re-read the payout until it goes terminal:
curl https://api.jenzy.com/v1/payouts/0d5e63b2-59f3-4d2a-8f57-2f14a3c14f6d \
  -H "Authorization: Bearer $JENZY_API_KEY"
On failure the hold is released back to available automatically, and failure.code tells you whether a new payout is worth submitting. A failed payout is never retried by Hermes — resubmission is always a new payout with a new Idempotency-Key.