title: Virtual Cards source_url: /developer-api/v1/virtual-cards summary: Issue fund-backed virtual cards for people or conventional backend payment flows. Deliver card details to a user's browser through a Ramp-served iframe, or retrieve them through the Vault API for an approved server-side flow. content: Issue fund-backed virtual cards for people or conventional backend payment flows. Deliver card details to a user's browser through a Ramp-served iframe, or retrieve them through the Vault API for an approved server-side flow. Looking to equip AI agents with cards? Follow the Agentic Payments guide A virtual card program where Ramp handles issuance and policy enforcement, and you pick how card details are surfaced: Embedded iframe (browser-side) — your backend mints a short-lived token; your frontend loads a Ramp-served iframe; the iframe renders card details directly to the user. Your servers never touch the PAN. Use when end users in your product need to see and use card numbers themselves. Vault API (server-side) — your backend creates a card and retrieves the PAN, CVV, and expiration in one synchronous call. Use when your service pays vendors directly, automates AP/travel bookings, or executes payments from a backend workflow. Both patterns deliver details for a fund-backed virtual card. Embedded Cards starts with an existing card; the Vault API creates the fund and card when it returns the details. Vault API requires production approval Ramp reviews your use case, security controls, and PCI handling before your app can retrieve full PANs and CVVs server-side in production. All customers can use the Vault API in Sandbox. Submit a Developer API support ticket to begin the review. Pattern A (embedded iframe) does not require this approval. Estimated time: 1–3 hours for a working prototype. Prerequisite knowledge: OAuth on Ramp; basic backend for both patterns, basic frontend for the iframe pattern. Embedded iframe Vault API Card data flows to The end user's browser, via Ramp iframe Your backend PCI scope Your service is out of scope on the data plane Your service is in scope on the data plane When to use End user needs to see the card and use it themselves Backend pays a vendor or books travel Production access Available after scope setup and origin verification Approval required Requires embedded_cards:write scope, verified parent_origin cards:read_vault scope, production approval Required: A Ramp account and an app with the appropriate scope. The embedded pattern also requires an existing virtual card backed by a fund; the Vault API creates the backing fund and card in one request. Recommended: Read Cards for the conceptual model and Spend Controls for fund configuration. Create and manage funds with the Funds API. Prerequisites for Embedded: An HTTPS origin you control (parent_origin), access to your Ramp business's Developer settings, and the ability to serve a verification file from that origin. Prerequisites for Vault: Ramp production approval. Sandbox works without approval. Pattern A: Embedded iframe Surface card details inside your own product so end users see and use card numbers without your servers ever touching the data. Verify every parent origin Before an origin can render Embedded Cards, add and verify it in Ramp. New integrations must also load the business-specific iframe URL, https://embed.ramp.com/business/{business_id}. Loading https://embed.ramp.com directly is not supported for new integrations. A four-step handshake: your backend mints an embed token for a specific card; your frontend loads a Ramp-served iframe; the iframe renders card data directly to the user. Security: token handling Never store embed tokens client-side. Mint them on demand from your backend. Tokens are short-lived but should still be treated as bearer credentials. 1. Enable the embedded_cards:write scope Sandbox: enable embedded_cards:write in the developer dashboard. Production: enable embedded_cards:write, then add and verify each production origin in Developer settings. 2. Add and verify your parent origins In Ramp, open your app from Developer settings and find Allowed origins. Enter the exact HTTPS origin that will host the iframe in Origin URL, select Add URL, then copy the token under Verify domain ownership. Production does not support localhost origins You cannot add or verify a localhost origin for a production integration. To develop or test Embedded Cards locally, configure the localhost origin in Sandbox and use the Sandbox iframe URL. At each origin, publish a text file at: The verification file must contain only the token The entire file contents must be the Ramp-issued verification token. Do not add spaces, line breaks, a byte-order mark, HTML, comments, or any other content. Return to Allowed origins and select Verify for the URL. Ramp must be able to fetch the file directly over HTTPS: redirects, wildcard origins, and non-default ports are not supported. The verification response must complete within 5 seconds and must not exceed 1 KiB. You can add multiple origins. Publish the same business verification token at /.well-known/ramp-verification.txt on every origin, then verify each origin separately. If you remove and later re-add an origin, you must verify it again. Verify: each URL shows a Verified status in Ramp before you try to render the iframe. If verification fails, confirm that the file is publicly accessible and its contents exactly match the displayed token. 3. Issue a card Create a fund using the Funds API; a virtual card is issued automatically. Capture its card_id to mint embed tokens for it. 4. Build the backend embed-token endpoint Your backend needs an endpoint your frontend can call to mint a token. It accepts a card_id and parent_origin, calls Ramp, and returns the token. POST /developer/v1/embedded/cards/{card_id}/embed Mint a short-lived embed token for a card. Shape callout: Your backend route is a thin pass-through: accept card_id and parent_origin from your frontend, forward to Ramp with your bearer token, return the embed_init_token. Never expose your Ramp access token to the browser. Verify: call your backend endpoint with a real card_id and your origin; you should get back an embed_init_token. 5. Render the iframe on the frontend Fetch the token from your backend and post it into a Ramp-hosted iframe. Shape callout — the iframe handshake: The root URLs https://demo-embed.ramp.com and https://embed.ramp.com remain available only for legacy integrations. They do not use your business's self-service allowed-origin list. New integrations must use /business/{business_id}. Use the id returned by GET /developer/v1/business as business_id. The parent_origin you pass when minting the token must match window.location.origin of the page hosting the iframe — exact protocol, host, and port. See What is parent_origin? below. 6. Test the integration Navigate to the Embedded Card Demo, paste an embed_init_token, and press Load Embed. The origin hosting the iframe — must exactly match window.location.origin of the page loading the embed and an origin you verified in Ramp. Ramp validates the origin server-side, blocking unauthorized domains from rendering your users' card details. Examples: Production: "https://your-app-domain.com" Staging: "https://staging.your-app-domain.com" Match must be exact — protocol (https:// vs http://) and port both count. Mismatched origins fail to load. Pattern B: Vault API Issue a card and retrieve PAN, CVV, and expiration in a single synchronous request. Your backend holds the data and passes it to a vendor, travel partner, or supplier. Production access requires Ramp approval Ramp reviews your use case, security controls, and PCI handling before the Vault API can return full PANs and CVVs in production. All customers can use the Vault API in Sandbox. Submit a Developer API support ticket to begin the review. 1. Enable the Vault scopes Enable cards:read_vault, limits:write, and funds:write (and optionally users:read) on your application. The Vault creation endpoint currently requires limits:write; terminating its backing fund requires funds:write. In Sandbox these work immediately; for production, begin the access review with a Developer API support ticket. 2. Build the client The Vault API uses a different base URL than the standard Developer API: https://demo-vault-api.ramp.com for Sandbox, https://vault-api.ramp.com for production. Copy your Client ID and Client Secret into a .env: 3. Issue a card and retrieve its details /cards/vault Create a fund, issue a virtual card, and return full card details in one request. Verify: call /cards/vault in Sandbox; the response should include a full pan and cvv. 4. Pass card details to the vendor Use the returned PAN, CVV, and expiration to submit payment to the vendor, travel system, or processor. Use card details only transiently for the approved payment flow. Do not store or log PANs or CVVs. 5. Terminate the card Virtual cards created via POST /cards/vault return both a spend_limit_id and a card.id. The spend_limit_id is the backing fund's ID. To permanently terminate the card, synchronously terminate that fund with DELETE /developer/v1/funds/{fund_id}. The Vault API creates a fund with an associated virtual card. Terminating the fund terminates the card and can affect every card or member attached to that fund. Termination is irreversible. Verify every production parent_origin in Ramp (Embedded) or complete the production access review (Vault) before launching. Mint embed tokens and Vault card details just-in-time. Never cache PANs or tokens client-side. Subscribe to transactions.cleared webhooks to track spend, refunds, and reversals on virtual cards. Refunds fire on locked or terminated cards too — watch for negative amount values. Plan card lifecycle. For embedded cards, terminate when the user-facing flow ends. For Vault cards, terminate the underlying fund (not the card directly) when winding down. Synchronous lifecycle. Fund creation and termination return their result directly; don't poll a deferred-task endpoint. Agent Cards — give an AI agent a purchase-scoped credential for one approved checkout. Spend programs — programs template the funds that auto-issue virtual cards. Cards — card variants and lifecycle. Spend Controls — funds, spend programs, and approvals that back every card. Business — retrieve the business_id required in the self-service iframe URL. Funds — create funds, which auto-issue virtual cards. Cards (Virtual) — list virtual cards and retrieve their backing fund_id. Cards (Physical) — physical card management. Transactions — settled spend per card and per fund. Webhooks — transactions.cleared for spend events. Authorization — business:read, embedded_cards:write, cards:read_vault, limits:write, and funds:write scopes. FAQ From the Funds API — each card in a fund's cards array has a card_id. Yes. Enable embedded_cards:write for your production app, then add and verify every production origin in Ramp. The embed fails to load. Match must be exact, including protocol and port. Yes. Refunds and reversals route to the original card even after lock or termination. Subscribe to transactions.cleared and watch for negative amount values. Technically yes, but it's unusual. Pick one exposure mechanism per card so the operational model stays clear.