To integrate with Jekimo, your server needs to handle two main API calls: gettoken and check. Here’s how the process should be implemented:
The user visits your verification page or login page.
Optionally, you can define a minimum age required for access by passing a min-age and two-fa parameters during the gettoken request.
Your server makes a POST request to /v1.1/auth/gettoken with your API key and optional parameters like min-age.
Your page then displays the QR code (or the link) to the user. The user must scan the QR code with their phone app to authorize themselves.
Your server must periodically check the token status by calling /v1.1/auth/check every 5 seconds. The token is valid for 120 seconds.
Pass the token and your API key in the request headers.
Possible responses:
created — waiting for user to scan and authorize.OK — user successfully authorized.KO — user not recognized or authorization failed.OK, the user can be authenticated in your system (e.g., using their email address provided during login).KO, display an error message and allow the user to retry.OK or KO) is returned.The token is short-lived and tied to a single authorization session. Your server must handle retries gracefully if the token expires or if the user fails to authorize within the validity period.
curl -X POST "https://www.jekimo.com/app.php/v1.1/auth/gettoken" \
-H "x-api-key: YOUR_SECRET_API_KEY" \
-H "min-age: 18" \
-H "two-af: false" \
-H "Content-Type: application/x-www-form-urlencoded"
{
"token": "b916b66831cab6567be9956b6f87cf64c539f1f89e1f04577a8be24af73d5d8d",
"timestamp": 1764499200,
"qrcode": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA..."
"url": "https://www.jekimo.com/app.php/v1.1/en/user/login/b916b66831..."
}
{
"error": "Invalid API key"
}
curl -X POST "https://www.jekimo.com/app.php/v1.1/auth/check" \
-H "x-api-key: YOUR_SECRET_API_KEY" \
-H "token: b916b66831cab6567be9956b6f87cf64c539f1f89e1f04577a8be24af73d5d8d" \
-H "Content-Type: application/x-www-form-urlencoded"
{
"status": "created" // Waiting for user to scan QR code (valid for 120 seconds)
"risk": false // Initial risk value false
"pin": 0 // 0 for no two-factor authentication ( two-fa ), or a 6-digit number (e.g., 293812) you have to send to the user via email if twoaf is true and risk is flagged
}
{
"status": "OK" // User successfully authenticated
"risk": true // risk: true or false depending on Jekimo’s analysis of the user’s verification.
"pin": 0 // 0 for no two-factor authentication ( two-fa ), or a 6-digit number (e.g., 293812) you have to send to the user via email if twoaf is true and risk is flagged
}
{
"status": "KO" // User not recognized or failed authentication
"risk": true // risk value is true
"pin": 0 // 0 for no two-factor authentication ( two-fa ), or a 6-digit number (e.g., 293812) you have to send to the user via email if twoaf is true and risk is flagged
}
{
"error": "Invalid Token"
}
// your-website-url/jekimo-check.php
<?php
$token = $_POST['token'] ?? '';
$apiKey = 'YOUR_SECRET_API_KEY';
$ch = curl_init("https://www.jekimo.com/app.php/v1.1/auth/check");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"x-apy-key: $apiKey",
"token: $token",
"Content-Type: application/x-www-form-urlencoded"
]);
$response = curl_exec($ch);
curl_close($ch);
header('Content-Type: application/json');
echo $response; // Successful response: { "status": "OK", "risk": false, "pin": 0 }
?>
// JavaScript code to run on the page displaying the QR code or verification link
async function pollJekimo(token, attempt = 1) {
const maxAttempts = 24; // 24 calls max ~ 120 seconds
try {
const res = await fetch('your-website-url/jekimo-check.php', {
method: 'POST',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
body: `token=${encodeURIComponent(token)}`
});
const data = await res.json();
if (data.status === "OK") {
window.location.href = '/dashboard';
} else if (data.status === "KO") {
alert("Access denied: authentication failed.");
} else if (data.status === "created" && attempt < maxAttempts) {
setTimeout(() => pollJekimo(token, attempt + 1), 5000); // 5 seconds interval
} else if (attempt >= maxAttempts) {
alert("Verification timeout. Please try again.");
}
} catch (err) {
console.error(err);
if (attempt < maxAttempts) {
setTimeout(() => pollJekimo(token, attempt + 1), 5000);
} else {
alert("Verification timeout due to network error. Please try again.");
}
}
}
// start polling
pollJekimo('USER_TEMP_TOKEN_FROM_JEKIMO');