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

# Create Card

> Issue a new virtual Mastercard or Visa prepaid card programmatically. Specify cardholder, amount, and product. POST /cards.

## Overview

Issue a new virtual card to a cardholder. The cardholder must have verified KYC status and your business wallet must have sufficient balance for the card amount plus fees.

## Prerequisites

1. **Verified Cardholder**: The cardholder must exist and have `status: ACTIVE`
2. **Sufficient Balance**: Wallet must cover: `amount (in USD) + issuanceFee`
3. **Active Application**: Your app must be in `ACTIVE` status

## Request Body

| Field           | Type    | Required | Description                                                                                                                      |
| --------------- | ------- | -------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `cardholderId`  | string  | Yes      | ID of the cardholder to issue card to                                                                                            |
| `amount`        | number  | Yes      | Initial funding amount in product currency (minimum \$5 or €5)                                                                   |
| `name`          | string  | No       | Name on card (defaults to cardholder name)                                                                                       |
| `productId`     | string  | No       | Card product to issue (from [List Products](/v3/api-reference/cards/products)). Defaults to the product marked `isDefault: true` |
| `spendingLimit` | integer | No       | **Deprecated** — Use `productId` instead. Monthly spending limit: `5000` or `10000` (default: 5000)                              |

<Warning>
  **Deprecation Notice**: The `spendingLimit` field is deprecated and will be removed in a future version. Use `productId` to select the card product, which determines the spending limit, brand, and currency automatically. If both `productId` and `spendingLimit` are provided, `productId` takes precedence.
</Warning>

## Example Usage

<CodeGroup>
  ```php PHP theme={null}
  <?php
  // Recommended: use productId
  $data = [
      'cardholderId' => 'ch_a1b2c3d4e5f6',
      'amount' => 100.00,
      'name' => 'ALICE EXAMPLE',
      'productId' => 'MCUSD1'
  ];

  $ch = curl_init('https://api.fyatu.com/api/v3/cards');
  curl_setopt_array($ch, [
      CURLOPT_RETURNTRANSFER => true,
      CURLOPT_POST => true,
      CURLOPT_HTTPHEADER => [
          'Authorization: Bearer ' . $accessToken,
          'Content-Type: application/json'
      ],
      CURLOPT_POSTFIELDS => json_encode($data)
  ]);

  $response = curl_exec($ch);
  $result = json_decode($response, true);

  if ($result['success']) {
      echo "Card created: " . $result['data']['id'] . "\n";
      echo "Brand: " . $result['data']['brand'] . "\n";
      echo "Currency: " . $result['data']['currency'] . "\n";
      echo "Balance: " . $result['data']['initialBalance'] . "\n";
  }
  ```

  ```javascript Node.js theme={null}
  // Recommended: use productId
  const response = await fetch('https://api.fyatu.com/api/v3/cards', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${accessToken}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      cardholderId: 'ch_a1b2c3d4e5f6',
      amount: 100.00,
      name: 'ALICE EXAMPLE',
      productId: 'MCUSD1'
    })
  });

  const result = await response.json();
  if (result.success) {
    console.log('Card created:', result.data.id);
    console.log('Brand:', result.data.brand);
    console.log('Currency:', result.data.currency);
  }
  ```
</CodeGroup>

## EUR Card Example

When issuing a EUR-denominated card, the `amount` is specified in EUR. Your wallet (USD) is debited the equivalent in USD at the current exchange rate.

```javascript theme={null}
const response = await fetch('https://api.fyatu.com/api/v3/cards', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${accessToken}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    cardholderId: 'ch_a1b2c3d4e5f6',
    amount: 100.00,        // €100 EUR
    productId: 'MCEUR1'
  })
});

// Response:
// {
//   "data": {
//     "id": "crd_...",
//     "brand": "MASTERCARD",
//     "currency": "EUR",
//     "initialBalance": 100.00   // €100 on card
//   }
// }
// Wallet debited: ~$108.70 USD (100 / EUR rate) + issuance fee
```

## Response Fields

| Field            | Type           | Description                                                               |
| ---------------- | -------------- | ------------------------------------------------------------------------- |
| `id`             | string         | Unique card identifier                                                    |
| `cardholderId`   | string         | The cardholder this card belongs to                                       |
| `name`           | string         | Name printed on the card                                                  |
| `last4`          | string \| null | Last 4 digits of the card number. `null` when status is `PROCESSING`      |
| `maskedNumber`   | string \| null | Masked card number (e.g., `****4829`). `null` when status is `PROCESSING` |
| `expiryDate`     | string \| null | Card expiration date (MM/YYYY). `null` when status is `PROCESSING`        |
| `brand`          | string         | Card brand: `MASTERCARD` or `VISA`                                        |
| `currency`       | string         | Card currency: `USD` or `EUR`                                             |
| `status`         | string         | Card status: `ACTIVE` or `PROCESSING` (see below)                         |
| `initialBalance` | number         | Initial funding amount in card currency                                   |
| `createdAt`      | string         | Card creation timestamp                                                   |

## Card Status on Creation

Some card products are created asynchronously. When this happens, the API returns immediately with `status: PROCESSING` and card details (`last4`, `maskedNumber`, `expiryDate`) will be `null`.

Once the card is ready, a [`card.created`](/v3/api-reference/webhooks/events) webhook is sent with the full card details and `status: ACTIVE`. If creation fails, a `card.failed` webhook is sent and the held balance is released.

| Status       | Meaning                                                                    |
| ------------ | -------------------------------------------------------------------------- |
| `ACTIVE`     | Card is ready to use immediately                                           |
| `PROCESSING` | Card is being created — listen for `card.created` or `card.failed` webhook |

<Info>
  You can poll `GET /cards/{cardId}` to check the card status, but **we strongly recommend using webhooks** instead of polling.
</Info>

## Webhook Events

### `card.created`

Sent when a `PROCESSING` card becomes active:

```json theme={null}
{
  "event": "card.created",
  "data": {
    "cardId": "crd_a1b2c3...",
    "cardholderId": "CH-ABC123",
    "type": "VIRTUAL",
    "brand": "MASTERCARD",
    "currency": "USD",
    "last4": "4532",
    "status": "ACTIVE"
  }
}
```

### `card.failed`

Sent when a `PROCESSING` card fails to be created. The held balance is automatically released.

```json theme={null}
{
  "event": "card.failed",
  "data": {
    "cardId": "crd_a1b2c3...",
    "cardholderId": "CH-ABC123",
    "status": "FAILED",
    "reason": "Card provider creation failed"
  }
}
```

## Error Responses

| Error Code                       | Description                                              |
| -------------------------------- | -------------------------------------------------------- |
| `APP_INACTIVE`                   | Application is not active                                |
| `CARDHOLDER_INACTIVE`            | Cardholder is not active (KYC not verified)              |
| `INSUFFICIENT_BALANCE`           | Business wallet balance is too low                       |
| `PRODUCT_NOT_FOUND`              | Card product not found                                   |
| `PRODUCT_INACTIVE`               | Card product is currently inactive                       |
| `PRODUCT_UNAVAILABLE`            | Card product is temporarily unavailable for new issuance |
| `RATE_UNAVAILABLE`               | Unable to fetch exchange rate for EUR products           |
| `HOLD_FAILED`                    | Failed to hold balance from business wallet              |
| `PROVIDER_NOT_CONFIGURED`        | Card provider account not configured                     |
| `CARD_CREATION_FAILED`           | Failed to create card at the bank partner                |
| `CARDHOLDER_REGISTRATION_FAILED` | Failed to register cardholder with card provider         |
| `CARDHOLDER_RESTRICTED`          | Cardholder has been restricted by the card provider      |
| `BUSINESS_KYB_REQUIRED`          | Business KYB verification incomplete                     |

<Tip>
  Use the [List Products](/v3/api-reference/cards/products) endpoint to discover available card products and their fees before creating a card.
</Tip>


## OpenAPI

````yaml v3/openapi.json POST /cards
openapi: 3.1.0
info:
  title: FYATU API v3
  description: >-
    FYATU API v3 with JWT authentication for Collections, Payouts, and Card
    Issuing.
  version: 3.0.0
  contact:
    name: FYATU Support
    url: https://fyatu.com
    email: support@fyatu.com
servers:
  - url: https://api.fyatu.com/api/v3
    description: Production
security: []
tags:
  - name: Authentication
    description: JWT token management endpoints
  - name: Account
    description: Business account, wallet, and address management
  - name: Collections
    description: Accept payments from customers via checkout sessions
  - name: Refunds
    description: Issue refunds for completed collections
  - name: Payouts
    description: Send money to Fyatu account holders
  - name: Cardholders
    description: Cardholder management for card issuing programs
  - name: Cards
    description: Issue, fund, freeze, and manage virtual cards
  - name: Webhooks
    description: Webhook configuration and management
paths:
  /cards:
    post:
      tags:
        - Cards
      summary: Create Card
      description: >-
        Issue a new virtual card to a cardholder. The cardholder must have
        verified KYC status. The card is funded with the specified amount on
        creation.


        **Response codes:**

        - `201` — Card created successfully. The card is immediately active and
        funded.

        - `202` — Request accepted but still processing. This happens when the
        card provider does not respond in time. The card may still be created —
        Fyatu will recover it automatically. Use the `localCardId` in the
        response to poll for the final card.
      operationId: createCard
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateCardRequest'
            example:
              cardholderId: ch_a1b2c3d4e5f6
              name: ALICE EXAMPLE
              amount: 100
              productId: MCUSD1
      responses:
        '201':
          description: Card created successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CardResponse'
              example:
                success: true
                status: 201
                message: Card created successfully
                data:
                  id: crd_8f3a2b1c4d5e6f7890abcdef12345678
                  cardholderId: ch_1a2b3c4d5e6f7890abcdef1234567890
                  name: JAMES WILSON
                  last4: '4829'
                  maskedNumber: '****4829'
                  expiryDate: 01/2030
                  brand: MASTERCARD
                  currency: USD
                  status: ACTIVE
                  initialBalance: 100
                  createdAt: '2026-01-17 10:00:00'
                meta:
                  requestId: req_a1b2c3d4e5f6
                  timestamp: '2026-01-17T10:00:00+00:00'
        '202':
          description: >-
            Card creation accepted — processing in background. The card provider
            did not respond in time. Fyatu will recover the card automatically
            once the provider confirms. Poll the List Cards endpoint using the
            `localCardId` to check when the card appears.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  status:
                    type: integer
                    example: 202
                  message:
                    type: string
                  data:
                    type: object
                    properties:
                      localCardId:
                        type: string
                        description: >-
                          Internal card ID assigned at request time. Use this to
                          identify the card once it is recovered.
                      cardholderId:
                        type: string
                      nameOnCard:
                        type: string
                      amount:
                        type: number
                      currency:
                        type: string
                      status:
                        type: string
                        example: PENDING
              example:
                success: true
                status: 202
                message: Card creation is being processed
                data:
                  localCardId: crd_8f3a2b1c4d5e6f7890abcdef12345678
                  cardholderId: ch_1a2b3c4d5e6f7890abcdef1234567890
                  nameOnCard: JAMES WILSON
                  amount: 100
                  currency: USD
                  status: PENDING
                meta:
                  requestId: req_a1b2c3d4e5f6
                  timestamp: '2026-01-17T10:00:00+00:00'
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                validation:
                  summary: Validation error
                  value:
                    success: false
                    status: 400
                    message: Validation failed
                    error:
                      code: VALIDATION_ERROR
                      details:
                        amount: Amount must be at least $5
                cardholder_inactive:
                  summary: Cardholder not active
                  value:
                    success: false
                    status: 400
                    message: Cardholder is not active
                    error:
                      code: CARDHOLDER_INACTIVE
                business_kyb_required:
                  summary: Business KYB required
                  value:
                    success: false
                    status: 400
                    message: >-
                      Business KYB documents are required to create cards.
                      Please complete business verification first.
                    error:
                      code: BUSINESS_KYB_REQUIRED
                insufficient_balance:
                  summary: Insufficient wallet balance
                  value:
                    success: false
                    status: 400
                    message: 'Insufficient balance. Required: $103.50, Available: $50.00'
                    error:
                      code: INSUFFICIENT_BALANCE
                product_not_found:
                  summary: Card product not found
                  value:
                    success: false
                    status: 404
                    message: Card product not found
                    error:
                      code: PRODUCT_NOT_FOUND
                product_inactive:
                  summary: Card product inactive
                  value:
                    success: false
                    status: 400
                    message: This card product is currently inactive
                    error:
                      code: PRODUCT_INACTIVE
                product_unavailable:
                  summary: Card product unavailable for issuance
                  value:
                    success: false
                    status: 400
                    message: >-
                      This card product is temporarily unavailable for new card
                      issuance
                    error:
                      code: PRODUCT_UNAVAILABLE
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          description: Card creation failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                provider_error:
                  summary: Provider registration failed
                  value:
                    success: false
                    status: 500
                    message: Failed to register with card provider
                    error:
                      code: PROVIDER_ERROR
                card_creation_failed:
                  summary: Card creation failed
                  value:
                    success: false
                    status: 500
                    message: Failed to create card
                    error:
                      code: CARD_CREATION_FAILED
      security:
        - BearerAuth: []
components:
  schemas:
    CreateCardRequest:
      type: object
      required:
        - cardholderId
        - amount
      properties:
        cardholderId:
          type: string
          description: ID of the cardholder to issue card to
        name:
          type: string
          minLength: 4
          description: Name on card (defaults to cardholder name if not provided)
        amount:
          type: number
          minimum: 5
          description: Initial funding amount in product currency (minimum $5 or €5)
        productId:
          type: string
          description: >-
            Card product to issue (from List Products endpoint). Determines
            brand, currency, and spending limit. Defaults to the product marked
            isDefault if not provided.
          example: MCUSD1
        spendingLimit:
          type: integer
          enum:
            - 5000
            - 10000
          default: 5000
          description: Deprecated — Use productId instead. Monthly spending limit in USD.
          deprecated: true
    CardResponse:
      type: object
      properties:
        success:
          type: boolean
          example: true
        status:
          type: integer
        message:
          type: string
        data:
          $ref: '#/components/schemas/Card'
        meta:
          $ref: '#/components/schemas/Meta'
    ErrorResponse:
      type: object
      properties:
        success:
          type: boolean
          example: false
        status:
          type: integer
          example: 401
        message:
          type: string
          example: Invalid credentials
        error:
          $ref: '#/components/schemas/Error'
        meta:
          $ref: '#/components/schemas/Meta'
    Card:
      type: object
      properties:
        id:
          type: string
          description: Unique card identifier
        cardholderId:
          type: string
          description: Associated cardholder ID
        name:
          type: string
          description: Name on card
        last4:
          type: string
          nullable: true
          description: Last 4 digits of card number. Null when status is PROCESSING
        maskedNumber:
          type: string
          nullable: true
          description: >-
            Masked card number (e.g., 5234********1234). Null when status is
            PROCESSING
        expiryDate:
          type: string
          nullable: true
          description: Expiry date (MM/YYYY). Null when status is PROCESSING
        brand:
          type: string
          enum:
            - MASTERCARD
            - VISA
          description: Card network brand
        type:
          type: string
          enum:
            - VIRTUAL
            - PHYSICAL
            - METAL
          description: Card form factor
        status:
          type: string
          enum:
            - ACTIVE
            - PROCESSING
            - FROZEN
            - SUSPENDED
            - TERMINATED
            - FAILED
        isReloadable:
          type: boolean
          description: Whether card can be funded
        createdAt:
          type: string
          format: date-time
    Meta:
      type: object
      properties:
        requestId:
          type: string
          description: Unique request ID for tracking
          example: req_abc123def456
        timestamp:
          type: string
          format: date-time
          description: ISO 8601 timestamp of the response
    Error:
      type: object
      properties:
        code:
          type: string
          description: Error code for programmatic handling
          example: AUTH_INVALID_CREDENTIALS
        details:
          type: array
          items:
            $ref: '#/components/schemas/ValidationError'
          description: Validation error details (for VALIDATION_ERROR)
    ValidationError:
      type: object
      properties:
        field:
          type: string
          description: Field that failed validation
          example: appId
        message:
          type: string
          description: Validation error message
          example: AppId is required
  responses:
    Unauthorized:
      description: Authentication required or token invalid
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            success: false
            status: 401
            message: Unable to identify business
            error:
              code: AUTH_TOKEN_INVALID
            meta:
              requestId: req_abc123
              timestamp: '2026-01-05T10:30:00+00:00'
    NotFound:
      description: Resource not found
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            success: false
            status: 404
            message: Wallet not found
            error:
              code: RESOURCE_NOT_FOUND
            meta:
              requestId: req_abc123
              timestamp: '2026-01-05T10:30:00+00:00'
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: JWT access token obtained from /auth/token

````