Toucan Tokenization Overview

Toucan by Pagos allows you to either replace or augment your current vaulting strategy to begin using network tokens in the place of primary account numbers (PAN). With Toucan, we make it easy for you to access network services directly with your own dedicated account, and control how and where you deploy network tokenization.

This guide outlines the Toucan process to make network tokenization more accessible:

  1. Authentication with Toucan
  2. Provisioning a token from a primary account number (PAN)
  3. Obtaining a cryptogram for transacting with the network token
  4. Getting the status of a token



Check out our Toucan Testing guide to get access to the Toucan Sandbox.


To ensure only authorized entities access our services, we authenticate the identity of each client that submits requests to Toucan services. Learn more in our Toucan Authentication guide.

Provisioning a Network Token

“Provisioning a network token” refers to the step you take to convert a PAN into a network token. This is the critical step that signals to an issuer that your company is establishing a relationship with a cardholder that will persist over time. Every time you use the network token for a transaction, that context is accessible to the issuer.

You can provision a network token on POST: /tokenize

Transacting With a Network Token

Before you can process a transaction with a network token, you must first fetch a cryptogram for that token. A cryptogram is an issuer-generated value for the transaction you’re processing, and is a key mechanism to the additional trust issuing banks give network tokens.

You can test this using the API on POST: /transact


Keep in Mind

When you sell recurring subscriptions, you aren’t required to fetch a cryptogram at this time—you can use the details of the token and the expiration date.

Getting the Status of a Network Token

Once you have provisioned a network token there will be instances when you will want to check the token status and basic token information, such as network, last 4 digits of the PAN, or expiration date for the underlying PAN.

There are three possible statuses that a network token can be in:

  1. Active - the token is active and can be used to transact with
  2. Suspended - the token is temporarily suspended by the merchant
  3. Deleted - the token has been deleted by the merchant

You can test this using the API on GET: /status

Client Sample

The following example demonstrates a tokenize call, transact call, and token status call with a Mastercard test card:

import fetch from "node-fetch";
import forge from "node-forge";

const config = {
   CLIENTKEY: process.env.CLIENTKEY,
   APIHOST: process.env.APIHOST

if(config.CLIENTKEY == null || config.PRIVATEKEY == null || config.APIHOST == null) {
   console.log("please set CLIENTKEY, PRIVATEKEY and APIHOST as environment vars");

const authorizationScheme = 'V1-HMAC-SHA256';

function computeHash(message, base64key) {
   var key = forge.util.decode64(base64key);
   var hmac = forge.hmac.create();
   hmac.start('sha256', key);
   return forge.util.encode64(hmac.digest().bytes());

function createAuthHeader(clientKey, date, privateKey, bodyJ) {
   var payloadToSign = clientKey + date + bodyJ;

   var computedSignature = computeHash(payloadToSign, privateKey);
   let header = authorizationScheme + ', Signature: ' + computedSignature;
   return header;

function createHeaders(cfg, bodyJSON, contentType = 'application/json') {
   let date=new Date().toISOString();
   let authHeader = createAuthHeader(cfg.CLIENTKEY, date, cfg.PRIVATEKEY, bodyJSON);
   let headers = {
       'X-Client-Key': cfg.CLIENTKEY,
       'X-Date': date,
       'Authorization': authHeader
   if(contentType != null)
       headers['Content-Type'] = contentType;
   return headers;

async function tokenize(cfg, cardToTokenize ) {
   let bodyJSON = JSON.stringify(cardToTokenize);
   let headers = createHeaders(cfg, bodyJSON);
   const res = await fetch(`${cfg.APIHOST}/api/tokenize`, {
     headers: headers,
     method: 'POST',
     body: bodyJSON
   return await res.json();

async function transact(cfg, tokenRef) {
   let bodyJSON = JSON.stringify({});
   let headers = createHeaders(cfg, bodyJSON);
   const res = await fetch(`${cfg.APIHOST}/api/transact/${tokenRef}`, {
     method: 'POST',
     body: bodyJSON

   return await res.json();

async function tokenStatus(cfg, tokenRef) {
   let headers = createHeaders(cfg, "", "");
   const res = await fetch(`${cfg.APIHOST}/api/tokens/${tokenRef}/status`, {
       method: 'GET',

   return await res.json();

let card = {
   'accountNumber': '5204736150000216',
   'expirationDate': {
       'year': '2022',
       'month': '12'

// test runner
(async () => {
   // tokenize a card,
   let token = await tokenize(config, card);

   // create a cryptogram
   let cryptogram = await transact(config, token.toucanTokenRefId);
   // fetch a status of a token   
   let status = await tokenStatus(config, token.toucanTokenRefId);

 # how to run

 npm install node-forge
 npm install node-fetch
 # edit package.json, add a key "type": "module"
 # in your shell, set
 export CLIENTKEY=somekey
 export PRIVATEKEY=someprivatekey
 export APIHOST=

 # run job
 node toucan.js