Get one payout
Fetch a single transaction by id, scoped to your client, with its full event
trail and a retryable hint. A transaction owned by another client is
reported as 404.
Required scope: payouts:read.
Authorization
bearerAuth x8xTimestamp x8xSignature Your client API key. Authorization: Bearer <API key>. The gateway stores
only sha256(key); keys are rotatable and revocable.
In: header
Unix time (seconds) at which the request was signed. Must be within 300s of gateway time.
In: header
Hex HMAC-SHA256(signingSecret, "{timestamp}.{rawBody}") over the exact raw
request body (empty string for GET). Defeats tampering and replay.
In: header
Path Parameters
The gateway transaction id.
uuidResponse Body
application/json
application/json
application/json
application/json
application/json
application/json
import { PayoutClient } from '@8x-payout/sdk';const client = new PayoutClient({ baseUrl: process.env.PAYOUT_BASE_URL!, apiKey: process.env.PAYOUT_API_KEY!, signingSecret: process.env.PAYOUT_SIGNING_SECRET!,});const txn = await client.getPayout(transactionId);console.log(txn.status, txn.settledAt, txn.events);{ "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "source": "string", "payeeId": "79417842-2e1e-4110-a361-89b9f39b36ed", "idempotencyKey": "string", "amountCents": 0, "currency": "string", "status": "requested", "provider": "stripe", "providerRef": "string", "reason": "string", "ref": "string", "failureKind": "transient", "createdAt": "2019-08-24T14:15:22Z", "updatedAt": "2019-08-24T14:15:22Z", "liftingFeeCents": 0, "claimUrl": "string", "retryable": true, "statusReason": "string", "events": [ { "from": "requested", "to": "requested", "reason": "string", "at": "2019-08-24T14:15:22Z" } ]}Create many payouts in one call POST
Pay many people in a single signed request — the **email + amount** contract. Each item identifies a payee by **`payeeId`** (one you own) **or** by **`email`** (the gateway resolves-or-creates a payee keyed by that email), plus an `amountCents`. As always the body carries **no destination** — each rail is resolved server-side from the payee's KYC-locked method. The response is **`207 Multi-Status`** with one entry per row, in request order: `status: ok` carries the created/replayed `transaction` (inspect its own `status` — an un-onboarded `email` row comes back `held`), `status: error` carries a stable `error` code from the closed per-row enum on `BatchPayoutResultItem.error`. A failing row **never** aborts the others. **Exactly-once.** Each row's idempotency key is its own `idempotencyKey` when set, else it is derived from the batch key and the row's **payee identity** (not its array position). So re-sending the same batch key with rows added, removed, or reordered replays the rows already paid and pays only the genuinely new ones — it never double-pays. Two rows targeting the **same** payee without explicit per-row keys are ambiguous and rejected (`400 duplicate_target`); give them distinct `idempotencyKey`s to pay the same payee twice in one batch. **Required scope:** `payouts:write`. Items that use `email` (which mint a payee identity) additionally require `payees:write`.
Retry a transiently-failed payout POST
Re-run a payout that `failed` with a **transient** cause (e.g. the company wallet was momentarily underfunded) — check the `retryable` hint on `GET /payouts/{id}` first. The retry re-sends under the SAME rail idempotency code, so the rail dedupes: exactly-once is preserved and a retry can never double-pay. A payout that is not `failed`, or whose failure was **permanent** (bad destination, not onboarded, unsupported currency), returns `409`. See the Error & held-reason catalog for the concrete action per `statusReason`. **Required scope:** `payouts:write`.