Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.bavlio.com/llms.txt

Use this file to discover all available pages before exploring further.

Bavlio does not yet enforce a unified pagination contract. Three patterns coexist. Check /openapi.json for any endpoint’s definitive request and response shape.

Three patterns in use

offset + limit

Most list endpoints accept ?offset=0&limit=100. Default limit varies per endpoint (commonly 50 or 100). Continue until response contains fewer rows than limit.
Example
GET /api/v1/campaigns/?offset=0&limit=100

has_more flag

Some endpoints return { items: [...], has_more: bool }. Continue until has_more is false. Use the last item id as the next page anchor where applicable.
Example
GET /api/v1/personalize/history?after_id=<id>

no pagination

Some endpoints return the full collection in one response (sender profiles, templates). Safe to call once.
Example
GET /api/v1/sender-profiles/

Drain-all helper

Handles both offset+limit and has_more shapes. Falls back cleanly when the response is a flat list (no pagination).
Python
def drain_all(client, path, *, page_size=100, **params):
    """Drain a list endpoint that uses offset+limit pagination."""
    offset = 0
    while True:
        response = client.get(path, params={**params, "offset": offset, "limit": page_size})
        response.raise_for_status()
        items = response.json()
        if not isinstance(items, list):
            payload = items
            items = payload.get("items", [])
            yield from items
            if not payload.get("has_more"):
                return
        else:
            yield from items
            if len(items) < page_size:
                return
        offset += page_size

Common gotchas

  • Default limits vary. Some endpoints default to 50, some to 100, some to no pagination at all. Always pass an explicit limit to make behavior predictable.
  • Order is not stable across pages for some endpoints under heavy concurrent writes. If you need a consistent snapshot, paginate by a stable id range rather than offset, or freeze the list and resume on failure.
  • Some endpoints have no pagination at all. Sender profiles and templates return the full collection. Calling them once is correct.

Roadmap

A unified cursor-based pagination contract (?cursor=&limit= with next_cursor + has_more envelope) is on the roadmap. Until then, treat each endpoint as having its own contract and check the OpenAPI spec.