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

# Transactions

> Query card transaction history

Retrieve transaction history for any card issued through your partner account.

## List card transactions

Fetch transactions for a specific card using cursor-based pagination:

<CodeGroup>
  ```bash cURL theme={null}
  curl "https://api.contro.me/v1/partner/cards/{cardId}/transactions?limit=20" \
    -H "x-contro-api-key: $CONTRO_API_KEY"
  ```

  ```typescript SDK (Node) theme={null}
  const transactions = await contro.cards.listTransactions(cardId, { limit: 20 });

  for (const tx of transactions.data) {
    console.log(`${tx.type} ${tx.amount} ${tx.currency} at ${tx.merchant}`);
  }
  ```

  ```python SDK (Python) theme={null}
  transactions = contro.cards.list_transactions(card_id, limit=20)

  for tx in transactions.data:
      print(f"{tx.type} {tx.amount} {tx.currency} at {tx.merchant}")
  ```

  ```typescript TypeScript (fetch) theme={null}
  const transactions = await fetch(
    `${BASE_URL}/partner/cards/${cardId}/transactions?limit=20`,
    { headers }
  ).then((r) => r.json());

  for (const tx of transactions.data) {
    console.log(`${tx.type} ${tx.amount} ${tx.currency} at ${tx.merchant}`);
  }
  ```
</CodeGroup>

### Query parameters

| Parameter | Type | Default | Description |
| - | - | - | - |
| `page` | integer | 1 | Page number |
| `limit` | integer | 20 | Items per page (1–100) |
| `status` | string | - | Filter by transaction status (e.g. `accepted`, `pending`, `declined`). |
| `type` | string | - | Filter by transaction type (e.g. `purchase`, `refund`, `AUTH`, `debit`). |
| `from` | string | - | ISO 8601 start timestamp (inclusive). |
| `to` | string | - | ISO 8601 end timestamp (inclusive). |

### Response

```json theme={null}
{
  "data": [
    {
      "id": "tx_abc123",
      "type": "purchase",
      "maskedCardNo": "0000",
      "direction": "D",
      "amount": 42.50,
      "currency": "USD",
      "currencyPrecision": 2,
      "billingAmount": 42.50,
      "billingCurrencyCode": "USD",
      "billingCurrencyPrecision": 2,
      "billingTimestamp": "2026-03-20T14:35:00Z",
      "status": "completed",
      "merchant": "Coffee Shop",
      "timestamp": "2026-03-20T14:30:00Z"
    }
  ],
  "total": 1,
  "page": 1,
  "limit": 20
}
```

### Transaction fields

| Field | Type | Description |
| - | - | - |
| `id` | string | Transaction ID. Example: `"tx_abc123"` |
| `type` | string | Transaction type. One of `purchase`, `refund`, `withdrawal`, `fee` |
| `maskedCardNo` | string \| null | Last 4 digits of the card number used. Example: `"0000"` |
| `direction` | string \| null | Transaction direction. `C`: credit, `D`: debit |
| `amount` | number \| null | Transaction amount in the card's currency unit. Example: `42.50` |
| `currency` | string \| null | ISO 4217 currency code. Example: `"USD"` |
| `currencyPrecision` | number \| null | Decimal precision of the transaction currency. Example: `2` |
| `billingAmount` | number \| null | Billing amount in the billing currency. Example: `42.50` |
| `billingCurrencyCode` | string \| null | ISO 4217 billing currency code. Example: `"USD"` |
| `billingCurrencyPrecision` | number \| null | Decimal precision of the billing currency. Example: `2` |
| `billingTimestamp` | string \| null | ISO 8601 billing/clearing timestamp |
| `status` | string | Transaction status. One of `pending`, `completed`, `declined`, `reversed` |
| `merchant` | string \| null | Merchant name. Example: `"Coffee Shop"` |
| `timestamp` | string | ISO 8601 transaction timestamp. Example: `"2026-03-20T14:30:00Z"` |

## Pagination

To paginate through all transactions, pass the `nextCursor` from each response:

<CodeGroup>
  ```typescript SDK (Node) theme={null}
  // The SDK handles pagination automatically
  const allTransactions = [];
  let page = await contro.cards.listTransactions(cardId, { limit: 100 });

  allTransactions.push(...page.data);
  while (page.hasMore) {
    page = await contro.cards.listTransactions(cardId, {
      limit: 100,
      cursor: page.nextCursor,
    });
    allTransactions.push(...page.data);
  }
  ```

  ```python SDK (Python) theme={null}
  all_transactions = []
  page = contro.cards.list_transactions(card_id, limit=100)

  all_transactions.extend(page.data)
  while page.has_more:
      page = contro.cards.list_transactions(card_id, limit=100, cursor=page.next_cursor)
      all_transactions.extend(page.data)
  ```

  ```typescript TypeScript (fetch) theme={null}
  let cursor: string | undefined;
  const allTransactions = [];

  do {
    const url = new URL(`${BASE_URL}/partner/cards/${cardId}/transactions`);
    url.searchParams.set("limit", "100");
    if (cursor) url.searchParams.set("cursor", cursor);

    const page = await fetch(url, { headers }).then((r) => r.json());
    allTransactions.push(...page.data);
    cursor = page.hasMore ? page.nextCursor : undefined;
  } while (cursor);
  ```
</CodeGroup>

## Real-time notifications

For real-time transaction updates, configure [webhooks](/partner/webhooks) to receive events as transactions occur, rather than polling.
