> ## Documentation Index
> Fetch the complete documentation index at: https://docs.jenzy.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart

> From API key to a confirmed payout, in five calls.

<Warning>
  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.
</Warning>

<Steps>
  <Step title="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:

    ```bash theme={null}
    curl https://api.jenzy.com/v1/ping \
      -H "Authorization: Bearer $JENZY_API_KEY"
    ```

    ```json theme={null}
    {
      "org": "Acme Remittances Ltd",
      "mode": "live",
      "key_prefix": "jz_live_AbC123Xy"
    }
    ```
  </Step>

  <Step title="Check your balance">
    Payouts draw down your prefunded balance. `available` is what you can
    spend now; `held` is reserved by payouts still in flight.

    ```bash theme={null}
    curl https://api.jenzy.com/v1/balance \
      -H "Authorization: Bearer $JENZY_API_KEY"
    ```

    ```json theme={null}
    { "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.
  </Step>

  <Step title="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.

    ```bash theme={null}
    curl https://api.jenzy.com/v1/operators \
      -H "Authorization: Bearer $JENZY_API_KEY"
    ```

    ```json theme={null}
    {
      "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`.
  </Step>

  <Step title="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.

    ```bash theme={null}
    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.

    ```json theme={null}
    {
      "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](/errors) for every code. For a bank payout the body is
    `{ amount_mwk, bank_uuid, account_number, account_name }` — all four
    required.
  </Step>

  <Step title="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](/webhooks).

    **Polling** — re-read the payout until it goes terminal:

    ```bash theme={null}
    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](/errors#failure-codes). A failed payout is never retried by
    Hermes — resubmission is always a new payout with a new
    `Idempotency-Key`.
  </Step>
</Steps>
