Skip to main content
These examples perform one NGN withdrawal from beginning to end:
  1. Quote the withdrawal using a signed request.
  2. Confirm that the quote contains an available route.
  3. Add one stable business idempotency key and submit the same intent.
  4. Persist the returned transaction ID and complete the workflow from its terminal webhook.
Create a staging key with wallets:withdraw in the Stabyl staging app. Store both values shown at creation: the API key authenticates the account and the signing secret signs withdrawal requests.
These examples submit a withdrawal in the configured environment. Start with staging and replace the sample amount and destination with valid staging test values. Run them only from a trusted server-side environment; never expose the API key or signing secret in browser, mobile, desktop, or user-controlled code.

Node.js

This example requires Node.js 20 or later and uses only built-in APIs.

Python

This example requires Python 3.10 or later. Install its two dependencies:

Complete the workflow with webhooks

Subscribe the receiving endpoint to withdrawal.success, withdrawal.partial, and withdrawal.failed. After submitting a withdrawal:
  1. Persist the response data.id with its pending status and business idempotency key.
  2. Verify and deduplicate every webhook before applying it.
  3. Match data.transaction.id in the webhook to the persisted withdrawal.
  4. Mark it successful or failed from the webhook event type and transaction snapshot.
See Withdrawal webhook events for the exact payloads and Webhook overview for signature verification, deduplication, and retry behavior. REST remains the recovery path. If delivery is delayed or your webhook endpoint was unavailable, read GET /partner/wallets/transactions/{id} to reconcile the stored transaction. This is an on-demand repair and periodic backstop, not a requirement to poll every submitted withdrawal.

Retrying an uncertain submission

If the submit request times out or the connection drops before a response:
  1. Reuse the exact same submit payload and idempotency_key.
  2. Generate a new timestamp and UUID nonce.
  3. Sign the new canonical payload.
  4. Submit again, then reconcile the returned transaction ID.
Both signedPost and signed_post generate new transport credentials on each call. Do not regenerate the business idempotency_key, change the item order, or modify any submitted field during that retry. The helpers throw on every non-2xx response. In production, treat 429 and 503 SIGNING_VERIFICATION_UNAVAILABLE as retryable with bounded backoff and a new nonce, and everything else as a hard failure. Both helpers sign pathname + search from the full URL, which is why the base URL must include /v1: the server verifies the signature over the complete request path. Production keys use the sb_live prefix with the same sig1_ seed layout as the staging key shown above. The same signing helpers work with the USD payload documented in Withdrawals, and with a multi-beneficiary items list as shown in Bulk withdrawals. Only the body changes; the signing, submit, and webhook steps stay the same.