Skip to content
Private preview: new accounts are by invitation only. Ask for one

Pagination

Long lists come in pages. Pass next_cursor back as cursor until it is null.

ip_domains, domain_history and lookup_asn (its ranges) return their lists in pages.

ParameterMeaning
limitItems per page, 1 to 1000; 100 when left out. On the Free plan a page holds at most 100: a larger limit is lowered, and next_cursor carries on.
cursorThe previous page's next_cursor, unchanged. Leave it out for the first page.

Each page has next_cursor, which is null on the last page. Each page counts one request.

import os

import requests

API = "https://api.ipalmanac.com"
HEADERS = {"Authorization": f"Bearer {os.environ['IPALMANAC_API_KEY']}"}


def domains_on(ip: str) -> list[dict]:
    """Every domain interval seen on the IP, ended ones included."""
    items, cursor = [], None
    while True:
        params = {"include_ended": "true", "limit": 1000}
        if cursor:
            params["cursor"] = cursor
        response = requests.get(f"{API}/v1/ip/{ip}/domains", headers=HEADERS, params=params, timeout=30)
        response.raise_for_status()
        page = response.json()
        items += page["items"]
        cursor = page["next_cursor"]
        if cursor is None:
            return items

When a cursor stops working

A cursor belongs to the query it came from and to the data snapshot that answered it.

  • Sent with a different query, it gets 400 invalid_cursor.
  • Once the data is updated, it gets 410 cursor_expired: start again without a cursor. Each page's release.id names its snapshot, so pages with the same release.id belong together.

Not paged

domain_hosting returns everything in one response. For a domain with more than 5,000 answer intervals it covers the most recent ones and sets truncated: true.

On this page