Pagination
All list endpoints in the Smartbills API return paginated results. The SDK provides a consistentSBListResponse<T> wrapper that includes both the data and pagination metadata.
Documentation Index
Fetch the complete documentation index at: /llms.txt
Use this file to discover all available pages before exploring further.
Work with paginated API responses using SBListResponse in the Smartbills JavaScript SDK.
SBListResponse<T> wrapper that includes both the data and pagination metadata.
interface SBListResponse<T> {
data: T[]; // Array of items on the current page
pagination: SBPagination; // Pagination metadata
}
interface SBPagination {
count: number; // Total number of items across all pages
limit: number; // Number of items per page
currentPage: number; // Current page number (1-based)
pageCount: number; // Total number of pages
filters?: Record<string, unknown>; // Applied filters
sorts?: Record<string, string>; // Applied sort criteria
}
const response = await client.expenses.listBusiness({
page: 1,
limit: 25,
});
console.log(`Items: ${response.data.length}`);
console.log(`Total: ${response.pagination.count}`);
console.log(`Page: ${response.pagination.currentPage} of ${response.pagination.pageCount}`);
interface PaginationRequest {
page?: number; // Page number (1-based, default: 1)
limit?: number; // Items per page (default varies by endpoint)
sortBy?: string; // Field to sort by
sortDirection?: 'asc' | 'desc'; // Sort order
}
const { data: expenses } = await client.expenses.listBusiness({
page: 1,
limit: 50,
sortBy: 'createdAt',
sortDirection: 'desc',
});
async function getAllExpenses() {
const allExpenses = [];
let currentPage = 1;
let hasMore = true;
while (hasMore) {
const { data, pagination } = await client.expenses.listBusiness({
page: currentPage,
limit: 100,
});
allExpenses.push(...data);
hasMore = currentPage < pagination.pageCount;
currentPage++;
}
return allExpenses;
}
async function fetchAllPages<T>(
fetcher: (params: { page: number; limit: number }) => Promise<SBListResponse<T>>,
limit = 100
): Promise<T[]> {
const allItems: T[] = [];
let page = 1;
let totalPages = 1;
do {
const response = await fetcher({ page, limit });
allItems.push(...response.data);
totalPages = response.pagination.pageCount;
page++;
} while (page <= totalPages);
return allItems;
}
// Usage
const allExpenses = await fetchAllPages(
(params) => client.expenses.listBusiness(params)
);
const allVendors = await fetchAllPages(
(params) => client.vendors.listBusiness(params)
);
async function* paginateExpenses(
params?: Partial<ExpenseListRequest>
) {
let page = 1;
let totalPages = 1;
do {
const response = await client.expenses.listBusiness({
...params,
page,
limit: params?.limit ?? 100,
});
for (const expense of response.data) {
yield expense;
}
totalPages = response.pagination.pageCount;
page++;
} while (page <= totalPages);
}
// Process expenses one at a time without loading all into memory
for await (const expense of paginateExpenses({ sortBy: 'amount' })) {
console.log(expense.id, expense.amount);
}
const { pagination } = await client.expenses.listBusiness({
page: 1,
limit: 20,
});
const hasNextPage = pagination.currentPage < pagination.pageCount;
const hasPreviousPage = pagination.currentPage > 1;
console.log(`Has next: ${hasNextPage}`);
console.log(`Has previous: ${hasPreviousPage}`);
const { data, pagination } = await client.expenses.listBusiness({
page: 1,
limit: 25,
// Additional filters depend on the endpoint
});
// pagination.count reflects the total matching the filter, not the overall total
console.log(`Matched ${pagination.count} expenses`);
Was this page helpful?