Skip to main content
This walkthrough takes you end to end in the sandbox: authenticate, pin your version, create a user and a virtual account, simulate a deposit, and make a payout. Every example uses the sandbox base URL https://api.balampay.com/sandbox.
Sandbox seed IDs are tenant-scoped placeholders. The sandbox does not ship working shared seed IDs — values like verified_user_id, virtual_account_id, and recipient_id are placeholders, not live resources. Sandbox tenancy isolates these resources per client, so any baked-in UUID would return 404 for an integrator using their own api_key.To run this flow end to end today, ask your Kira contact to provision a verified user (plus its virtual account and a recipient) in your sandbox tenant, then use those IDs in steps 6 and 7. Cross-tenant shared seeds are coming, but are not available yet.
1

Get your credentials

Kira provides three credentials for your tenant:
  • api_key — sent as the x-api-key header on every request, including /auth.
  • client_id and password — exchanged at POST /auth for a short-lived access token.
Keep them out of source control. The examples below read them from environment variables:
export KIRA_API_KEY="<your api_key>"
export KIRA_CLIENT_ID="<your client_id>"
export KIRA_PASSWORD="<your password>"
2

Authenticate

Call POST /auth with your client_id and password in the body and your x-api-key header. The /auth endpoint itself needs only x-api-key — no bearer token yet.
curl https://api.balampay.com/sandbox/auth \
  -H "x-api-key: $KIRA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "client_id": "'"$KIRA_CLIENT_ID"'", "password": "'"$KIRA_PASSWORD"'" }'
The response wraps the token in the success envelope:
{
  "message": "...",
  "data": {
    "access_token": "...",
    "expires_in": 3600,
    "token_type": "Bearer"
  }
}
Use the returned access_token as your bearer token on every other request. It is valid for 3600 seconds, so refresh it before it expires.
export ACCESS_TOKEN="<data.access_token from the response>"
See Authentication for the full token lifecycle.
3

Pin your version

Pin your account to version 2026-04-14 with POST /v1/versioning/upgrade. This call is idempotent — run it once.
curl https://api.balampay.com/sandbox/v1/versioning/upgrade \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "x-api-key: $KIRA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "target_version": "2026-04-14" }'
Until you pin, send X-Api-Version: 2026-04-14 on each request. Once pinned, your account default is the pinned version and the header becomes optional. See Versioning for details.
4

Create a user

Create a user with POST /v1/users. A user is either an individual or a business. source_of_funds is required — omitting it most commonly triggers an automatic KYC rejection.
curl https://api.balampay.com/sandbox/v1/users \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "x-api-key: $KIRA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{ "type": "individual", "source_of_funds": "salary", "...": "..." }'
The sandbox does not auto-verify, but it can auto-reject. Verification runs automatically on create and can flip a user to terminal REJECTED within seconds if required KYC data is missing. Submit a complete user (scalar values may be fake; images must look real), then ask your Kira contact to flip it to VERIFIED. Gate your state machine on status, not verification_status.
5

Create a virtual account

Create a virtual account for the user with POST /v1/virtual-accounts.
curl https://api.balampay.com/sandbox/v1/virtual-accounts \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "x-api-key: $KIRA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{ "user_id": "<verified user id>", "...": "..." }'
There is one ACT virtual account per user. Re-creating returns 409 Conflict — reuse the existing VA via the list or get endpoints. A VA being approved does not mean funds are ready: confirm readiness via account_number being a real value (non-null and not "PENDING-ACT-ACCOUNT").
6

Simulate a deposit (sandbox)

Fund the virtual account by simulating a deposit with POST /v1/virtual-accounts/{id}/simulate-deposit, where {id} is the VA id from the previous step.
curl https://api.balampay.com/sandbox/v1/virtual-accounts/$VA_ID/simulate-deposit \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "x-api-key: $KIRA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "amount": "100.00", "...": "..." }'
simulate-deposit returns 201 with status: "completed" immediately. The simulated deposit does not appear in GET /v1/virtual-accounts/{id}/deposits and does not change the balance — the sandbox balance is a fixed provider value. Confirmation is the 201 response itself plus the virtual_account.deposit_funds_received webhook. settlement_triggered: false on a fiat deposit is normal, not an error.
7

Make a payout

Payouts are a two-step flow. First preview to get a fee breakdown with POST /v1/virtual-accounts/{id}/payout/preview, then create the payout with POST /v1/virtual-accounts/{id}/payout.
# 1. Preview — returns a fee breakdown
curl https://api.balampay.com/sandbox/v1/virtual-accounts/$VA_ID/payout/preview \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "x-api-key: $KIRA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "recipient_id": "<recipient id>", "amount": "50.00" }'

# 2. Create the payout
curl https://api.balampay.com/sandbox/v1/virtual-accounts/$VA_ID/payout \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "x-api-key: $KIRA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{ "recipient_id": "<recipient id>", "amount": "50.00" }'
There is no fee schedule endpoint and no dry_run mode. Preview returns 400 "Total fees exceed or equal the payout amount" for amounts below the minimum (~$3 for SWIFT) — the only way to find the minimum is to iterate. The 201 create response returns lowercase status: "created", while GET /v1/payouts/{id} returns CREATED for the same payout — compare statuses case-insensitively.

Next steps

Authentication

The full token lifecycle, required headers, and credential handling.

Webhooks

Register an endpoint and consume deposit, user, and payout events.

API reference

Browse every endpoint, request shape, and response in the interactive reference.