TRAILBASE|DOCUMENTATION

SDK Reference

Complete API reference for the Trailbase TypeScript/JavaScript SDK. Includes all methods, configuration options, type definitions, and error handling.

Installation

npm install @trailbase/sdk

TrailbaseClient Constructor

Initialize the Trailbase client with your API key and configuration:

Syntax

new TrailbaseClient(config: AuditLogConfig)

Parameters

ParameterTypeRequiredDescription
apiKeystringYesYour Trailbase API key
tenantIdstringYesYour tenant identifier
baseUrlstringNoAPI base URL (default: https://api.trailbase.frozo.ai)
flushIntervalnumberNoAutomatic batching interval in ms (default: 1000). Set to 0 to disable batching.
maxBatchSizenumberNoMax events per batch (default: 50)
maxRetriesnumberNoMax retry attempts for failed requests (default: 3)

Example

import { TrailbaseClient } from '@trailbase/sdk';

const trailbase = new TrailbaseClient({
  apiKey: process.env.TRAILBASE_API_KEY!,
  tenantId: 'tenant_acme',
  flushInterval: 2000,     // Batch every 2 seconds
  maxBatchSize: 100,       // Up to 100 events per batch
  maxRetries: 5,           // Retry up to 5 times
});

Event Logging Methods

log()

Log a single audit event. Events are automatically batched based on flushInterval.

Syntax

await trailbase.log(event: Omit<AuditEventInput, 'tenant_id'>): Promise<void>

Parameters

FieldTypeRequiredDescription
actionstringYesAction performed (e.g., user.login)
actorobjectYesWho performed the action
actor.idstringYesUnique actor identifier
actor.emailstringYesActor email address
actor.ipstringNoActor IP address
actor.user_agentstringNoActor user agent string (max 1024 chars)
resourceobjectYesWhat was acted upon
resource.typestringYesResource type (e.g., document)
resource.idstringYesResource identifier
outcomeenumYesResult: success, failure, or denied
metadataobjectNoAdditional context (max 64KB JSON)
event_idstringNoCustom event ID (UUID). Auto-generated if omitted.
event_timestringNoISO 8601 timestamp. Defaults to server time.

Example

await trailbase.log({
  action: 'document.delete',
  actor: {
    id: 'user_alice',
    email: 'alice@acme.com',
    ip: '192.168.1.1',
  },
  resource: {
    type: 'document',
    id: 'doc_q5w8r9',
  },
  outcome: 'success',
  metadata: {
    reason: 'user_request',
    document_name: 'Q4 Financial Report.pdf',
  },
});

logBatch()

Send multiple events immediately, bypassing the automatic batching queue.

Syntax

await trailbase.logBatch(events: AuditEventInput[]): Promise<BatchEventResponse>

Parameters

  • events - Array of events (max 100 events per batch)

Returns

{
  accepted: number;
  events: Array<{
    event_id: string;
    received_at: string;
  }>;
}

Example

const response = await trailbase.logBatch([
  {
    tenant_id: 'tenant_acme',
    action: 'user.login',
    actor: { id: 'user_1', email: 'user1@acme.com' },
    resource: { type: 'session', id: 'sess_1' },
    outcome: 'success',
  },
  {
    tenant_id: 'tenant_acme',
    action: 'user.login',
    actor: { id: 'user_2', email: 'user2@acme.com' },
    resource: { type: 'session', id: 'sess_2' },
    outcome: 'success',
  },
]);

console.log(`Accepted: ${response.accepted} events`);

trackEvent()

Simplified event logging with optional fields (alias for log()).

Syntax

await trailbase.trackEvent(event: {
  action: string;
  actor: { id: string; email?: string; ip?: string; user_agent?: string };
  resource?: { type: string; id: string };
  outcome?: 'success' | 'failure' | 'denied';
  metadata?: Record<string, unknown>;
}): Promise<void>

Example

await trailbase.trackEvent({
  action: 'user.signup',
  actor: { id: 'user_new', email: 'new@acme.com' },
  // resource defaults to { type: 'system', id: 'unknown' }
  // outcome defaults to 'success'
});

flush()

Manually flush the event queue, sending all pending events immediately.

Syntax

await trailbase.flush(): Promise<void>

Example

await trailbase.log({ /* event 1 */ });
await trailbase.log({ /* event 2 */ });

// Send immediately instead of waiting for flushInterval
await trailbase.flush();

shutdown()

Flush remaining events and cleanup resources. Call before process exit.

Syntax

await trailbase.shutdown(): Promise<void>

Example

process.on('SIGTERM', async () => {
  await trailbase.shutdown();
  process.exit(0);
});

Alert Methods

createAlertRule()

Create a new alert rule.

Syntax

await trailbase.createAlertRule(rule: {
  name: string;
  type: string;
  condition: Record<string, any>;
  severity?: string;
  channels?: string[];
  webhookIds?: string[];
  cooldownMin?: number;
}): Promise<any>

Example

const rule = await trailbase.createAlertRule({
  name: 'Failed Login Spike',
  type: 'threshold',
  condition: {
    action: 'user.login',
    outcome: 'failure',
    count: 5,
    window_seconds: 300,
  },
  severity: 'high',
  channels: ['email', 'slack'],
  cooldownMin: 30,
});

listAlertRules()

List all alert rules for the authenticated tenant.

Syntax

await trailbase.listAlertRules(): Promise<any>

updateAlertRule()

Update an existing alert rule.

Syntax

await trailbase.updateAlertRule(ruleId: string, updates: Record<string, any>): Promise<any>

Example

await trailbase.updateAlertRule('rule_xyz', {
  severity: 'critical',
  cooldownMin: 60,
});

deleteAlertRule()

Delete an alert rule.

Syntax

await trailbase.deleteAlertRule(ruleId: string): Promise<any>

listAlerts()

List alerts with optional filters.

Syntax

await trailbase.listAlerts(filters?: {
  status?: string;
  severity?: string;
  limit?: number;
  offset?: number;
}): Promise<any>

Example

const alerts = await trailbase.listAlerts({
  status: 'FIRING',
  severity: 'high',
  limit: 20,
});

acknowledgeAlert()

Acknowledge a firing alert.

Syntax

await trailbase.acknowledgeAlert(alertId: string): Promise<any>

resolveAlert()

Resolve an alert.

Syntax

await trailbase.resolveAlert(alertId: string): Promise<any>

Compliance Methods

runComplianceCheck()

Run a compliance check against a framework.

Syntax

await trailbase.runComplianceCheck(framework: string): Promise<any>

Parameters

  • framework - Framework name: SOC2, HIPAA, or GDPR

Example

const results = await trailbase.runComplianceCheck('SOC2');

if (results.passed) {
  console.log('SOC 2 compliance: PASS');
} else {
  console.error('SOC 2 compliance: FAIL');
  results.checks
    .filter(c => !c.passed)
    .forEach(c => console.error(`  ${c.control}: ${c.message}`));
}

getComplianceResults()

Get compliance check results, optionally filtered by framework.

Syntax

await trailbase.getComplianceResults(framework?: string): Promise<any>

listPolicyPacks()

List available compliance policy packs.

Syntax

await trailbase.listPolicyPacks(): Promise<any>

Type Definitions

AuditEventInput

interface AuditEventInput {
  event_id?: string;        // UUID, auto-generated if omitted
  event_time?: string;      // ISO 8601, defaults to server time
  tenant_id: string;        // Automatically set by SDK
  actor: {
    id: string;             // Required
    email: string;          // Required
    ip?: string;            // Optional
    user_agent?: string;    // Optional, max 1024 chars
  };
  action: string;           // Required
  resource: {
    type: string;           // Required
    id: string;             // Required
  };
  outcome: 'success' | 'failure' | 'denied';
  metadata?: Record<string, unknown>;  // Max 64KB
  request_id?: string;      // Optional request correlation ID
}

BatchEventResponse

interface BatchEventResponse {
  accepted: number;
  events: Array<{
    event_id: string;
    received_at: string;
  }>;
}

AuditLogConfig

interface AuditLogConfig {
  apiKey: string;           // Required
  tenantId: string;         // Required
  baseUrl?: string;         // Default: 'https://api.trailbase.frozo.ai'
  flushInterval?: number;   // Default: 1000ms
  maxBatchSize?: number;    // Default: 50
  maxRetries?: number;      // Default: 3
}

Error Handling

Error Types

The SDK throws standard JavaScript errors with descriptive messages:

try {
  await trailbase.log({
    action: 'user.login',
    actor: { id: 'user_1', email: 'invalid-email' },
    resource: { type: 'session', id: 'sess_1' },
    outcome: 'success',
  });
} catch (error) {
  if (error instanceof Error) {
    // Validation error
    if (error.message.includes('Valid email is required')) {
      console.error('Invalid email format');
    }

    // API error
    if (error.message.includes('401')) {
      console.error('Authentication failed - check API key');
    }

    // Rate limit
    if (error.message.includes('429')) {
      console.error('Rate limited - retry after delay');
    }
  }
}

Common Error Codes

StatusErrorCauseSolution
400Bad RequestInvalid event schemaCheck event fields match AuditEventInput type
401UnauthorizedInvalid API keyVerify API key is correct and active
403ForbiddenTenant mismatchEnsure tenantId matches API key
429Too Many RequestsRate limit exceededReduce request rate or contact support
500Internal Server ErrorServer errorRetry with exponential backoff (automatic)

Retry Behavior

The SDK automatically retries failed requests with exponential backoff for retryable errors (429, 502, 503, 504):

// Retry schedule
Attempt 1: Immediate
Attempt 2: +1 second
Attempt 3: +2 seconds
Attempt 4: +4 seconds
Attempt 5: +8 seconds (final, if maxRetries = 5)

Best Practices

  • Use environment variables: Never hardcode API keys
  • Enable batching: Default settings (1s interval, 50 events/batch) are optimal for most use cases
  • Don't await in hot paths: Let events queue asynchronously
  • Flush on shutdown: Call shutdown() before process exit
  • Handle errors gracefully: Log audit failures but don't block user operations
  • Use request IDs: Pass request_id for request correlation
  • Keep metadata under 64KB: Store large data separately and reference by ID

Ready to Build?

Check out the practical guides for complete implementation examples.

Edit this page on GitHub