Node SDK: Filtering & Pagination

Filtering Time Entries

All list methods accept filter parameters:

const entries = await keito.timeEntries.list({
  source: 'agent',
  project_id: 'prj_abc',
  user_id: 'usr_agent_01',
  from: '2026-03-01',
  to: '2026-03-31',
  is_running: false,
  limit: 100,
});

Available Filters

ParameterTypeDescription
sourcestringFilter by source: web, cli, api, agent
project_idstringFilter by project
user_idstringFilter by user
fromstringStart date (inclusive, YYYY-MM-DD)
tostringEnd date (inclusive, YYYY-MM-DD)
is_runningbooleanFilter running timers only
limitnumberResults per page (default 50, max 200)
cursorstringPagination cursor

Pagination

The SDK uses cursor-based pagination. Each response includes next_cursor when more results exist:

let cursor: string | undefined;
const allEntries = [];

do {
  const page = await keito.timeEntries.list({
    project_id: 'prj_abc',
    cursor,
    limit: 200,
  });

  allEntries.push(...page.data);
  cursor = page.next_cursor ?? undefined;
} while (cursor);

console.log(`Total entries: ${allEntries.length}`);

Filtering Expenses

Expenses support the same filter parameters:

const llmExpenses = await keito.expenses.list({
  source: 'agent',
  project_id: 'prj_abc',
  from: '2026-03-01',
});

const totalCost = llmExpenses.data.reduce(
  (sum, exp) => sum + exp.total_cost, 0
);
console.log(`Total LLM cost: £${totalCost.toFixed(2)}`);

Combining Filters

Filters are combined with AND logic:

// Agent entries for a specific project in March
const entries = await keito.timeEntries.list({
  source: 'agent',
  project_id: 'prj_abc',
  from: '2026-03-01',
  to: '2026-03-31',
});