## Card API Documentation

> **Recommended:** You can use [infini-skill](https://github.com/infini-money/infini-skill) to integrate with Infini APIs faster. The skill provides ready-to-use integration capabilities for the card API before you implement the raw requests below.


Card endpoints are used to apply for, list, query, reveal, top up, redeem, freeze, and unfreeze organization cards issued to your members.

All Card API prefix:

`/v2/cards`

### Card Identifier

The only card identifier merchants use is the internal **`id`**:

- **`data.id`** from **`POST /v2/cards/apply`**
- **`cards[].id`** from **`GET /v2/cards/list`**
- The **`id`** passed to **`GET /v2/cards/status`**, **`POST /v2/cards/reveal`**, **`POST /v2/cards/top-up`**, **`POST /v2/cards/redeem`**, **`POST /v2/cards/freeze`**, and **`POST /v2/cards/unfreeze`**


### Authentication and Permissions

All endpoints use HMAC-SHA256 authentication with **`Date`**, **`Digest`** when the request has a body, and **`Authorization`** with **`keyId`**. See [Chapter 4: Authorization and Security Mechanisms](/docs/en/4-authorization).

| Permission | Endpoints |
|  --- | --- |
| `card.create` | `POST /v2/cards/apply`, `GET /v2/cards/list`, `GET /v2/cards/status`, `POST /v2/cards/top-up`, `POST /v2/cards/redeem`, `POST /v2/cards/freeze`, `POST /v2/cards/unfreeze` |
| `card.reveal` | `POST /v2/cards/reveal` |


> **IP whitelist:** API keys that include `card.create` or `card.reveal` must be configured with a non-empty IP whitelist when created or updated in the merchant dashboard.


### Response Envelope

All endpoints use the standard `code` / `message` / `data` envelope. Business success is indicated by `code === 0`; a non-zero `code` indicates an error and `message` carries the details.

### Apply Card

**POST** /v2/cards/apply

Creates a card application and initial top-up flow for an organization member.

- **Required permission:** `card.create`


#### Request Body

| Field | Type | Required | Description |
|  --- | --- | --- | --- |
| product_id | integer | Yes | Card product ID. `1` = Infini Lite, `2` = Infini Pro, `101` = Infini AI |
| top_up_amount | string | Yes | Initial top-up amount, decimal string |
| token_type | string | Yes | Token type, for example `USDT` or `USDC` |
| user_email | string | Yes | Organization member business account email under this merchant |
| holder_name | string | Yes | Card holder name |
| card_alias | string | No | Optional card alias |


#### Product IDs

| product_id | Product |
|  --- | --- |
| `1` | Infini Lite |
| `2` | Infini Pro |
| `101` | Infini AI |


#### Request Example

```json
{
  "product_id": 1,
  "top_up_amount": "100.00",
  "token_type": "USDT",
  "user_email": "jane@example.com",
  "holder_name": "Jane Doe",
  "card_alias": "Travel card"
}
```

#### Response Example

```json
{
  "code": 0,
  "message": "",
  "data": {
    "id": "a441831c-a5c7-4bed-8f61-793738afd5bc",
    "status": "init",
    "total_top_up_amount": "100.00",
    "total_fee": "1.00",
    "total_pay_amount": "101.00",
    "message": ""
  }
}
```

### List Cards

**GET** /v2/cards/list

Returns a paginated list of organization cards for the merchant.

- **Required permission:** `card.create`


#### Query Parameters

| Field | Type | Required | Description |
|  --- | --- | --- | --- |
| status | string | No | Card status filter, comma-separated, for example `active,pending` |
| card_alias | string | No | Card alias filter |
| page | integer | No | Page number, starting at `1`; default `1` |
| page_size | integer | No | Items per page, max `100`; default `20` |


#### Response Example

```json
{
  "code": 0,
  "message": "",
  "data": {
    "cards": [
      {
        "id": "a441831c-a5c7-4bed-8f61-793738afd5bc",
        "mask": "411111******1111",
        "holder_name": "Jane Doe",
        "card_alias": "Travel card",
        "status": "active",
        "currency": "USD",
        "available_balance": "50.25",
        "user_id": "usr_01HXYZ",
        "created_at": 1714464000,
        "updated_at": 1714550400
      }
    ],
    "total": 1,
    "page": 1,
    "page_size": 20,
    "total_pages": 1
  }
}
```

### Get Card Status

**GET** /v2/cards/status?id={id}

Returns lifecycle status and summary fields for one card. After **`POST /v2/cards/apply`**, poll until **`status`** becomes **`active`**.

- **Required permission:** `card.create`


#### Query Parameters

| Field | Type | Required | Description |
|  --- | --- | --- | --- |
| id | string | Yes | Internal card `id` from apply or list |


#### Response Example

```json
{
  "code": 0,
  "message": "",
  "data": {
    "id": "a441831c-a5c7-4bed-8f61-793738afd5bc",
    "status": "pending",
    "card_alias": "Travel card",
    "mask": "",
    "holder_name": "Jane Doe",
    "currency": "USD",
    "available_balance": "0",
    "user_id": "usr_01HXYZ",
    "created_at": 1714464000,
    "updated_at": 1714464100
  }
}
```

### Reveal Card

**POST** /v2/cards/reveal

Returns the full PAN, CVV, and expiry. This is sensitive data; do not log or persist these values in client applications.

- **Required permission:** `card.reveal`


#### Request Body

| Field | Type | Required | Description |
|  --- | --- | --- | --- |
| id | string | Yes | Internal card `id` from apply or list |


#### Request Example

```json
{
  "id": "a441831c-a5c7-4bed-8f61-793738afd5bc"
}
```

#### Response Example

```json
{
  "code": 0,
  "message": "",
  "data": {
    "card_number": "4111111111111111",
    "cvv": "123",
    "expiration_mmyy": "1228",
    "card_currency": "USD"
  }
}
```

### Top Up Card

**POST** /v2/cards/top-up

Adds funds to an organization card.

- **Required permission:** `card.create`


#### Request Body

| Field | Type | Required | Description |
|  --- | --- | --- | --- |
| id | string | Yes | Internal card `id` from apply or list |
| amount | string | Yes | Top-up amount |
| token_type | string | Yes | Token type, for example `USDT` or `USDC` |
| note | string | No | Optional top-up note |


#### Response Example

```json
{
  "code": 0,
  "message": "",
  "data": {
    "tx_id": "tx_123",
    "card_balance": "150.25"
  }
}
```

### Redeem Card

**POST** /v2/cards/redeem

Redeems funds from an organization card.

- **Required permission:** `card.create`


#### Request Body

| Field | Type | Required | Description |
|  --- | --- | --- | --- |
| id | string | Yes | Internal card `id` from apply or list |
| amount | string | Yes | Redeem amount |
| token_type | string | Yes | Token type, for example `USDT` or `USDC` |
| note | string | No | Optional redeem note |


#### Response Example

```json
{
  "code": 0,
  "message": "",
  "data": {
    "tx_id": "tx_123",
    "card_balance": "80.25"
  }
}
```

### Freeze Card

**POST** /v2/cards/freeze

Freezes an organization card.

- **Required permission:** `card.create`


#### Request Body

| Field | Type | Required | Description |
|  --- | --- | --- | --- |
| id | string | Yes | Internal card `id` from apply or list |


#### Response Example

```json
{
  "code": 0,
  "message": "",
  "data": {
    "success": true,
    "message": "Card frozen"
  }
}
```

### Unfreeze Card

**POST** /v2/cards/unfreeze

Unfreezes an organization card.

- **Required permission:** `card.create`


#### Request Body

| Field | Type | Required | Description |
|  --- | --- | --- | --- |
| id | string | Yes | Internal card `id` from apply or list |


#### Response Example

```json
{
  "code": 0,
  "message": "",
  "data": {
    "success": true,
    "message": "Card unfrozen"
  }
}
```