Check payout readiness

GET
/api/v1/payees/{id}/readiness

The pull backstop: can we pay this person right now, via which rail, and if not, what's blocking? Always correct even if a payee.updated webhook was missed. blockers is a list of machine-readable reasons (e.g. kyc_incomplete, not_payable).

Required scope: payees:read.

Authorization

bearerAuth x8xTimestamp x8xSignature
AuthorizationBearer <token>

Your client API key. Authorization: Bearer <API key>. The gateway stores only sha256(key); keys are rotatable and revocable.

In: header

x-8x-timestamp<token>

Unix time (seconds) at which the request was signed. Must be within 300s of gateway time.

In: header

x-8x-signature<token>

Hex HMAC-SHA256(signingSecret, "{timestamp}.{rawBody}") over the exact raw request body (empty string for GET). Defeats tampering and replay.

In: header

Path Parameters

id*string

The gateway payee id.

Formatuuid

Response 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 ready = await client.getReadiness(payeeId);if (!ready.payable) console.log(ready.blockers);
{  "payable": true,  "provider": "stripe",  "onboardingStatus": "none",  "blockers": [    "string"  ],  "payability": {    "state": "ready",    "label": "string",    "description": "string",    "action": "string",    "provider": "stripe",    "onboardingStatus": "none",    "payable": true,    "blockers": [      {        "code": "string",        "label": "string",        "description": "string",        "action": "string",        "severity": "info"      }    ]  },  "routing": {    "source": "test_mode",    "country": "string",    "heldReason": "string",    "blockers": [      "string"    ],    "preferredProvider": "stripe"  },  "sideshiftResumable": true,  "sideshiftWithdrawalStatus": "pending",  "sideshiftWithdrawableCents": 0}

Create a hosted onboarding link POST

Get a **gateway-hosted, rail-agnostic** onboarding URL for a payee — like a Stripe account link. Redirect your (already-authenticated) creator to the returned `url`, or embed it as an iframe; they need **no separate gateway login**. The URL points at the gateway's own `/onboard` page carrying a short-lived signed token — never at Tipalti/Stripe directly — and the gateway renders the right rail behind it. `returnUrl` is where the creator is sent when they finish. It **must** be an absolute `https` URL whose host is either your **registered webhook domain** (the host of your configured webhook URL) or the gateway's own origin; anything else is rejected at request time with `400 invalid_return_url` (open-redirect protection). Localhost over `http` is allowed in non-production environments only. When the payee becomes payable, the gateway fires a [`payee.updated`](#tag/webhooks) webhook. The onboarding experience depends on the payee's resolved rail. Custodial rails (Stripe, Tipalti) run hosted KYC and payout-method setup up front — the payee becomes payable only after they finish, at which point `payee.updated` fires. Custody-free rails (Grade, SideShift) are payable-by-design at account creation; KYC and method selection happen inline at claim/withdraw time via the claim link the payout produces, so there is no method to pre-set here. **Required scope:** `onboarding:write`.

Get the payee's wallet balance GET

The payee's wallet balance — the SAME numbers the hosted payouts portal shows — so a consuming platform's own wallet (e.g. 8x-core) stays in sync with the portal by construction rather than re-deriving from its own ledger. Like `/readiness`, this is a **pull backstop**: always correct even if a balance webhook was missed. The cent amounts describe where the payee's money is in the payout lifecycle: - `withdrawableCents` — still-**owed** disbursements, not yet released into a payout. This is what the payee could withdraw right now. - `onTheWayCents` — genuinely **in transit** (submitted to a rail, awaiting settlement) — not money that still needs the payee to act. - `actionNeededCents` — money the **creator must still claim/withdraw** before it can move (e.g. a Grade payout that's been triggered but is unclaimed, or a SideShift leg-1 awaiting the payee) — NOT yet on the way. - `landedCents` — **lifetime settled** (paid). A cumulative total, not a current balance. - `heldBelowMinimumCents` — money **held only because it's under the rail's economical floor** (a `below_min_payout` hold that self-releases once the balance clears the floor). 0 when nothing is floor-held. - `minPayoutCents` — the **floor** that held money must clear to release: the floor of the rail it's held on, or (when nothing is held) the payee's currently-resolved active rail. 0 if the rail can't be resolved. - `provider` — the payee's **single resolved payout rail** (null if none). Lets a consumer tell whether `actionNeededCents` is SideShift leg-1 money already staged in the wallet (withdrawable now via leg 2) or a Grade claim / Stripe auto-send. `currency` is the ISO 4217 code for these amounts. **Required scope:** `payees:read`.