Skip to main content
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. To let a cardholder set their PIN, call the view-token endpoint with enabled_views: ["pin-set"]. The API always returns 200 OK with a secure_view_url for PIN setup — regardless of whether pin_set is true or false. Open that URL in an iframe or WebView and the cardholder can set (or change) their PIN directly.
The 422 PIN_NOT_SET error only occurs when you request card data or PIN reveal (enabled_views: ["data"], ["pin-view"]) while pin_set is still false. It does not occur when requesting ["pin-set"] to set the PIN.
Card PINs are set and changed through Yativo’s hosted secure page, powered by the card network’s Partner Secure Elements (PSE) service. 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-set"] for initial setup or PIN change, or ["pin-view"] to reveal the current PIN. Pass your brand theme to customise the page.
2

You receive a secure_view_url

The API returns 200 OK with a short-lived secure_view_url and the current pin_set status. This always succeeds for ["pin-set"] requests — even when pin_set is false.
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

Card network confirms via webhook

Once saved, the card network 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-set"] in both cases.

Request a PIN view token

Call this from your backend using your issuer access 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
Controls which tabs appear on the hosted page. Accepted values:Pass ["pin-set"] for initial setup or PIN change. Pass ["data", "pin-view", "pin-set"] to show all three tabs at once. The legacy value "pin" is accepted as an alias for "pin-set".
theme
object
Brand the hosted page with your colours and logo. All fields optional.

Embed the hosted PIN page

Pass secure_view_url directly as the src of an iframe. No SDK or client-side JavaScript required.
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 the card network. It is not sourced from a direct API lookup — treat it as the last known state. You can read it from: Per-card, in GET /v1/card-issuer/customers/{customerId}:
Per-customer top-level (true only when every card has a PIN):
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:
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

Notes