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);
});
- Full reference: npm — loomapi-js
- Source: github.com/loomapi/loomapi-js
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
- Full reference: pypi.org/project/loomapi-python
- Source: github.com/loomapi/loomapi-python
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...
- Full reference: packagist.org/packages/loomapi/loomapi-php
- Source: github.com/loomapi/loomapi-php
Common features
All three SDKs provide:
| Feature | Detail |
|---|---|
| All 5 endpoints | startVerification, completeVerification, validateToken, submitVerification, getVerificationStatus |
| Automatic retries | 429 respects Retry-After; 5xx uses exponential back-off (default 3 retries) |
| Structured errors | Typed error class with errorCode, statusCode, requestId, details |
| Rate-limit headers | rateLimit.limit, rateLimit.remaining, rateLimit.reset on every response |
| Webhook utility | verifyWebhookSignature — 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.