Payment Methods
A payment method registers a source for agentic purchases and provisions every payment rail it supports. It carries no spending authority, so one payment method backs many allowances, each of which mints payment credentials.
Create a Payment Method
Registers the source with every supported provider in parallel and returns the outcome of each rail.
Permissions
agentic:payment-method:create
Available to public and private applications.
Request
curl 'https://api.basistheory.com/agentic/payment-methods' \
-X 'POST' \
-H 'BT-API-KEY: <PUBLIC_API_KEY>' \
-H 'BT-IDEMPOTENCY-KEY: pm-create-shopper-card-v1' \
-H 'Content-Type: application/json' \
--data '{
"source": {
"type": "basis_theory_card_token",
"token_id": "7d9f4a48-4f14-4b29-9f0a-3b4dd75f6c21"
},
"consumer": {
"email": "shopper@example.com",
"id": "8e7d3f98-3e7b-4ab2-bd48-44e70cc8ec3f",
"country_code": "US",
"language_code": "en-US"
}
}'
Headers
| Header | Required | Description |
|---|---|---|
BT-API-KEY | Yes | Public or private application key with agentic:payment-method:create. Never expose a private key in browser code |
BT-IDEMPOTENCY-KEY | No | Opts into durable retry handling. Without it, every request is a new create operation. See Idempotency |
Request Parameters
| Attribute | Required | Type | Description |
|---|---|---|---|
source | Yes | object | The source for this payment method |
consumer | Yes | object | The consumer this payment method belongs to |
agent_id | No | string | Non-empty. Optional attribution to an agent owned by the tenant; an unknown ID returns 404 AGENT_NOT_FOUND. Informational only and does not authorize the caller |
Source Object
source is a discriminated union on type. Switch on type rather than assuming its shape.
| Attribute | Required | Type | Description |
|---|---|---|---|
type | Yes | string | Exactly basis_theory_card_token |
token_id | Yes | uuid | ID of a Basis Theory card token readable within the tenant. A missing token, or a token whose type is not card, returns 400 INVALID_TOKEN |
Consumer Object
| Attribute | Required | Type | Description |
|---|---|---|---|
email | Yes | string | Valid email address. Rails that verify the consumer use it to identify them |
id | No | uuid | Your identifier for the consumer. Generated and returned when omitted. Use it to list a consumer's payment methods |
country_code | No | string | ISO 3166-1 alpha-2 country of residence. Lowercase is normalized to uppercase |
language_code | No | string | BCP 47 language tag, 2 to 35 characters, canonicalized on input |
Response
Returns a payment method object with 201, including when every rail failed at its provider. Read the rails array before using the payment method.
{
"id": "pm_h2Kd91mAqLwX",
"source": {
"type": "basis_theory_card_token",
"token_id": "7d9f4a48-4f14-4b29-9f0a-3b4dd75f6c21"
},
"status": "active",
"consumer": {
"email": "shopper@example.com",
"id": "8e7d3f98-3e7b-4ab2-bd48-44e70cc8ec3f",
"country_code": "US",
"language_code": "en-US"
},
"card": {
"brand": "visa",
"bin": "424242",
"last4": "4242",
"expiration_month": 12,
"expiration_year": 2030,
"funding": "credit",
"issuer": { "name": "Example Bank", "country": "US" },
"issuer_country": { "alpha2": "US", "name": "UNITED STATES OF AMERICA", "numeric": "840" },
"segment": "Consumer",
"display": {
"art_url": "https://assets.vims.visa.com/vims/cardart/6f7c1e9d",
"background_color": "#1A1F71",
"foreground_color": "#FFFFFF",
"description": "Visa Signature",
"issuer_name": "Example Bank"
}
},
"rails": [
{
"rail": "agentic-token",
"provider": "vic",
"status": "enabled",
"provider_ids": {
"vpan_enrollment_id": "6f7c1e9d",
"provisioned_token_id": "8a2b4c1f"
}
},
{
"rail": "spt",
"provider": "stripe",
"status": "error",
"error": { "code": "CARD_REJECTED" }
}
],
"created_at": "2030-07-06T17:30:00.000Z",
"updated_at": "2030-07-06T17:30:00.000Z"
}
The idempotency key, not the source or consumer, defines sameness: a different or omitted key creates a distinct payment method even when the source and consumer are identical. After 409 CREATE_OUTCOME_UNKNOWN the key is terminal; recover by listing payment methods as described in Errors and Recovery. Perform the same list check before retrying a keyless create whose response was lost.
Errors: 400 VALIDATION_ERROR, 400 INVALID_TOKEN, 400 UNSUPPORTED_PROVIDER, 404 AGENT_NOT_FOUND, 409 IDEMPOTENCY_CONFLICT, 409 IDEMPOTENCY_IN_PROGRESS, 409 CREATE_OUTCOME_UNKNOWN.
List Payment Methods
Permissions
agentic:payment-method:get
Request
curl 'https://api.basistheory.com/agentic/payment-methods?consumer_id=8e7d3f98-3e7b-4ab2-bd48-44e70cc8ec3f&size=20' \
-H 'BT-API-KEY: <PRIVATE_API_KEY>'
Query Parameters
| Parameter | Required | Type | Default | Description |
|---|---|---|---|---|
size | No | integer | 20 | 1 through 100. Out of range returns 400 |
start | No | string | — | Opaque cursor from the previous response's pagination.next |
consumer_id | No | uuid | — | Return only payment methods for one consumer |
status | No | string | active | active, deleted, or all |
Response
Returns a paginated list of payment method objects using the platform's cursor pagination. A filtered page can return fewer than size results while more remain, so treat the absence of pagination.next, not a short page, as the end of the results.
{
"data": [
{ "id": "pm_h2Kd91mAqLwX", "...": "..." }
],
"pagination": {
"next": "eyJQSyI6",
"page_size": 1
}
}
Get a Payment Method
Permissions
agentic:payment-method:get
Request
curl 'https://api.basistheory.com/agentic/payment-methods/pm_h2Kd91mAqLwX' \
-H 'BT-API-KEY: <PRIVATE_API_KEY>'
Request Parameters
| Attribute | Required | Type | Description |
|---|---|---|---|
payment_method_id | Yes | string | ID of the payment method to retrieve |
Response
Returns a payment method object, or 404 PAYMENT_METHOD_NOT_FOUND when the ID does not exist within the tenant.
Retry a Payment Method Rail
Re-runs provisioning for one rail without recreating the payment method. Use it after a transient provider failure, and to resolve a rail left pending.
Permissions
agentic:payment-method:create
Available to public and private applications.
Request
curl 'https://api.basistheory.com/agentic/payment-methods/pm_h2Kd91mAqLwX/rails/retry' \
-X 'POST' \
-H 'BT-API-KEY: <PUBLIC_API_KEY>' \
-H 'Content-Type: application/json' \
--data '{
"rail": "spt",
"provider": "stripe"
}'
Request Parameters
| Attribute | Required | Type | Description |
|---|---|---|---|
payment_method_id | Yes | string | ID of the payment method |
rail | Yes | string | agentic-token or spt. Must be present on the payment method |
provider | Yes | string | vic, agentpay, or stripe. Must be valid for the rail |
Only rails whose status is error or pending can be retried. Any other status returns 400 VALIDATION_ERROR.
Response
Returns the complete updated payment method object with 200, so the new rail status can be read directly from it.
Errors: 400 VALIDATION_ERROR, 400 RAIL_NOT_FOUND, 400 PAYMENT_METHOD_DELETED, 404 PAYMENT_METHOD_NOT_FOUND, 422 when the provider rejects the retry, such as 422 CARD_REJECTED or 422 RAIL_ENROLLMENT_INVALID, and 409 RAIL_ALREADY_ENROLLED when the provider reports the source as already enrolled. A rejected retry leaves the stored rail in error.
It can also return 409 PAYMENT_METHOD_OPERATION_IN_PROGRESS, 409 PAYMENT_METHOD_DELETE_IN_PROGRESS, or 409 PAYMENT_METHOD_DELETE_INCOMPLETE; see Operations in Progress.
List Payment Method Errors
Returns sanitized provider failures for the payment method and the operations beneath it, retained for 90 days.
Permissions
agentic:payment-method:get
Request
curl 'https://api.basistheory.com/agentic/payment-methods/pm_h2Kd91mAqLwX/errors' \
-H 'BT-API-KEY: <PRIVATE_API_KEY>'
Query Parameters
| Parameter | Required | Type | Default | Description |
|---|---|---|---|---|
size | No | integer | 20 | 1 through 100 |
start | No | string | — | Opaque cursor from the previous response's pagination.next |
Response
Returns a paginated list of provider error objects. Provider response bodies, provider messages, sensitive source data, and credential values are never included.
Delete a Payment Method
Permissions
agentic:payment-method:delete
Request
curl 'https://api.basistheory.com/agentic/payment-methods/pm_h2Kd91mAqLwX' \
-X 'DELETE' \
-H 'BT-API-KEY: <PRIVATE_API_KEY>'
Response
Returns 204 with no body.
Deletion is idempotent: repeating a successful delete succeeds without another provider call and without changing updated_at. Deletion requires no child operation to be in flight, so a concurrent allowance create, rail retry, or mint returns 409 PAYMENT_METHOD_OPERATION_IN_PROGRESS.
Errors: 404 PAYMENT_METHOD_NOT_FOUND, 409 PAYMENT_METHOD_OPERATION_IN_PROGRESS, 409 PAYMENT_METHOD_DELETE_IN_PROGRESS, 500 PROVIDER_ALLOWANCE_CANCEL_FAILED when a child allowance cannot be cancelled at its provider (e.g. a vic allowance). A delete that stopped during its cascade is resumed by repeating the DELETE; child operations, not this endpoint, return PAYMENT_METHOD_DELETE_INCOMPLETE.
Rails and Providers
A rail is identified by the rail and provider pair together. Only these combinations are valid:
rail | provider | Provider program | Credential formats |
|---|---|---|---|
agentic-token | vic | Visa Intelligent Commerce | card, network-token, mpp |
agentic-token | agentpay | Mastercard Agent Pay | card, network-token, mpp |
spt | stripe | Stripe Shared Payment Tokens | identifier, mpp |
Any other pairing returns 400 VALIDATION_ERROR naming the provider field. A pairing that is valid but not present on the resource returns 400 RAIL_NOT_FOUND.
Rails follow from the source: a Visa card provisions vic, a Mastercard card provisions agentpay, and either can back the spt rail. The provider is not a caller input.
Treat rail and provider as reported capabilities, not a product choice. Do not infer or select a provider yourself: read the pair off the resource and send it back only when an endpoint asks you to identify an existing rail. A payment method's rails array and an allowance's rails are the authoritative list of what that resource can do.
Payment Method Object
| Attribute | Type | Description |
|---|---|---|
id | string | Prefixed with pm_ |
source | object | The source object supplied at creation |
status | string | active or deleted |
consumer | object | The consumer object, including a generated id when one was not supplied |
card | object | Present when the source is a card: non-sensitive card metadata resolved from the token and enriched by the enrolling provider |
rails | array | One payment method rail per provisioned rail |
agent_id | string | Present when supplied at creation |
created_at | string | ISO 8601 timestamp |
updated_at | string | ISO 8601 timestamp. Changes only for externally observable state, not for internal lock or counter activity |
Payment Method Rail Object
| Attribute | Type | Description |
|---|---|---|
rail | string | The rail this entry provisions. See Rails and Providers |
provider | string | The provider operating the rail. See Rails and Providers |
status | string | enabled, pending, or error. See rail statuses |
error | object | Present only when status is error. Contains a stable machine-readable code drawn from the rail error codes |
provider_ids | object | Provider-native reference identifiers, all string values. Informational for support and correlation; the key set varies by provider and is not a stable contract |
Rail Statuses
| Status | Meaning |
|---|---|
enabled | Provisioning succeeded. Allowances can be created against this rail |
pending | Provisioning will resolve asynchronously. Retry the rail to pick up the result |
error | The provider rejected or failed provisioning. error.code carries the reason |
Clients must handle all three. A rail in enabled or pending never carries an error object.
Card Object
Every field is optional, since availability depends on the token and on what the enrolling provider returned.
| Attribute | Type | Description |
|---|---|---|
brand | string | Card network reported by the vault, such as visa. The agentic-token rail requires visa or mastercard; the spt rail accepts any network Stripe supports, so treat this as an open string |
bin | string | Card BIN |
last4 | string | Last four digits of the card |
expiration_month | integer | Card expiration month |
expiration_year | integer | Four-digit card expiration year |
funding | string | Funding type, such as credit or debit |
type | string | Always card |
segment | string | Card segment, such as Consumer |
issuer | object | name and country of the issuing bank |
issuer_country | object | alpha2, name, and numeric ISO 3166 representations |
display | object | Provider-supplied card display data |
Full card numbers and security codes are never stored on or returned by a payment method.
Card Display Object
Presentation data supplied by the provider that enrolled the card. Use it to render the card rather than inferring issuer branding. A rail retry that eventually succeeds backfills these values if the first attempt did not return them.
| Attribute | Type | Description |
|---|---|---|
art_url | string | Issuer card art, hosted by the provider |
background_color | string | Hex color for a card tile when no art is available |
foreground_color | string | Hex color for text on that tile |
description | string | Short product name, such as Visa Signature |
issuer_name | string | Issuing bank name |
Every field is nullable; fall back to {brand} •••• {last4} when one is absent.