# Open an Onramp Session

A card onramp session that delivers crypto to one of the user's wallets, and the client secret that opens the payment widget.

## Overview

- `walletId` names one of the user's wallets — or `addressId` an address the user proved, where your tenant allows it; exactly one of the two (`400` `CARD_ONRAMP_DESTINATION_INVALID`). Aurea reads the address. The wallet must be one whose key Aurea holds or has seen proven (a watch-only import is refused), an EVM wallet for an EVM pair and a Solana wallet for a Solana pair. The session is **locked to that address and network** — see [Where the crypto goes](https://docs.aureahub.com/docs/guide-card-onramp.md).
- `sourceAmount` (fiat, at most 2 decimals) or `destinationAmount` (crypto, at most the token's decimals), never both, only suggests an amount: the user can change it in the widget.
- Aurea passes this request's IP address to the payment provider, which decides from it whether it can serve the user: call it from the user's device, not from your server.
- With an `Idempotency-Key`, the same key and request answer `200` with the same session, its client secret and `idempotency-replayed: true`, and the payment provider is not asked for a second one; a session still `creating` is asked again with the same key at the payment provider. The same key with another request answers `409` `IDEMPOTENCY_KEY_REUSED`; a key whose session the payment provider refused, `409` `CARD_ONRAMP_SESSION_FAILED`. The key is looked up only after every other check has passed.
- Refusals before the payment provider is called, when nothing is stored: `403` `CARD_ONRAMP_OFF` where your tenant does not offer the onramp in that environment; `400` `CARD_ONRAMP_PAIR_UNAVAILABLE` (with `details.available`), `CARD_ONRAMP_PAIR_NOT_SOLD_IN_CURRENCY` (with `details.sourceCurrencies`), `CARD_ONRAMP_DESTINATION_NOT_ALLOWED`, `CARD_ONRAMP_AMOUNT_INVALID`, `IDEMPOTENCY_KEY_INVALID`; `404` `CARD_ONRAMP_WALLET_NOT_FOUND`.
- The payment provider's refusals, with the payment provider's status, code and request id in `details`: `403` `CARD_ONRAMP_CUSTOMER_UNSUPPORTED` (the payment provider cannot serve this user), `400` `CARD_ONRAMP_INVALID_REQUEST`, `503` `CARD_ONRAMP_DISABLED`, `CARD_ONRAMP_MERCHANT_NOT_SET_UP`, `CARD_ONRAMP_AUTHENTICATION_FAILED` or `CARD_ONRAMP_RATE_LIMITED`, `502` when the payment provider cannot be reached. The session is then `failed`, except after no answer or a rate limit, when it stays `creating`.

## Endpoint

### `POST /v1/ramp/card/sessions`

Authentication: bearer token required.

Opens a card onramp session for one of the user's wallets.

**Headers**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `Idempotency-Key` | string | no | Up to 255 letters, digits, `-` or `_`; see above |

**Request body**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `walletId` | string (uuid) | no | One of the user's wallets — or addressId instead |
| `addressId` | string (uuid) | no | An address the user proved (403 `CARD_ONRAMP_PROVEN_ADDRESSES_OFF` where your tenant does not allow it, 404 `CARD_ONRAMP_ADDRESS_NOT_FOUND` once revoked) — or walletId instead |
| `pair` | string | yes | `currency/network`, one of the configuration's pairs |
| `isTestnet` | boolean | no | `true` for the sandbox |
| `sourceCurrency` | string | no | `eur` or `usd`; the tenant's default otherwise |
| `sourceAmount` | string | no | Suggested fiat amount |
| `destinationAmount` | string | no | Suggested crypto amount |

**Responses**

`201` Created

```json
{
  "session": {
    "id": "444417bc-0675-4d3a-8831-bd1cbedc9738",
    "environment": "sandbox",
    "status": "initialized",
    "providerStatus": "initialized",
    "providerSessionId": "cos_1QAbCdEfGhIjKlMn",
    "pair": {
      "name": "usdc/ethereum",
      "currency": "usdc",
      "network": "ethereum",
      "aureaChain": "ethereum",
      "family": "evm",
      "sourceCurrencies": ["eur", "usd"]
    },
    "destination": {
      "kind": "aurea_wallet",
      "walletId": "990b620f-a1f5-4317-9c77-974270328a92",
      "addressId": null,
      "address": "0xC0207704CaEB9342cf491Ad4a177F43592df65a7"
    },
    "customer": null,
    "requested": {
      "sourceCurrency": "eur",
      "sourceAmount": "50.00",
      "destinationAmount": null
    },
    "amounts": {
      "sourceCurrency": "eur",
      "sourceAmount": "50.00",
      "destinationAmount": null,
      "networkFee": null,
      "transactionFee": null
    },
    "transactionId": null,
    "failureCode": null,
    "createdAt": "2026-09-24T14:30:00.274Z",
    "updatedAt": "2026-09-24T14:30:00.289Z"
  },
  "clientSecret": "cos_1QAbCdEfGhIjKlMn_secret_Xy9ZkLmNoPqRsTuVwXyZ01",
  "publishableKey": "pk_test_51QAbCdEfGhIjKlMnOpQrStUv"
}
```

`200` Replayed

```json
{
  "session": {
    "id": "444417bc-0675-4d3a-8831-bd1cbedc9738",
    "environment": "sandbox",
    "status": "initialized",
    "providerStatus": "initialized",
    "providerSessionId": "cos_1QAbCdEfGhIjKlMn",
    "pair": {
      "name": "usdc/ethereum",
      "currency": "usdc",
      "network": "ethereum",
      "aureaChain": "ethereum",
      "family": "evm",
      "sourceCurrencies": ["eur", "usd"]
    },
    "destination": {
      "kind": "aurea_wallet",
      "walletId": "990b620f-a1f5-4317-9c77-974270328a92",
      "addressId": null,
      "address": "0xC0207704CaEB9342cf491Ad4a177F43592df65a7"
    },
    "customer": null,
    "requested": {
      "sourceCurrency": "eur",
      "sourceAmount": "50.00",
      "destinationAmount": null
    },
    "amounts": {
      "sourceCurrency": "eur",
      "sourceAmount": "50.00",
      "destinationAmount": null,
      "networkFee": null,
      "transactionFee": null
    },
    "transactionId": null,
    "failureCode": null,
    "createdAt": "2026-09-24T14:30:00.274Z",
    "updatedAt": "2026-09-24T14:30:00.309Z"
  },
  "clientSecret": "cos_1QAbCdEfGhIjKlMn_secret_Xy9ZkLmNoPqRsTuVwXyZ01",
  "publishableKey": "pk_test_51QAbCdEfGhIjKlMnOpQrStUv"
}
```

`403` Onramp off

```json
{
  "statusCode": 403,
  "error": "ForbiddenError",
  "message": "The card onramp is not switched on for this tenant in sandbox.",
  "details": {
    "code": "CARD_ONRAMP_OFF",
    "environment": "sandbox"
  }
}
```

`400` Pair not offered

```json
{
  "statusCode": 400,
  "error": "BadRequestError",
  "message": "This tenant does not offer usdc/base through the onramp in sandbox.",
  "details": {
    "code": "CARD_ONRAMP_PAIR_UNAVAILABLE",
    "available": [
      "usdc/ethereum",
      "usdc/solana"
    ]
  }
}
```

`403` the payment provider cannot serve the user

```json
{
  "statusCode": 403,
  "error": "StripeOnrampError",
  "message": "The card onramp cannot be offered to this customer",
  "details": {
    "code": "CARD_ONRAMP_CUSTOMER_UNSUPPORTED",
    "providerStatus": 400,
    "providerCode": "crypto_onramp_unsupportable_customer",
    "providerParam": "customer_ip_address",
    "providerRequestId": "req_8Kd02LmQpXyZ01"
  }
}
```

`409` Key reused

```json
{
  "statusCode": 409,
  "error": "ConflictError",
  "message": "This Idempotency-Key was sent with another request",
  "details": {
    "code": "IDEMPOTENCY_KEY_REUSED"
  }
}
```

---

Web version: https://docs.aureahub.com/#card-onramp-create
