Skip to main content

Partner Handoff

Partner Handoff lets you drop a user who is already signed in to your application straight into the Kora Remittance flow — landing on the dashboard with an active session, without a second phone/OTP login. It is the recommended way to minimise drop-off when embedding transfers.

How it works​

┌──────────────┐   1. mint    ┌────────────────┐
│ Your backend │─────────────▶│ Kora auth │
│ │◀─────────────│ /partner-token │
└──────┬───────┘ {token,url} └────────────────┘
│ 2. redirect browser to redirectUrl
▼
┌──────────────┐ 3. exchange ┌────────────────┐
│ /handoff │─────────────▶│ Kora auth │
│ (hosted UI) │◀─────────────│ /exchange-token│
└──────┬───────┘ {session} └────────────────┘
│ 4. land on dashboard (signed in)
▼
Transfer flow
  1. Your backend mints a one-time handoff token.
  2. You redirect the user's browser to the returned URL.
  3. The hosted handoff page exchanges the token for a session.
  4. The user lands in the dashboard, already authenticated.

Step 1: Mint a handoff token​

Call from your backend with your partner key. The token is one-time-use and short-lived.

curl -X POST "https://api.korastratum.com/api/v1/remittance/auth/partner-token" \
-H "X-Partner-API-Key: $KORA_PARTNER_KEY" \
-H "Content-Type: application/json" \
-d '{
"partnerUserId": "usr_abc123",
"phone": "+15551234567",
"email": "user@example.com",
"firstName": "Alex",
"lastName": "Rivera",
"countryCode": "US",
"returnUrl": "https://app.yourbrand.com/wallet",
"context": { "cashOutBalanceUsd": "25.00" }
}'
FieldRequiredNotes
partnerUserIdyesYour stable id for the user; links to the Kora user across handoffs
phone / emailrecommendedUsed to match or create the Kora user
firstName / lastName / countryCode / dateOfBirthoptionalPre-fills the profile
returnUrloptionalWhere "back to your app" links go; must pass your allowlist (https by default)
contextoptionalArbitrary values passed through to the flow (e.g. a cash-out amount to pre-fill)

Response:

{
"token": "<one-time-jwt>",
"redirectUrl": "https://app.yourbrand.com/handoff?t=<one-time-jwt>",
"expiresIn": 120
}

Step 2: Redirect the user​

Send the user's browser to redirectUrl. The hosted handoff page reads the token from the query string and immediately exchanges it, so it never persists in browser history.

Step 3: Exchange (handled for you)​

The hosted /handoff page calls POST /auth/exchange-token with the token and receives a normal session. If you build your own handoff page instead of using the hosted one, exchange it yourself:

curl -X POST "https://api.korastratum.com/api/v1/remittance/auth/exchange-token" \
-H "Content-Type: application/json" \
-d '{ "token": "<one-time-jwt>" }'

The response is a session (token, refreshToken, expiresIn) you use as the end-user session token for creating transfers and listing history.

warning

Handoff establishes a session; it does not bypass compliance. A user who has not completed KYC will still be routed through identity verification before a transfer can settle.

Security notes​

  • Handoff tokens are one-time-use and expire in ~2 minutes.
  • returnUrl is validated against your tenant's allowlist before the token is signed. By default only https targets are accepted; contact us to allowlist a custom scheme or host (e.g. a deep link back into your mobile app).
  • The partner key is a server-side secret — never ship it in a client.