# Issuing for agents

Learn how to issue cards for agents.

Issuing for agents lets you issue virtual cards that agents can use to make purchases autonomously, with spend controls, real-time authorisation decisioning and full transaction visibility. Before your agent makes a purchase, you can decide what it can spend, where and how much. Cards are backed by financial accounts and issued using Stripe Issuing APIs.

## Issuing for agents products

You can use Issuing for agents with the following Issuing products:

| Product | Description | Request access |
| --- | --- | --- |
| Cards for your own business | Use Issuing to give each agent its own virtual card with per-agent spend limits, merchant category controls and custom authorisation rules. Common use cases include buying inventory to resell, covering operational expenses and making purchases to fulfil a service. | [Apply in the Stripe Dashboard](https://dashboard.stripe.com/issuing/overview) |
| Cards for your platform | If you’re a platform, such as a fintech, vertical SaaS or marketplace, you can use Issuing to let agents spend on behalf of the businesses or consumers on your platform. Issue commercial cards for business customers managing expenses or consumer cards for individuals making personal purchases. Your cardholders configure their own spend limits, merchant category restrictions and authorisation rules. You retain transaction-level visibility across all cards that your platform issues. | [Contact Stripe](https://stripe.com/contact/embedded-finance) |

## Issuing for agents capabilities

| Capability | Description |
| --- | --- |
| [Single-use cards](https://docs.stripe.com/issuing/controls/lifecycle-controls.md) | Issue virtual cards scoped to a single task or session. Cards are automatically invalidated after use. |
| [Real-time authorisations](https://docs.stripe.com/issuing/controls/real-time-authorizations.md) | Approve or decline every transaction using webhooks. Make authorisation decisions based on a business’s details and the card’s metadata. You own the authorisation integration. |
| [Spend controls](https://docs.stripe.com/issuing/controls/spending-controls.md#limit-a-cardholders-monthly-spend-across-all-of-their-cards) | Set limits on how much and how often consumers can spend and which merchant categories are allowed. You can set controls at the card or cardholder level. |
| [Full transaction visibility](https://docs.stripe.com/issuing/purchases/transactions.md) | Track every transaction including captures, refunds, partial captures, over-captures and force captures, and reconcile them back to the originating card and purchase using metadata. |
| [Advanced fraud signals](https://docs.stripe.com/issuing/controls/radar.md#get-started-with-radar) | Get machine learning-generated risk scores on every authorisation, including fraud risk, merchant dispute risk and card testing detections. Opt in within the Stripe Dashboard. |

## Pay in agentic payment flows

Agents can pay with Issuing through these supported paths:

- **Browser checkout**: [Retrieve the virtual card’s credentials](https://docs.stripe.com/issuing/cards/virtual.md#retrieve-virtual-card-details) and use the card directly. For one-off purchases, use [Issuing lifecycle controls](https://docs.stripe.com/issuing/controls/lifecycle-controls.md) to create a single-use card.
- **Stripe-backed programmatic payments**: For flows such as [MPP](https://docs.stripe.com/payments/machine/mpp.md) or [UCP](https://docs.stripe.com/agentic-commerce/ucp/stripe-payments-handler.md), see [Pay with Issuing in agentic payment flows](https://docs.stripe.com/issuing/agents/programmatic-checkout.md). That guide walks through funding the purchase with an Issuing card and issuing a scoped [Shared Payment Token (SPT)](https://docs.stripe.com/agentic-commerce/concepts/shared-payment-tokens.md) for the seller.

The sections below apply throughout any agent payment, including programmatic flows.

## Spend controls 

Before an agent ever makes a purchase, you can define what it’s allowed to spend, where and how often. These controls are set at card creation and can be updated at any time. You can tighten them when a task changes scope, loosen them when more budget is approved or remove them for trusted agents with broad mandates.

Merchant category controls restrict the card to specific types of businesses. For example, a travel booking agent should only be able to charge airlines and hotels, and not restaurants or retail stores:

```curl
curl https://api.stripe.com/v1/issuing/cards \
 -u "{{SECRET_KEY}}:" \
 -d "cardholder"="ich_123" \
 -d "currency"="usd" \
 -d "type"="virtual" \
 -d "status"="active" \
 -d "spending_controls[allowed_categories][]"="airlines_air_carriers" \
 -d "spending_controls[allowed_categories][]"="hotels_motels_and_resorts"
```

Spend limits set how much the card can be charged, either per transaction or over a rolling period:

```curl
curl https://api.stripe.com/v1/issuing/cards/ic_123 \
 -u "{{SECRET_KEY}}:" \
 -d "spending_controls[spending_limits][0][amount]"=100000 \
 -d "spending_controls[spending_limits][0][interval]"="monthly" \
 -d "spending_controls[spending_limits][1][amount]"=10000 \
 -d "spending_controls[spending_limits][1][interval]"="per_authorization"
```

## Real-time authorization 

After you pass a card to an agent, every purchase attempt triggers a real-time authorisation request before the charge goes through. This lets you approve or decline the transaction based on your spending rules, fraud signals, merchant category restrictions or context about what the agent is told to do.

First, listen for `issuing_authorization.request` events. Each event contains the business, amount and any metadata you attached to the card when you issued it. There is a 2 second default timeout to respond before Stripe falls back to the card’s default rules:

```json
{
 "type": "issuing_authorization.request",
 "data": {
   "object": {
     "id": "iauth_123",
     "amount": 9900,
     "merchant_data": {
       "name": "Acme Supplies",
       "category_code": "5045",
       "city": "San Francisco",
       "country": "US"
     },
     "card": {
       "metadata": {
         "agent_id": "agent_fulfillment_01",
         "customer_order_id": "order_8821",
         "allowed_merchant": "supplier_acme"
       }
     }
   }
 }
}
```

Next, use the authorisation payload to run any checks your business requires before approving. Common patterns include:

- **Business match**: Verify the business name or category matches the agent’s task
- **Amount confirmation**: Confirm the charge is within the expected budget for the order or task
- **Velocity check**: Flag if the agent has attempted an unusual number of transactions in a short window
- **Fraud signals**: Cross-reference the business’s country, IP or category against known fraud patterns

If the transaction looks legitimate, approve it. If anything looks off, decline it and flag with the agent or a human reviewer.

You can use Stripe advanced fraud tools in your decision making process. Stripe evaluates every authorisation for fraud signals and produces a risk score you can factor into your approval logic:

```json
{
 "type": "issuing_authorization.request",
 "data": {
   "object": {
     "id": "iauth_123",
     "amount": 9900,
     "fraud_challenges": [],
     "network_risk_score": 23,
     "merchant_data": {
       "name": "Acme Supplies",
       "category_code": "5045"
     },
     "verification_data": {
       "address_line1_check": "match",
       "postal_code_check": "match",
       "cvc_check": "match"
     }
   }
 }
}
```

A low risk score alongside passing address and CVC checks is a signal to approve. A high risk score, especially combined with a mismatched address or an unfamiliar business country, is a signal to decline and investigate before letting the agent proceed.

## Monitor the agent’s transactions

Every transaction your agent makes is traceable. Use Stripe webhooks and transaction data to track spend, catch anomalies, reconcile purchases and dispute overcharges automatically, without manual oversight.

### Detect unusual spending

Agents can continuously scan transaction history to detect unusual purchases, such as charges from unfamiliar businesses, transactions that exceed typical amounts or activity outside expected hours. When an agent detects a suspicious transaction, it can automatically freeze the card or flag it for review.

First, pull recent transactions for a cardholder to give your agent a window of activity to review:

```curl
curl -G https://api.stripe.com/v1/issuing/transactions \
 -u "{{SECRET_KEY}}:" \
 -d "cardholder"="ich_123" \
 -d "limit"=100
```

Next, pass the transaction list to your agent. Flag any transaction where the merchant category falls outside what’s expected, or where the amount is significantly higher than the cardholder’s historical average:

```json
{
 "transactions": [
   {
     "amount": 42000,
     "merchant_data": { "category_code": "5999", "name": "Unknown Merchant" },
     "card": {
       "metadata": { "agent_id": "agent_finance_01", "cost_center": "engineering" }
     }
   }
 ]
}
```

If the agent flags a transaction, freeze the card immediately while the issue is investigated:

```curl
curl https://api.stripe.com/v1/issuing/cards/ic_123 \
 -u "{{SECRET_KEY}}:" \
 -d "status"="inactive"
```

### Track spending against budgets

Every card can carry a spend limit, a monthly maximum, a per-transaction maximum, or both. Agents can monitor how much of that budget has been used in real time and take action before a limit is reached by alerting the cardholder, requesting a budget increase or blocking new purchases until the next period resets.

First, subscribe to `issuing_authorization.created` to capture each purchase as it’s approved:

```json
{
 "type": "issuing_authorization.created",
 "data": {
   "object": {
     "amount": 15000,
     "card": {
       "spending_controls": {
         "spending_limits": [{ "amount": 50000, "interval": "monthly" }]
       },
       "metadata": { "agent_id": "agent_finance_01" }
     }
   }
 }
}
```

As authorisations come in, add them up against the card’s monthly limit. When spend crosses a threshold (for example, 80%), notify the cardholder or adjust the limit:

```curl
curl https://api.stripe.com/v1/issuing/cards/ic_123 \
 -u "{{SECRET_KEY}}:" \
 -d "spending_controls[spending_limits][0][amount]"=40000 \
 -d "spending_controls[spending_limits][0][interval]"="monthly"
```

### Reconcile purchases automatically

After a purchase settles, usually within 1-2 days of the original authorisation, Stripe creates a transaction record with the final amount and business details. Agents can use this to automatically match charges to the tasks or orders that triggered them, flag discrepancies where the settled amount differs from what was authorised and keep your books up to date without manual intervention.

First, subscribe to `issuing_transaction.created` to receive a notification each time a charge fully settles:

```json
{
 "type": "issuing_transaction.created",
 "data": {
   "object": {
     "amount": 7500,
     "merchant_data": { "name": "Logistics Co", "category_code": "4215" },
     "card": {
       "metadata": {
         "customer_order_id": "order_8821",
         "agent_id": "agent_fulfillment_01"
       }
     }
   }
 }
}
```

Use the metadata on the transaction to match it back to the originating order or task in your system. If the settled amount differs from what was originally authorised, flag it for review:

```curl
curl https://api.stripe.com/v1/issuing/transactions \
 -u "{{SECRET_KEY}}:" \
 -d "cardholder"="ich_123" \
 -d "created[gte]"=1672531200
```

### Catch and dispute overcharges

When a card is used, Stripe first creates an authorisation for the expected amount. When the charge fully settles, Stripe creates a transaction and the two amounts don’t always match. A restaurant might add a tip, a supplier might ship a partial order but charge in full or a business might process the wrong amount. Agents can automatically compare what was authorised against what was charged and file a dispute on your behalf if there is a mismatch.

When a transaction settles, retrieve the original authorisation to compare amounts:

```curl
curl https://api.stripe.com/v1/issuing/authorizations/iauth_123 \
 -u "{{SECRET_KEY}}:"
```

Your agent compares the authorised amount against the settled transaction amount. If the difference exceeds a threshold you define, it flags the transaction and initiates a dispute:

```json
{
 "authorization_amount": 7500,
 "transaction_amount": 9200,
 "delta": 1700,
 "card": {
   "metadata": {
     "customer_order_id": "order_8821",
     "agent_id": "agent_fulfillment_01"
   }
 }
}
```

You can also file a dispute directly against the transaction:

```curl
curl https://api.stripe.com/v1/issuing/disputes \
 -u "{{SECRET_KEY}}:" \
 -d "transaction"="ipi_123" \
 -d "evidence[reason]"="canceled" \
 -d "evidence[incorrect_amount][dispute_amount]"=7500 \
 -d "evidence[incorrect_amount][original_transaction]"="ipi_123"
```

Next, subscribe to `issuing_dispute.updated` to track the status of open disputes and notify the cardholder when a dispute is resolved and funds are recovered:

```json
{
 "type": "issuing_dispute.updated",
 "data": {
   "object": {
     "status": "won",
     "amount": 1700,
     "transaction": "ipi_123"
   }
 }
}
```

## See also

- [Pay with Issuing in agentic payment flows](https://docs.stripe.com/issuing/agents/programmatic-checkout.md)
- [Issuing for your business](https://docs.stripe.com/issuing/for-your-business.md)
- [Issuing for your platform](https://docs.stripe.com/issuing.md)
- [Agentic spending for personal expenses](http://link.com/agents)
