registercheckby openlaw group
Get started

Pagination

One envelope for every list and search, one cursor, and the ceilings that apply.

Every list and every search answers the same envelope and pages forward with the same cursor: roles, events, documents, statements, shareholders, monitors, lists, search results and filter hits alike.

ParameterDefaultMaximum
limit20100
cursor—the next_cursor of the page before

The reference-data lists — /legal-forms, /courts, /role-types, /industries, /event-types, /event-groups — carry no default: omit limit and the whole list arrives in one page, next_cursor null. Their vocabularies are fixed, and a client that renders one reads it whole — /industries' 2,030 codes included. Name a limit below the list's size and the answer pages like any other list's.

curl "https://api.registercheck.de/v1/companies/{company_id}/roles?limit=50" \
  -H "Authorization: Bearer $REGISTERCHECK_API_KEY"
{
  "object": "page",
  "data": [{ "object": "role", "id": "rol_01h455vb4pex5vsknk084sn02q" }],
  "next_cursor": "eyJ2IjoxLCJrIjoibGlzdENvbXBhbnlSb2xlcyJ9"
}

next_cursor is null on the last page, and that is the only end signal. Pass it back as cursor to get the next page:

def every_item(session, url, **params):
    cursor = None
    while True:
        page = session.get(url, params={**params, "limit": 100,
                                        **({"cursor": cursor} if cursor else {})}).json()
        yield from page["data"]
        cursor = page["next_cursor"]
        if cursor is None:
            return

The same loop walks every list in the API. Treat the cursor as opaque: what is inside it is not part of the contract and may change. It holds the list and its filters, not the page size, so the next page may ask for another limit. POST /search/companies/filter takes limit and cursor in the body.

A cursor belongs to one list

A cursor from a different list, or from the same list with different filters, answers 400 validation_failed naming cursor, not an empty page. A caller paging with the wrong cursor has a bug, and answering with nothing would hide it.

Pages only go forward. To start over, leave out cursor.

What some pages add

  • Search and filter add total_count: matches across the whole result set, or null when it cannot be counted cheaply. Check for null before showing it.
  • A company's shareholders add extract: how current the shareholder list behind the page is, and whether one was filed at all. See the glossary.

Ceilings

Asking for limit=101 answers 400 (limit=1001 on the company filter, whose pages hold up to 1,000); 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 1 credit per 10 returned results, up to 1,000 companies a page.

Array parameters

A parameter that takes several values repeats its name, once per value:

curl "https://api.registercheck.de/v1/events?type=company.name.changed&type=company.address.changed" \
  -H "Authorization: Bearer $REGISTERCHECK_API_KEY"

A comma-joined value (type=company.name.changed,company.address.changed) is not read as two values: it answers 400 validation_failed, so it can never silently match nothing.

Unknown parameters are rejected

A query parameter the endpoint does not read answers 400 validation_failed and costs nothing. errors[].name names it. GET /formations?legal_form_code=gmbh is refused: the parameter is legal_form, and legal_form_code is the name it had before 2026-10-02.

On this page