Stripe Issuing's standalone card platform → the Naive /cards primitive
Cardholder, issue a Card against it, set spending_controls,
and watch authorizations and transactions stream in. It is a genuinely powerful card platform, and
the API is excellent. But run directly, it is also a separate vendor account:
- Cards live behind your Stripe secret key, Stripe dashboard, and Stripe’s
Cardholder/Cardobject graph — funded from a pooled Issuing/Treasury balance you top up yourself. - A Stripe
Cardholderscopes cards and nothing else. It is a KYC entity for issuing — it has no idea about the agent’s inbox, its vault secrets, its OAuth connections, or any other KYC you ran. - “Who let this agent issue a $5k card, and what else can this agent touch?” is answered in Stripe for cards, and in unrelated systems for everything else. There is no shared accountability.
/cards primitive gives the agent the same capability —
full Visa/Mastercard virtual cards via the managed_virtual provider — but rooted in
one identity:
- The tenant user that holds a card is the same user that owns its email inbox, its vault secrets, its KYC, and its connections.
- Whether an agent may issue or fund a card — and up to what total — is decided by that user’s Account Kit at execution time, not by trusting your own code to check first.
- Every cardholder create, card issue, top-up, and transaction lands in the same per-user activity log as everything else the agent does.
Stripe and related marks are trademarks of Stripe, Inc., used here for identification only. Naive is not affiliated with or endorsed by Stripe; card funding may use hosted checkout, but this guide does not describe Stripe’s internal Issuing implementation.
Tested against: Stripe Node SDK
stripe v17 (Issuing
API, versions 2025-12-15 / 2026-04-22, per docs.stripe.com/api/issuing,
snapshot June 2026) and the Naive API (base https://api.usenaive.ai/v1, docs snapshot June 2026)
plus the Naive Node SDK @usenaive-sdk/server.Version notes:- Naive’s
managed_virtualprovider issues a full Visa/Mastercard virtual card (cardholder required, no spending cap); the defaultprepaid_giftprovider is a prepaid Visa gift card (capped at $150, no cardholder). This guide targetsmanaged_virtual, the closest match to a direct Stripe Issuing card. - Stripe Issuing card credentials (
number,cvc) are retrieved viacards.retrieve(id, { expand })and require your platform to be PCI-compliant or to use Stripe Elements. Naive returns them fromGET /v1/cards/:id/detailsonce the card isactive. - Both are evolving APIs — verify method names and the funding model against your installed versions.
Concept map
Before / after: the core path
The path that matters for almost every agent that spends money is register a cardholder, issue a card, then read its credentials. Here it is on both platforms.- Funding model. Stripe Issuing typically draws from a pooled Issuing/Treasury balance you
top up. Naive funds each card through a hosted checkout (
checkout_url) for the card’s amount, then issues it oncheck-payment. There is no shared balance to manage. - Spend limits. Stripe’s
spending_controlscan include per-interval and per-MCC rules. Naive’sspending_limit_centsis a single funded cap per card — simpler, but not category- or interval-aware. See the gaps. - The cardholder is your identity, not a standalone KYC object. In Stripe a
Cardholderexists only for issuing. In Naive the cardholder hangs off a tenant user that also owns the agent’s inbox, vault, connections, and KYC.
Funding and issuing
Both platforms separate “create the card” from “the card can spend.” Stripe does it with a balance; Naive does it with a per-card checkout.- On Naive, issuing a card, creating a cardholder, and topping up are sensitive and may be
approval-gated by the Account Kit — the call can return
202 { status: "pending_approval", approval_id }until a human approves, then the API replays it. - A card’s status moves
pending_payment → activeaftercheck-paymentconfirms funding. See Card statuses.
Minimal viable migration
The smallest swap that keeps a spending agent running is cardholder → issue → reveal. You do not need to recreate Treasury, per-MCC controls, or Account Kits to make your first card.1
Install the SDK and set your key
NAIVE_API_KEY (a server-side key from the dashboard).2
Map your users
A Stripe
Cardholder becomes a Naive tenant user with a cardholder
attached. Reuse your own database id as external_id so the mapping is 1:1, or pass it straight
into naive.forUser(id).3
Recreate the cardholder once per identity
Replace
stripe.issuing.cardholders.create({ name, billing }) with
POST /v1/cards/cardholder (firstName, lastName, billing…, dob…). One cardholder per
tenant user covers all of that user’s managed_virtual cards.4
Swap card issuance
Replace
stripe.issuing.cards.create with client.cards.create({ name, spending_limit_cents, provider: "managed_virtual" }), open the returned checkout_url, then check-payment to issue.5
Read credentials and ship
Replace
cards.retrieve(id, { expand:["number","cvc"] }) with GET /v1/cards/:id/details.
At this point you are off your direct Stripe Issuing integration for the core path. Everything
below is upside, not a requirement.Consolidate further once you’re on Naive
This is where the migration pays for itself. With Stripe Issuing direct, aCardholder isolates
cards and nothing else. On Naive, the unit of isolation is a tenant user, and it isolates
the agent’s entire footprint.
Gain #1 — one identity across primitives
- With Stripe Issuing, the agent’s cards are an island. With Naive,
naive.forUser(acme.id)is a single handle to cards and email and vault and connections and KYC. - You provision a customer’s whole agent footprint from one identity, and tear it down from one place. Sibling tenants can never read each other’s cards, secrets, or inboxes.
Gain #2 — execution-time permission enforcement
- Whether an agent may issue or fund a card is policy on the Account Kit — not a check you hand-write, and not “we trust the agent to call the right function.”
- The agent’s code is identical for every tier —
client.cards.create({ … }). Whether the call runs is decided by the caller’s kit at execution time:primitives_config.cards.enabled: false→ the exact same line returnsforbidden, no code change.requiresApproval: true→ issuing, cardholder creation, and top-ups freeze as a pending approval; the API replays them only after a human approves.- The funded
spending_limit_centscaps how much was loaded onto the card — spend is generally bounded by that funded amount, though treat issuer/network behavior as authoritative for edge cases.
- Stripe gates who has Issuing access at the Connect-account level and per-authorization via your own webhook logic. Naive additionally gates the issuance and funding decision per tenant user, declaratively, with no per-swipe handler to run. (Per-authorization MCC control is still a Stripe strength — see gaps.)
Gain #3 — unified accountability
- Every cardholder create, card issue, top-up, and transaction for a customer lands in one per-user activity log — alongside their email, vault, and connection events, not in a separate Stripe dashboard:
- That is the question that is hard to answer when cards live in Stripe, email lives in another vendor, and secrets live somewhere else. Under Naive it is a single query.
What does not map yet
A migration guide that hides gaps is worse than none. The core path (cardholder → issue → reveal → transactions → cancel) maps cleanly, but Stripe Issuing has real capabilities Naive’s/cards does
not match today. Check this list against your app before you commit — some of these are why you
might stay on Stripe Issuing direct.
Where to go next
/cardsprimitive — full cardholder/issue/fund/transaction lifecycle- Cards API reference — exact request/response shapes
cardsSDK sub-client — typed method signatures- Account Kits and Approvals — the policy model that makes execution-time issuance governance real
- Tenant users — the identity that the consolidation hangs off
Related reading (blog)
- Why consolidate agent infra on one governed identity — migration thesis behind this guide
- Building AI Agents Into Your SaaS — tenant user anchor for every migration
- Spend Caps Approvals Revocation For Ai Agents — card spend caps and approval gates