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

# Control card spending

> Attach spend limits and spending rules to cards, and check available balance

Every card charge is authorized against a **card limit** — an amount, a validity window, and the spending **rules** it may use. Rules let you approve or block transactions by merchant category, amount, country, time, and more. This guide covers attaching a limit to an existing card, defining spending rules, removing a limit, and reading how much is still available.

## How spending controls fit together

Two objects work together to decide whether a card transaction is approved:

* A **card limit rule** describes *where and how* a card may spend. It's a named set of **conditions** — each condition tests one attribute of the transaction (the merchant category, the amount, the country, the time, …). **All** conditions in a rule must match for the rule to allow a transaction (`AND`). A rule is reusable: create it once and reference it from many limits. Each rule you create returns a `ruleId`.
* A **card limit** authorizes spend: it caps an `amount` (in centavos), is valid between `startDate` and `endDate`, applies to one or more `cardIds`, and references one or more `ruleIds`. A transaction is allowed when it falls inside the amount and window **and** **any one** of the referenced rules matches (`OR`).

In short: conditions inside a rule are `AND`; rules inside a limit are `OR`.

```mermaid theme={null}
flowchart LR
  txn[Card transaction] --> limit[Card limit<br/>amount + window]
  limit -->|any rule matches OR| ruleA[Rule A<br/>all conditions AND]
  limit -->|any rule matches OR| ruleB[Rule B<br/>all conditions AND]
```

`FLEX_INTERNATIONAL` is a permissive default you can pass as a `ruleId` while you get started, then replace with your own rules (defined below).

## Add a limit to an existing card

Use this before each charge on a reusable card, or whenever you want to top up a card's authorized amount.

```bash theme={null}
curl -X POST \
  'https://api.banking.v2.portao3.com.br/realms/{realmId}/organizations/{organizationId}/accounts/{accountId}/card-limit' \
  -H 'Authorization: Bearer <accessToken>' \
  -H 'x-environment: LIVE' \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "Rule",
    "amount": 3500,
    "startDate": "2026-07-01",
    "endDate": "2026-07-01",
    "cardIds": ["661d6bdbea0c92b33803a8ad"],
    "ruleIds": ["FLEX_INTERNATIONAL"]
  }'
```

A `201` confirms the limit was attached. `amount` is in centavos; set `startDate`/`endDate` to today's date for a same-day charge.

Reference: [`POST .../card-limit`](/api-reference/banking/cards/realms-organizations-accounts-card-limit)

## Check the available amount

Read a card's active limits to see how much is left to spend. `availableAmount` decreases as transactions clear; `pendingAmount` reflects authorized-but-not-cleared spend.

```bash theme={null}
curl 'https://api.banking.v2.portao3.com.br/realms/{realmId}/organizations/{organizationId}/accounts/{accountId}/wallets/{walletId}/cards/{cardId}/card-limit' \
  -H 'Authorization: Bearer <accessToken>' \
  -H 'x-environment: LIVE'
```

```json theme={null}
[
  {
    "_id": "68910e1ff339631b6222d9b6",
    "name": "Teste",
    "amount": 500,
    "status": "ACTIVE",
    "availableAmount": 500,
    "pendingAmount": 0
  }
]
```

Reference: [`GET .../cards/{cardId}/card-limit`](/api-reference/banking/cards/realms-organizations-accounts-wallets-cards-card-limit)

## Remove a limit

Delete a limit by its `cardLimitId` to stop further authorizations against it (for example, to close out a reusable card).

```bash theme={null}
curl -X DELETE \
  'https://api.banking.v2.portao3.com.br/realms/{realmId}/organizations/{organizationId}/accounts/{accountId}/card-limit/{cardLimitId}' \
  -H 'Authorization: Bearer <accessToken>' \
  -H 'x-environment: LIVE'
```

A `204` confirms removal.

Reference: [`DELETE .../card-limit/{cardLimitId}`](/api-reference/banking/cards/realms-organizations-accounts-card-limit-2)

## Define a rule

A rule is a `description` plus a `rules` array of conditions. Each condition tests one transaction `property` against a `comparative` value using an `operator`. **All** conditions must match for the rule to allow a transaction. The response returns a `ruleId` (under `external.ruleId` and as the document `_id`) you reference from a card limit.

This single-condition rule allows everything except merchant category `3001`:

```bash theme={null}
curl -X POST \
  'https://api.banking.v2.portao3.com.br/realms/{realmId}/organizations/{organizationId}/accounts/{accountId}/card-limit-rule' \
  -H 'Authorization: Bearer <accessToken>' \
  -H 'x-environment: LIVE' \
  -H 'Content-Type: application/json' \
  -d '{
    "description": "BLOCK_MCC_3001",
    "rules": [
      { "property": "mcc", "operator": "NOT_EQUAL", "comparative": "3001" }
    ]
  }'
```

### Transaction properties

A condition can test any of these properties:

| Property               | What it tests                         |
| ---------------------- | ------------------------------------- |
| `mcc`                  | Merchant category code.               |
| `merchantId`           | Merchant identifier.                  |
| `merchantName`         | Merchant name.                        |
| `merchantCity`         | Merchant city.                        |
| `merchantCountry`      | Merchant country.                     |
| `acquiringCountryCode` | Acquirer country.                     |
| `billingAmount`        | Billed amount, in centavos.           |
| `txnCurrency`          | Transaction currency.                 |
| `msgType`              | Message type of the authorization.    |
| `txnType`              | Transaction type.                     |
| `effectiveAtHour`      | Hour of day the transaction occurred. |
| `effectiveAtWeekday`   | Weekday the transaction occurred.     |

### Operators

| Operator                                 | Meaning                  | `comparative` format     |
| ---------------------------------------- | ------------------------ | ------------------------ |
| `EQUALS` / `NOT_EQUAL`                   | Equal to / not equal to  | a single value           |
| `GREATER_THAN` / `GREATER_THAN_OR_EQUAL` | Greater than (or equal)  | a single number          |
| `LESS_THAN` / `LESS_THAN_OR_EQUAL`       | Less than (or equal)     | a single number          |
| `BETWEEN` / `NOT_BETWEEN`                | Inside / outside a range | two values, `"min, max"` |
| `IN` / `NOT_IN`                          | In / not in a list       | comma-separated list     |
| `CONTAINS` / `NOT_CONTAINS`              | Substring match          | a single value           |
| `MATCHES` / `NOT_MATCHES`                | Regular-expression match | a regex                  |

<Note>
  Each test exposes both the positive and the negated form (`EQUALS` / `NOT_EQUAL`, `IN` / `NOT_IN`, …), so you don't need a separate "negate" flag — pick the operator that expresses your intent.
</Note>

### A multi-condition rule

Because conditions are combined with `AND`, this rule allows only grocery-store purchases (MCC `5411`) under R\$ 500,00:

```json theme={null}
{
  "description": "GROCERY_UNDER_500",
  "rules": [
    { "property": "mcc", "operator": "EQUALS", "comparative": "5411" },
    { "property": "billingAmount", "operator": "LESS_THAN", "comparative": "50000" }
  ]
}
```

To express "grocery **or** pharmacy", use the `IN` operator on a single condition (`"comparative": "5411, 5912"`), or create two separate rules and reference both `ruleId`s from one limit (rules in a limit are `OR`).

<Warning>
  When `property` is `mcc` with `EQUALS`/`NOT_EQUAL`, `comparative` must be a valid merchant category code. When `property` is `merchantCountry` or `acquiringCountryCode` with `EQUALS`/`NOT_EQUAL`, `comparative` must be a valid ISO country code. Invalid values are rejected.
</Warning>

Update a rule later with the PUT endpoint, referencing its `cardLimitRuleId`.

Reference: [`POST .../card-limit-rule`](/api-reference/banking/cards/realms-organizations-accounts-card-limit-rule-1) · [`PUT .../card-limit-rule/{cardLimitRuleId}`](/api-reference/banking/cards/realms-organizations-accounts-card-limit-rule-3)

## Next steps

<CardGroup cols={2}>
  <Card title="Issue virtual cards" icon="credit-card" href="/guides/issue-virtual-cards">
    Create a card and read its PAN and CVV.
  </Card>

  <Card title="Manage and monitor cards" icon="list" href="/guides/manage-cards">
    Block, unblock, and read the transaction history for a card.
  </Card>
</CardGroup>
