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,
  per_page: 100,
});

Available Filters

Parameter Type Description
source string Filter by source: web, cli, api, agent, calendar, desktop
project_id string Filter by project
user_id string Filter by user
from string Start date (inclusive, YYYY-MM-DD)
to string End date (inclusive, YYYY-MM-DD)
is_running boolean Filter running timers only
page number Page number, starting at 1
per_page number Results per page

Pagination

The SDK uses API page pagination. Each response includes the current page, total pages, and a nextPage() helper:

const allEntries = [];

let page = await keito.timeEntries.list({
  project_id: 'prj_abc',
  page: 1,
  per_page: 200,
});

while (true) {
  allEntries.push(...page.data);
  if (!page.hasNextPage()) break;
  page = await page.nextPage();
}

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',
});