Skip to main content
List endpoints in the Predexy API return results in pages rather than all at once. You control the page size and position using two query parameters — limit and offset — and every paginated response includes a meta object that tells you exactly where you are and how many total results exist. This makes it straightforward to build efficient polling loops, bulk exports, and infinite-scroll interfaces.

Query parameters

Add limit and offset directly to your request URL as query parameters.
ParameterTypeDefaultMaximumDescription
limitinteger50200Number of items to return in this response
offsetinteger0Number of items to skip before returning results
Both parameters are optional. Omitting them returns the first 50 results.

The meta object

Every paginated response wraps results in a data array and includes a meta object:
{
  "data": [...],
  "meta": {
    "count": 50,
    "total": 312,
    "offset": 0,
    "limit": 50
  }
}
FieldTypeDescription
countintegerNumber of items in the current response page
totalintegerTotal items matching your query across all pages
offsetintegerThe offset value used for this response
limitintegerThe limit value used for this response
Use total to calculate how many pages remain. Use count to detect the last page — when count is less than limit, you’ve reached the end.
The arbitrage endpoints do not always return a total count. On those endpoints, rely on meta.count to detect the end of results: when count is less than limit, there are no more pages.

Fetching a page with curl

To fetch the second page of 25 results, set offset=25 and limit=25:
curl
curl -H "X-API-Key: pdx_your_key_here" \
  "https://api.predexy.com/api/v1/external/arbitrage/opportunities?limit=25&offset=25"
To fetch the maximum page size, use limit=200:
curl
curl -H "X-API-Key: pdx_your_key_here" \
  "https://api.predexy.com/api/v1/discover?limit=200&offset=0"

Iterating through all pages in Python

The function below fetches all results from a paginated endpoint by incrementing offset until all items have been retrieved. It uses limit=200 to minimize the number of requests:
python
import requests
from typing import Any

API_KEY = "pdx_your_key_here"
BASE_URL = "https://api.predexy.com"

def fetch_all(path: str, params: dict | None = None) -> list[Any]:
    """Fetch all pages from a Predexy list endpoint."""
    headers = {"X-API-Key": API_KEY}
    page_size = 200
    offset = 0
    all_items = []

    while True:
        query = {**(params or {}), "limit": page_size, "offset": offset}
        response = requests.get(f"{BASE_URL}{path}", headers=headers, params=query)
        response.raise_for_status()

        body = response.json()
        data = body.get("data", [])
        meta = body.get("meta", {})

        all_items.extend(data)
        offset += meta.get("count", 0)

        # Stop when we've received fewer items than requested
        # or when offset has reached total (if total is available)
        total = meta.get("total")
        if total is not None and offset >= total:
            break
        if meta.get("count", 0) < page_size:
            break

    return all_items

# Example: fetch all discovery items
questions = fetch_all("/api/v1/discover")
print(f"Fetched {len(questions)} questions.")
Use limit=200 for bulk data fetching. It’s the maximum allowed and reduces the number of round trips — especially useful for one-time exports or building a local snapshot of all canonical questions.

The meta.source field on arbitrage endpoints

Arbitrage responses include an additional meta.source field that indicates where the data was served from:
ValueMeaning
databaseResults were read directly from the primary database — fresh, authoritative data
cacheResults were served from the cache layer — may be up to a few seconds behind the latest scan
(empty string)Source is not tracked for this response type
You can use meta.source to understand data freshness when timing is critical. If you need the most current opportunity data, check that meta.source is database or confirm that freshness.is_stale is false on individual opportunities.
Serving from cache is normal and expected under high load. Stale cache entries are typically only a few seconds old. If freshness is critical to your strategy, also check the detected_at and last_seen_at fields on individual opportunities.