> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lancer-erp.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Pagination and money

> How list endpoints page, and why every amount is an integer number of agorot.

## Money is integer agorot

Every amount in the API is an **integer number of agorot**. One shekel is 100 agorot.

| You mean | Send / read |
| - | - |
| ₪1 | `100` |
| ₪59.90 | `5990` |
| ₪5,900 | `590000` |
| ₪15,000 | `1500000` |

Amount fields end in `Agorot`, so you can't confuse them with shekels: `amountAgorot`, `paidAgorot`, `creditedAgorot`, `refundedAgorot`, `budgetAgorot`, `retainerAmountAgorot`, `expectedValueAgorot`.

> [!TIP]
>
> Convert at the edge of your system and keep integers everywhere else. Floating-point shekels (`59.9 * 100 = 5989.999…`) are a classic source of off-by-one-agora bugs. Use `Math.round(shekels * 100)` once, at input.

```javascript theme={null}
const toAgorot = (shekels) => Math.round(Number(shekels) * 100);
const formatIls = (agorot) =>
  new Intl.NumberFormat('he-IL', { style: 'currency', currency: 'ILS' }).format(agorot / 100);

formatIls(590000); // "‏5,900.00 ₪"
```

### What a payment request's amounts mean

| Field | Meaning |
| - | - |
| `amountAgorot` | What the client was asked to pay |
| `paidAgorot` | What has been paid against it so far |
| `creditedAgorot` | What was credited (credit notes) |

Still owed = `amountAgorot - paidAgorot - creditedAgorot`. A payment's `refundedAgorot` is how much of that payment was refunded.

## Pagination

List endpoints (`GET /v1/clients`, `/v1/projects`, `/v1/payment-requests`, `/v1/payments`) take two query parameters:

**page** `integer` (default: 1)

1-based page number.

**pageSize** `integer` (default: 25)

Items per page, 1 to 100.

They all return the same envelope:

**items** `array`

The page of results.

**total** `integer`

How many results match, across all pages.

**page** `integer`

The page you asked for.

**pageSize** `integer`

The page size used.

### Read everything

```javascript Node.js theme={null}
async function* all(path, params = {}) {
  for (let page = 1; ; page++) {
    const qs = new URLSearchParams({ ...params, page, pageSize: 100 });
    const res = await fetch(`https://api.lancer-erp.com/api${path}?${qs}`, {
      headers: { Authorization: `Bearer ${process.env.LANCER_API_KEY}` },
    });
    if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
    const { items, total } = await res.json();
    yield* items;
    if (page * 100 >= total || items.length === 0) return;
  }
}

for await (const p of all('/v1/payments', { since: '2026-11-01' })) {
  console.log(p.id, p.amountAgorot / 100);
}
```

```python Python theme={null}
import os, requests

def all_items(path, **params):
    page = 1
    while True:
        r = requests.get(
            f"https://api.lancer-erp.com/api{path}",
            params={**params, "page": page, "pageSize": 100},
            headers={"Authorization": f"Bearer {os.environ['LANCER_API_KEY']}"},
            timeout=10,
        )
        r.raise_for_status()
        body = r.json()
        yield from body["items"]
        if page * 100 >= body["total"] or not body["items"]:
            return
        page += 1

for p in all_items("/v1/payments", since="2026-11-01"):
    print(p["id"], p["amountAgorot"] / 100)
```

> [!NOTE]
>
> Mind the [rate limit](https://docs.lancer-erp.com/guides/errors-and-rate-limits.md#rate-limits) (60 requests a minute) when paging through large lists, and prefer filters (`since`, `clientId`, `status`) over reading everything.

## Dates and IDs

* Timestamps (`createdAt`, `paidAt`, …) are ISO 8601 in UTC, for example `2026-11-12T08:30:00.000Z`.
* Calendar dates (`dueDate`, `startDate`, the `since` filter) are `yyyy-MM-dd`. Lancer's business calendar is Asia/Jerusalem.
* IDs are opaque strings. Don't parse them.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.