Skip to main content
A complete walk-through of the pool settlement integration: you fund a central pool, StablePay allocates INR to your escrow balance, and you disburse INR to your users. The request/response shapes are identical in sandbox and production — only the base URL and API key prefix change.
This recipe covers the pool_settlement flow. The escrow balance and payout steps require pool_settlement enabled on your account. The KYC steps apply to any flow.
Every request carries your key: Authorization: Bearer <API_KEY>

Onboard & verify KYC

1

Create the user

No OTP / mobile verification is required to proceed with KYC.
Request
Response · 201
Keep the userId — every KYC and payout call is scoped to it.
2

Verify PAN

The mandatory identity anchor. Real government-DB check in production; auto-verified on any valid-format PAN in sandbox.
Request
Response
3

Submit KYC (foreign ID)

Share the identity document you collected — e.g. a foreign driving-license number for an NRI with no Aadhaar/passport. This satisfies the identity requirement and the declaration in one call.
Request
Response
A 403 "Partner-attested KYC is not enabled" means the endpoint is live but not enabled for your account — contact StablePay. Indian users can skip this step and verify with Aadhaar (DigiLocker) or passport instead.
4

Verify bank account

The payout destination — always required. Penny-drop in production; auto-verified in sandbox.
Request
Response
KYC is now verified. Status flips to verified once all three identity legs are complete — order doesn’t matter, each call recomputes the status:verified = PAN + identity (foreign DL via /kyc/submit, or Aadhaar / passport) + bankThe user reaches verified only after all three — not just after /kyc/submit.

Check KYC status (poll until verified)

Poll to confirm the user reached verified. The attestation block reflects the foreign-ID submission.
Response
A method that isn’t complete returns { "verified": false }. Treat an absent verified key as false.

Disburse INR (pool settlement)

The steps below require pool_settlement enabled on your account. Your INR escrow is funded when StablePay allocates INR against your settled USDT.
1

Check escrow balance

Your available INR to disburse — the same balance shown in the Client Portal.
Response
inr is what you can pay out. A larger payout fails with INSUFFICIENT_BALANCE.
2

Trigger the payout

A single call — debits your escrow and pays the user’s verified bank over IMPS. The Idempotency-Key header is required, and the user must be KYC-verified with a verified bank.
Request
Response
A 200 means the bank rail accepted the transfer, not that it settled. Confirm the final outcome via the status endpoint or webhook below. When TDS is off, settlementInr equals amountInr.
3

Check the payout status

Poll the transaction for its final state and UTR. The path accepts either the StablePay transactionId or your own partnerReference — so if a create call timed out and you never received the transactionId, look it up by the reference you sent.
Response
transaction.status is payout_processing until settled, then completed (or failed). payout.status carries the rail result — SUCCESS (with a UTR), DEEMED (bank-accepted, no UTR yet), or FAILED (escrow debit reversed).
Instead of polling, register a webhook URL to receive the payout outcome in real time. See the Webhooks guide for setup and signature verification. You’ll receive, in order:
transaction.payout_completed

Sandbox vs Production

Sandbox test cues

  • Drive payout outcomes by the cents of amountInr: normal cents settle; ending in .11 forces a failure; .22 forces a DEEMED (bank-accepted, no UTR).
  • OTP, where used elsewhere, is always 123456 in sandbox. It is not required for this flow.
  • To test a payout, your sandbox escrow must hold INR — ask StablePay to seed it (there is no self-serve funding endpoint).
  • TDS (§194S) is a per-account setting. When on, it’s withheld from the gross; the user receives settlementInr and your escrow is debited the full amountInr.