Changelog

Versioned changes to the 8x Payout Gateway public API.

The public API (/api/v1) is versioned. Within a version, changes are additive only (new optional fields, new endpoints); anything breaking gets a new version path.

v1.2.0 2026-09-24

Additive: a version 2 payout status vocabulary. No breaking changes. New clients default to version 2; existing clients stay on status version 1 (every v1 request and response is unchanged) and migrate to v2 per-source when their consumer is ready.

  • A payout's status now follows your client's status version, on the payout.status webhook and on every REST payout response (POST and GET /api/v1/payouts, GET /api/v1/payouts/{id}, POST /api/v1/payouts/{id}/release, POST /api/v1/payouts/{id}/retry, POST /api/v1/payouts/batch). The webhook and REST always use the same version.
  • Version 1 (legacy — existing clients): requested, authorized, submitted, paid, failed, returned, held.
  • Version 2 is the default for new clients (existing clients opt in via 8x ops): owed, sent, awaiting_withdraw, paid, failed, returned, held. The map from version 1 is in Status versions.
  • New PayoutStatusV2 schema in the OpenAPI spec. The status properties on Transaction, TransactionEvent and PayoutStatusEvent accept either vocabulary. The status filter on GET /api/v1/payouts still takes version 1 words only.

v1.1.0 2026-06-28

Additive: bulk payouts (the "email + amount" contract) and the owed/withdraw endpoints. No breaking changes — every v1.0.0 request and response is unchanged. Endpoints:

  • POST /api/v1/payouts/batch — create up to 100 payouts in one signed call. Each item names a payee by payeeId (one you own) or by email (the gateway resolves-or-creates the payee). Returns 207 Multi-Status with one result per row; a failing row never aborts the others. Each row is idempotent on its own idempotencyKey, or the batch key + the row's payee identity when omitted — so re-sending a batch with rows added/removed/reordered under the same key never double-pays. Requires payouts:write (and payees:write for any email item).
  • POST /api/v1/payouts/{id}/retry — re-drive a failed+transient payout under the same key.
  • POST /api/v1/payouts/{id}/release — re-run routing/caps on a held payout after you clear its blocker.
  • POST /api/v1/disbursements — push owed/IOU rows (the pull/wallet model), idempotent per (source, externalRef); returns 207 Multi-Status.
  • POST /api/v1/payees/{id}/methods — adopt an already-KYC'd Stripe or Tipalti account as the payee's payout method (verified live).
  • POST /api/v1/payees/{id}/portal-link — email the payee a signed, single-use hosted-wallet sign-in link.
  • POST /api/v1/payees/{id}/withdraw — consolidate a payee's owed rows into a single payout.
  • GET /api/v1/payees/{id}/balance — the payee's owed balance.

v1.0.0 2026-06-24

Initial public contract. Endpoints:

  • POST /api/v1/payees — create / idempotently re-fetch a payee.
  • GET /api/v1/payees — list payees (filter by kyc, payable; cursor-paginated).
  • GET /api/v1/payees/{id} — fetch one payee.
  • POST /api/v1/payees/{id}/onboarding-link — gateway-hosted, rail-agnostic onboarding link.
  • GET /api/v1/payees/{id}/readiness — payout readiness + blockers.
  • POST /api/v1/payouts — create a payout, idempotent on (client, idempotencyKey).
  • GET /api/v1/payouts — list payouts (filter by status; cursor-paginated).
  • GET /api/v1/payouts/{id} — fetch one transaction with its event trail and retryable hint.

Webhooks (signed, gateway → customer):

  • payee.updated — onboarding/payability changed.
  • payout.status — payout state changed.

Auth: bearer API key + HMAC request signing (x-8x-timestamp / x-8x-signature, 5-minute window, replay-protected mutations) + per-route scopes. Test mode routes everything through the mock provider.

On this page