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
| Parameter | Type | Description |
|---|---|---|
source | string | Filter by source: web, cli, api, agent |
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 |
limit | number | Results per page (default 50, max 200) |
cursor | string | Pagination 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',
});