Use this file to discover all available pages before exploring further.
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.
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:
Your backend calls POST /yativo-card/{yativoCardId}/cards/{cardId}/view-token
Yativo returns a secure_view_url — a hosted, tokenized page
Your frontend embeds that URL in an <iframe>
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.
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.
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}
Your frontend must never call the Yativo API directly with your credentials. Always proxy the token request through your backend:
Express.js
TypeScript SDK
Frontend (after fetch)
React
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/v1/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);});
import { YativoSDK } from '@yativo/crypto-sdk';const sdk = new YativoSDK({ baseURL: 'https://crypto-api.yativo.com/api/v1/', apiKey: process.env.YATIVO_API_KEY!, apiSecret: process.env.YATIVO_API_SECRET!,});// In your backend route handler:const result = await sdk.cards.getViewToken( 'yc_01HX9KZMB3F7VNQP8R2WDGT4E5', // yativoCardId 'card_01HX9KZMB3F7VNQP8R2WDGT4E5', // cardId { enabled_views: ['data', 'pin'], theme: { accent_color: '#813AE3', border_radius: 16, }, });// Send result.data.secure_view_url to your frontendreturn res.json({ url: result.data.secure_view_url });
<!-- Your frontend fetches the URL from your backend, then sets it on the iframe --><div id="card-view-wrapper"> <iframe id="card-iframe" title="Secure Card View" width="420" height="740" style="border:0;border-radius:16px;" allow="clipboard-read; clipboard-write"> </iframe></div><script> async function showCardDetails() { // Fetch from YOUR backend — never call Yativo directly from the browser const res = await fetch('/api/card-view-token', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ enabled_views: ['data', 'pin'] }), }); if (!res.ok) { console.error('Failed to get card view token'); return; } const { secure_view_url } = await res.json(); document.getElementById('card-iframe').src = secure_view_url; } showCardDetails();</script>
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.
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 codecurl -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
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 cardnode scripts/test-card-secure-view.js <api_key> <api_secret> <yativo_card_id> <card_id># With custom views and themeENABLED_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.