Skip to main content
Card details (PAN, CVV, expiry) and the card PIN each use separate view tokens. You must request the correct enabled_views for each use case. Never reuse a token between sessions.

How it works

Sensitive card data is never returned in plain API responses. Instead, Yativo hosts a secure card view page and provides you with a short-lived URL to embed in your application:
  1. Your backend calls POST /yativo-card/{yativoCardId}/cards/{cardId}/view-token
  2. Yativo returns a secure_view_url — a hosted, tokenized page
  3. Your frontend embeds that URL in an <iframe>
  4. The hosted page renders the sensitive data directly — your application never touches the raw values
View tokens expire quickly. Always request a fresh token immediately before rendering and never cache or log secure_view_url.

Step 1 — Request a view token

Call this from your backend. The token is scoped to the views you request.
POST /yativo-card/{yativoCardId}/cards/{cardId}/view-token
yativoCardId
string
required
The Yativo Card account ID (yativo_card_id) returned during onboarding.
cardId
string
required
The card ID from card creation.
enabled_views
array
Which views to enable on the hosted page. Accepted values: "data" (card number, CVV, expiry), "pin" (view/set PIN). Omit to show all available views.
access_code
string
Optional extra PIN or unlock code the user must enter before the card details are revealed. Adds an additional layer of protection for high-security flows.
theme
object
Optional theme customization for the hosted page. All fields are optional.
theme.accent_color
string
Primary brand color (hex). Default: #813AE3
theme.background_color
string
Page background color (hex).
theme.panel_color
string
Card panel background color (hex).
theme.text_color
string
Primary text color (hex).
theme.muted_color
string
Secondary/muted text color (hex).
theme.border_radius
number
Border radius in pixels.
theme.font_family
string
CSS font-family string (e.g. "Inter, sans-serif").
theme.logo_url
string
URL of your logo to display on the hosted page.
curl -X POST 'https://crypto-api.yativo.com/api/yativo-card/yc_01HX9KZMB3F7VNQP8R2WDGT4E5/cards/card_01HX9KZMB3F7VNQP8R2WDGT4E5/view-token' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "enabled_views": ["data"]
  }'
{
  "status": "success",
  "data": {
    "secure_view_url": "https://crypto-api.yativo.com/api/card-view?token=eyJhbGciOiJIUzI1NiIs...",
    "expires_at": "2026-03-26T12:01:00Z",
    "last_four": "4242",
    "enabled_views": ["data", "pin"],
    "requires_access_code": false
  }
}
interface ViewTokenResponse {
  secure_view_url: string;          // Hosted page URL — embed this in an iframe
  expires_at: string;               // ISO 8601 — token is invalid after this
  last_four: string;                // Last 4 digits — safe to display without the iframe
  enabled_views: string[];          // Which views are active: ["data"] | ["pin"] | ["data", "pin"]
  requires_access_code: boolean;    // True if access_code was set; user must enter it before details are shown
}

Step 2 — Embed the iframe

Pass the secure_view_url directly as the src of an iframe. No SDK or additional JavaScript is required.
<iframe
  src="https://crypto-api.yativo.com/api/card-view?token=eyJhbGciOiJIUzI1NiIs..."
  title="Secure Card View"
  width="420"
  height="740"
  style="border: 0; border-radius: 16px;"
  allow="clipboard-read; clipboard-write"
></iframe>
The hosted page is fully responsive. Recommended dimensions: 420 × 740px for card details, 420 × 520px for PIN-only views.

Step 3 — Backend proxy (required)

Your frontend must never call the Yativo API directly with your credentials. Always proxy the token request through your backend:
import express from 'express';

const app = express();
app.use(express.json());

app.post('/api/card-view-token', async (req, res) => {
  // 1. Authenticate your own user first
  const user = await authenticateRequest(req);
  if (!user) return res.status(401).json({ error: 'Unauthorized' });

  const { enabled_views, access_code, theme } = req.body;

  // 2. Validate enabled_views — only accept known values
  const VALID_VIEWS = ['data', 'pin'];
  if (enabled_views && !enabled_views.every(v => VALID_VIEWS.includes(v))) {
    return res.status(400).json({ error: 'Invalid enabled_views' });
  }

  // 3. Look up this user's card IDs from your own database
  const { yativoCardId, cardId } = await getUserCardIds(user.id);

  // 4. Call Yativo from your backend — credentials never leave the server
  const response = await fetch(
    `https://crypto-api.yativo.com/api/yativo-card/${yativoCardId}/cards/${cardId}/view-token`,
    {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${process.env.YATIVO_API_KEY}`,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        ...(enabled_views ? { enabled_views } : {}),
        ...(access_code ? { access_code } : {}),
        ...(theme ? { theme } : {}),
      }),
    }
  );

  if (!response.ok) {
    return res.status(502).json({ error: 'Failed to get view token' });
  }

  const data = await response.json();
  // Return only the URL — do not cache it
  res.json(data.data);
});

View options reference

enabled_views valueWhat the hosted page shows
["data"]Card number (PAN), CVV, expiry — no PIN tab
["pin"]View current PIN / set new PIN — no card number tab
["data", "pin"]Both tabs, user can switch between them
Card data and PIN are rendered by separate internal components on the hosted page. Each view type is independently secured — requesting ["data"] does not expose any PIN functionality.

Access code flow

When you pass access_code in the token request, requires_access_code: true is returned. The hosted page will prompt the user to enter that code before revealing any card details. Use this for:
  • Confirming user intent before showing the full card number
  • Adding a secondary verification step in high-value contexts
# Request with access code
curl -X POST '.../view-token' \
  -d '{ "enabled_views": ["data"], "access_code": "7291" }'

# Your user will see a prompt to enter 7291 before card details are shown

Testing

Use the test script in the backend repo to verify the full flow against your running server:
# Basic test (picks first card on the account)
node scripts/test-card-secure-view.js <api_key> <api_secret>

# Target a specific card
node scripts/test-card-secure-view.js <api_key> <api_secret> <yativo_card_id> <card_id>

# With custom views and theme
ENABLED_VIEWS=data,pin THEME_ACCENT_COLOR=#813AE3 \
  node scripts/test-card-secure-view.js <api_key> <api_secret>
The script will print the secure_view_url and a ready-to-paste iframe snippet.

Virtual Cards

Create and manage virtual cards.

API Reference — View Token

Full parameter reference for the view-token endpoint.