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

# Wallet Card Enablement

> The one-time, per-wallet grant that lets Dakota recover settled card spend, and nothing else

<Warning>
  **Cards is available in sandbox only while we finish development.** Dakota enables Cards per
  account. The Cards endpoints are in the [API reference](/api-reference/introduction), marked
  **Sandbox only**. Endpoints, fields, and flows can still change before release.
</Warning>

Dakota wallets are non-custodial, and card settlement moves money out of the wallet each time a purchase clears. So before a wallet can fund any card, the customer signs a **card-settlement enablement** for it. They sign once per wallet, not per card or per purchase. Cards work with **EVM wallets only**.

## What the grant allows

| Allows | Does not allow |
| - | - |
| Recovering settled card spend from **this wallet** | Moving funds from any other wallet |
| Sending it to **one destination**, set by Dakota and fixed when the enablement is created | Sending anywhere else, or changing the destination later |
| Covering every card on the wallet | Acting as a general spending authority |

The wallet keeps working normally. Enablement does not lock it or make Dakota a signer on the customer's own payments.

## Enable a wallet

```mermaid theme={null}
sequenceDiagram
    participant App as Your application
    participant Signer as Customer's signer
    participant Dakota as Dakota API

    App->>Signer: Present the enable_card_settlement intent
    Signer-->>App: Signatures
    App->>Dakota: POST /wallets/{wallet_id}/card_enablement
    Dakota-->>App: state "attaching"
    Dakota--)App: webhook wallet.card_enablement.completed
    Note over App,Dakota: state "active": cards can be issued
```

**1. Have the customer sign the intent.** The intent contains only three fields, so you can build it straight away:

```json theme={null}
{
  "type": "enable_card_settlement",
  "wallet_id": "2tQRvK9pRzM4nVbW8sHqL5jXmYt",
  "idempotency_key": "7d3f6c2e-9a41-4f3b-bd1c-2e5a8f0c4b19"
}
```

The customer signs it like any other [endorsed request](/documentation/signing-guide), with the same keys, including [passkeys](/documentation/webauthn-signing). Do not include a settlement destination: Dakota supplies it, and an intent that contains `settlement_destination` is refused with `400`.

**2. Submit it** with [`POST /wallets/{wallet_id}/card_enablement`](/api-reference/cards/enable-card-settlement-on-a-wallet):

```json theme={null}
POST /wallets/{wallet_id}/card_enablement
X-Idempotency-Key: 7d3f6c2e-9a41-4f3b-bd1c-2e5a8f0c4b19

{
  "signatures": ["<base64-encoded signature>"],
  "intent": {
    "type": "enable_card_settlement",
    "wallet_id": "2tQRvK9pRzM4nVbW8sHqL5jXmYt",
    "idempotency_key": "7d3f6c2e-9a41-4f3b-bd1c-2e5a8f0c4b19"
  }
}
```

The response has `state: "attaching"`.

**3. Wait for `wallet.card_enablement.completed`.** The enablement is then `active`, and you can issue cards against the wallet. The webhook payload records what the customer signed: the intent hash, the signing key, and the settlement destination. Keep it as your acceptance record. [`GET /wallets/{wallet_id}/card_enablement`](/api-reference/cards/get-a-wallets-card-enablement) returns the same state.

## States

| `state` | Meaning |
| - | - |
| `not_enabled` | Nothing signed. |
| `attaching` | Signed, not in force yet. Cards cannot be issued. |
| `active` | Cards can be issued. |
| `detach_requested`, `detached` | The grant is being, or has been, withdrawn. There is no call to withdraw it yet. |

## When enablement is refused

Dakota checks these before it records anything, so a refused call leaves nothing behind.

| Response | Cause | What to do |
| - | - | - |
| `403 cards-tos-not-accepted` or `403 cards-capability-unavailable` | The customer's Cards capability is not `available`. | [Activate the customer](/documentation/cards/activation) first. |
| `422 wallet-family-not-supported` | The wallet is not an EVM wallet. | Use an EVM wallet. |
| `409 card-enablement-precondition` with `code` `no_customer_policy`, `customer_policy_ambiguous`, or `customer_policy_shared` | The wallet needs exactly one customer [policy](/documentation/policies), attached to this wallet only. | Attach, detach, or create a dedicated policy, then retry. |
| `409 card-enablement-precondition` with any other `code` | Dakota's settlement setup for your account is incomplete. | Contact Dakota. |
| `409 card-enablement-conflict` | A replay disagrees with the enablement already recorded. | See below. |

## Retrying a failed attempt

Replaying the call on an `active` enablement does nothing. While it is `attaching`, how you retry depends on what went wrong:

| What happened | What to do |
| - | - |
| A temporary failure, such as a `503` | Replay the **same intent with the same signatures**. Re-signing the same intent is rejected as a conflicting replay. |
| The endorsement was rejected | Build a corrected intent with a **new** `idempotency_key`, have it signed again, and submit it. Replaying the original request returns the same rejection. |
