SDKs

Official LoomAPI SDKs for JavaScript/TypeScript, Python, and PHP.

SDKs

LoomAPI ships official SDKs for JavaScript/TypeScript, Python, and PHP. Each SDK wraps the full API surface, handles retries and rate-limit back-off, surfaces typed errors, and includes a verifyWebhookSignature utility.


JavaScript / TypeScript

Supports Node.js 18+ and all modern browsers. Ships both CJS and ESM builds.

npm install loomapi-js
import { LoomAPI, verifyWebhookSignature } from 'loomapi-js';

const client = new LoomAPI({ apiKey: process.env.LOOM_TENANT_API_KEY! });

// Start a verification
const { verificationId, sessionUrl } = await client.startVerification({
  userAgent: req.headers['user-agent'],
  ip: req.ip,
});

// Validate the token the user returns with
const { valid, over18 } = await client.validateToken({ token: tokenFromSession });
if (valid && over18) {
  // grant access
}

Webhook signature verification:

app.post('/webhooks/loom', express.raw({ type: 'application/json' }), (req, res) => {
  const signature = req.headers['x-webhook-signature'] as string;
  if (!verifyWebhookSignature(req.rawBody, signature, process.env.LOOM_WEBHOOK_SECRET!)) {
    return res.status(401).send('Unauthorized');
  }
  const event = JSON.parse(req.body);
  // handle event...
  res.sendStatus(200);
});

Python

Requires Python 3.8+ and requests.

pip install loomapi-python
from loomapi import LoomAPI, LoomAPIError, verify_webhook_signature

client = LoomAPI(api_key=os.environ['LOOM_TENANT_API_KEY'])

# Start a verification
verification = client.start_verification(
    user_agent=request.headers.get('User-Agent', ''),
    ip=request.remote_addr,
)

# Validate the token the user returns with
result = client.validate_token(token_from_session)
if result['valid'] and result['over18']:
    pass  # grant access

Webhook signature verification (Flask):

@app.route('/webhooks/loom', methods=['POST'])
def webhook():
    raw_body = request.get_data(as_text=True)
    signature = request.headers.get('X-Webhook-Signature', '')
    if not verify_webhook_signature(raw_body, signature, LOOM_WEBHOOK_SECRET):
        return 'Unauthorized', 401
    event = request.get_json()
    # handle event...
    return '', 200

PHP

Requires PHP 7.4+, ext-curl, and ext-json.

composer require loomapi/loomapi-php
use LoomAPI\LoomAPI;
use LoomAPI\LoomAPIException;

$client = new LoomAPI($_ENV['LOOM_TENANT_API_KEY']);

// Start a verification
$verification = $client->startVerification(
    $_SERVER['HTTP_USER_AGENT'] ?? '',
    $_SERVER['REMOTE_ADDR'] ?? ''
);

// Validate the token the user returns with
$result = $client->validateToken($tokenFromSession);
if ($result['valid'] && $result['over18']) {
    // grant access
}

Webhook signature verification:

$rawBody  = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'] ?? '';

if (!LoomAPI::verifyWebhookSignature($rawBody, $signature, getenv('LOOM_WEBHOOK_SECRET'))) {
    http_response_code(401);
    exit('Unauthorized');
}

$event = json_decode($rawBody, true);
// handle event...

Common features

All three SDKs provide:

FeatureDetail
All 5 endpointsstartVerification, completeVerification, validateToken, submitVerification, getVerificationStatus
Automatic retries429 respects Retry-After; 5xx uses exponential back-off (default 3 retries)
Structured errorsTyped error class with errorCode, statusCode, requestId, details
Rate-limit headersrateLimit.limit, rateLimit.remaining, rateLimit.reset on every response
Webhook utilityverifyWebhookSignature — HMAC-SHA256 with constant-time comparison

Error handling

Each SDK throws / raises a typed error for non-2xx responses:

// JS
try {
  await client.startVerification({});
} catch (e) {
  if (e instanceof LoomAPIError) {
    console.error(e.errorCode);   // e.g. 'UNAUTHENTICATED_TENANT'
    console.error(e.statusCode);  // e.g. 401
    console.error(e.requestId);   // correlate with support
  }
}

See Errors for all error codes and meanings.


Prefer the REST API directly?

If you do not want a library dependency, the REST API is small and works from any HTTP client. See the cURL examples and Node.js examples for copy-paste code.