Skip to main content

Overview

The MarketPageFetcher class provides access to the Market Navigation API — a hierarchical system for browsing markets by category, applying dynamic filters, and paginating results. All endpoints are public and require no authentication.

Setup

from limitless_sdk.api import HttpClient
from limitless_sdk.market_pages import MarketPageFetcher

http_client = HttpClient(base_url="https://api.limitless.exchange")
page_fetcher = MarketPageFetcher(http_client)
Fetch the full navigation hierarchy. Each node represents a browseable category with a URL path.
navigation = await page_fetcher.get_navigation()

for node in navigation:
    print(f"{node.name}{node.path}")
    for child in node.children:
        print(f"  {child.name}{child.path}")
FieldTypeDescription
idstrUnique identifier
namestrDisplay name
slugstrURL-friendly identifier
pathstrFull URL path (e.g. /crypto)
iconstr | NoneOptional icon name
childrenlist[NavigationNode]Nested child nodes

Resolving a Page by Path

Convert a URL path into a MarketPage with its filters, metadata, and breadcrumb. The SDK handles 301 redirects internally.
page = await page_fetcher.get_market_page_by_path("/crypto")

print(f"Page: {page.name}")
print(f"Filters: {len(page.filter_groups)} groups")
print(f"Breadcrumb: {' > '.join(b.name for b in page.breadcrumb)}")

MarketPage Fields

FieldTypeDescription
idstrPage identifier (used for get_markets())
namestrDisplay name
slugstrURL-friendly identifier
full_pathstrFull URL path
descriptionstr | NonePage description
base_filterdictDefault filter applied to this page
filter_groupslist[FilterGroup]Available filter groups
metadatadictPage metadata
breadcrumblist[BreadcrumbItem]Navigation breadcrumb

Fetching Markets for a Page

Use get_markets() with the page ID to fetch markets. Supports offset and cursor pagination, sorting, and dynamic filters.

Offset Pagination

result = await page_fetcher.get_markets(page.id, {
    "page": 1,
    "limit": 20,
    "sort": "-updatedAt",
})

for market in result.data:
    print(f"{market.slug}{market.title}")

print(f"Page {result.pagination.page} of {result.pagination.total_pages}")

Cursor Pagination

first_page = await page_fetcher.get_markets(page.id, {
    "cursor": "",
    "limit": 20,
    "sort": "-updatedAt",
})

for market in first_page.data:
    print(market.slug)

if first_page.cursor.next_cursor:
    next_page = await page_fetcher.get_markets(page.id, {
        "cursor": first_page.cursor.next_cursor,
        "limit": 20,
    })
You cannot use cursor and page in the same request. Choose one pagination strategy.

Filtering

Pass a filters dictionary. Values can be a single string or a list for multi-select filters.
# Single filter
result = await page_fetcher.get_markets(page.id, {
    "filters": {"ticker": "btc"},
})

# Multiple values (OR logic)
result = await page_fetcher.get_markets(page.id, {
    "filters": {"ticker": ["btc", "eth"]},
})

# Combined filters
result = await page_fetcher.get_markets(page.id, {
    "limit": 10,
    "sort": "-updatedAt",
    "filters": {
        "ticker": ["btc", "eth"],
        "duration": "hourly",
    },
})

Parameters

ParameterTypeDescription
pageintPage number (offset pagination)
limitintResults per page
sortstrSort field with optional - prefix for descending
cursorstrCursor token (cursor pagination). Use "" for the first request.
filtersdictFilter key-value pairs. Values can be str or list[str].

Sort Options

ValueDescription
createdAt / -createdAtSort by creation date (ascending / descending)
updatedAt / -updatedAtSort by last update
deadline / -deadlineSort by expiration deadline
id / -idSort by market ID

Property Keys

Property keys define the available filter dimensions (e.g. “ticker”, “duration”). Each key has a set of options.
# List all property keys
keys = await page_fetcher.get_property_keys()

for key in keys:
    print(f"{key.name} ({key.type})")
    if key.options:
        for opt in key.options[:3]:
            print(f"  {opt.label}: {opt.value}")

Single Key and Options

key = await page_fetcher.get_property_key(keys[0].id)
print(f"{key.name}{len(key.options or [])} options")

# Fetch options separately (supports parent filtering for hierarchical keys)
options = await page_fetcher.get_property_options(key.id)

# Child options filtered by parent
child_options = await page_fetcher.get_property_options(key.id, parent_id=options[0].id)

PropertyKey Fields

FieldTypeDescription
idstrUnique identifier
namestrDisplay name
slugstrURL-friendly identifier
typestr"select" or "multi-select"
is_systemboolWhether this is a system-defined key
optionslist[PropertyOption] | NoneAvailable options (when fetched inline)
metadatadictKey metadata
created_atstrISO 8601 creation timestamp
updated_atstrISO 8601 last update timestamp

Complete Example

import asyncio
from limitless_sdk.api import HttpClient
from limitless_sdk.market_pages import MarketPageFetcher

async def main():
    http_client = HttpClient(base_url="https://api.limitless.exchange")
    page_fetcher = MarketPageFetcher(http_client)

    # Browse the navigation tree
    navigation = await page_fetcher.get_navigation()
    print(f"Top-level categories: {len(navigation)}")

    # Resolve a page
    page = await page_fetcher.get_market_page_by_path("/crypto")
    print(f"\nPage: {page.name}")
    print(f"Available filters: {[fg.name for fg in page.filter_groups]}")

    # Fetch markets with filters
    result = await page_fetcher.get_markets(page.id, {
        "limit": 5,
        "sort": "-updatedAt",
        "filters": {"ticker": ["btc", "eth"]},
    })

    for market in result.data:
        print(f"  {market.slug}{market.title}")

    # Explore property keys
    keys = await page_fetcher.get_property_keys()
    for key in keys:
        print(f"\n{key.name} ({key.type}):")
        options = await page_fetcher.get_property_options(key.id)
        for opt in options[:5]:
            print(f"  {opt.label}")

    await http_client.close()

asyncio.run(main())