Skip to main content

Agentic Credentials for Purchases

Allow an AI agent to make purchases on behalf of a consumer using Basis Theory's Agentic Commerce API
On-boarding is required for Production Access. Agentic Commerce supports Visa cards through Visa Intelligent Commerce. Mastercard support via Mastercard Agent Pay is available through a limited waitlist — contact support@basistheory.com to request access.

AI agents need the ability to make purchases on behalf of consumers — booking travel, ordering products, or paying for services. The Agentic Commerce API turns a card stored in Basis Theory into a tokenized card credential that an agent can use at checkout, with consumer verification and spending limits built in.

This guide walks through the full flow: creating an agent, enrolling a card, verifying the enrollment with the consumer, setting spending rules via instructions, verifying the instruction, and retrieving tokenized card credentials for the agent to use.

Consumer Verification Flow

The consumer sees this sequence when verifying their card enrollment and approving a purchase:

Core Concepts

ConceptWhat It IsAnalogy
EnrollmentA card registered with Visa for AI agent use. Created from a BT card token.Like adding a card to Apple Pay™ — the card is "enrolled" so it can be used without exposing the real number.
VerificationCardholder proves they approve the enrollment. Done via SMS/email OTP + passkey creation.Like the OTP you get when adding a card to a digital wallet — proves you own the card.
AgentAn AI entity that can use enrolled cards to make purchases. Has a name and a list of enrollments it can access.Like giving a personal assistant your credit card — but with spending rules attached.
InstructionA purchase intent with spending rules (max amount, currency, expiry). Must reference an active enrollment.Like saying "you can spend up to $500 on electronics, but only until Friday."
CredentialsA one-time-use tokenized card credential (number, expiry, CVC) generated from an approved instruction. Used at merchant checkout.Like a tokenized representation of the original card that works once and expires. The agent uses this at checkout.

How It Works

  1. Collect Card Data — securely collect and tokenize card data using Basis Theory Elements (frontend).
  2. Create an Agent — register the AI agent that will make purchases (backend).
  3. Enroll a Card — link a Basis Theory card token to the agent via a network provider (backend).
  4. Verify Enrollment — the consumer confirms ownership of the card through OTP and passkey creation (frontend).
  5. Create an Instruction — set spending rules for a specific purchase (backend).
  6. Verify Instruction — the consumer approves the purchase via passkey authentication (frontend).
  7. Retrieve Credentials — the agent receives tokenized card credentials to complete checkout (backend).
  8. Manage Enrolled Cards — consumers can remove enrolled cards from your application (backend).

Prerequisites

Basis Theory Account

You need a Basis Theory account to store card data and interact with the Agentic Commerce API. Sign up for free if you do not have one.

Agentic Commerce Access

Enable Agentic Commerce on your tenant by requesting access to the Agentic Commerce quota in the Basis Theory Portal under Settings → Quotas. For sandbox testing, see the test cards and mock flows.

Browser and Device Requirements

FIDO2/WebAuthn Required

Enrollment verification requires FIDO2/WebAuthn support on the consumer's device and browser. If the consumer's environment does not support WebAuthn, the SDK will fail with a WEBAUTHN_NOT_SUPPORTED error.

If a consumer encounters this error, advise them to:

  • Use a modern browser (Chrome, Safari, Firefox, Edge) on a device that supports biometrics or a security key
  • Update their browser and operating system to the latest version
  • Try a different device if their current one does not support WebAuthn

Public Application

You will need a Public Application to authenticate requests. Click here to create one using the Basis Theory Customer Portal.

This will create an application with the following Access Controls:

  • Permissions: token:create, enrollment:verify, agent:instruction:verify
Save the key from the created Public Application as it will be used later in this guide.

This application is used in the frontend for collecting card data and for the consumer verification flows (enrollment and instruction verification).

Private Application

You will need a Private Application to allow your backend to call Basis Theory APIs. Click here to create one using the Basis Theory Customer Portal.

This will create an application with the following Access Controls:

  • Permissions: enrollment:create, enrollment:get, enrollment:delete, agent:create, agent:get, agent:update, agent:delete, agent:instruction:create, agent:instruction:get, agent:instruction:update, agent:instruction:delete, agent:instruction:credentials
Save the key from the created Private Application as it will be used later in this guide.

This application is used in the backend for managing agents, enrollments, instructions, and retrieving credentials.

1. Collecting Card Data with Elements

Use Basis Theory Elements to securely collect and tokenize card data without your systems touching sensitive information.

Configure Elements SDK

Basis Theory Elements are available for the following platforms:

Add Card Elements to Your Page

<div id="cardNumber"></div>
<div style="display: flex;">
<div id="cardExpirationDate" style="width: 100%;"></div>
<div id="cardVerificationCode" style="width: 100%;"></div>
</div>
<button id="submit">Submit</button>
import { basistheory } from '@basis-theory/web-elements';

let bt;
let cardNumberElement;
let cardExpirationDateElement;
let cardVerificationCodeElement;

async function init() {
bt = await basistheory('<PUBLIC_API_KEY>');

cardNumberElement = bt.createElement('cardNumber', {
targetId: 'myCardNumber'
});
cardExpirationDateElement = bt.createElement('cardExpirationDate', {
targetId: 'myCardExpiration'
});
cardVerificationCodeElement = bt.createElement('cardVerificationCode', {
targetId: 'myCardVerification'
});

await Promise.all([
cardNumberElement.mount('#cardNumber'),
cardExpirationDateElement.mount('#cardExpirationDate'),
cardVerificationCodeElement.mount('#cardVerificationCode'),
]);

cardNumberElement.on('change', ({ cardBrand }) => {
cardVerificationCodeElement.update({ cardBrand });
});

document.getElementById("submit").addEventListener("click", submit);
}

async function submit() {
try {
const token = await bt.tokens.create({
type: 'card',
data: {
number: cardNumberElement,
expiration_month: cardExpirationDateElement.month(),
expiration_year: cardExpirationDateElement.year(),
cvc: cardVerificationCodeElement,
}
});
console.log('Token created:', token.id);
// Send token.id to your backend for enrollment
} catch (error) {
console.error(error);
}
}

init();

2. Create an Agent

Register the AI agent that will make purchases. Each agent represents a distinct bot or assistant in your system.

curl -X POST https://api.basistheory.com/agentic/agents \
-H 'BT-API-KEY: <BT_API_KEY>' \
-H 'Content-Type: application/json' \
-d '{
"name": "Shopping Assistant"
}'
Response
{
"id": "agt_fukICjsY2xzRCECiTCbKM",
"name": "Shopping Assistant",
"status": "active",
"created_at": "2026-01-15T10:30:00Z"
}

Save the agent id — you will use it in all subsequent API calls.

See the Agents API Reference for all available operations.

3. Enroll a Card

Enroll a Basis Theory card token with a network provider. The card brand is auto-detected, and the appropriate network (Visa or Mastercard) handles the enrollment.

curl -X POST https://api.basistheory.com/agentic/enrollments \
-H 'BT-API-KEY: <BT_API_KEY>' \
-H 'Content-Type: application/json' \
-d '{
"token_id": "<TOKEN_ID>",
"consumer": {
"email": "consumer@example.com"
}
}'
Response
{
"id": "enr_wNe75VKdzvojI9iD5fJxr",
"provider": "visa",
"status": "pending_verification",
"card": {
"brand": "visa",
"bin": "424032",
"last4": "0359",
"expiration_month": 11,
"expiration_year": 2029,
"display": {
"art_url": "https://assets.vims.visa.com/vims/cardart/abc123",
"background_color": "1A1F71",
"foreground_color": "FFFFFF",
"description": "Visa Signature",
"issuer_name": "Chase"
}
},
"created_at": "2026-01-15T10:31:00Z"
}

The enrollment starts in pending_verification status and moves to active after the consumer completes verification.

See the Enrollments API Reference for all available operations.

4. Verify Enrollment

The consumer must verify they own the card. This involves an OTP challenge from the card network followed by passkey creation for future use. Use the @basis-theory/react-agentic SDK to handle the verification flow in your frontend.

Install the SDK:

npm install @basis-theory/react-agentic

Wrap your application with the BtAiProvider and use the useAgentic hook to call verifyEnrollment:

import { BtAiProvider } from '@basis-theory/react-agentic';

function App() {
return (
<BtAiProvider apiKey="<PUBLIC_API_KEY>" environment="production">
<VerifyEnrollment enrollmentId="enr_wNe75VKdzvojI9iD5fJxr" />
</BtAiProvider>
);
}
import { useAgentic } from '@basis-theory/react-agentic';

function VerifyEnrollment({ enrollmentId }) {
const { verifyEnrollment } = useAgentic();

const handleVerify = async () => {
try {
const result = await verifyEnrollment(enrollmentId);
console.log('Enrollment verified:', result);
// Enrollment status is now "active"
} catch (error) {
// Store error details for debugging and support
console.error('Verification failed:', error.message);
if (error.traceId) {
console.error('Trace ID:', error.traceId); // BT-TRACE-ID for support
console.error('Error code:', error.code); // e.g., "PROVIDER_VERIFICATION_FAILED"
console.error('Provider correlation:', error.debug?.provider_correlation); // Visa Correlation ID
}
}
};

return (
<button onClick={handleVerify}>
Verify Card Enrollment
</button>
);
}

The BtAiProvider must wrap any component that uses the useAgentic hook. It authenticates requests using your Public API key. Set environment to "test" when using a test tenant — the SDK uses mock providers that don't require HTTPS. See the React Agentic SDK reference for all provider props.

verifyEnrollment renders a modal that guides the consumer through:

  1. OTP verification — the card network sends a one-time code to the consumer's registered contact method.
  2. Passkey creation — a passkey is created on the consumer's device for faster verification on future requests.

After successful verification, the enrollment status changes from pending_verification to active.

The verification modal displays "Basis Theory" branding by default. You can customize the visual appearance of the modal — including colors, typography, and borders — using the theme prop on BtAiProvider. See Theming for the full list of design tokens.

5. Create an Instruction

Once the enrollment is active, create an instruction that defines the spending rules for a specific purchase. Instructions control how much the agent can spend and when the authorization expires.

Description Appears in Passkey Prompt

Either the description field or the merchant name will appear in the passkey verification prompt shown to the consumer — one or the other is required. If you provide a description, write it as a human-readable purchase intent (e.g., "plan and book a trip to Europe"). Note that the word "to" is static in the prompt and cannot be changed, so structure your description accordingly.

curl -X POST https://api.basistheory.com/agentic/agents/agt_fukICjsY2xzRCECiTCbKM/instructions \
-H 'BT-API-KEY: <BT_API_KEY>' \
-H 'Content-Type: application/json' \
-d '{
"enrollment_id": "enr_wNe75VKdzvojI9iD5fJxr",
"amount": {
"value": "500.00",
"currency": "USD"
},
"description": "plan and book a trip to Europe",
"expires_at": "2026-02-20T00:00:00Z"
}'
Response
{
"id": "ins_luPDv2xm3Yb8RjFJz9oTC",
"enrollment_id": "enr_wNe75VKdzvojI9iD5fJxr",
"status": "pending_verification",
"amount": {
"value": "500.00",
"currency": "USD"
},
"expires_at": "2026-02-20T00:00:00Z",
"created_at": "2026-01-15T10:35:00Z"
}

Instruction Statuses

StatusDescription
pendingAwaiting provider approval
pending_verificationProvider approved; awaiting consumer verification
approvedConsumer verified; credentials can be retrieved
expiredPast the expires_at time
cancelledCancelled before use
failedVerification or provider failure

See the Instructions API Reference for all available operations.

6. Verify Instruction

The consumer must approve each instruction via passkey authentication. Use the verifyInstruction method from the useAgentic hook. This component must also be wrapped by the BtAiProvider (see Step 4).

import { useAgentic } from '@basis-theory/react-agentic';

function VerifyInstruction({ agentId, instructionId }) {
const { verifyInstruction } = useAgentic();

const handleVerify = async () => {
try {
const result = await verifyInstruction(agentId, instructionId);
console.log('Instruction approved:', result);
// Instruction status is now "approved"
} catch (error) {
console.error('Verification failed:', error.message);
if (error.traceId) {
console.error('Trace ID:', error.traceId);
console.error('Error code:', error.code);
console.error('Provider correlation:', error.debug?.provider_correlation);
}
}
};

return (
<button onClick={handleVerify}>
Approve Purchase
</button>
);
}

verifyInstruction renders a modal that prompts the consumer to authenticate with their passkey. After successful verification, the instruction status changes from pending_verification to approved.

7. Retrieve Credentials

Once the instruction is approved, retrieve tokenized card credentials from your backend. The response contains a card number, expiry, and CVC that the agent can use at checkout.

curl -X POST https://api.basistheory.com/agentic/agents/agt_fukICjsY2xzRCECiTCbKM/instructions/ins_luPDv2xm3Yb8RjFJz9oTC/credentials \
-H 'BT-API-KEY: <BT_API_KEY>' \
-H 'Content-Type: application/json' \
-d '{
"merchant": {
"name": "Amazon",
"url": "https://www.amazon.com",
"country_code": "US"
},
"products": [
{
"name": "Widget",
"price": 99.99,
"quantity": 2
}
],
"shipping_address": {
"line1": "123 Main St",
"city": "San Francisco",
"state": "CA",
"postal_code": "94105",
"country_code": "US"
}
}'
Response
{
"card": {
"number": "4111111111111111",
"expiration_month": "12",
"expiration_year": "2026",
"cvc": "123"
},
"expires_at": "2026-02-20T00:00:00Z"
}
The credentials returned are tokenized card credentials — a tokenized representation of the original card, not a virtual card funded by another card. These credentials should still be treated securely and requests should only be made from your backend.

The agent can now use these credentials to complete a purchase at the specified merchant.

See the Credentials API Reference for request and response details.

8. Manage Enrolled Cards

Consumers must be able to remove enrolled cards from your application. Use the DELETE /agentic/enrollments/{id} endpoint to remove an enrollment when a consumer requests it.

curl -X DELETE https://api.basistheory.com/agentic/enrollments/enr_wNe75VKdzvojI9iD5fJxr \
-H 'BT-API-KEY: <BT_API_KEY>'

A successful deletion returns a 204 No Content response. Any active instructions associated with the deleted enrollment will no longer be usable.

See the Enrollments API Reference for details.

Going Live

Before launching in production, complete every item below.

Your UI

  • Display issuer card art. Render the card.display.art_url from the enrollment response when showing enrolled cards. Showing only the Visa logo is not sufficient — display the actual issuer card art (Chase, Capital One, etc.) in your card management screens. Use the background_color and foreground_color fields to render the card accurately.
  • Show Terms & Privacy Policy. Present links to your Terms of Service and Privacy Policy either on first wallet launch or every time a card is added. Cardholders must be explicitly aware of what the wallet will do with their card data before enrolling. Your Privacy Policy must disclose that card and identity data is shared with Visa for AI agent purchases. This cannot be buried in fine print.
  • Provide a "Remove Card" option. Consumers must be able to unenroll a card at any time. See Step 8.
  • Build a notification flow for payment approval. When an agent creates an instruction, your application must notify the consumer that approval is needed. Common pattern: send a link (via chat, SMS, or email) to a page that calls verifyInstruction. Basis Theory does not send notifications — your app manages the delivery.
  • Prevent duplicate enrollments. Before creating a new enrollment, check whether the card is already enrolled for this consumer by comparing the token.fingerprint and the consumer's user ID against existing enrollments. The API does not currently prevent duplicates, so this check must be implemented on your side.

Error Handling

  • Handle partial enrollment failures. When enrollment partially fails (e.g., the card registers but VIC provisioning fails), the API still returns the enrollment object with card art and display data preserved. Show the card with its art even if it cannot be used for purchases yet — provisioning retries happen automatically. Do not hide the card or show a generic error.
  • Log Visa Correlation IDs. On errors, capture error.debug?.provider_correlation alongside the BT trace ID. Both are required for Visa support escalations.
  • Store BT-TRACE-ID on all errors. All API responses include this header. On errors, the response body may also contain debug.provider_correlation. Log both values — they are essential for troubleshooting with Basis Theory support.

Visa Review

  • Record demo videos. Visa Legal requires two videos of your implementation:
    1. Add Card Flow — show push notifications, verification (OTP), and passkey creation
    2. Payment Instruction — show the agent interaction and passkey authentication for approving a purchase
  • Confirm KYC data collection. At minimum, collect the consumer's email address before enrollment.

FAQ

What card issuers are not supported?

Visa is currently live in the US market supporting consumer cards for most banks. Some known exceptions are JP Morgan Chase branded cards and Commercial cards (e.g., Ramp or Business cards). Mastercard is currently live in the US market.

Which card brands are supported?

Visa cards are supported through Visa Intelligent Commerce. Mastercard support via Mastercard Agent Pay is available through a limited waitlist — contact support@basistheory.com to request access. The card brand is auto-detected during enrollment based on the Basis Theory token data.

Can I also process my own payments with the cards collected?

Yes. To process payments with your tokenized card data, refer to these guides:

  • Charge a Card — process payments with various processors including Stripe, Adyen, and others
  • Verify a Card — validate cards by performing $0 authorizations before processing actual payments

Can I integrate with other agentic platforms with cards collected?

Once you have a Basis Theory Token, you can use it with any payment processor or agentic payments partner. The Basis Theory platform provides flexible options for integrating without being locked into any specific provider.

What happens if the consumer does not complete verification?

The enrollment remains in pending_verification status. You can retry verification or delete the enrollment and create a new one. Instructions cannot be created against a pending_verification enrollment.

How long are credentials valid?

Credentials expire based on the expires_at value set on the instruction. After expiry, the instruction status changes to expired and new credentials cannot be retrieved.

What countries and card types are supported?

US consumer Visa cards are supported — Bank of America, Wells Fargo, and Capital One are confirmed. Small Business and Commercial cards (e.g., Ramp) are not currently enabled. International cards (e.g., from Revolut Spain or Argentina) may enroll but fail at purchase authorization. If enrollment fails, check the debug.provider_correlation value in the error response and contact support@basistheory.com for current market availability.

Can I see spending activity or transaction history for a credential?

No. Once credentials are retrieved and used at checkout, there is no API to view transaction history or spending activity for that credential. Authorization results are handled by the merchant's payment processor, not Basis Theory.

What consumer information do I need to collect for KYC?

The enrollment API requires the consumer's email address. This must be collected before creating an enrollment.

How do I handle consumer notification for payment approval?

When an agent creates an instruction, your application is responsible for notifying the consumer that approval is needed. A common pattern is to send the consumer a link (via chat, SMS, or email) to a web page that calls verifyInstruction. The consumer opens the link, authenticates via passkey, and the instruction moves to approved status. Basis Theory does not send notifications directly — your application manages the delivery mechanism.

What happens if enrollment partially fails?

The enrollment is still saved with card art and display data preserved. Your UI should show the card even if VIC provisioning failed — do not hide it or show a generic error. If the issuer is later supported, provisioning retries automatically.

Can I use tokenized credentials for recurring or subscription payments?

Contact support@basistheory.com for current recurring transaction support.

What happens when a consumer verifies from a different device?

By default, the SDK triggers full ID&V and passkey creation on the new device. Configure the onNewDevice prop on BtAiProvider to control this behavior — set it to "eject" to reject verification on unrecognized devices instead. See BtAiProvider props.

What KYC/privacy disclosures do I need in my app?

Present your Terms of Service and Privacy Policy either on first wallet launch or every time a card is added. Your Privacy Policy must disclose that card and identity data is shared with Visa for the purpose of enabling AI agent purchases. This is a Visa requirement — it cannot be buried in fine print.