> ## 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.

# Unload Card

> Return funds from a card back to your program ledger. POST /cards/{id}/unload. Requires cards:write scope.

## Overview

Transfers funds from a card back to your **program ledger**. Use this to reclaim unused balances, or to zero out a card before terminating it.

The card must be `ACTIVE` — you cannot unload from a `FROZEN` card.

<Warning>
  **Unloading is asynchronous.** A successful (`2xx`) response means the request was **accepted and is pending confirmation from the card provider** — funds are **not** returned to the program ledger until confirmed, and the provider may still **reject** the unload. The unload transaction stays `PENDING` until confirmed. Use the [`CARD_UNLOADED`](/v3.20/webhooks/events/card-unloaded) (confirmed — ledger credited) and [`CARD_UNLOAD_FAILED`](/v3.20/webhooks/events/card-unload-failed) (rejected — no credit) webhooks as the source of truth. Both echo the caller `reference` for reconciliation.
</Warning>

## Path Parameters

| Parameter | Type   | Description                 |
| --------- | ------ | --------------------------- |
| `id`      | string | The card ID (prefix `crd_`) |

## Request Body

| Field       | Type   | Required | Description                                                                                      |
| ----------- | ------ | -------- | ------------------------------------------------------------------------------------------------ |
| `amount`    | number | Yes      | Amount in full currency units (e.g. `25.00` = \$25). Must not exceed the card's current balance. |
| `reference` | string | No       | Optional caller-supplied reference echoed back in the response and webhook                       |

## Idempotency

Unloads are idempotent on the **`reference`** field. If you retry an unload with the same
`reference` for the same card, the API returns the **original** result and does **not** withdraw
again — a client retry or accidental double-submit can never drain the card twice or produce a
spurious `INSUFFICIENT_CARD_BALANCE` failure on the second attempt.

<Tip>
  Always send a stable, unique `reference` per logical unload. The same `reference` you send here
  is echoed back on the `CARD_UNLOADED` webhook (see below), so you can correlate the async result
  with this response.
</Tip>

## Example

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.fyatu.com/api/v3.20/cards/crd_01HXYZ5555ABCDEF1111/unload \
    -H "Authorization: Bearer $FYATU_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{ "amount": 25.00, "reference": "reclaim-op-002" }'
  ```

  ```javascript Node.js theme={null}
  const resp = await fetch(
    'https://api.fyatu.com/api/v3.20/cards/crd_01HXYZ5555ABCDEF1111/unload',
    {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${process.env.FYATU_API_KEY}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ amount: 25.00, reference: 'reclaim-op-002' })
    }
  );
  const body = await resp.json();
  console.log('Unloaded:', body.data.amount);         // 25
  console.log('Transaction:', body.data.transactionId);
  ```

  ```python Python theme={null}
  import os, requests

  resp = requests.post(
      'https://api.fyatu.com/api/v3.20/cards/crd_01HXYZ5555ABCDEF1111/unload',
      headers={'Authorization': f'Bearer {os.environ["FYATU_API_KEY"]}'},
      json={'amount': 25.00, 'reference': 'reclaim-op-002'}
  )
  data = resp.json()['data']
  print('Unloaded:', data['amount'])
  print('Transaction:', data['transactionId'])
  ```
</CodeGroup>

## Success Response (200)

```json theme={null}
{
  "success": true,
  "status": 200,
  "message": "Card unloaded",
  "data": {
    "cardId":        "crd_01HXYZ5555ABCDEF1111",
    "amount":        25.00,
    "currency":      "USD",
    "reference":     "reclaim-op-002",
    "transactionId": "txn_01HXYZ9999ABCDEF3333"
  },
  "meta": {
    "requestId": "req_01HXY123456ABCDEF",
    "platform": "Fyatu CaaS",
    "timestamp": "2026-05-26T10:00:00Z"
  }
}
```

<Note>
  This 200 response means the unload was **accepted** and the card debit was initiated at the
  provider. Settlement is confirmed asynchronously by the `CARD_UNLOADED` webhook.
</Note>

## Webhook

A `CARD_UNLOADED` event fires once the provider confirms the withdrawal and your program
balance has been credited. It **echoes the same `reference` and `transactionId` as the API
response above**, so you can join the two directly:

```json theme={null}
{
  "event":      "CARD_UNLOADED",
  "eventId":    "evt_01HXY123456ABCDEF",
  "businessId": "BUS1A2B3C4D5E6F",
  "environment": "LIVE",
  "timestamp":  "2026-05-26T10:00:00Z",
  "data": {
    "cardId":             "crd_01HXYZ5555ABCDEF1111",
    "amount":             25.00,
    "currency":           "USD",
    "reference":          "reclaim-op-002",
    "transactionId":      "txn_01HXYZ9999ABCDEF3333",
    "ledgerTransactionId": "ltx_01HXYZ0000ABCDEF4444",
    "timestamp":          "2026-05-26T10:00:00Z"
  }
}
```

| Field                 | Matches                          | Meaning                                                            |
| --------------------- | -------------------------------- | ------------------------------------------------------------------ |
| `reference`           | your request + the API response  | Your caller-supplied reference — the idempotency & correlation key |
| `transactionId`       | the API response `transactionId` | The unload transaction record                                      |
| `ledgerTransactionId` | —                                | The program-ledger entry created when your balance was credited    |

If the provider ultimately rejects the withdrawal, a `CARD_UNLOAD_FAILED` event fires instead,
carrying the same `reference` and `transactionId` so you can reconcile the failure to your request.

## Error Codes

| Code                          | HTTP | Cause                                                                                                                                             |
| ----------------------------- | ---- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| `CARD_NOT_FOUND`              | 404  | Card does not exist or belongs to another business/environment                                                                                    |
| `CARD_ALREADY_TERMINATED`     | 422  | Card is already terminated                                                                                                                        |
| `INSUFFICIENT_CARD_BALANCE`   | 422  | Requested unload amount exceeds the card's current balance                                                                                        |
| `INVALID_AMOUNT`              | 400  | Amount is zero or negative                                                                                                                        |
| `CARD_WITHDRAWAL_UNAVAILABLE` | 503  | Card withdrawal is temporarily unavailable — either paused by Fyatu, or a transient processing issue on our side. Nothing was moved; retry later. |
| `INSUFFICIENT_SCOPE`          | 403  | Key lacks `cards:write` scope                                                                                                                     |


## OpenAPI

````yaml v3.20/openapi.json POST /cards/{id}/unload
openapi: 3.1.0
info:
  title: FYATU CaaS API v3.20
  description: >-
    FYATU Cards-as-a-Service API â€” API key authentication, Cardholder
    lifecycle, Card issuance, Transactions, Webhooks, and Programs.
  version: 3.20.0
  contact:
    name: FYATU Support
    url: https://fyatu.com
    email: support@fyatu.com
servers:
  - url: https://api.fyatu.com/api/v3.20
    description: >-
      FYATU CaaS API â€” the environment (LIVE or SANDBOX) is determined by the
      API key, not the URL
security:
  - BearerAuth: []
tags:
  - name: Meta
    description: Liveness, account info, and supported event types
  - name: Account
    description: Account-level balance and funding status
  - name: Programs
    description: Read card program configuration
  - name: Cardholders
    description: Create and manage cardholder profiles
  - name: Cards
    description: Issue, fund, freeze, and terminate virtual cards
  - name: Transactions
    description: Read-only card transaction history
  - name: Webhooks
    description: Manage webhook endpoints for real-time event delivery
  - name: Products
    description: Read card product configurations
paths:
  /cards/{id}/unload:
    post:
      tags:
        - Cards
      summary: Unload a card
      description: Pull funds back from a card to the program ledger.
      operationId: unloadCard
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
          example: crd_01HXYZ5555ABCDEF1111
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - amount
              properties:
                amount:
                  type: number
                  format: double
                  example: 25
                reference:
                  type: string
                  example: reclaim-op-002
      responses:
        '200':
          description: Card unloaded
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CardUnloadResponse'
              example:
                success: true
                status: 200
                message: Card unloaded
                data:
                  cardId: crd_01HXYZ5555ABCDEF1111
                  amount: 25
                  currency: USD
                  reference: reclaim-op-002
                  transactionId: ltx_01HXYZ9999ABCDEF3333
                meta:
                  requestId: req_a1b2c3d4e5f6a7b8c9d0e1f2
                  platform: Fyatu CaaS
                  timestamp: '2026-05-26T10:00:00Z'
        '400':
          $ref: '#/components/responses/ValidationError'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          description: Insufficient card balance
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                success: false
                status: 422
                message: Insufficient card balance
                error:
                  code: INSUFFICIENT_CARD_BALANCE
                  detail: Insufficient card balance
                meta:
                  requestId: req_a1b2c3d4e5f6a7b8c9d0e1f2
                  platform: Fyatu CaaS
                  timestamp: '2026-05-22T15:00:00Z'
        '429':
          $ref: '#/components/responses/RateLimitExceeded'
        '500':
          $ref: '#/components/responses/InternalError'
components:
  schemas:
    CardUnloadResponse:
      type: object
      properties:
        success:
          type: boolean
          example: true
        status:
          type: integer
          example: 200
        message:
          type: string
          example: Card unloaded
        data:
          type: object
          properties:
            cardId:
              type: string
              example: crd_01HXYZ5555ABCDEF1111
            amount:
              type: number
              description: Amount unloaded in full currency units
              example: 25
            currency:
              type: string
              example: USD
            reference:
              type: string
              description: Caller-supplied reference echoed back
              example: reclaim-op-002
            transactionId:
              type: string
              example: ltx_01HXYZ9999ABCDEF3333
        meta:
          $ref: '#/components/schemas/Meta'
    Error:
      type: object
      properties:
        success:
          type: boolean
          example: false
        status:
          type: integer
          example: 422
        message:
          type: string
          example: Human readable message
        error:
          $ref: '#/components/schemas/ErrorBody'
        meta:
          $ref: '#/components/schemas/Meta'
    Meta:
      type: object
      properties:
        requestId:
          type: string
          example: req_a1b2c3d4e5f6a7b8c9d0e1f2
        platform:
          type: string
          example: Fyatu CaaS
        timestamp:
          type: string
          format: date-time
          example: '2026-05-22T15:00:00Z'
    ErrorBody:
      type: object
      properties:
        code:
          type: string
          example: VALIDATION_ERROR
        detail:
          type: string
          example: dateOfBirth must be in YYYY-MM-DD format
  responses:
    ValidationError:
      description: Request validation failed
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            success: false
            status: 422
            message: Validation failed
            error:
              code: VALIDATION_ERROR
              detail: dateOfBirth must be in YYYY-MM-DD format
            meta:
              requestId: req_a1b2c3d4e5f6a7b8c9d0e1f2
              platform: Fyatu CaaS
              timestamp: '2026-05-22T15:00:00Z'
    Unauthorized:
      description: Missing or invalid API key
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            missing:
              summary: API key missing
              value:
                success: false
                status: 401
                message: API key is required
                error:
                  code: AUTH_TOKEN_MISSING
                  detail: API key is required
                meta:
                  requestId: req_a1b2c3d4e5f6a7b8c9d0e1f2
                  platform: Fyatu CaaS
                  timestamp: '2026-05-22T15:00:00Z'
            invalid:
              summary: API key invalid
              value:
                success: false
                status: 401
                message: Invalid API key
                error:
                  code: AUTH_TOKEN_INVALID
                  detail: Invalid API key
                meta:
                  requestId: req_a1b2c3d4e5f6a7b8c9d0e1f2
                  platform: Fyatu CaaS
                  timestamp: '2026-05-22T15:00:00Z'
    Forbidden:
      description: Scope denied or business suspended
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            success: false
            status: 403
            message: Scope denied
            error:
              code: INSUFFICIENT_SCOPE
              detail: This endpoint requires the cards:write scope
            meta:
              requestId: req_a1b2c3d4e5f6a7b8c9d0e1f2
              platform: Fyatu CaaS
              timestamp: '2026-05-22T15:00:00Z'
    NotFound:
      description: Resource not found or does not belong to your business
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    RateLimitExceeded:
      description: Rate limit exceeded
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            success: false
            status: 429
            message: Rate limit exceeded
            error:
              code: RATE_LIMIT_EXCEEDED
              detail: Too many requests
            meta:
              requestId: req_a1b2c3d4e5f6a7b8c9d0e1f2
              platform: Fyatu CaaS
              timestamp: '2026-05-22T15:00:00Z'
    InternalError:
      description: Unexpected server error
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            success: false
            status: 500
            message: Internal error
            error:
              code: INTERNAL_ERROR
              detail: An unexpected error occurred
            meta:
              requestId: req_a1b2c3d4e5f6a7b8c9d0e1f2
              platform: Fyatu CaaS
              timestamp: '2026-05-22T15:00:00Z'
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      description: >-
        API key from the FYATU CaaS portal. Pass as `Authorization: Bearer
        <key>`.

````