Pagination
Cursors for lists, page tokens for search, and the ceilings that apply.
There are two shapes, and which one you get depends on what you are reading.
Lists of a thing you already found
Officers, events, documents, statements, shareholders, monitors, lists — anything hanging off a record you already have — page with a cursor.
| Parameter | Default | Maximum |
|---|---|---|
limit | 20 | 100 |
starting_after | — | the id of an object in the list |
ending_before | — | the id of an object in the list |
starting_after and ending_before take the id of an object you have already seen, not
a number. They cannot be combined.
curl "https://api.registercheck.de/v1/companies/{company_id}/officers?limit=50" \
-H "Authorization: Bearer $REGISTERCHECK_API_KEY"{
"object": "list",
"data": [{ "id": "8f14e45f-ceea-467a-9c3a-4d5b8e5a1c22", "object": "officer" }],
"has_more": true,
"url": "/v1/companies/{company_id}/officers"
}Walk it by passing the last id you saw:
def all_officers(session, company_id):
cursor = None
while True:
params = {"limit": 100}
if cursor:
params["starting_after"] = cursor
page = session.get(f"{BASE}/companies/{company_id}/officers", params=params).json()
yield from page["data"]
if not page["has_more"]:
return
cursor = page["data"][-1]["id"]An unknown cursor is an error, not an empty page
Passing an id that is not in this list returns 400, not an empty result. That is
deliberate: a caller paging with an id from a different list has a bug, and answering
with nothing would hide it.
Search results
Search and filter endpoints page with an opaque token instead, because the result set is not a list of objects you can point into.
| Parameter | Default | Maximum |
|---|---|---|
limit | 20 | 100 |
page | — | the next_page of the previous result |
{
"object": "search_result",
"data": [],
"has_more": true,
"next_page": "2",
"total_count": 4213
}total_count— matches across the whole result set, ornullwhen it cannot be counted cheaply. Check fornullbefore showing it.next_page— pass it back aspage.nullon the last page.
def all_matches(session, **params):
page = None
while True:
result = session.get(f"{BASE}/search/companies",
params={**params, "limit": 100, **({"page": page} if page else {})}).json()
yield from result["data"]
if not result["has_more"]:
return
page = result["next_page"]Treat next_page as opaque. It happens to be a number today; that is not a promise.
Both shapes agree on two things
data always holds the items, and has_more always tells you whether to keep going. If
you only ever read those two fields, the same loop works against either.
Asking for limit=101 returns 400; it is not silently clamped.
Each page is a separate billable call. Walking 4,000 search results at 100 per page is
40 calls — 40 credits for search, but 40,000 if you then read every company at 10 credits
each. Consider POST /search/companies/filter,
which answers a structured query for 25 credits a page.
Unknown parameters are ignored
Query parameters the endpoint does not recognise are dropped rather than rejected.
?name=Siemens on an endpoint whose parameter is q returns an unfiltered page, not
an error. Check your parameter names against the reference when a result set looks larger
or more random than it should.