kodo-sdk
v0.4.0
Published
Official JavaScript/TypeScript SDK for Kodo Status Pages - Server & Browser
Maintainers
Readme
kodo-sdk
Official JavaScript/TypeScript SDK for Kodo Status Pages.
Installation
npm install kodo-sdk
# or
yarn add kodo-sdk
# or
pnpm add kodo-sdkQuick Start
import { Kodo } from 'kodo-sdk';
const kodo = new Kodo({
apiKey: process.env.KODO_API_KEY!,
baseUrl: 'https://your-kodo-instance.com', // optional
});
// Send a heartbeat
await kodo.heartbeat('monitor-id');
// Create an incident
const incident = await kodo.incidents.create({
title: 'Database connectivity issues',
severity: 'major',
message: 'Investigating slow query times',
});
// Resolve it later
await kodo.incidents.resolve(incident.id, {
message: 'Root cause identified and fixed',
});Features
Process Health
Observe whether your async work actually completes — not just whether the edge returns 200. Wrap a unit of work with workflow() and instrument each step with step(). Your control flow is unchanged: step() runs your function, times it, records success/failure, and rethrows on error.
await kodo.workflow('checkout-fulfillment', async (wf) => {
await wf.step('charge_card', () => stripe.charge(order));
await wf.step('reserve_inventory', () => inventory.reserve(order));
await wf.step('notify_warehouse', () => warehouse.notify(order));
await wf.step('mark_fulfilled', () => db.markFulfilled(order));
});On completion (success or failure) the run appears under Dashboard → Process Health, grouped by workflow name. You get completion rate, p95 duration, failed runs and the exact step that broke, plus in-flight and stuck-run detection.
Telemetry is fire-and-forget — a failure to report never throws into your process. Kōdo only observes; retries, checkpointing, and durability stay with your engine (use it alongside Temporal, BullMQ, Cloudflare Workflows, or raw queues).
Server-side only —
workflow()is for backend processes (workers, jobs, route handlers). Process Health is available on plans that include distributed tracing.
Heartbeats
Perfect for monitoring cron jobs, background workers, and scheduled tasks.
// Simple heartbeat
await kodo.heartbeat('backup-job');
// With additional info
await kodo.heartbeat('worker-1', {
status: 'up',
response_time_ms: 1523,
message: 'Processed 1000 items',
});Incidents
Full lifecycle management for incidents.
// List incidents
const incidents = await kodo.incidents.list({ status: 'investigating' });
// Create incident
const incident = await kodo.incidents.create({
title: 'API Latency Spike',
severity: 'minor',
status: 'investigating',
message: 'Seeing increased response times',
services: ['api', 'database'], // Link to affected services
});
// Update incident
await kodo.incidents.update(incident.id, {
status: 'identified',
message: 'Root cause found: database connection pool exhaustion',
});
// Resolve incident
await kodo.incidents.resolve(incident.id, {
message: 'Connection pool configuration updated. Monitoring.',
});
// Delete incident
await kodo.incidents.delete(incident.id);Services
Manage your monitored services.
// List services
const services = await kodo.services.list();
// Create service
const service = await kodo.services.create({
name: 'Payment API',
description: 'Handles all payment processing',
});
// Update status
await kodo.services.setStatus(service.id, 'degraded');
// Quick status changes
await kodo.services.up(service.id); // Mark operational
await kodo.services.down(service.id); // Mark major outageMetrics
Push internal metrics for automatic health detection.
await kodo.pushMetrics({
service: 'API Gateway',
metrics: {
error_rate: 2.5,
response_time_ms: 245,
cpu_percent: 65,
memory_percent: 78,
},
});Framework Examples
Next.js API Route
// app/api/health/route.ts
import { Kodo } from 'kodo-sdk';
const kodo = new Kodo({ apiKey: process.env.KODO_API_KEY! });
export async function GET() {
await kodo.heartbeat('api-health');
return Response.json({ status: 'ok' });
}Express.js Middleware
import express from 'express';
import { Kodo } from 'kodo-sdk';
const app = express();
const kodo = new Kodo({ apiKey: process.env.KODO_API_KEY! });
// Heartbeat on each request
app.use((req, res, next) => {
kodo.heartbeat('express-api').catch(console.error);
next();
});
// Error reporting
app.use((err, req, res, next) => {
if (err.critical) {
kodo.incidents.create({
title: `Critical: ${err.message}`,
severity: 'critical',
}).catch(console.error);
}
next(err);
});Background Worker
import { Kodo } from 'kodo-sdk';
const kodo = new Kodo({ apiKey: process.env.KODO_API_KEY! });
async function processJob() {
const start = Date.now();
try {
// Do work...
await processItems();
// Report success
await kodo.heartbeat('job-processor', {
status: 'up',
response_time_ms: Date.now() - start,
});
} catch (error) {
// Report failure
await kodo.heartbeat('job-processor', {
status: 'down',
message: error.message,
});
// Create incident if critical
await kodo.incidents.create({
title: 'Job processor failed',
severity: 'major',
message: error.stack,
});
}
}Error Handling
import { Kodo, ApiError } from 'kodo-sdk';
const kodo = new Kodo({ apiKey: 'invalid-key' });
try {
await kodo.incidents.list();
} catch (error) {
if (error instanceof ApiError) {
console.error(`API Error: ${error.message}`);
console.error(`Status: ${error.status}`);
console.error(`Body: ${JSON.stringify(error.body)}`);
}
}TypeScript Support
Full TypeScript support with exported types:
import type {
Incident,
Service,
CreateIncidentOptions,
HeartbeatOptions,
} from 'kodo-sdk';License
MIT
