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/json

Request Headers

HeaderDescriptionRequired
x-api-keyYour Secret API Key (found in Integrations & API in the dashboard).Yes
x-organisation-idYour 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

  1. Idempotency: Webhook requests may occasionally be retried by the server. Ensure your processing logic checks if a session_id has already been processed in your database before executing duplicate side effects.
  2. Fast Response: Always respond to webhook HTTP POST requests with a 200 OK status immediately before running heavy background processes.
  3. Reconciliation: Use custom key-value pairs inside the metadata object (internal_user_id, order_id, etc.) to reconcile incoming webhook payloads with your database records easily.