Quickstart

Get up and running with LoomAPI in minutes.

You can get a prototype integration running in under 15 minutes.

This guide walks you through the four-step verification flow: getting an API key, starting a verification, completing it with evidence, and validating the resulting JWT token. Code examples are provided in Node.js, Python, and PHP. Once you have a token, you can gate access to age-restricted content without handling raw ID data.

Verification Flow

Start VerificationPOST /verify/startVerification IDStore this IDCompletePOST /verify/completeJWT TokenIf approvedRejected

Step 1: Get Your API Key

Before you can make API calls, you need a tenant account and API key.

Quick Options:

Each tenant gets an isolated environment with separate rate limits, quotas, and billing. Test accounts use the mock provider and are free up to a usage cap.

Once you have your API key, include it in the x-tenant-api-key header for all requests. Keep this key secure—it authenticates all API calls for your tenant.

Step 2: Start a verification

Call POST /verify/start to initiate a verification session. You'll need to provide the user's userAgent and ipaddress for rate limiting and fraud detection.

The response includes a verificationId that uniquely identifies this verification session. Store this ID—you'll need it in the next step to complete the verification.

javascript
const response = await fetch('https://project-halo-api.onrender.com/verify/start', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'x-tenant-api-key': 'your-api-key-here',
  },
  body: JSON.stringify({
    userAgent: 'Mozilla/5.0...',
    ip: '192.168.1.1',
  }),
});

if (!response.ok) {
  const error = await response.json();
  throw new Error(`API Error: ${error.error} - ${error.message}`);
}

const data = await response.json();
console.log('Verification ID:', data.verificationId);

Step 3: Complete a verification

Once you have verification evidence (from your identity provider like Veriff), call POST /verify/complete with the verificationIdfrom step 2 and your evidence object.

If the verification is approved, the response includes a JWT token. This token is time-limited (default 24 hours) and contains verification metadata without any PII. Store this token securely—you'll use it to validate access on subsequent requests.

javascript
const response = await fetch('https://project-halo-api.onrender.com/verify/complete', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'x-tenant-api-key': 'your-api-key-here',
  },
  body: JSON.stringify({
    verificationId: 'verification-id-from-start',
    evidence: {}, // Your verification evidence
  }),
});

if (!response.ok) {
  const error = await response.json();
  throw new Error(`API Error: ${error.error} - ${error.message}`);
}

const data = await response.json();
if (data.status === 'approved') {
  console.log('Token:', data.token);
} else {
  console.log('Verification rejected:', data.status);
}

Step 4: Validate token

On each request where you need to verify age, call POST /tokens/validatewith the JWT token from step 3. This endpoint checks that the token is valid, not expired, and belongs to your tenant.

The response includes valid (boolean) and over18(boolean) fields. If both are true, grant access to age-restricted content. If the token is invalid or expired, prompt the user to complete a new verification.

javascript
const response = await fetch('https://project-halo-api.onrender.com/tokens/validate', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'x-tenant-api-key': 'your-api-key-here',
  },
  body: JSON.stringify({
    token: 'jwt-token-from-verification',
  }),
});

if (!response.ok) {
  const error = await response.json();
  throw new Error(`API Error: ${error.error} - ${error.message}`);
}

const data = await response.json();
if (data.valid && data.over18) {
  console.log('User is verified and over 18');
} else {
  console.log('Token invalid or user under 18:', data.reason);
}