# Cards

Issue and manage virtual cards — list, create, read details, freeze, set limits, and cancel.

Issue USD virtual cards for your organization and manage their lifecycle. Every card is identified by an opaque Dolafy `id` — treat it as a stable string and do not parse its format.

## List cards

```http
GET /v1/cards
x-api-key: dlfy_live_...
```

### Query parameters

| Parameter | Default | Description |
|-----------|---------|-------------|
| `status` | `not_cancelled` | One of `active`, `frozen`, `cancelled`, `not_cancelled`, `all`. |
| `limit` | `100` | Page size, capped at `100`. |
| `offset` | `0` | Number of records to skip. |

### Response

```json
{
  "cards": [
    {
      "id": "126b6996-9c99-4732-9a58-3d8721e30bc8",
      "title": "Growth Ads - Meta",
      "status": "active",
      "type": "virtual",
      "currency": "USD",
      "last4": "4242",
      "expiryDate": "05/29",
      "spendLimit": 1000,
      "spendLimitFrequency": "per30DayPeriod",
      "currentSpend": 125.75
    }
  ],
  "pagination": {
    "limit": 100,
    "offset": 0,
    "hasMore": false
  }
}
```

Page forward by requesting the next page with `offset += limit` while `pagination.hasMore` is `true`.

## Issue a card

```http
POST /v1/cards
x-api-key: dlfy_live_...
Idempotency-Key: card-growth-meta-001
content-type: application/json
```

Returns `201 Created`. `Idempotency-Key` is required to avoid duplicate cards on retries.

### Request

```json
{
  "title": "Growth Ads - Meta",
  "spendLimitAmount": 1000,
  "spendLimitFrequency": "per30DayPeriod"
}
```

- `title` is the card label. If omitted, Dolafy generates a short label like `API Card A1B2C3`.
- Spend limits are optional. Omit both `spendLimitAmount` and `spendLimitFrequency` to issue a card with no custom limit.
- Supported `spendLimitFrequency` values: `perAuthorization`, `per24HourPeriod`, `per7DayPeriod`, `per30DayPeriod`, `perYearPeriod`, `allTime`.

### Response

```json
{
  "card": {
    "id": "126b6996-9c99-4732-9a58-3d8721e30bc8",
    "title": "Growth Ads - Meta",
    "status": "active",
    "type": "virtual",
    "currency": "USD",
    "last4": "4242",
    "expiryDate": "05/29",
    "spendLimit": 1000,
    "spendLimitFrequency": "per30DayPeriod",
    "currentSpend": 0
  }
}
```

Issuance requires authorized-user terms to have been accepted in the dashboard; otherwise the call returns `409 authorized_user_terms_required`. Standard issuance limits (active-card cap, minimum balance, and issuance fees) still apply.

## Card details

Returns the sensitive card number and CVV. Call this **server-side only** and avoid logging or storing these values unless your compliance program permits it.

```http
GET /v1/cards/126b6996-9c99-4732-9a58-3d8721e30bc8/details
x-api-key: dlfy_live_...
```

```json
{
  "card": {
    "id": "126b6996-9c99-4732-9a58-3d8721e30bc8",
    "title": "Growth Ads - Meta",
    "status": "active",
    "type": "virtual",
    "currency": "USD",
    "last4": "4242",
    "expiryDate": "05/29",
    "expiryMonth": 5,
    "expiryYear": 2029,
    "cardNumber": "4111111111114242",
    "cvv": "123",
    "spendLimit": 1000,
    "spendLimitFrequency": "per30DayPeriod",
    "currentSpend": 125.75
  }
}
```

## Freeze and unfreeze

```http
POST /v1/cards/:cardId/pause
POST /v1/cards/:cardId/unpause
```

`pause` freezes a card (`status: "frozen"`); `unpause` reactivates it (`status: "active"`). Both return the full card object.

## Update the spend limit

```http
PATCH /v1/cards/:cardId/limit
content-type: application/json
```

```json
{
  "spendLimitAmount": 2500,
  "spendLimitFrequency": "per30DayPeriod"
}
```

`spendLimitAmount` must be a positive USD amount. `spendLimitFrequency` is required and accepts the same values as issuance. Returns the card with its updated limit.

## Cancel a card

```http
POST /v1/cards/:cardId/cancel
```

Permanently cancels the card (`status: "cancelled"`). Cancelling a card frees an active-card slot.
