Retrieve Bills
Fetch bills for linked accounts, filter by date and status, check sync progress, and trigger on-demand synchronization.
Fetch Bills for a Linked Account
Once link exchange returns an account_link_id, call GET /v1/bills with the account_link_id to retrieve bills. Because this is a billable read, send an Idempotency-Key. Reuse it only when retrying the same page.
GET /v1/bills
const response = await fetch(
'https://sandbox.api.billerapi.com/v1/bills?account_link_id=' + linkId,
{
headers: {
'Authorization': `Bearer ${process.env.BILLERAPI_API_KEY}`,
'Idempotency-Key': crypto.randomUUID(),
},
}
);
const data = await response.json();
console.log(data.bills);
// Returns: array of bills with amount, status, due_date, line_items
// Pagination: has_more, next_cursorNote
account_link_id. Link-scoped access tokens are accepted only by supported single-resource operations such as bill detail and statements. See the Getting Started guide for the full Link flow.Filter by Date and Status
Narrow results using query parameters. All filters are optional and can be combined.
Query Parameters
| Field | Type | Description |
|---|---|---|
| account_link_id* | string | ID of the linked account |
| start_date | string | ISO 8601 date — only return bills on or after this date |
| end_date | string | ISO 8601 date — only return bills on or before this date |
| status | string | Filter by bill status: PENDING, PAID, OVERDUE, CANCELLED |
| source | string | Filter by data source: BILLER_DIRECT, SCRAPING, OCR, EMAIL |
| limit | number | Max bills per page (default 25, max 100) |
| cursor | string | Pagination cursor from a previous response |
Filtered request
const params = new URLSearchParams({
account_link_id: linkId,
start_date: '2026-01-01',
end_date: '2026-03-31',
status: 'PENDING',
limit: '50',
});
const response = await fetch(
`https://sandbox.api.billerapi.com/v1/bills?${params}`,
{
headers: {
'Authorization': `Bearer ${process.env.BILLERAPI_API_KEY}`,
},
}
);
const { bills, has_more, next_cursor } = await response.json();Tip
has_more is true, pass next_cursor as the cursor parameter in the next request.Check Sync Status
Before fetching bills, you may want to check whether the account's data is up to date. Call GET /v1/bills/sync to get the current sync state.
GET /v1/bills/sync
const response = await fetch(
'https://sandbox.api.billerapi.com/v1/bills/sync?account_link_id=' + linkId,
{
headers: {
'Authorization': `Bearer ${process.env.BILLERAPI_API_KEY}`,
},
}
);
const { sync_state } = await response.json();
console.log(sync_state.status); // "SYNCED" | "SYNCING" | "FAILED"
console.log(sync_state.last_synced); // ISO 8601 timestamp
console.log(sync_state.progress); // 0-100 when SYNCINGTrigger a Sync
If the data is stale or you need the latest bills immediately, trigger an on-demand sync with POST /v1/bills/sync/trigger.
POST /v1/bills/sync/trigger
const response = await fetch(
'https://sandbox.api.billerapi.com/v1/bills/sync/trigger',
{
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.BILLERAPI_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
account_link_id: linkId,
sync_type: 'INCREMENTAL', // or 'FULL'
priority: 'normal',
}),
}
);
const { sync_task_id, status, estimated_duration } = await response.json();
// Poll GET /v1/bills/sync until status is "SYNCED"Tip
INCREMENTAL syncs for day-to-day updates. Reserve FULL syncs for initial onboarding or when you suspect missing data.Webhook Events
Instead of polling, register a webhook to receive real-time notifications when bills change. The key bill-related events are:
bill.created— a new bill was retrievedbill.updated— an existing bill changed (status, amount, due date)sync.completed— a sync finished for a linked accountsync.failed— a sync failed (credentials expired, biller unavailable)
Note