Accédez au tableau de bord
Votre organisation est ouverte par l’équipe Sekyro AI. Un administrateur vous invite avec un rôle ; acceptez l’invitation avec l’adresse invitée.
Tous les rôles
Un lien hébergé sans code, ou l’API depuis votre serveur : choisissez l’intégration qui convient à votre équipe, testez-la en Sandbox, puis passez en Live.
Les quatre façons d’intégrer Sekyro AI, côte à côte. Commencez par la plus simple : vous pourrez en ajouter une autre plus tard sur la même application.
| Critère | Liens hébergés | API serveur | Web et React | iOS et Android |
|---|---|---|---|---|
| Disponibilité | Disponible | Disponible | À confirmer | Prévu |
| Code à écrire | Aucun | Votre serveur | Votre serveur et votre site | Votre serveur et votre application |
| Où la personne se vérifie | Page hébergée Sekyro AI, ouverte depuis un lien | Page hébergée de la session | Dans votre site | Dans votre application |
| Plateforme à déclarer | Aucune — une application sans plateforme sert les liens hébergés | Aucune | Web : origines autorisées | iOS : Team ID et bundle ID · Android : package et empreintes SHA-256 |
| Clé d’API | Non : les liens se créent dans le tableau de bord | Oui, côté serveur uniquement | Oui, côté serveur uniquement | Oui, côté serveur uniquement |
Faites défiler le tableau horizontalement
Le parcours d’une intégration, dans l’ordre où le tableau de bord le propose. Chaque étape indique qui peut la réaliser.
Votre organisation est ouverte par l’équipe Sekyro AI. Un administrateur vous invite avec un rôle ; acceptez l’invitation avec l’adresse invitée.
Tous les rôles
Nommez-la et choisissez ses plateformes. Le Web demande des origines autorisées, iOS et Android des identifiants. Sans plateforme, l’application sert l’API et les liens hébergés.
AdministrateurDéveloppeur
Partez d’un profil de départ et vérifiez l’aperçu des étapes. L’accès au registre dépend des droits de votre organisation.
AdministrateurDéveloppeur
Un administrateur crée la clé de l’application. Le secret n’est affiché qu’une fois : copiez-le dans votre gestionnaire de secrets.
Administrateur
Avec le démarrage rapide ci-dessous ou un lien hébergé, puis inspectez la session — et l’éventuelle revue — dans le tableau de bord.
AdministrateurDéveloppeur
Quand l’environnement Live est ouvert pour votre organisation, créez une clé Live et remplacez la clé Sandbox côté serveur.
Administrateur
Créez une session depuis votre serveur avec une clé Sandbox de votre application.
// Next.js Server Actions (App Router) backed by @sekyro/node.
//
// Two jobs live on YOUR server, never in the browser:
// 1. startVerification — create a session BOUND to the user's NNI and hand
// the page nothing but the one-time client token.
// 2. decideVerification — read the authoritative session and decide.
//
// The API key is a server secret. The client token is the end user's flow
// credential: returned once by `sessions.create`, never logged, never stored
// in a cookie or URL.
"use server";
import { Sekyro, SekyroApiError, type Session } from "@sekyro/node";
const sekyro = new Sekyro({
apiKey: requireEnv("SEKYRO_API_KEY"),
// Production is the default. For the sandbox set
// SEKYRO_API_BASE_URL=https://api-staging.sekyro.ai/api/v2 with an sk_test_ key.
baseUrl: process.env.SEKYRO_API_BASE_URL ?? "https://api.sekyro.ai/api/v2",
});
export interface StartVerificationResult {
sessionId: string;
/** Hand this to the page (`createVerification({ clientToken })`). Returned ONCE. */
clientToken: string;
/** ISO 8601 — the capture must finish before this. */
expiresAt: string;
}
/**
* Create a session bound to `nni`. The browser never sends the NNI: the SDK
* submits `population_registry` with an empty input and the server uses the
* bound value (a browser that sends a DIFFERENT nni gets 409 `nni_locked`).
*
* `attempt` is your own counter per user: the idempotency key makes a network
* retry of the SAME attempt return the SAME session instead of minting two.
*/
export async function startVerification(
userId: string,
nni: string,
attempt: number,
): Promise<StartVerificationResult> {
try {
const created = await sekyro.sessions.create(
// No recipe here: the API key belongs to an app, and the app's eKYC
// profile decides the steps (e.g. population_registry → liveness →
// face_match for the "Mauritania: registry" profile).
{ locale: "ar", input: { nni } },
{ idempotencyKey: `kyc:${userId}:${attempt}` },
);
// Persist the id BEFORE returning: the webhook can arrive before the page
// reports back, and your handler must be able to find the user by session.
await saveSessionId(userId, created.id);
return {
sessionId: created.id,
clientToken: created.clientToken,
expiresAt: created.expiresAt,
};
} catch (err) {
if (err instanceof SekyroApiError) {
// `retryable` covers network, timeout, 429, 5xx and idempotency_in_progress:
// back off and call again with the SAME idempotencyKey.
throw new Error(
`Sekyro AI ${err.code} (request ${err.requestId ?? "n/a"}), retryable=${err.retryable}`,
);
}
throw err;
}
}
export type Decision = "approved" | "rejected" | "pending" | "expired";
export interface DecideResult {
decision: Decision;
session: Session;
}
/**
* The ONLY place a verdict is decided. Call it when the page reports
* `onResult`, and again from your webhook handler on async transitions.
*/
export async function decideVerification(sessionId: string): Promise<DecideResult> {
const session = await sekyro.sessions.get(sessionId);
return { decision: decide(session), session };
}
function decide(session: Session): Decision {
switch (session.status) {
case "completed":
// `outcome` is `approved | review | rejected`; `review` here means a
// human decided the session is complete but flagged — treat as pending
// until your own policy says otherwise.
if (session.outcome === "approved") return "approved";
if (session.outcome === "rejected") return "rejected";
return "pending";
case "failed":
return "rejected";
case "review_pending":
// Parked for human review (up to 48 h). Wait for `session.review_decided`.
return "pending";
case "expired":
// The user did not finish in time: offer a new session.
return "expired";
case "created":
case "in_progress":
return "pending";
}
}
function requireEnv(name: string): string {
const value = process.env[name];
if (value === undefined || value === "") throw new Error(`${name} is not set`);
return value;
}
// Replace with your database write.
async function saveSessionId(_userId: string, _sessionId: string): Promise<void> {}Vous avez déjà un accès ? Connectez-vous avec Ibtikar ID pour gérer vos applications, vos clés et vos sessions.
Pas encore d’accès ? Votre organisation l’obtient auprès de l’équipe Sekyro AI, puis un administrateur vous invite.
Décrivez votre service et les personnes que vous devez vérifier. L’équipe Sekyro AI vous aide à choisir l’intégration et ouvre votre accès Sandbox.