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.