Backend Verification & Webhooks
To guarantee security and prevent client-side response tampering, your backend server should always perform server-to-server verification or listen for webhooks before granting user access or updating account states.
1. Backend Session Lookup API
When the client-side SDK finishes a verification flow, it returns a session_id. Send this session_id to your backend server, where your server can query Prembly's backend API securely using your Secret Key.
Endpoint Specification
GET /api/v1/checker-widget/sdk/sessions/{session_id}/ HTTP/1.1
Host: api.prembly.com
x-api-key: your_secret_api_key
x-organisation-id: your_org_id
Content-Type: application/jsonRequest Headers
| Header | Description | Required |
|---|---|---|
x-api-key | Your Secret API Key (found in Integrations & API in the dashboard). | Yes |
x-organisation-id | Your Prembly Organisation ID. | Yes |
Response Example
{
"status": true,
"detail": "Session fetched successfully",
"response": {
"session_id": "550e8400-e29b-41d4-a716-446655440000",
"verification_status": "VERIFIED",
"user_ref": "usr_9921",
"confidence_score": 0.98,
"created_at": "2026-10-06T10:00:00Z",
"metadata": {
"internal_user_id": "usr_9921",
"plan": "premium"
}
}
}2. Webhook Integration
Configure a HTTP POST webhook endpoint in your Prembly dashboard (Integrations & API → Webhook Settings) to receive real-time notifications when a user completes a verification session asynchronously.
Node.js / Express Webhook Listener Example
const express = require('express');
const app = express();
app.post('/api/webhooks/prembly', express.json(), async (req, res) => {
try {
const { event, session_id, data } = req.body;
console.log(`Received Prembly Webhook Event: ${event}`);
if (event === 'verification.completed') {
const { user_ref, metadata, verification_status } = data;
if (verification_status === 'VERIFIED') {
console.log(`User ${user_ref} successfully verified for session ${session_id}`);
// Update user status in your internal database
await updateUserVerificationState(metadata.internal_user_id, true);
} else {
console.warn(`User ${user_ref} verification failed or incomplete.`);
}
}
// Always respond quickly with 200 OK to acknowledge receipt
return res.status(200).json({ received: true });
} catch (err) {
console.error('Error processing webhook:', err);
return res.status(500).json({ error: 'Webhook processing failed' });
}
});
app.listen(3000, () => console.log('Webhook server running on port 3000'));Python / FastAPI Webhook Listener Example
from fastapi import FastAPI, Request, Response, status
app = FastAPI()
@app.post("/api/webhooks/prembly")
async def prembly_webhook_handler(request: Request):
payload = await request.json()
event = payload.get("event")
session_id = payload.get("session_id")
data = payload.get("data", {})
if event == "verification.completed":
verification_status = data.get("verification_status")
metadata = data.get("metadata", {})
if verification_status == "VERIFIED":
# Process verification logic securely
print(f"Session {session_id} verified for internal ID: {metadata.get('internal_user_id')}")
return Response(content='{"received": true}', status_code=status.HTTP_200_OK, media_type="application/json")Webhook Best Practices
- Idempotency: Webhook requests may occasionally be retried by the server. Ensure your processing logic checks if a
session_idhas already been processed in your database before executing duplicate side effects. - Fast Response: Always respond to webhook HTTP POST requests with a
200 OKstatus immediately before running heavy background processes. - Reconciliation: Use custom key-value pairs inside the
metadataobject (internal_user_id,order_id, etc.) to reconcile incoming webhook payloads with your database records easily.