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.

InstallationQuick StartConfigurationAuthenticationAPI MethodsError HandlingExamples

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

Quick 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
});
OptionTypeDescription
baseUrlrequiredstringAPI endpoint URL. Use https://sandbox-api.truthlocks.com for testing.
authrequiredAuthConfigAuthentication configuration. See Authentication section.
timeoutnumberRequest timeout in milliseconds. Default: 30000.
maxRetriesnumberMax retries for transient errors (429, 500, 502, 503). Default: 3.
idempotencyPrefixstringPrefix 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

MethodHTTPDescription
client.issuers.create(data)POSTCreate a new issuer organization
client.issuers.get(id)GETGet issuer by UUID
client.issuers.list()GETList all issuers for the tenant
client.issuers.trust(id)POSTMark issuer as trusted (enables minting)
client.issuers.suspend(id)POSTTemporarily suspend an issuer
client.issuers.revoke(id, reason)POSTPermanently revoke an issuer

Keys

MethodHTTPDescription
client.keys.register(issuerId, data)POSTRegister an Ed25519 signing key
client.keys.list(issuerId)GETList all keys for an issuer
client.keys.rotate(kid, data)POSTRotate a signing key
client.keys.reportCompromise(kid)POSTReport a key as compromised

Attestations

MethodHTTPDescription
client.attestations.mint(data)POSTMint a new signed attestation
client.attestations.get(id)GETGet attestation by ID
client.attestations.list()GETList attestations with filters
client.attestations.revoke(id, data)POSTRevoke an attestation
client.attestations.supersede(id, data)POSTReplace with a new version
client.attestations.getProofBundle(id)GETGet cryptographic proof bundle

Verification

MethodHTTPDescription
client.verify.verifyOnline(data)POSTVerify attestation against transparency log

API Keys

MethodHTTPDescription
client.apiKeys.list()GETList all API keys
client.apiKeys.create(data)POSTCreate a new API key
client.apiKeys.revoke(id)DELETERevoke an API key

Audit

MethodHTTPDescription
client.audit.query(params)GETQuery audit event log
client.audit.export(data)POSTExport audit log as CSV/JSON

Governance

MethodHTTPDescription
client.governance.listRequests()GETList pending governance requests
client.governance.createRequest(data)POSTSubmit a governance request
client.governance.approveRequest(id)POSTApprove a governance request
client.governance.executeRequest(id)POSTExecute 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 CodeStatusDescription
ISSUER_NOT_TRUSTED403Issuer must be trusted before minting
KEY_NOT_FOUND404Signing key not registered for this issuer
QUOTA_EXCEEDED429Minting or verification quota exhausted
INVALID_SCHEMA400Schema ID not recognized
DUPLICATE_IDEMPOTENCY409Idempotency key already used
PAYLOAD_TOO_LARGE413Payload 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 Managernpm, yarn, or pnpm
Registry TokenRequired from Truthlocks Console