---
title: "Issue an agent card"
method: POST
path: "/agents/me/cards"
tags: ["Agent Operations"]
---

# Issue an agent card

`POST /agents/me/cards`

## Request

- Base URL: `https://api.lightspark.com/grid/2025-10-13`
- URL: `https://api.lightspark.com/grid/2025-10-13/agents/me/cards`
- Auth: HTTP bearer

Issue a virtual card for the authenticated agent. The card belongs to the agent's customer, who must have KYC status `APPROVED` and have accepted the cardholder agreement where the platform requires one. Its spend counts against the agent's policy limits as the agent's sends do, and Grid's default agent merchant-category blocks apply. Requires the ISSUE_CARDS permission; reading the card afterwards needs MANAGE_CARDS.

**Standard card** (`kind` omitted or `STANDARD`): as `POST /cards` with `agentId` does for the platform. While any of the agent's standard cards is not `CLOSED`, including one the platform issued for it, the request is rejected with `AGENT_CARD_EXISTS`. New cards start in `status: "PROCESSING"` and follow the same status transitions and `card.status_change` webhooks as cards issued with `POST /cards`.

**Purchase card** (`kind: PURCHASE`): a single-use card for one online purchase of `amount`, paid from the customer's Embedded Wallet with the agent's delegated key. Available only where the platform enables agent purchase cards. Its limit (`purchase.spendLimit`) is `amount` plus an allowance for tax and shipping, and that limit is evaluated against the agent's policy as a send of the same amount would be:
- Under the policy's approval threshold, and with `defaultExecutionMode`
  `AUTO`, the card is issued at once and returned with `201`.

- Otherwise the request becomes an `ISSUE_PURCHASE_CARD` agent action in
  `PENDING_APPROVAL`, returned with `202`, and the
  `AGENT_ACTION.PENDING_APPROVAL` webhook fires. The card is issued when
  the action is approved with `POST /agents/{agentId}/actions/{actionId}/approve`;
  the action then carries `cardId`. Poll `GET /agents/me/actions/{actionId}`
  for the outcome.

- A request the policy denies outright (over a spending limit, or a
  funding account the policy does not allow) is rejected with `403`.

The card is closed by its first approved authorization, and Grid closes it if it is still unused at `purchase.expiresAt`. Purchase cards are not counted by the one-standard-card rule, but an agent may hold only a limited number of open purchase cards, counting those awaiting approval; beyond that the request is rejected with `PURCHASE_CARD_LIMIT_REACHED`.

**Recurring purchase card** (`kind: PURCHASE`, `recurring: true`): for a subscription, a card saved with a merchant, a hotel or car rental, or an order that ships in parts. Available only where the platform enables recurring purchase cards. The card locks to the first merchant that charges it and declines every other merchant; that merchant may charge it again, up to `amount` in any trailing month (from a charge back to the same date a month earlier), with no allowance added. It always becomes an `ISSUE_PURCHASE_CARD` action awaiting the customer's approval and is returned with `202`, whatever the policy's approval threshold or execution mode, though a request the policy denies is still rejected with `403`. Its charges count against the agent's policy limits as they are authorized. It has no `purchase.expiresAt` and stays open until the customer or platform closes it (`PATCH /cards/{id}` with `status: CLOSED`, a `substatus` and a `reason`). Pausing the agent does not close it, but its charges are declined while the agent is paused; deleting the agent freezes it, and `POST /agents/{agentId}/card-handover` with `kind=PURCHASE` can move it to the customer's next agent. Recurring cards have their own, smaller limit on open cards, counting those awaiting approval, and do not use up the room for single-use cards. Card details are never returned here; request them with `POST /agents/me/cards/{cardId}/reveal`.

Card issuance cannot be reversed, so an `Idempotency-Key` header is required. Keys are scoped to the agent: a retry by the same agent with the same key returns what the first request created, whatever has changed since, and another agent's key never matches. For a purchase card, a retry returns the issued card with `201`, or the action with `202` while it is pending, rejected or failed.

## Headers

- `Idempotency-Key` string, required

## Request body

- AgentCardCreateRequest: Request body for `POST /agents/me/cards`. Without `kind`, or with `kind: STANDARD`, it issues the agent's standard card. With `kind: PURCHASE` it requests a single-use purchase card for one online purchase of `amount`, or with `recurring: true` a recurring purchase card that may spend up to `amount` a month at one merchant.
  - `fundingSource` string, required: Internal account id that funds the card. The account must belong to the agent's customer and be denominated in a card-eligible currency; otherwise the request is rejected with `INVALID_INPUT`. A `PURCHASE` card must be funded from an Embedded Wallet on which the agent holds an active delegated key.
  - `kind` 'STANDARD' | 'PURCHASE': How an agent card is used and funded. | Kind | Description | |------|-------------| | `STANDARD` | A card issued for the agent, by the platform with `POST /cards` or by the agent with `POST /agents/me/cards`. The customer holds the card details and its spend comes from the customer's account; that spend counts against the agent's policy limits as the agent's sends do. The agent can read the card, tighten its merchant categories, and freeze it. | | `PURCHASE` | A single-use virtual card the agent issued for one online purchase with `POST /agents/me/cards`. It is funded from the customer's Embedded Wallet, its spend counts against the agent's policy limits, and it closes after its first approved authorization or when it expires unused. A recurring purchase card (`purchase.recurring`) is instead locked to the first merchant that charges it, may be charged there again up to its monthly limit, and stays open until it is closed. The agent reads its number, expiry and CVV through `POST /agents/me/cards/{cardId}/reveal`. |
  - `amount` integer: The purchase amount in the smallest unit of USD. Required for `kind: PURCHASE` and rejected otherwise. Grid adds an allowance for tax and shipping to set the card's limit; see `AgentPurchaseCardDetails`. For a recurring card it is the monthly limit itself, with no allowance added, so include tax and shipping in it. Each platform sets the largest amount an agent may ask for, separately for single-use and recurring cards; a larger one is rejected with `INVALID_INPUT`.
  - `description` string: What the card is for, such as the merchant and item, shown to the customer when they approve it. Allowed only with `kind: PURCHASE`.
  - `recurring` boolean: Request a recurring purchase card: one that locks to the first merchant that charges it and may be charged there again, up to `amount` in any trailing month (from a charge back to the same date a month earlier), until it is closed. Use it for a subscription, a card saved with a merchant, a hotel or car rental, or an order that ships in parts. It always needs the customer's approval, whatever the agent's policy says, and is available only where the platform enables recurring purchase cards. `true` is allowed only with `kind: PURCHASE`; `false` is accepted with any kind.

## Response `201`

Card created. A standard card starts in `PROCESSING` while the issuer provisions it. A purchase card is returned with `purchase` set.

- AgentCard: A card that belongs to the authenticated agent: the card itself and how the agent may use it.
  - `card` Card, required
    - `id` string, required: System-generated unique card identifier
    - `customerId` string, required: The id of the `Customer` who holds this card.
    - `platformCardId` string: Platform-specific card identifier generated by the server.
    - `status` 'PENDING_KYC' | 'PROCESSING' | 'PENDING_AUTH' | 'ACTIVE' | 'FROZEN' | 'CLOSED', required: Lifecycle status of a card. | Status | Description | |-------|-------------| | `PENDING_KYC` | The cardholder has not yet completed KYC. Cards in this status cannot transact. | | `PROCESSING` | The card has been requested and is being provisioned with the issuer. | | `PENDING_AUTH` | The issuer has provisioned the card, but its USDB Embedded Wallet funding source lacks an active delegated signing key. Complete `POST /auth/delegated-keys` before using the card. | | `ACTIVE` | The card is live and can authorize transactions. | | `FROZEN` | The card is temporarily disabled by the platform or by Grid. New authorizations are declined with `cardDeclinedReason: CARD_NOT_ACTIVE`. Existing settlements and refunds continue to reconcile. A card Grid froze for review, or one frozen as `COMPROMISED`, cannot be unfrozen by the platform. | | `CLOSED` | The card is permanently closed. Terminal, irreversible status. |
    - `statusReason` 'DELEGATION_REQUIRED' | 'ISSUER_REJECTED' | 'CLOSED_BY_PLATFORM' | 'CLOSED_BY_GRID': Reason a card reached a terminal or non-active status. Present on `PENDING_AUTH` and `CLOSED` cards, and on cards that fail provisioning before reaching `ACTIVE`. | Reason | Description | |--------|-------------| | `DELEGATION_REQUIRED` | The card funding source has no usable delegated signing key. Present while the card is `PENDING_AUTH`. | | `ISSUER_REJECTED` | The card issuer rejected provisioning during `PROCESSING`. | | `CLOSED_BY_PLATFORM` | The card was closed via `PATCH /cards/{id}` (`status: CLOSED`) by the platform. | | `CLOSED_BY_GRID` | The card was closed by Grid (e.g. compliance or risk action). |
    - `brand` 'VISA' | 'MASTERCARD': Card network brand. Read-only — determined by Grid when the card is provisioned with the issuer.
    - `form` 'VIRTUAL', required: Physical form factor of the card. Only `VIRTUAL` is supported in v1; `PHYSICAL` will be added in a later release.
    - `pinStatus` 'NOT_SET' | 'OK' | 'BLOCKED': State of the card's PIN. On the Card resource, this is the last known status and is present whenever PIN management is supported. An absent value means PIN management is unavailable for this card; it does not mean `NOT_SET`. Use `GET /cards/{id}` to retrieve `pinStatus`. | Status | Description | |--------|-------------| | `NOT_SET` | No PIN has been set on the card. PIN verification is not enabled. Set one with `POST /cards/{id}/set-pin` or the hosted form returned by `GET /cards/{id}/pin-entry-url`. | | `OK` | A PIN is set and usable. | | `BLOCKED` | The PIN was entered incorrectly three consecutive times and is refused until cleared with `POST /cards/{id}/pin/unblock`, or replaced with `POST /cards/{id}/set-pin`. |
    - `pinUnblockAvailableAt` string, date-time: Earliest time another PIN unblock attempt is allowed. Absent until the unblock allowance is used. Changing the PIN does not reset this time.
    - `last4` string: Last four digits of the card PAN.
    - `expMonth` integer: Card expiration month (1–12).
    - `expYear` integer: Card expiration year (four digits).
    - `fundingSource` string, required: Internal account id that funds this card.
    - `cardCapabilities` CardCapabilities: Actions supported by the card program associated with this resource.
      - `supportsVelocityLimits` boolean, required: Whether this card program supports platform-managed limits through `/card-velocity-limits`. Supported where Grid makes authorization decisions; false where the issuer makes them. Amounts use the card's currency, regardless of its funding source.
      - `supports3dSecurePassword` boolean, required: Whether cards in this program accept a caller-supplied `threeDSecurePassword`.
      - `supportsPanReveal` boolean, required: Whether cards in this program can be revealed through `POST /cards/{id}/reveal`.
      - `supportsDigitalWalletTokenization` boolean, required: Whether cards in this program can be added to Apple Pay, Google Pay, or Samsung Pay from your app through `POST /cards/{id}/tokenize`. Manual entry into a wallet works regardless of this flag.
    - `maxNetworkRiskScore` integer, nullable: Maximum normalized network risk score allowed for real-time card authorizations. Scores range from 0 (lowest risk) to 999 (highest risk). Visa scores are normalized by multiplying the raw 0–99 score by 10. Scores equal to the ceiling are allowed. Authorizations without a score are also allowed. The lowest configured card or platform ceiling applies. Null means no card-specific ceiling. Platform controls still apply.
    - `allowedMccs` string[]: Merchant category codes the card may spend at. Present only on a card issued for an agent; absent when that card may spend at any category not blocked.
    - `blockedMccs` string[]: Merchant category codes a card issued for an agent declines, with `cardDeclinedReason: BLOCKED`. Present only on such a card, which also declines Grid's default agent categories unless `defaultMccBlocksLifted` is true.
    - `agentId` string: The agent the card was issued for, when there is one.
    - `defaultMccBlocksLifted` boolean: Whether the platform lifted Grid's default agent merchant-category blocks on this card. Present only for a card issued for an agent.
    - `currency` string: Currency the card transacts in, fixed at issuance by its card program. USDB-funded cards transact in USD, with funding converted at 1 USDB = 1 USD. Spending limits use the smallest unit of the card's currency (USD cents for USDB-funded cards). Changing the funding source does not change the card's currency or spending-limit units.
    - `processorRef` string: Opaque processor-side reference for the card (e.g. the Lithic card token). Useful for cross-referencing in the processor's dashboards; not used for any Grid request routing.
    - `issuerRef` string: Opaque identifier for the card on the issuer of record (e.g. the Lead Bank account/card identifier). Useful for cross-referencing in issuer dashboards; not used for any Grid request routing.
    - `createdAt` string, date-time, required: Creation timestamp
    - `updatedAt` string, date-time, required: Last update timestamp
  - `agentId` string, required: The agent the card belongs to.
  - `agentCardKind` 'STANDARD' | 'PURCHASE', required: How an agent card is used and funded. | Kind | Description | |------|-------------| | `STANDARD` | A card issued for the agent, by the platform with `POST /cards` or by the agent with `POST /agents/me/cards`. The customer holds the card details and its spend comes from the customer's account; that spend counts against the agent's policy limits as the agent's sends do. The agent can read the card, tighten its merchant categories, and freeze it. | | `PURCHASE` | A single-use virtual card the agent issued for one online purchase with `POST /agents/me/cards`. It is funded from the customer's Embedded Wallet, its spend counts against the agent's policy limits, and it closes after its first approved authorization or when it expires unused. A recurring purchase card (`purchase.recurring`) is instead locked to the first merchant that charges it, may be charged there again up to its monthly limit, and stays open until it is closed. The agent reads its number, expiry and CVV through `POST /agents/me/cards/{cardId}/reveal`. |
  - `effectiveBlockedMccs` string[], required: Every merchant category code the card declines: `blockedMccs` plus the categories Grid blocks for agent cards, unless the platform lifted those defaults (`defaultMccBlocksLifted`).
  - `purchase` AgentPurchaseCardDetails: The purchase a `PURCHASE` card was requested for. The card's issuer-enforced limit is `spendLimit`: the purchase amount plus an allowance for tax and shipping, or for a recurring card the amount itself, over any trailing month.
    - `amount` integer, required: The purchase amount the agent asked for, in the smallest unit of `currency`.
    - `spendLimit` integer, required: The most the card can be charged in its one purchase, in the smallest unit of `currency`: `amount` plus an allowance for tax and shipping of 15% of `amount`, at most 1000 (USD 10.00). For a recurring card it is `amount`, and it caps what the card can be charged in any trailing month: from a charge back to the same date a month earlier. The card issuer declines a charge above it, and it is the amount checked against the agent's policy when the card is requested.
    - `currency` string, required: ISO 4217 code of the purchase currency. Known values: `USD`. Treat an unrecognized value as a currency you cannot display rather than an error.
    - `description` string: What the agent said the card is for, such as the merchant and item. Shown to the customer when they approve the card. Supplied by the agent and not verified by Grid.
    - `fundingSource` string, required: The customer's Embedded Wallet internal account that pays for the purchase.
    - `recurring` boolean: Whether the card is a recurring purchase card: locked to the first merchant that charges it and reusable there, up to `spendLimit` each trailing month, until it is closed. Absent or `false` for a single-use card.
    - `expiresAt` string, date-time: When Grid closes the card if it has not been used. Present once a single-use card is issued; a recurring card has none.

## Other responses

- `202`: The purchase card needs the customer's approval. Returns the `ISSUE_PURCHASE_CARD` agent action, in `PENDING_APPROVAL` on the first request; a retry with the same `Idempotency-Key` returns it in its current status.
- `400`: Bad request. Returned with `CARDHOLDER_KYC_NOT_APPROVED` when the customer's KYC status is not `APPROVED`, with `CARDHOLDER_AGREEMENT_NOT_ACCEPTED` when the platform requires a cardholder agreement the customer has not accepted, and with `INVALID_INPUT` when the `Idempotency-Key` header is missing or too long, when the funding source does not belong to the customer or is not denominated in a card-eligible currency, when `amount` is missing for a purchase card or supplied for a standard one, when `recurring` is `true` for a standard card, when `amount` is over the largest purchase (or, for a recurring card, monthly limit) the platform allows agents to ask for, when a purchase card's funding source is not an Embedded Wallet the agent holds an active delegated key on or the agent's policy is not in USD, and for general invalid parameters.
- `401`: Unauthorized
- `403`: Forbidden - Agents API or agent cards are not enabled for the platform, agent purchase cards are not enabled for a `kind: PURCHASE` request, recurring purchase cards are not enabled for a `recurring: true` request, the agent is paused, the agent does not have the ISSUE_CARDS permission, or the agent's policy denies the purchase card (its `reason` starts with `Agent policy denied the purchase card:` followed by the denial, such as `DAILY_LIMIT_EXCEEDED`)
- `409`: Conflict. Returned with `AGENT_CARD_EXISTS` when the agent already holds a standard card that is not `CLOSED`, with `PURCHASE_CARD_LIMIT_REACHED` when it holds the most open purchase cards (or recurring purchase cards) allowed, with `CARD_LIMIT_REACHED` when the platform has reached the maximum number of live cards it may hold, and with `CONFLICT` when the agent already used the `Idempotency-Key` for a different card request.
- `500`: Internal service error
- `501`: Not implemented in this environment. Environments without a configured card issuer return `501 NOT_IMPLEMENTED`.

## Changes

> 115 revisions in range; 2 not diffed.

- **2026-11-02** `f90f21cf21e8`: 2 info
  - added the optional property `previousQuote` to the response with the `202` status
  - added the optional property `priceTolerance` to the response with the `202` status
- **2026-11-02** `e3a3f79a161f`: 3 info
  - added the new optional request property `recurring`
  - added the optional property `purchase/recurring` to the response with the `201` status
  - added the optional property `purchaseCard/recurring` to the response with the `202` status
- **2026-10-28** `d996ddfb9d2b`: 5 info
  - added the optional property `details/missingFields` to the response with the `400` status
  - added the optional property `details/permission` to the response with the `403` status
  - added the optional property `details/policyDenialReason` to the response with the `403` status
  - added the optional property `details/refusalReason` to the response with the `400` status
  - …1 more
- **2026-10-28** `5abf2bb56bcb`: 1 warning
  - added the new `CORRIDOR_UNDER_MAINTENANCE` enum value to the `code` response property for the response status `403`
- …earlier changes not shown

[Operation history](https://skmtc.dev/lightsparkdev/apis/grid-api/changes/agents/me/cards/post.md)

---

[API](https://skmtc.dev/lightsparkdev/apis/grid-api.md) - [All operations](https://skmtc.dev/lightsparkdev/apis/grid-api/llms.txt) - [OpenAPI document](https://skmtc.dev/lightsparkdev/apis/grid-api/revisions/7a1db46ec552?raw)
