Node SDK: Agent Integration

Your application decides when work counts as time and whether to record an expense. The SDK supplies ordinary API methods; it does not infer token prices or automatically delete failed work.

Record a completed operation

This is a user-defined helper, not an SDK export. Supply the work date in the workspace’s timezone. It records elapsed time only after work succeeds, using source: 'api' for a custom integration.

import { Keito } from '@keito-ai/sdk';
import { randomUUID } from 'node:crypto';

const keito = new Keito();

async function recordCompletedWork<T>(
  projectId: string,
  taskId: string,
  spentDate: string,
  work: () => Promise<T>,
): Promise<T> {
  const operationId = randomUUID();
  const started = performance.now();
  const result = await work();
  const seconds = Math.max(1, Math.round((performance.now() - started) / 1000));
  await keito.timeEntries.create({
    project_id: projectId,
    task_id: taskId,
    spent_date: spentDate,
    hours: seconds / 3600,
    source: 'api',
    notes: 'Completed automated operation',
    metadata: { session_id: operationId, duration_seconds: seconds },
  }, { idempotencyKey: `completed-work-${operationId}` });
  return result;
}

For running timers, use startTimer and stopTimer. A user can have only one running timer. Concurrent workers should record completed durations separately rather than repeatedly replace one another’s timers. Persist operation IDs and reconcile uncertain writes before rerunning work; a fresh helper invocation deliberately has a new identity.

Record expense cost explicitly

Discover the project and category first. For an amount-based category, call expenses.create with total_cost. For a configured per-unit category, use units; the category supplies the rate. See Expenses.

Add token counts or provider references to metadata only when useful and nonsensitive. They do not establish a price by themselves. Expense recording and client invoicing are separate actions.

Source and identity

source: 'api' is suitable for custom automation. Keito’s lifecycle capture uses source: 'agent' with a separately validated metadata contract; setting a source is not permission to bypass that contract or act as another person. A key follows its bound identity’s current permissions and assignments.