> ## Documentation Index
> Fetch the complete documentation index at: https://docs.expys.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Wallet

> Read a member's points balance and lifetime totals, in the org's points currency.

The wallet is a member's points balance. `wallet` returns the spendable balance
alongside lifetime received and spent totals, denominated in your org's points
currency.

<Note>
  These are **member-mode** calls: they use the member token, not the
  Org-API-Key. See [Authentication](/authentication). Whether you read sandbox or
  live balances is selected by the key the token was minted from - see
  [Environments](/environments).
</Note>

## Get the wallet

`wallet()` calls `GET /v1/wallet` and returns a `Wallet` for the member the token
was minted for. The snippet below reads the balance, totals, and currency (it
also shows the wallet embedded in [eligibility](/guides/eligibility)):

<CodeGroup>
  ```typescript TypeScript theme={null}
  import { initialize } from "@expys/sdk";

  const token = process.env.EXPYS_MEMBER_TOKEN;
  if (!token) {
    throw new Error(
      "Set EXPYS_MEMBER_TOKEN (a member token from your backend's /v1/auth/exchange)",
    );
  }

  const expys = initialize({
    baseUrl: process.env.EXPYS_BASE_URL,
    environment: "sandbox",
    token,
  });

  async function main(): Promise<void> {
    // externalUserID names the member when a machine token calls on their behalf.
    const eligibility = await expys.eligibility({
      externalUserID: process.env.EXPYS_EXTERNAL_USER_ID,
    });
    console.log(`tier: ${eligibility.tier}`);
    console.log(`wallet (from eligibility): ${eligibility.wallet.balance}`);

    const wallet = await expys.wallet();
    console.log(
      `wallet: balance=${wallet.balance} received=${wallet.amountReceived} ` +
        `spent=${wallet.amountSpent} ${wallet.currency.symbol} (${wallet.currency.name})`,
    );
  }
  ```

  ```swift Swift theme={null}
  import ExpysSDK
  import Foundation

  @main
  struct EligibilityWalletExample {
    static func main() async throws {
      let environment = ProcessInfo.processInfo.environment
      guard let token = environment["EXPYS_MEMBER_TOKEN"] else {
        fatalError("Set EXPYS_MEMBER_TOKEN (a member token from your backend's /v1/auth/exchange)")
      }
      let baseURL =
        environment["EXPYS_BASE_URL"].flatMap(URL.init(string:))
        ?? ExpysConfiguration.defaultBaseURL

      let client = ExpysClient(
        configuration: ExpysConfiguration(token: token, environment: .sandbox, baseURL: baseURL)
      )

      // externalUserID names the member when a machine token calls on their behalf.
      let eligibility = try await client.eligibility(
        externalUserID: environment["EXPYS_EXTERNAL_USER_ID"]
      )
      print("tier: \(eligibility.tier)")
      print("wallet (from eligibility): \(eligibility.wallet.balance)")

      let wallet = try await client.wallet()
      print(
        "wallet: balance=\(wallet.balance) received=\(wallet.amountReceived) "
          + "spent=\(wallet.amountSpent) \(wallet.currency.symbol) (\(wallet.currency.name))"
      )
    }
  }
  ```

  ```kotlin Kotlin theme={null}
  package com.expys.sdk.examples.eligibilitywallet

  import com.expys.sdk.ExpysClient
  import com.expys.sdk.ExpysConfiguration
  import kotlinx.coroutines.runBlocking

  fun main() = runBlocking {
    val token = System.getenv("EXPYS_MEMBER_TOKEN")
      ?: error("Set EXPYS_MEMBER_TOKEN (a member token from your backend's /v1/auth/exchange)")

    val client = ExpysClient.create(
      ExpysConfiguration(
        token = token,
        baseUrl = System.getenv("EXPYS_BASE_URL") ?: ExpysConfiguration.DEFAULT_BASE_URL,
      ),
    )

    // externalUserID names the member when a machine token calls on their behalf.
    val eligibility = client.eligibility(externalUserID = System.getenv("EXPYS_EXTERNAL_USER_ID"))
    println("tier: ${eligibility.tier}")

    val wallet = client.wallet()
    println("balance: ${wallet.balance} ${wallet.currency.symbol}")
    println("received: ${wallet.amountReceived}, spent: ${wallet.amountSpent}")
  }
  ```
</CodeGroup>

```bash curl theme={null}
curl https://api.expys.com/v1/wallet \
  -H "Authorization: Bearer YOUR_MEMBER_TOKEN"
```

## The Wallet schema

| Field             | Type   | Description                                                                   |
| ----------------- | ------ | ----------------------------------------------------------------------------- |
| `balance`         | number | Spendable points available now. This is what a redemption is checked against. |
| `amountReceived`  | number | Lifetime total of points the member has received.                             |
| `amountSpent`     | number | Lifetime total of points the member has spent.                                |
| `currency.name`   | string | The points-currency name (for example, your org's points brand).              |
| `currency.symbol` | string | The points-currency symbol, for display next to amounts.                      |

<Note>
  `balance` is the spendable amount and the figure a redemption is checked
  against - a redemption fails with `INSUFFICIENT_POINTS` when `balance` is below
  the offer's `pointsPrice`. `amountReceived` and `amountSpent` are running
  lifetime totals and do not decrease when points are spent.
</Note>

## Minting and the ledger

Reading the wallet is member-mode, but **minting points is server-side**. Credit
points and inspect the per-transaction ledger (`walletTransactions`) from your
backend - see [Points and wallet](/guides/points-and-wallet).

## Next steps

<CardGroup cols={2}>
  <Card title="Points and wallet" icon="coins" href="/guides/points-and-wallet">
    Server-side minting and the credit/debit transaction ledger.
  </Card>

  <Card title="Eligibility" icon="user-check" href="/guides/eligibility">
    Read tier and wallet together in one call.
  </Card>

  <Card title="Redemptions" icon="ticket" href="/guides/redemptions">
    Spend the balance by redeeming offers.
  </Card>
</CardGroup>
