SDK
JavaScript / TypeScript SDK
Official TypeScript/JavaScript SDK for the Truthlock platform. Fully typed, with automatic authentication, idempotency keys, retry with exponential backoff, and tree-shakeable exports.
Installation
Public package: The
@truthlock/sdk package is available on the public npm registry. No special configuration required.Terminalbash
npm install @truthlock/sdk
# or
yarn add @truthlock/sdk
# or
pnpm add @truthlock/sdkQuick Start
quickstart.tsTypeScript
import { TruthlockClient, Algorithm, Verdict } from '@truthlock/sdk';
// 1. Create client
const client = new TruthlockClient({
baseUrl: 'https://api.truthlocks.com',
auth: {
type: 'apiKey',
apiKey: 'tl_live_...',
tenantId: 'your-tenant-id',
},
});
// 2. Create and trust an issuer
const issuer = await client.issuers.create({
name: 'My Organization',
legal_name: 'My Organization Inc.',
display_name: 'My Org',
});
await client.issuers.trust(issuer.id);
// 3. Register a signing key
await client.keys.register(issuer.id, {
kid: 'key-2026',
alg: Algorithm.Ed25519,
public_key_b64url: 'your-public-key-base64url',
});
// 4. Mint an attestation (with optional email delivery)
const attestation = await client.attestations.mint({
issuer_id: issuer.id,
kid: 'key-2026',
alg: Algorithm.Ed25519,
schema: 'degree',
claims: {
student_name: 'Jane Doe',
institution: 'State University',
degree_type: 'Bachelor of Science',
field_of_study: 'Computer Science',
graduation_date: '2026-05-15',
},
recipient_email: 'jane.doe@example.com', // optional
});
console.log('Attestation ID:', attestation.id);
console.log('Log index:', attestation.log_index);
// 5. Verify the attestation
const result = await client.verify.verifyOnline({
attestation_id: attestation.id,
});
if (result.verdict === Verdict.Valid) {
console.log('Attestation verified successfully');
}Configuration
Configuration optionsTypeScript
const client = new TruthlockClient({
// Required
baseUrl: 'https://api.truthlocks.com', // API base URL
auth: { ... }, // See Authentication below
// Optional
timeout: 30_000, // Request timeout in ms (default: 30s)
maxRetries: 3, // Auto-retry with exponential backoff
idempotencyPrefix: 'my-app', // Prefix for auto-generated idempotency keys
});| Option | Type | Description |
|---|---|---|
baseUrlrequired | string | API endpoint URL. Use https://sandbox-api.truthlocks.com for testing. |
authrequired | AuthConfig | Authentication configuration. See Authentication section. |
timeout | number | Request timeout in milliseconds. Default: 30000. |
maxRetries | number | Max retries for transient errors (429, 500, 502, 503). Default: 3. |
idempotencyPrefix | string | Prefix for auto-generated idempotency keys on POST requests. |
Authentication
Three authentication methods are supported. API Key is recommended for server-side applications.
API Key (recommended)TypeScript
auth: {
type: 'apiKey',
apiKey: 'tl_live_...', // From Console > Settings > API Keys
tenantId: 'your-tenant-id', // From Console > Settings > General
}Bearer Token (session-based)TypeScript
auth: {
type: 'bearer',
token: 'eyJhbGciOi...', // JWT from login flow
}Service Key (machine-to-machine)TypeScript
auth: {
type: 'service',
apiKey: 'tl_svc_...',
tenantId: 'your-tenant-id',
}API Methods
All methods return typed Promises. For detailed request/response schemas, see the API Reference.
Issuers
| Method | HTTP | Description |
|---|---|---|
client.issuers.create(data) | POST | Create a new issuer organization |
client.issuers.get(id) | GET | Get issuer by UUID |
client.issuers.list() | GET | List all issuers for the tenant |
client.issuers.trust(id) | POST | Mark issuer as trusted (enables minting) |
client.issuers.suspend(id) | POST | Temporarily suspend an issuer |
client.issuers.revoke(id, reason) | POST | Permanently revoke an issuer |
Keys
| Method | HTTP | Description |
|---|---|---|
client.keys.register(issuerId, data) | POST | Register an Ed25519 signing key |
client.keys.list(issuerId) | GET | List all keys for an issuer |
client.keys.rotate(kid, data) | POST | Rotate a signing key |
client.keys.reportCompromise(kid) | POST | Report a key as compromised |
Attestations
| Method | HTTP | Description |
|---|---|---|
client.attestations.mint(data) | POST | Mint a new signed attestation |
client.attestations.get(id) | GET | Get attestation by ID |
client.attestations.list() | GET | List attestations with filters |
client.attestations.revoke(id, data) | POST | Revoke an attestation |
client.attestations.supersede(id, data) | POST | Replace with a new version |
client.attestations.getProofBundle(id) | GET | Get cryptographic proof bundle |
Verification
| Method | HTTP | Description |
|---|---|---|
client.verify.verifyOnline(data) | POST | Verify attestation against transparency log |
API Keys
| Method | HTTP | Description |
|---|---|---|
client.apiKeys.list() | GET | List all API keys |
client.apiKeys.create(data) | POST | Create a new API key |
client.apiKeys.revoke(id) | DELETE | Revoke an API key |
Audit
| Method | HTTP | Description |
|---|---|---|
client.audit.query(params) | GET | Query audit event log |
client.audit.export(data) | POST | Export audit log as CSV/JSON |
Governance
| Method | HTTP | Description |
|---|---|---|
client.governance.listRequests() | GET | List pending governance requests |
client.governance.createRequest(data) | POST | Submit a governance request |
client.governance.approveRequest(id) | POST | Approve a governance request |
client.governance.executeRequest(id) | POST | Execute an approved request |
Error Handling
All API errors throw a typed TruthlockError with the error code, message, and HTTP status.
Error handlingTypeScript
import { TruthlockError, ErrorCode } from '@truthlock/sdk';
try {
await client.attestations.mint(data);
} catch (err) {
if (err instanceof TruthlockError) {
console.error('Code:', err.code); // e.g. "ISSUER_NOT_TRUSTED"
console.error('Message:', err.message); // Human-readable message
console.error('Status:', err.status); // HTTP status code
switch (err.code) {
case ErrorCode.IssuerNotTrusted:
// Issuer needs to be trusted before minting
break;
case ErrorCode.KeyNotFound:
// Signing key not registered
break;
case ErrorCode.QuotaExceeded:
// Plan limit reached
break;
}
}
}| Error Code | Status | Description |
|---|---|---|
ISSUER_NOT_TRUSTED | 403 | Issuer must be trusted before minting |
KEY_NOT_FOUND | 404 | Signing key not registered for this issuer |
QUOTA_EXCEEDED | 429 | Minting or verification quota exhausted |
INVALID_SCHEMA | 400 | Schema ID not recognized |
DUPLICATE_IDEMPOTENCY | 409 | Idempotency key already used |
PAYLOAD_TOO_LARGE | 413 | Payload exceeds 50 MB limit |
Examples
Batch Minting
batch-mint.tsTypeScript
const employees = [
{ name: 'Alice', id: 'EMP-001', dept: 'Engineering' },
{ name: 'Bob', id: 'EMP-002', dept: 'Design' },
{ name: 'Carol', id: 'EMP-003', dept: 'Product' },
];
const results = await Promise.allSettled(
employees.map(emp =>
client.attestations.mint({
issuer_id: issuerId,
kid: 'key-2026',
alg: Algorithm.Ed25519,
schema: 'employment-verification',
claims: {
employee_name: emp.name,
employer: 'Acme Corp',
position: 'Staff',
department: emp.dept,
employment_type: 'Full-time',
start_date: '2026-01-15',
},
recipient_email: `${emp.name.toLowerCase()}@acme.com`,
})
)
);
const succeeded = results.filter(r => r.status === 'fulfilled').length;
console.log(`Minted ${succeeded}/${employees.length} attestations`);Webhook Signature Verification
webhook.tsTypeScript
import { verifyWebhookSignature } from '@truthlock/sdk';
app.post('/webhooks/truthlock', (req, res) => {
const signature = req.headers['x-truthlock-signature'];
const isValid = verifyWebhookSignature(
req.body,
signature,
process.env.WEBHOOK_SECRET!,
);
if (!isValid) {
return res.status(401).json({ error: 'Invalid signature' });
}
const event = req.body;
switch (event.type) {
case 'attestation.minted':
console.log('New attestation:', event.data.id);
break;
case 'attestation.revoked':
console.log('Revoked:', event.data.id);
break;
}
res.status(200).json({ received: true });
});Requirements
| Node.js | >= 18.0 |
| TypeScript | >= 4.7 (optional but recommended) |
| Package Manager | npm, yarn, or pnpm |
| Registry Token | Required from Truthlocks Console |