Liberty91

Pagination and errors.

Last updated 18 Sept 20263 min read

Every list endpoint in the API shares one pagination model, and every error shares one shape. Handle them once in your client and the whole surface behaves consistently.

Cursor pagination

List responses are wrapped in an envelope:

{
  "next": "https://api.liberty91.com/api/v1/iocs/?cursor=cD0yMDI2LTA3LTAx",
  "previous": null,
  "results": [ ... ]
}

Follow next until it is null, and you have walked the full result set. The next value is a complete URL, so you do not need to build cursor parameters yourself. Cursors are opaque; do not parse or store them beyond the current walk.

A page holds at most 25 records, and 25 is also the default. You can pass a smaller ?page_size=, but a larger one is clamped to 25 rather than rejected, so the only way to get more records is to follow next. A first request needs no page parameter at all:

curl "https://api.liberty91.com/api/v1/iocs/" \
  -H "X-API-Key: $LIBERTY91_API_KEY"

A complete walk in Python looks like this:

import requests
 
url = "https://api.liberty91.com/api/v1/iocs/"
headers = {"X-API-Key": LIBERTY91_API_KEY}
 
iocs = []
while url:
    page = requests.get(url, headers=headers).json()
    iocs.extend(page["results"])
    url = page["next"]
Tip

Cursor pagination stays consistent while you walk it, even as new data arrives, which is exactly what you want when syncing IOCs on a schedule. Combine it with the since filter on the IOC list to fetch only what is new since your last run.

Errors

Errors use standard HTTP status codes with a small JSON body:

{ "detail": "Missing scope: iocs.read" }
StatusMeaningWhat to do
400An unknown filter value, a malformed date, or an invalid bodyRead detail; it names the field
401Missing, malformed, revoked or expired API keyCheck the header and the key's validity
403Key lacks the required scopeGrant the scope named in detail
404Object not found, or not in your accountVerify the ID belongs to your tenant
409The user who created the key is no longer active on the accountRotate the key
429Rate limited or monthly credits exhaustedBack off for the Retry-After seconds; check X-Credits-Remaining to tell the two apart
503An upstream dependency is temporarily unavailableRetry with backoff; write operations are not retried server-side, so resubmit them
Note

A filter value we do not recognise is a 400, not an empty result set. A mistyped sector or status silently returning zero rows would read as "nothing matches", which is the opposite of the truth.

Failed requests (4xx and 5xx) never consume credits, so defensive retry logic costs you nothing beyond the rate limit.

Frequently asked questions

How does pagination work in the Liberty91 API?

List endpoints use cursor pagination. Each response contains next and previous URLs alongside the results array; follow next until it is null and you have the full set.

What is the maximum page size?

25 items, which is also the default. A larger page_size is clamped to 25 rather than rejected, so follow next to get the rest of the set.

What format are API errors in?

Standard HTTP status codes with a JSON body of the form {"detail": "message"}. 4xx and 5xx responses are never charged credits.

Was this page helpful?