Référence API

Documentation complète de l'API ZYKAY.

URLs

ServiceURL
Widget (script tag)https://widget-app.zykay.com/v4/loader.min.js
API Partnerhttps://api.zykay.com

Endpoints

POST /v1/exchange

Échange un grant_code contre un pass_token et les résultats de vérification.

Documentation complète

Exemple rapide :

curl -X POST https://api.zykay.com/v1/exchange \
  -H "Content-Type: application/json" \
  -H "X-Partner-ID: pk_live_xxx" \
  -H "X-Partner-Timestamp: 1700000000" \
  -H "X-Partner-Nonce: 550e8400-e29b-41d4-a716-446655440000" \
  -H "X-Partner-Signature: IiqKqzxLThjE4anzR2UGycy5JrJKSjjD2m3R81RxsW8" \
  -d '{"grant_code":"g_abc123..."}'

Réponse :

{
  "pass_token": "p_xyz789...",
  "expires_in": 14400,
  "age_over_18": true,
  "scopes": ["isAdult"],
  "attributes": {
    "age_over_18": true
  }
}

POST /v1/introspect

Vérifie la validité d'un pass_token et retourne les attributs de vérification.

Documentation complète

Exemple rapide :

curl -X POST https://api.zykay.com/v1/introspect \
  -H "Content-Type: application/json" \
  -H "X-Partner-ID: pk_live_xxx" \
  -H "X-Partner-Timestamp: 1700000000" \
  -H "X-Partner-Nonce: 550e8400-e29b-41d4-a716-446655440000" \
  -H "X-Partner-Signature: ..." \
  -d '{"pass_token":"p_xyz789..."}'

Réponse :

{
  "active": true,
  "scope": "multi_scope_verification",
  "attributes": {
    "age_over_18": true,
    "is_french": true
  },
  "scopes_verified": ["isAdult", "isFrench"]
}

Authentification HMAC

Toutes les requêtes à l'API doivent être signées avec HMAC-SHA256.

Headers requis

HeaderDescription
X-Partner-IDVotre Partner ID (pk_live_xxx)
X-Partner-TimestampTimestamp Unix en secondes
X-Partner-NonceUUID v4 unique par requête
X-Partner-SignatureSignature HMAC-SHA256 (base64url)

Génération de la signature

const crypto = require('crypto');
 
function base64url(buffer) {
  return buffer.toString('base64')
    .replace(/\+/g, '-')
    .replace(/\//g, '_')
    .replace(/=+$/, '');
}
 
// 1. Hash du body (SHA256)
const bodyHash = base64url(
  crypto.createHash('sha256').update(JSON.stringify(body)).digest()
);
 
// 2. Chaîne canonique
const canonical = `${bodyHash}.${timestamp}.${partnerId}.${nonce}`;
 
// 3. IMPORTANT: Décoder le secret base64
const secretBytes = Buffer.from(partnerSecret, 'base64');
 
// 4. Signature HMAC
const signature = base64url(
  crypto.createHmac('sha256', secretBytes).update(canonical).digest()
);
⚠️

Le Partner Secret est encodé en base64. Vous DEVEZ le décoder avant de l'utiliser pour HMAC.

Scopes disponibles

ScopeTypeRésultatPDFPortefeuille EUDI
isAdultBinaireage_over_18: trueOuiOui
isFrenchBinaireis_french: trueOuiOui
isEUBinaireis_eu: trueOuiOui
isMaleBinaireis_male: trueOuiNon
isFemaleBinaireis_female: trueOuiNon
isUniqueNullifiernullifier: "0x..."OuiOui
revealNationalityDisclosurenationality: "FRA"OuiNon
revealBirthYearDisclosurebirth_year: 1990OuiNon
⚠️

isMale et isFemale sont mutuellement exclusifs. Les scopes marqués Non pour le Portefeuille EUDI ne sont pas disponibles avec data-client-proof-mode="true".

Référence complète des scopes

Codes d'erreur

CodeHTTPDescription
MISSING_HEADERS401Headers requis manquants
INVALID_PARTNER403Partner ID non reconnu
TIMESTAMP_SKEW401Timestamp décalé > 5 minutes
INVALID_SIGNATURE401Signature HMAC incorrecte
REPLAY_DETECTED401Nonce déjà utilisé
INVALID_GRANT400Grant code invalide ou expiré

Liste complète des codes d'erreur

Rate limits

Les limites publiées et la stratégie de retry sont documentées ici:

Politique de Rate-Limit

Documentation