Pagination
Все endpoints, возвращающие коллекции (реестр клиентов, история операций, список проверок), используют единый формат пагинации по принципу Laravel paginate().
Query-параметры
page
integer
optional
Номер страницы, начиная с 1.
Default:
1per_page
integer
optional
Сколько элементов на странице. Максимум — 100. Передача большего значения вернёт
422.Default:
20sort
string
optional
Поле сортировки. Префикс
- для DESC: sort=-created_at. Поддерживаемые поля указаны в каждом endpoint отдельно.filter[*]
mixed
optional
Фильтрация. Синтаксис:
filter[status]=pending, filter[date_from]=2026-05-01. Поддерживаемые ключи — в каждом endpoint.| Name | Type | Required | Description |
|---|---|---|---|
page
|
integer
|
optional |
Номер страницы, начиная с 1.
Default:
1 |
per_page
|
integer
|
optional |
Сколько элементов на странице. Максимум — 100. Передача большего значения вернёт 422.
Default:
20 |
sort
|
string
|
optional |
Поле сортировки. Префикс - для DESC: sort=-created_at. Поддерживаемые поля указаны в каждом endpoint отдельно.
|
filter[*]
|
mixed
|
optional |
Фильтрация. Синтаксис: filter[status]=pending, filter[date_from]=2026-05-01. Поддерживаемые ключи — в каждом endpoint.
|
Формат ответа
{
"data": [
{ "id": "...", ... },
{ "id": "...", ... }
],
"links": {
"first": "https://fin-os.io/api/v1/customers?page=1",
"last": "https://fin-os.io/api/v1/customers?page=42",
"prev": null,
"next": "https://fin-os.io/api/v1/customers?page=2"
},
"meta": {
"current_page": 1,
"from": 1,
"to": 20,
"per_page": 20,
"total": 837,
"last_page": 42,
"path": "https://fin-os.io/api/v1/customers"
}
}
meta
current_page
integer
optional
Текущая страница.
last_page
integer
optional
Общее число страниц.
per_page
integer
optional
Размер страницы (эхо параметра запроса).
total
integer
optional
Общее число элементов в коллекции (с учётом фильтров).
from
integer
optional
Номер первого элемента на странице (для UI «1–20 из 837»).
to
integer
optional
Номер последнего элемента на странице.
| Name | Type | Required | Description |
|---|---|---|---|
current_page
|
integer
|
optional | Текущая страница. |
last_page
|
integer
|
optional | Общее число страниц. |
per_page
|
integer
|
optional | Размер страницы (эхо параметра запроса). |
total
|
integer
|
optional | Общее число элементов в коллекции (с учётом фильтров). |
from
|
integer
|
optional | Номер первого элемента на странице (для UI «1–20 из 837»). |
to
|
integer
|
optional | Номер последнего элемента на странице. |
Курсорная пагинация лент
Для длинных лент (история операций клиента, движения мастер-счёта) page-based быстро деградирует - большой OFFSET сканирует много строк. Такие эндпоинты вместо page принимают курсор:
GET /api/v1/customers/{uuid}/transactions?starting_after=ctx_9c12d&per_page=100
starting_after - идентификатор последней полученной записи, он же meta.next_cursor предыдущего ответа. В ответе приходят meta.has_more и meta.next_cursor (null, когда лента закончилась). Неизвестный или устаревший курсор ошибкой не считается - вернётся первая страница.
Полный обход коллекции
✦
Не качайте всё одной страницей
per_page=10000 вернёт 422. Если нужно выгрузить всю историю - итерируйте по страницам (для лент - по курсору), а не увеличивайте размер страницы.
Примеры кода
# Первая страница
curl -X GET "https://fin-os.io/api/v1/customers?page=1&per_page=50" \
-H "Authorization: Bearer ${TOKEN}"
# С фильтром по статусу и сортировкой
curl -X GET "https://fin-os.io/api/v1/customers?\
filter[status]=active&\
filter[date_from]=2026-05-01&\
sort=-created_at&\
per_page=20" \
-H "Authorization: Bearer ${TOKEN}"
// Полный обход всех страниц
async function* iterateAll(url, headers) {
let page = 1;
while (true) {
const res = await fetch(`${url}?page=${page}&per_page=100`, { headers });
const body = await res.json();
for (const item of body.data) yield item;
if (!body.links.next) break;
page++;
}
}
for await (const customer of iterateAll('https://fin-os.io/api/v1/customers',
{ 'Authorization': `Bearer ${TOKEN}` })) {
console.log(customer.uuid, customer.phone);
}
// Обход всех страниц через генератор
function iterateAll(string $url, string $token): \Generator
{
$page = 1;
while (true) {
$body = Http::withToken($token)
->get($url, ['page' => $page, 'per_page' => 100])
->json();
foreach ($body['data'] as $item) {
yield $item;
}
if (! $body['links']['next']) break;
$page++;
}
}
foreach (iterateAll('https://fin-os.io/api/v1/customers', $token) as $customer) {
// process $customer
}
import requests
def iterate_all(url, headers):
page = 1
while True:
r = requests.get(url, params={'page': page, 'per_page': 100}, headers=headers)
body = r.json()
for item in body['data']:
yield item
if not body['links']['next']:
break
page += 1
for customer in iterate_all(
'https://fin-os.io/api/v1/customers',
headers={'Authorization': f'Bearer {TOKEN}'},
):
print(customer['uuid'], customer['phone'])