Skip to main content

Card Controls

Card controls let you enforce spending policy at authorization time — before a transaction is approved. Your agents operate autonomously within the boundaries you define.

Spending limits

Set per-transaction, daily, and monthly caps in cents. When a transaction would exceed any cap, it is declined immediately.
ControlExample valueBehavior
Per-transaction limit$500 (50000 cents)Declines any single charge above the threshold
Daily limit$2,000 (200000 cents)Declines once same-day spend reaches the cap
Monthly limit$12,000 (1200000 cents)Prevents budget drift over long-running agent tasks

MCC restrictions

Merchant Category Codes (MCCs) identify the type of business a merchant operates. You can restrict a card to an allow-list of approved categories, or block specific high-risk categories outright.
ModeMCC codesUse case
Allow-list5045, 5734, 5817Approve only software and SaaS purchases
Block-list7995, 4829Block gambling and wire transfers regardless of spend headroom
Common MCC codes:
  • 5045 — Computers and peripherals
  • 5734 — Computer software stores
  • 5817 — Computer game stores
  • 5411 — Grocery stores
  • 7995 — Gambling
  • 4829 — Wire transfers

Velocity controls

Velocity rules constrain how many transactions a card can make within a time window. This prevents bursty spend patterns where each individual charge is within the per-transaction limit but aggregate activity crosses policy boundaries. Example: allow a maximum of 5 transactions per 10 minutes and 40 transactions per day.

Pre-approval pattern

When preApproval.enabled is true, Anima calls your pre-approval endpoint synchronously during the Stripe authorization window before approving the transaction.
Stripe Issuing gives approximately 2 seconds to respond. Your pre-approval logic must complete within that window. Keep checks synchronous and deterministic — move analytics or enrichment to async workers that run after the decision.

Apply controls

Call POST /api/identities/:id/cards/:cardId/controls to set or update all controls for a card.
await fetch(`/api/identities/${identityId}/cards/${cardId}/controls`, {
  method: "POST",
  headers: { "content-type": "application/json" },
  body: JSON.stringify({
    spending: {
      perTransactionCents: 50000,
      dailyCents: 200000,
      monthlyCents: 1200000,
    },
    mcc: {
      mode: "allow",
      values: ["5045", "5734", "5817"],
    },
    velocity: {
      maxTransactionsPer10Min: 5,
      maxTransactionsPerDay: 40,
    },
    preApproval: {
      enabled: true,
      timeoutMs: 1500,
    },
  }),
});

Request body

spending.perTransactionCents
number
Maximum single-transaction amount in cents.
spending.dailyCents
number
Maximum total spend per calendar day in cents.
spending.monthlyCents
number
Maximum total spend per calendar month in cents.
mcc.mode
string
Either "allow" (only listed MCCs pass) or "block" (listed MCCs are declined).
mcc.values
string[]
Array of four-digit MCC codes to apply the mode to.
velocity.maxTransactionsPer10Min
number
Maximum number of authorizations allowed in any rolling 10-minute window.
velocity.maxTransactionsPerDay
number
Maximum number of authorizations allowed per calendar day.
preApproval.enabled
boolean
When true, each authorization is held for your pre-approval endpoint before being approved or declined.
preApproval.timeoutMs
number
Milliseconds to wait for your pre-approval response. Must be under 2000. Defaults to 1500.

Best practices

Start with strict defaults — low limits, a narrow MCC allow-list, tight velocity rules — and loosen them deliberately as you gain confidence in each card program. It is much easier to expand permissions after the fact than to recover from unexpected spend.
Store a snapshot of the active controls alongside each authorization event. This makes post-incident review straightforward: you can immediately see which rule triggered a decline without reconstructing historical state.