A small Express app: a signed-in user clicks Verify my identity, goes through KayWhySee, and comes back to a page that shows the result. It uses Node 18 or later, for the built-in fetch.
link Set up
Terminal
mkdir kyc-example && cd kyc-example
npm init -y
npm install express
export KAYWHYSEE_API_KEY="kyc_live_..."
link The API client
Three small functions cover the whole API. Errors throw with the API's own code and message.
kaywhysee.js
const BASE_URL = "https://www.kaywhysee.com/api/v1";
async function call(method, path, body) {
const response = await fetch(BASE_URL + path, {
method,
headers: {
Authorization: `Bearer ${process.env.KAYWHYSEE_API_KEY}`,
"Content-Type": "application/json",
},
body: body ? JSON.stringify(body) : undefined,
});
const data = await response.json();
if (!response.ok) {
const error = new Error(data.error?.message ?? `HTTP ${response.status}`);
error.code = data.error?.code;
error.status = response.status;
throw error;
}
return data;
}
export const createSession = (reference, redirectUrl) =>
call("POST", "/sessions", { reference, redirect_url: redirectUrl });
export const getSession = (id) => call("GET", `/sessions/${encodeURIComponent(id)}`);
export const cancelSession = (id) => call("POST", `/sessions/${encodeURIComponent(id)}/cancel`);
link The app
server.js
import express from "express";
import { createSession, getSession } from "./kaywhysee.js";
const app = express();
const sessions = new Map(); // your database, in real life: user id -> session id
// Your own sign-in decides who this is.
const currentUserId = (req) => "user_1042";
app.post("/verify", async (req, res) => {
const userId = currentUserId(req);
const session = await createSession(userId, "http://localhost:3000/verified");
sessions.set(userId, session.id);
res.redirect(303, session.start_url);
});
app.get("/verified", async (req, res) => {
// Arriving here proves nothing: always ask the API.
const session = await getSession(sessions.get(currentUserId(req)));
if (session.outcome === "clear") return res.send("You're verified.");
if (session.outcome === "rejected") return res.send("We couldn't verify you.");
res.send(`Thanks! We're checking your details (status: ${session.status}).`);
});
app.get("/", (req, res) =>
res.send('<form method="post" action="/verify"><button>Verify my identity</button></form>'),
);
app.listen(3000, () => console.log("http://localhost:3000"));
link Run it
Terminal
node server.js
Open http://localhost:3000, click the button and finish on your phone.
Add "type": "module" to your package.json to use import as above.