Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.yativo.com/llms.txt

Use this file to discover all available pages before exploring further.

Every card — virtual and physical — starts with pin_set: false. Cardholders must set their PIN before card details (card number, CVV) can be viewed, and before chip-and-PIN or ATM transactions will work. When you call the view-token endpoint and pin_set is false, the API returns a 422 PIN_NOT_SET error with a ready-to-use pin_setup_url. Open that URL in an iframe or WebView and the cardholder can set their PIN immediately — then retry the view-token request once the webhook confirms. Card PINs are set and changed through Yativo’s hosted secure page, powered by Gnosis Pay’s Partner Secure Elements (PSE). The cardholder types their PIN directly inside a sandboxed iframe hosted by Yativo. The PIN never passes through your backend.

How it works

1

Your backend requests a PIN view token

Call POST /v1/yativo-card/customers/{yativoCardId}/cards/{cardId}/view-token with enabled_views: ["pin"] using your issuer credentials. Pass your brand theme to customise the page.
2

You receive a secure_view_url

The response includes a short-lived secure_view_url and the current pin_set status for that card.
3

Show the hosted page to the cardholder

Open the URL in an <iframe>, mobile WebView, or a new browser tab in your app. The cardholder enters and confirms their 4-digit PIN inside the hosted page.
4

Gnosis Pay confirms via webhook

Once saved, Gnosis Pay fires physical.card.pin.changed. Yativo receives it and flips pin_set to true on the card record.
The same flow handles both initial PIN setup and PIN changes — use enabled_views: ["pin"] in both cases.

Request a PIN view token

Call this from your backend using your issuer access token.
POST /v1/yativo-card/customers/{yativoCardId}/cards/{cardId}/view-token
yativoCardId
string
required
The customer’s yativo_card_id.
cardId
string
required
The card ID — works for both virtual and physical cards.
enabled_views
array
required
Pass ["pin"] to show only the PIN form. Pass ["data", "pin"] to show card details and PIN together (only after pin_set: true).
theme
object
Brand the hosted page with your colours and logo. All fields optional.
FieldTypeDescription
accent_colorstringHex colour for buttons and highlights
background_colorstringPage background
panel_colorstringCard panel background
text_colorstringPrimary text
logo_urlstringYour logo at the top of the page
border_radiusnumberCorner radius in px (8–36)
font_familystringCSS font-family string
curl -X POST 'https://crypto-api.yativo.com/api/v1/yativo-card/customers/yativo_card_customer_8f9a..._1769031332068/cards/afeb85fe-02f8-48da-b61e-84ad02704167/view-token' \
  -H 'Authorization: Bearer YOUR_ISSUER_ACCESS_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "enabled_views": ["pin"],
    "theme": {
      "accent_color": "#6366f1",
      "background_color": "#f5f5f5",
      "logo_url": "https://yourapp.com/logo.png",
      "border_radius": 16
    }
  }'
{
  "success": true,
  "data": {
    "secure_view_url": "https://crypto-api.yativo.com/api/v1/yativo-card/view/eyJhbGci...",
    "expires_at": "2026-05-18T12:05:00.000Z",
    "last_four": "4291",
    "card_type": "virtual",
    "holder_name": "Jane Doe",
    "pin_set": false,
    "enabled_views": ["pin"],
    "requires_access_code": false
  }
}

Embed the hosted PIN page

Pass secure_view_url directly as the src of an iframe. No SDK or client-side JavaScript required.
<iframe
  src="https://crypto-api.yativo.com/api/v1/yativo-card/view/eyJhbGci..."
  title="Set Card PIN"
  width="420"
  height="520"
  style="border: 0; border-radius: 16px;"
  allow="clipboard-read; clipboard-write"
></iframe>
Recommended iframe dimensions: 420 × 520px for PIN-only. Use 420 × 740px if showing card details and PIN together.

Checking PIN status

pin_set is updated when Yativo receives the physical.card.pin.changed webhook from Gnosis Pay. It is not sourced from the Gnosis API — treat it as the last known state. You can read it from: Per-card, in GET /v1/card-issuer/customers/{customerId}:
{
  "card_id": "afeb85fe-02f8-48da-b61e-84ad02704167",
  "card_type": "virtual",
  "status": "active",
  "pin_set": false
}
Per-customer top-level (true only when every card has a PIN):
{
  "cards_count": 2,
  "pin_set": false,
  "next_action": "Card is active — customer must set card PIN before in-store (PSE) payments will work"
}
On the view-token responsedata.pin_set is returned every time you call the view-token endpoint. To list all customers who still need to set a PIN:
GET /v1/card-issuer/customers?status=card_created
Then filter the results by pin_set: false.
pin_set reflects the last state received via webhook and may lag if a webhook was delayed. If a cardholder reports unexpected PIN_NOT_SET errors after completing PIN setup, they can retry — the server will re-evaluate when the webhook catches up.

Webhook confirmation

Subscribe to physical.card.pin.changed on your webhook endpoint. Yativo updates pin_set: true automatically when this event arrives — no polling needed.
Payload example
{
  "event": "physical.card.pin.changed",
  "data": {
    "cardToken": "afeb85fe-02f8-48da-b61e-84ad02704167",
    "yativo_card_id": "yativo_card_customer_8f9a..._1769031332068"
  }
}

Notes

DetailValue
Works forVirtual and physical cards
PIN formatExactly 4 digits (00009999)
Initial setup & changeSame enabled_views: ["pin"] flow for both
PIN never touches your serverEntered directly in the Yativo-hosted iframe
Brand customisationPass theme in the token request — applies to the hosted PIN page
Confirmationphysical.card.pin.changed webhook → pin_set: true
pin_set sourceWebhook only — not from Gnosis API
Online vs chip PINPSE updates the online PIN. The chip syncs on first ATM use (physical cards)