diff --git a/mintlify/openapi.yaml b/mintlify/openapi.yaml
index 9beb0ec9..1290b4eb 100644
--- a/mintlify/openapi.yaml
+++ b/mintlify/openapi.yaml
@@ -7030,7 +7030,7 @@ paths:
type: string
get:
summary: Get a card
- description: Retrieve a card by its system-generated id.
+ description: Retrieve a card by its system-generated id. This is the only endpoint that returns a populated `panEmbedUrl` — a fresh, short-lived signed URL is minted on each call. Fetch the card right before rendering the PAN-reveal iframe.
operationId: getCardById
tags:
- Cards
@@ -8566,7 +8566,7 @@ webhooks:
last4: '4242'
expMonth: 12
expYear: 2029
- panEmbedUrl: https://embed.lithic.com/iframe/...?t=...
+ panEmbedUrl: null
fundingSources:
- InternalAccount:019542f5-b3e7-1d02-0000-000000000002
currency: USD
@@ -8586,6 +8586,7 @@ webhooks:
state: CLOSED
stateReason: ISSUER_REJECTED
form: VIRTUAL
+ panEmbedUrl: null
fundingSources:
- InternalAccount:019542f5-b3e7-1d02-0000-000000000002
currency: USD
@@ -8607,6 +8608,7 @@ webhooks:
last4: '4242'
expMonth: 12
expYear: 2029
+ panEmbedUrl: null
fundingSources:
- InternalAccount:019542f5-b3e7-1d02-0000-000000000002
currency: USD
@@ -12321,7 +12323,7 @@ components:
- SAVINGS
bankName:
type: string
- description: The name of the bank
+ description: The name of the beneficiary's bank
minLength: 1
maxLength: 255
example: Banco GYT Continental
@@ -19693,9 +19695,11 @@ components:
description: Card expiration year (four digits).
example: 2029
panEmbedUrl:
- type: string
+ type:
+ - string
+ - 'null'
format: uri
- description: URL of the card processor's iframe that securely displays the PAN, CVV, and expiry to the cardholder. The full PAN and CVV never cross Grid's servers — render this URL in an iframe in your client to reveal card details.
+ description: Signed URL of the card processor's iframe that securely displays the PAN, CVV, and expiry to the cardholder. The full PAN and CVV never cross Grid's servers — render this URL in an iframe in your client to reveal card details. Populated ONLY on `GET /cards/{id}`; null on list, create, and update responses and in webhook payloads. The URL is short-lived (expires within minutes), so fetch the card right before rendering the iframe and never cache the URL.
example: https://embed.lithic.com/iframe/...?t=...
fundingSources:
type: array
diff --git a/mintlify/snippets/cards/issuing-cards.mdx b/mintlify/snippets/cards/issuing-cards.mdx
index f0c36bbd..aaf8f335 100644
--- a/mintlify/snippets/cards/issuing-cards.mdx
+++ b/mintlify/snippets/cards/issuing-cards.mdx
@@ -54,17 +54,32 @@ issuance is gated on KYC up front.
`POST /cards` returns immediately with `state: "PROCESSING"`. The
issuer provisions the card asynchronously; on success a
`CARD.STATE_CHANGE` webhook fires with the activated `Card` resource
-including the populated `last4`, `expMonth`, `expYear`, and
-`panEmbedUrl`.
+including the populated `last4`, `expMonth`, and `expYear`.
If the issuer rejects provisioning, the same webhook fires with
`state: "CLOSED"` and `stateReason: "ISSUER_REJECTED"`. That card is
terminal — issue a new one with a fresh `platformCardId` to retry.
+## Revealing the PAN
+
+To show the cardholder their full PAN, CVV, and expiry, fetch the
+single card right before rendering:
+
+```bash
+curl -X GET "$GRID_BASE_URL/cards/Card:019542f5-b3e7-1d02-0000-000000000010" \
+ -u "$GRID_CLIENT_ID:$GRID_CLIENT_SECRET"
+```
+
+The response includes a `panEmbedUrl` — a signed URL for the card
+processor's iframe that renders the full credentials directly to the
+cardholder. The full PAN and CVV never cross your servers or Grid's.
+
-Render `panEmbedUrl` in an iframe in your client to display the full
-PAN, CVV, and expiry to the cardholder. The full credentials never
-cross your servers.
+`panEmbedUrl` is populated **only** on `GET /cards/{id}` — it is null
+on list, create, and update responses and in webhook payloads. The URL
+is short-lived (it expires within minutes), so fetch the card each time
+the cardholder asks to reveal their details, immediately before
+rendering the iframe. Don't cache or store the URL.
## Errors to handle
diff --git a/mintlify/snippets/cards/quickstart.mdx b/mintlify/snippets/cards/quickstart.mdx
index 459fdc21..5fbd6f34 100644
--- a/mintlify/snippets/cards/quickstart.mdx
+++ b/mintlify/snippets/cards/quickstart.mdx
@@ -70,7 +70,7 @@ for the full table. When activation completes, a
"last4": "4242",
"expMonth": 12,
"expYear": 2029,
- "panEmbedUrl": "https://embed.lithic.com/iframe/...?t=...",
+ "panEmbedUrl": null,
"fundingSources": [
"InternalAccount:019542f5-b3e7-1d02-0000-000000000002"
],
@@ -84,9 +84,11 @@ for the full table. When activation completes, a
```
-Render `panEmbedUrl` in an iframe in your client to display the full
-PAN, CVV, and expiry to the cardholder. The full card credentials never
-cross your servers.
+To display the full PAN, CVV, and expiry to the cardholder, fetch
+`GET /cards/{id}` and render the returned `panEmbedUrl` in an iframe.
+The URL is short-lived and populated only on the single-card GET (it's
+null in webhook payloads), so fetch it right before rendering. The full
+card credentials never cross your servers.
## Simulate an authorization
diff --git a/mintlify/snippets/cards/terminology.mdx b/mintlify/snippets/cards/terminology.mdx
index db888832..eeb73669 100644
--- a/mintlify/snippets/cards/terminology.mdx
+++ b/mintlify/snippets/cards/terminology.mdx
@@ -60,4 +60,6 @@ high-urgency reconciliation alerts and are surfaced as
`panEmbedUrl` on the `Card` resource is the issuer's iframe URL that
renders the full PAN, CVV, and expiry directly to the cardholder. Render
it in an iframe in your client; the full credentials never cross
-{` `}Grid's servers.
+{` `}Grid's servers. The URL is short-lived and populated only on
+`GET /cards/{id}` — fetch the card right before rendering the iframe
+rather than caching the URL.
diff --git a/mintlify/snippets/cards/webhooks.mdx b/mintlify/snippets/cards/webhooks.mdx
index da0f8cd0..2b5340ad 100644
--- a/mintlify/snippets/cards/webhooks.mdx
+++ b/mintlify/snippets/cards/webhooks.mdx
@@ -47,7 +47,7 @@ activation after issuance:
"last4": "4242",
"expMonth": 12,
"expYear": 2029,
- "panEmbedUrl": "https://embed.lithic.com/iframe/...?t=...",
+ "panEmbedUrl": null,
"fundingSources": [
"InternalAccount:019542f5-b3e7-1d02-0000-000000000002"
],
@@ -62,8 +62,10 @@ activation after issuance:
Common branches to handle in your consumer:
-- `state: "ACTIVE"` after `PROCESSING` — the card is live; surface
- `panEmbedUrl` to the cardholder.
+- `state: "ACTIVE"` after `PROCESSING` — the card is live. To reveal
+ the full card details, fetch `GET /cards/{id}` right before rendering
+ its short-lived `panEmbedUrl` in an iframe — the field is always null
+ in webhook payloads.
- `state: "CLOSED"`, `stateReason: "ISSUER_REJECTED"` — the issuer
rejected provisioning; offer to issue a new card.
- `state: "FROZEN"` / `state: "ACTIVE"` — reflect the freeze toggle in
diff --git a/openapi.yaml b/openapi.yaml
index 9beb0ec9..1290b4eb 100644
--- a/openapi.yaml
+++ b/openapi.yaml
@@ -7030,7 +7030,7 @@ paths:
type: string
get:
summary: Get a card
- description: Retrieve a card by its system-generated id.
+ description: Retrieve a card by its system-generated id. This is the only endpoint that returns a populated `panEmbedUrl` — a fresh, short-lived signed URL is minted on each call. Fetch the card right before rendering the PAN-reveal iframe.
operationId: getCardById
tags:
- Cards
@@ -8566,7 +8566,7 @@ webhooks:
last4: '4242'
expMonth: 12
expYear: 2029
- panEmbedUrl: https://embed.lithic.com/iframe/...?t=...
+ panEmbedUrl: null
fundingSources:
- InternalAccount:019542f5-b3e7-1d02-0000-000000000002
currency: USD
@@ -8586,6 +8586,7 @@ webhooks:
state: CLOSED
stateReason: ISSUER_REJECTED
form: VIRTUAL
+ panEmbedUrl: null
fundingSources:
- InternalAccount:019542f5-b3e7-1d02-0000-000000000002
currency: USD
@@ -8607,6 +8608,7 @@ webhooks:
last4: '4242'
expMonth: 12
expYear: 2029
+ panEmbedUrl: null
fundingSources:
- InternalAccount:019542f5-b3e7-1d02-0000-000000000002
currency: USD
@@ -12321,7 +12323,7 @@ components:
- SAVINGS
bankName:
type: string
- description: The name of the bank
+ description: The name of the beneficiary's bank
minLength: 1
maxLength: 255
example: Banco GYT Continental
@@ -19693,9 +19695,11 @@ components:
description: Card expiration year (four digits).
example: 2029
panEmbedUrl:
- type: string
+ type:
+ - string
+ - 'null'
format: uri
- description: URL of the card processor's iframe that securely displays the PAN, CVV, and expiry to the cardholder. The full PAN and CVV never cross Grid's servers — render this URL in an iframe in your client to reveal card details.
+ description: Signed URL of the card processor's iframe that securely displays the PAN, CVV, and expiry to the cardholder. The full PAN and CVV never cross Grid's servers — render this URL in an iframe in your client to reveal card details. Populated ONLY on `GET /cards/{id}`; null on list, create, and update responses and in webhook payloads. The URL is short-lived (expires within minutes), so fetch the card right before rendering the iframe and never cache the URL.
example: https://embed.lithic.com/iframe/...?t=...
fundingSources:
type: array
diff --git a/openapi/components/schemas/cards/Card.yaml b/openapi/components/schemas/cards/Card.yaml
index 10ac4aca..5f77387e 100644
--- a/openapi/components/schemas/cards/Card.yaml
+++ b/openapi/components/schemas/cards/Card.yaml
@@ -51,13 +51,18 @@ properties:
description: Card expiration year (four digits).
example: 2029
panEmbedUrl:
- type: string
+ type:
+ - string
+ - 'null'
format: uri
description: >-
- URL of the card processor's iframe that securely displays the PAN, CVV,
- and expiry to the cardholder. The full PAN and CVV never cross Grid's
- servers — render this URL in an iframe in your client to reveal card
- details.
+ Signed URL of the card processor's iframe that securely displays the
+ PAN, CVV, and expiry to the cardholder. The full PAN and CVV never
+ cross Grid's servers — render this URL in an iframe in your client to
+ reveal card details. Populated ONLY on `GET /cards/{id}`; null on
+ list, create, and update responses and in webhook payloads. The URL
+ is short-lived (expires within minutes), so fetch the card right
+ before rendering the iframe and never cache the URL.
example: https://embed.lithic.com/iframe/...?t=...
fundingSources:
type: array
diff --git a/openapi/components/schemas/common/GtqAccountInfoBase.yaml b/openapi/components/schemas/common/GtqAccountInfoBase.yaml
index 8cf8e1be..250c9925 100644
--- a/openapi/components/schemas/common/GtqAccountInfoBase.yaml
+++ b/openapi/components/schemas/common/GtqAccountInfoBase.yaml
@@ -22,7 +22,7 @@ properties:
- SAVINGS
bankName:
type: string
- description: The name of the bank
+ description: The name of the beneficiary's bank
minLength: 1
maxLength: 255
example: Banco GYT Continental
diff --git a/openapi/paths/cards/cards_{id}.yaml b/openapi/paths/cards/cards_{id}.yaml
index 4aa75103..ff74cd02 100644
--- a/openapi/paths/cards/cards_{id}.yaml
+++ b/openapi/paths/cards/cards_{id}.yaml
@@ -7,7 +7,11 @@ parameters:
type: string
get:
summary: Get a card
- description: Retrieve a card by its system-generated id.
+ description: >-
+ Retrieve a card by its system-generated id. This is the only endpoint
+ that returns a populated `panEmbedUrl` — a fresh, short-lived signed
+ URL is minted on each call. Fetch the card right before rendering the
+ PAN-reveal iframe.
operationId: getCardById
tags:
- Cards
diff --git a/openapi/webhooks/card-state-change.yaml b/openapi/webhooks/card-state-change.yaml
index da96c3bb..679fd812 100644
--- a/openapi/webhooks/card-state-change.yaml
+++ b/openapi/webhooks/card-state-change.yaml
@@ -58,7 +58,7 @@ post:
last4: '4242'
expMonth: 12
expYear: 2029
- panEmbedUrl: https://embed.lithic.com/iframe/...?t=...
+ panEmbedUrl: null
fundingSources:
- InternalAccount:019542f5-b3e7-1d02-0000-000000000002
currency: USD
@@ -78,6 +78,7 @@ post:
state: CLOSED
stateReason: ISSUER_REJECTED
form: VIRTUAL
+ panEmbedUrl: null
fundingSources:
- InternalAccount:019542f5-b3e7-1d02-0000-000000000002
currency: USD
@@ -99,6 +100,7 @@ post:
last4: '4242'
expMonth: 12
expYear: 2029
+ panEmbedUrl: null
fundingSources:
- InternalAccount:019542f5-b3e7-1d02-0000-000000000002
currency: USD