> ## Documentation Index
> Fetch the complete documentation index at: https://rain-sandbox-trial.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Common Flows

> The full integration path from wallet setup to card spend, and when to call from your backend versus your app with a Client Session Token.

Integrate Rain embedded wallets end to end. This page maps each step to its guide. Create the wallet first: you need its address to create the user's application.

Here's the full path:

<div className="wf-diagram">
  <svg id="common-flows-pipeline" role="img" aria-label="The embedded wallet integration path: create the wallet, onboard the user and complete KYC, fund the wallet, issue the card, then spend and manage balances." viewBox="0 0 1080 120" width="1080" height="120" style={{width: "100%", height: "auto"}}><defs><marker id="arrow" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0,0 L10,5 L0,10 z" className="marker-fill-default" /></marker></defs><path d="M 196 64 L 236 64" fill="none" className="conn-default" stroke-width="1.7" marker-end="url(#arrow)" opacity="0.92" /><path d="M 412 64 L 452 64" fill="none" className="conn-default" stroke-width="1.7" marker-end="url(#arrow)" opacity="0.92" /><path d="M 628 64 L 668 64" fill="none" className="conn-default" stroke-width="1.7" marker-end="url(#arrow)" opacity="0.92" /><path d="M 844 64 L 884 64" fill="none" className="conn-default" stroke-width="1.7" marker-end="url(#arrow)" opacity="0.92" /><foreignObject x="20" y="30" width="176" height="68"><div className="card action"><span className="ct"><span className="tag" style={{color: "var(--accent)"}}>Wallet</span><span className="lab">Create the wallet</span></span></div></foreignObject><foreignObject x="236" y="30" width="176" height="68"><div className="card action"><span className="ct"><span className="tag" style={{color: "var(--accent)"}}>User</span><span className="lab">Onboard & complete KYC</span></span></div></foreignObject><foreignObject x="452" y="30" width="176" height="68"><div className="card action"><span className="ct"><span className="tag" style={{color: "var(--accent)"}}>Funding</span><span className="lab">Fund the wallet</span></span></div></foreignObject><foreignObject x="668" y="30" width="176" height="68"><div className="card action"><span className="ct"><span className="tag" style={{color: "var(--accent)"}}>Card</span><span className="lab">Issue the card</span></span></div></foreignObject><foreignObject x="884" y="30" width="176" height="68"><div className="card action"><span className="ct"><span className="tag" style={{color: "var(--accent)"}}>Spend</span><span className="lab">Spend & check balances</span></span></div></foreignObject></svg>
</div>

## Backend API key vs. Client Session Token

Rain accepts two kinds of caller. Be deliberate about which you use:

<Columns cols={2}>
  <Card title="Backend, with your primary API key" icon="server">
    The established, default path for calling Rain. Use your primary API key (`Api-Key` header) for everything server-side: creating and managing users, applications, contracts, cards, and payments.
  </Card>

  <Card title="App, with a Client Session Token (CST)" icon="mobile-screen">
    A newer, optional capability. A CST is a short-lived (about 1 hour) token scoped to a single, already-created user: your backend mints it from your API key, or the SDK's [built-in Rain API client](/sdks/embedded-wallets-authentication#built-in-rain-api-client) mints one automatically. Your app then sends it as `Authorization: Bearer cst_…` to call that user's endpoints directly, without shipping your primary API key to the device. A CST can't create users or mint other tokens.
  </Card>
</Columns>

### Backend or CST: which to use

Default to the backend API-key flow, since it's proven and covers every server-side operation. The main reason to reach for a CST is fetching a [withdrawal signature](/sdks/embedded-wallets-withdraw-collateral) on-device; everything else can stay on the backend.

## What runs where

Here's exactly which calls go where:

| Action                                              | Backend (API key) |                 App                 |
| --------------------------------------------------- | :---------------: | :---------------------------------: |
| Authenticate the wallet (Turnkey, Portal, or Privy) |        None       |    ✅ provider's SDK, outside Rain   |
| Create the application                              |         ✅         |    None (CST can't create users)    |
| Complete KYC                                        |         ✅         |           ✅ CST (optional)          |
| Mint a session token (CST)                          |         ✅         |   ✅ built-in client, automatically  |
| Fund card spend (move tokens on-chain)              |        None       |               ✅ wallet              |
| Read contracts · fetch signatures                   |         ✅         | ✅ built-in client or CST, after KYC |
| Create contracts, cards, or payments                |         ✅         |                 None                |

### Backend vs. app, in short

Creating and managing things is a backend API-key job; the app handles the wallet (through its provider) and on-chain actions, and, only if you opt into a CST, can make user-scoped Rain calls directly.

## The end-to-end flow

Each step maps to its own guide.

<Steps>
  <Step title="Authenticate the wallet">
    <Badge className="badge-rain-pink">App</Badge>

    Authenticate the user's wallet with your provider (Turnkey, Portal, or Privy), outside Rain. See [Authentication](/sdks/embedded-wallets-authentication).
  </Step>

  <Step title="Set up the wallet">
    <Badge className="badge-rain-pink">App</Badge>

    Build the SDK, resolve the wallet, and read its address. The address is required for the next step. See [Set up a wallet](/sdks/embedded-wallets-setup).
  </Step>

  <Step title="Create the user & complete KYC">
    <Badge className="badge-rain-pink">Backend</Badge>

    Create the user's application with the wallet address and complete KYC, using your API key. See [Create the user & KYC](/sdks/embedded-wallets-onboarding).
  </Step>

  <Step title="Fund the wallet">
    <Badge className="badge-rain-pink">App</Badge>

    Back the user's card spend with collateral: the user deposits tokens into their collateral contract, or, with [Real Time Funding](/docs/real-time-funding), keeps funds in the wallet to be pulled at authorization. See [Fund the wallet](/sdks/embedded-wallets-funding) and [Managing Collateral](/docs/managing-collateral).
  </Step>

  <Step title="Issue a card">
    <Badge className="badge-rain-pink">Backend</Badge>

    Issue a card for the approved user with your API key. See [Card Issuance](/sdks/card-issuance).
  </Step>

  <Step title="Spend & check balances">
    <Badge className="badge-rain-pink">App</Badge>

    The card draws on the user's funded spending power. Read wallet balances and send tokens with the SDK. See [Balances & Transactions](/sdks/embedded-wallets-balances-and-transactions).
  </Step>

  <Step title="Withdraw">
    <Badge className="badge-rain-pink">App</Badge> or <Badge className="badge-rain-pink">Backend + App</Badge>

    Fetch the admin withdrawal signature from Rain (in-app with the SDK's built-in Rain API client, or from your backend), then execute `withdrawCollateral` in the app. See [Withdraw Collateral](/sdks/embedded-wallets-withdraw-collateral).
  </Step>
</Steps>

<Info>
  Want the app to call user-scoped Rain endpoints directly, for example to fetch the withdrawal signature on-device? Mint a [Client Session Token](/sdks/embedded-wallets-authentication#mint-a-rain-session-token-backend). It's optional; the backend API-key flow covers these calls too.
</Info>

## FAQ

<AccordionGroup>
  <Accordion title="Do applications have to route through the backend?">
    Creating the application is backend-only: it creates the user, and a CST can't create users or mint other tokens. Completing KYC runs on your backend by default (the standard flow), but can optionally run from the app with a CST. When the app calls user-scoped Rain endpoints, the SDK's [built-in Rain API client](/sdks/embedded-wallets-authentication#built-in-rain-api-client) mints and caches the required CST automatically. The app's other jobs are the wallet and on-chain funding.
  </Accordion>

  <Accordion title="Can withdrawals be fully abstracted?">
    Almost, but not quite. The on-chain part is a single call: `withdrawCollateral` builds the transaction, signs it through the wallet, and submits it. But it needs an admin withdrawal signature from the Rain API first, so a withdrawal is always two steps:

    1. Fetch the signature: in-app with the SDK's `fetchAdminSignature` (the [built-in Rain API client](/sdks/embedded-wallets-authentication#built-in-rain-api-client)), or `GET /v1/issuing/users/:userId/signatures/withdrawals` from your backend (API key).
    2. Withdraw: pass the signature to `withdrawCollateral`, one SDK call. On Android, `autoSend = false` returns the raw transaction data if you'd rather submit it yourself.

    It can't collapse to a single call, because the admin signature must come from Rain's signing service. See [Withdraw Collateral](/sdks/embedded-wallets-withdraw-collateral).
  </Accordion>
</AccordionGroup>

## What's next

<Columns cols={3}>
  <Card title="Set Up a Wallet" icon="wallet" href="/sdks/embedded-wallets-setup">
    Build the SDK and create a wallet.
  </Card>

  <Card title="Create the user & KYC" icon="user-check" href="/sdks/embedded-wallets-onboarding">
    Onboard the user with the wallet address.
  </Card>

  <Card title="Fund the Wallet" icon="coins" href="/sdks/embedded-wallets-funding">
    Put funds behind the card.
  </Card>
</Columns>
