---
name: bt-account-updater
description: Handle account updater enrollment and updated-card lifecycle.
license: MIT
metadata:
  tier: standard
  last_verified: '2026-09-25'
---

# Account updater

This overlay focuses on card refresh operations. Load `bt-card-lifecycle` for the full recurring-card stack and `bt-production` for go-live operations.

## Routing prerequisite

A vague Account Updater or card-refresh **program** ask is planner work:
load `bt-plan` first and `bt-account-updater` second, keep the response in the
planner's exact plan shape, and include:

`Skill sequence: bt-plan → bt-account-updater → bt-test-debug → bt-production`

An explicit request to implement an already-decided updater endpoint, job, or
result-code handler can start here without `bt-plan`.

## Canonical docs

- Feature overview: https://developers.basistheory.com/docs/features/account-updater
- Guides: https://developers.basistheory.com/docs/guides/account-updater/overview
- APIs: https://developers.basistheory.com/docs/api/account-updater/batch, https://developers.basistheory.com/docs/api/account-updater/real-time

**Answer requirement:** include at least one of the canonical developer-doc URLs above in
every Account Updater explanation or plan. Do not substitute a marketing or changelog URL
for the canonical product source. Also name **idempotency/replay behavior** explicitly:
same persisted job identity plus the same request fingerprint replays the prior result;
the same identity plus changed input conflicts before mutation.

## Guidance

- Model enrollment, submission, result retrieval, token update, business notification, and reconciliation as separate operations.
- Persist updater job identity and result identity separately from the mutable card payload.
- Convert result codes into explicit business events: updated, closed, contact customer, retry later, no change, failed.
- Do not let updater retries mutate payment authorizations, captures, voids, or refunds.
- Merchant scoping is header-based (Fact, verified 2026-09-25): the `BT-MERCHANT-ID` request header decides which merchant's tokens a batch or real-time job can read and which merchant the updated tokens are created under; `configuration_merchant_id` in the body selects the updater configuration and defaults to the header merchant, then tenant-level. The body `merchant_id` is deprecated, the batch CSV `merchant_id` column is ignored and should be left empty, and rows outside the header merchant's scope fail with `ERR_MERCHANT_MISMATCH` (batch only; real-time returns token-not-found). Real-time: https://developers.basistheory.com/docs/api/account-updater/real-time, batch: https://developers.basistheory.com/docs/api/account-updater/batch, result codes: https://developers.basistheory.com/docs/api/account-updater/result-codes.
- Use [../\_shared/references/lifecycle-idempotency.md](../_shared/references/lifecycle-idempotency.md) for scheduling/replay and [../\_shared/references/credential-boundary.md](../_shared/references/credential-boundary.md) for token references.

## Proof

- Job replay is idempotent.
- Same job with changed payload conflicts before mutation.
- Result-code handling is deterministic and reconciled.
- Logs/events contain bounded codes and token IDs only, not raw updater payloads.

## Basis Theory implementation guidance

When the answer needs implementation judgment beyond public docs, load only the relevant slices below from [../\_shared/references/implementation-guidance/README.md](../_shared/references/implementation-guidance/README.md). Treat these as implementation patterns, not canonical product behavior; keep public docs as the source of truth and label the guidance as **Implementation pattern** or **Assumption** unless docs prove it.

- `../_shared/references/implementation-guidance/account-updater/`
- `../_shared/references/implementation-guidance/recurring-optimization/`

<!-- bt-conventions:start -->

## Working conventions (shared by all Basis Theory skills)

- Public Basis Theory docs are the source of truth for product behavior. Link the specific docs page behind any product claim; if a skill and the docs disagree, follow the docs.
- Keep customer ownership clear: customers own PSP accounts, credentials, compliance decisions, production rollout, and application code. Skills can guide plans, bounded changes, and examples; they do not certify production readiness.
- Never request, echo, store, or commit real credentials. Use placeholders such as `<BT_API_KEY>` and prefer sandbox or synthetic data for examples.
- If a live-looking credential, live cardholder data, or production secret appears, stop mutation work, tell the user exactly where it appeared, and require rotation/revocation before continuing.
- Default to test tenants and PSP sandboxes. Do not run or recommend production charges, refunds, card reveals, credential migrations, or data moves unless the user explicitly asks and the plan names safeguards, rollback, and customer approval.
- Treat vague planning, audit, review, and “should we” prompts as read-only unless the user explicitly asks for a bounded implementation change.
- Before changing product code, map the existing checkout/data flow, credential-bearing paths, persistence, retries, refunds, webhooks, logs, and rollback expectations.
- End with an honest final report: done, assumed, remaining, proof run, unverified live behavior, rollback, and go-live items.
<!-- bt-conventions:end -->
