A cardholder on a custom-limits program can tighten their own card. This page walks through one change end to end with Get this card’s policy and Update this card’s policy, then lists the rules the write enforces.
Only on accounts whose cards.limits.mode is custom in program capabilities. On a preset account, use Update card limit group instead.

Example: block gambling and cap ATM withdrawals

1. Read the policy

Three things to take from it:
  • version is 3. It goes in the request body.
  • mcc.mode is ALLOW_ALL_EXCEPT_BLOCKED, so to block gambling you add its code to block and leave allow empty.
  • limits.ceiling.atm says the program allows £200 per withdrawal and £500 a day. You can go lower, not higher. Bound the form by ceiling, not effective: once the card has limits of its own, effective shows those, while ceiling still shows how far they may be raised. 0 in ceiling means no ceiling. Amounts are in minor units (pence, cents).
  • If inertPaths lists a limits.card field, that value is saved but not in force: show it as inactive. Annual limits are always listed, because they are never enforced. If an update returns 400 naming a limit field, that value is above a limit on its own channel and has to be lowered before the save goes through.

2. Send the change

Only the two areas being changed are sent. pos is all zeros, which means “no setting of my own”, so the program’s POS limits keep applying. country and inputOptions are left out and stay as they were.

3. Use the response

The response is the full policy again with version 4, mcc.card and limits.card filled in, and effective recomputed: blocked now includes 7995 and atm.daily is 20000. Render from it directly. No need to call the GET again.

The four areas

Options a cardholder may choose from returns the full code lists with labels.

Rules

Look at the area’s mode in the GET.
  • ALLOW_ALL_EXCEPT_BLOCKED: everything is permitted unless listed. Put codes in block, keep allow empty. This is the usual case.
  • ALLOW_ONLY_SPECIFIED: nothing is permitted unless listed. Put codes in allow, keep block empty.
Filling the other list is a 400. Both keys must always be present.
Whatever you send for card becomes the cardholder’s complete setting. To add a second blocked merchant category, send both codes. To remove one, send the list without it. "card": null removes the cardholder’s setting entirely.
Compare against effective. You can block more categories or countries, allow fewer, or set a lower amount. Never the reverse. Anything the program has blocked stays blocked whatever you send; it shows in effective but not in card, and the app can’t remove it.Trying to loosen is a 400 CARD_POLICY_VALIDATION_FAILED whose message names the field, for example limits.card.atm.daily: 300000 exceeds program's 250000.
0 means “no limit of my own at this window”, so the program’s value applies. The whole card object is replaced on each write, so atm and pos and all their fields (five amounts plus four counts) are required every time, zeros included.single is per transaction. daily, weekly, and monthly are rolling totals. annual is accepted but not enforced. count caps the number of transactions per window.If limits.mode is COMBINED, ATM and POS share one daily, weekly, and monthly budget, and the tighter of the two values applies to both.
version is the number the GET returned. If someone else changed the policy in between, the write is refused with 409 CARD_POLICY_VERSION_CONFLICT. GET again and re-apply the change on the fresh version. This stops two screens silently overwriting each other.
The program has switched that area off. A write is accepted but changes nothing. Hide the control rather than show a disabled one.
Changes reach card authorizations within about a minute.