> ## Documentation Index
> Fetch the complete documentation index at: https://vetta.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Cards

> Buy prepaid virtual cards for a persona and reveal their credentials with the TypeScript SDK.

Every method takes the identity (an `idn_…` id or its name) as its first argument. Amounts are
integer micro-USD (`1 USD = 1_000_000`). Reads return a `Card` — never a credential.

```ts theme={"system"}
const cards = client.identities.cards

const quote = await cards.quote(identityId, { load_micro_usd: 50_000_000 })
quote.price_micro_usd // 50_500_000 — what issue() will debit from credits

const card = await cards.issue(identityId, { label: "Ads", load_micro_usd: 50_000_000 })
card.status // "issuing" | "active"; a short balance throws ApiError insufficient_credits

const active = await cards.list(identityId, { status: "active" })
const detail = await cards.get(identityId, card.id) // reconciles an "issuing" card with the issuer
```

`revealCredentials` is the one method that returns a `CardCredentials`, a separate type from `Card`
so a credential can never be spread into a read result. It is audited and answers `not_found` for a
card that is not `active`; keep the result out of logs.

```ts theme={"system"}
const credentials = await cards.revealCredentials(identityId, card.id)
credentials.number // string; pin / cvv / expiry / url / instructions may be null
```

Lifecycle and spend:

```ts theme={"system"}
await cards.retry(identityId, card.id)   // from failed
await cards.cancel(identityId, card.id)  // from active
await cards.refund(identityId, card.id)  // from pending_payment | failed

await cards.logTransaction(identityId, card.id, { amount_micro_usd: 1_299_000, merchant: "Example Ads" })
const spend = await cards.transactions(identityId, card.id, { limit: 50 })
```

Every write draws a new `Idempotency-Key`, so a retried `issue` would buy a second card. Pass the
first call's key, with the same body, on the retry instead, `cards.issue(identityId, body, { idempotencyKey })`,
and the retry returns the card the first call bought, debited once. A changed body under that key is
refused `idempotency_conflict`, as is a retry sent while the first call is still running; retry that
one again. See the [Cards API](https://vetta.sh/docs/api/cards.md) for statuses,
scopes and errors.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.