Table of contents

LP Intelligence Documentation

1. Overview

1.1 What is LP Intelligence

LP Intelligence is a structured data API for DeFi teams integrating liquidity and market data.

It provides indexed, queryable access to pools, swaps, account positions (current owner + identity + metadata), token metadata, and chain data — without requiring teams to build and maintain custom on-chain indexers.

The API abstracts raw on-chain events into protocol-aware data models designed for:

  • DeFi dashboards and frontends
  • Analytics and research teams
  • Backend systems and internal tooling
  • Teams integrating or evaluating Uniswap v4

The goal is to reduce integration time from months of indexing and ETL work to days of API integration.

Account position discovery (GET /api/v1/uniswap-v4/accounts/{address}/positions) is live in public beta: current NFT ownership, immutable position identity, and pool / token metadata. Per-position fee totals, live liquidity state, and LP analytics beyond that MVP are still in progress.

1.2 Supported Protocols

LP Intelligence currently supports:

  • Uniswap v4 (initial integration)

The architecture is designed for multi-protocol expansion. Future integrations will follow the same structured data model principles to ensure consistency across protocols.

1.3 Current Beta Status

LP Intelligence is currently in Public Beta.

Current characteristics:

  • Read-only API
  • Historical indexing available
  • Data freshness may lag (see Data Freshness section)
  • API access granted via request

Uniswap v4 hooks (current limitation):
LP Intelligence currently indexes core Uniswap v4 protocol contracts (e.g., PoolManager) and does not yet interpret or model hook-specific logic.

If a pool uses hooks that alter swap or liquidity behavior, derived fields may not fully reflect hook-level custom semantics. The hooks address is exposed as metadata when available.

1.4 Current Beta Scope

This section summarizes what is currently available and what is coming next.

Live — public beta API

  • Protocol: Uniswap v4 (Ethereum mainnet)
  • Read-only, historically indexed
  • GET /api/v1/uniswap-v4/pools — indexed liquidity pools
  • GET /api/v1/uniswap-v4/pools/{pool_id}/swaps — swap history per pool
  • GET /api/v1/uniswap-v4/accounts/{address}/swaps — swap history per account (filtered by transaction initiator tx.from)
  • GET /api/v1/uniswap-v4/tokens — token metadata for tokens appearing in indexed pools
  • GET /api/v1/chains — supported chain metadata
  • GET /api/v1/uniswap-v4/accounts/{address}/positionslive. Lists Uniswap v4 positions whose PositionManager ERC-721 is currently owned by address (latest Transfer per token_id). Returns ownership + identity + pool/token metadata; not live liquidity or accrued fees. ReDoc / OpenAPI: some deployments only publish a subset of paths in the embedded docs; this route may be omitted there while remaining available on the API.

In progress

  • GET /api/v1/uniswap-v4/positions/{position_id}/fees — lifetime cumulative fees per position (implemented in codebase but not mounted on the public router yet — unavailable until shipped)

Planned

  • Near real-time ingestion
  • Impermanent loss and PnL analytics
  • Multi-protocol expansion

1.5 Design Principles

LP Intelligence is built with the following principles:

Deterministic indexing

All responses are derived from deterministic indexing pipelines. Data is processed in strict block order to ensure consistency and reproducibility.

Structured, protocol-aware models

Rather than exposing raw contract events, the API provides:

  • Normalized pool objects
  • Structured swap data
  • Canonical token metadata
  • Chain metadata

This reduces client-side transformation logic and simplifies integration.

Account positions (ownership-based listing) are part of the live beta surface. Per-position fee endpoints, live liquidity / fee balances in responses, and richer LP analytics are still expanding.

Transparent data freshness

Each response includes indexing metadata:

  • indexed_to_block — the highest block included in the dataset
  • indexed_at — the timestamp when indexing completed

This allows clients to reason about freshness and build their own consistency guarantees.

Developer-first API design

  • Predictable pagination (limit, next_cursor)
  • Consistent response envelopes
  • Clear error formats
  • Versioned endpoints

The API is designed for application and backend integration.

2. Quickstart

This section demonstrates how to make your first request to the LP Intelligence API and understand the response structure.

The API is REST-based and returns JSON responses.

2.1 Base URL

All requests should be sent to:

https://api.lp-intelligence.com

All endpoints are versioned. The current version is:

/api/v1

Example full URL:

https://api.lp-intelligence.com/api/v1/uniswap-v4/pools

2.2 Authentication

During Public Beta, API access is granted via API key.

Requests must include your API key in the Authorization header:

Authorization: Bearer YOUR_API_KEY

Example:

curl https://api.lp-intelligence.com/api/v1/uniswap-v4/pools \
  -H "Authorization: Bearer YOUR_API_KEY"

If authentication fails, the API will return 401 Unauthorized.

2.3 First Request Example

The following example retrieves a list of indexed pools on Ethereum mainnet (chain_id=1).

curl "https://api.lp-intelligence.com/api/v1/uniswap-v4/pools?chain_id=1&limit=10" \
  -H "Authorization: Bearer YOUR_API_KEY"

Query parameters for this example:

  • chain_id — integer >= 1, default 1 (Ethereum mainnet in the backend enum). Identifies the EVM chain for the query.
  • limit — integer page size, default 50, minimum 1, maximum 500.

Optional parameters not shown in this curl (see §5.2): cursor, token.

2.4 Example Response

A successful response returns HTTP 200 OK and a JSON body:

{
    "indexed_to_block": 21955247,
    "indexed_at": "2025-03-01T23:16:47Z",
    "items": [
        {
            "chain_id": 1,
            "pool_id": "0xfa86f15833604c1ee16f0a2f7de9d04d244fd9248a3ffe71220f7718f21871fe",
            "pool_manager": "0x000000000004444c5dc75cb358380d2e3de08a90",
            "fee": 100,
            "tick_spacing": 1,
            "hooks": null,
            "created_block": 21954731,
            "created_timestamp": "2025-03-01T21:33:23Z",
            "token0": {
                "address": "0x6111f3e70fbe68c8d62c3340b32e978ddfd8b08a",
                "symbol": "SETH",
                "decimals": 18,
                "name": "Sethereum"
            },
            "token1": {
                "address": "0xdb99b0477574ac0b2d9c8cec56b42277da3fdb82",
                "symbol": "DECT",
                "decimals": 18,
                "name": "DEC Token"
            }
        },
        {
            "chain_id": 1,
            "pool_id": "0x08d3552d8874b93fdbd8947916c89a375b3c96c34fb49cdf5b8ca79aef020b5c",
            "pool_manager": "0x000000000004444c5dc75cb358380d2e3de08a90",
            "fee": 10000,
            "tick_spacing": 200,
            "hooks": null,
            "created_block": 21954709,
            "created_timestamp": "2025-03-01T21:28:59Z",
            "token0": {
                "address": "0x0000000000000000000000000000000000000000",
                "symbol": "ETH",
                "decimals": 18,
                "name": "Ether"
            },
            "token1": {
                "address": "0x940a2db1b7008b6c776d4faaca729d6d4a4aa551",
                "symbol": "DUSK",
                "decimals": 18,
                "name": "Dusk Network"
            }
        },
        ...
        {
            "chain_id": 1,
            "pool_id": "0xe16b9af685b248d4f3e54890353f6f5086a8608d05ed806c4876ce99d4e6c12a",
            "pool_manager": "0x000000000004444c5dc75cb358380d2e3de08a90",
            "fee": 3000,
            "tick_spacing": 60,
            "hooks": null,
            "created_block": 21953412,
            "created_timestamp": "2025-03-01T17:08:35Z",
            "token0": {
                "address": "0x0000000000000000000000000000000000000000",
                "symbol": "ETH",
                "decimals": 18,
                "name": "Ether"
            },
            "token1": {
                "address": "0xb9f599ce614feb2e1bbe58f180f370d05b39344e",
                "symbol": "PORK",
                "decimals": 18,
                "name": "PepeFork"
            }
        },
        {
            "chain_id": 1,
            "pool_id": "0x4a24fcf3c1cbebd80d09537c7aa15adf2d228aa1b9ba1b0e5fb82e66dc96c0d2",
            "pool_manager": "0x000000000004444c5dc75cb358380d2e3de08a90",
            "fee": 500,
            "tick_spacing": 10,
            "hooks": null,
            "created_block": 21953133,
            "created_timestamp": "2025-03-01T16:12:47Z",
            "token0": {
                "address": "0x2260fac5e5542a773aa44fbcfedf7c193bc2c599",
                "symbol": "WBTC",
                "decimals": 8,
                "name": "Wrapped BTC"
            },
            "token1": {
                "address": "0xdac17f958d2ee523a2206206994597c13d831ec7",
                "symbol": "USDT",
                "decimals": 6,
                "name": "Tether USD"
            }
        }
    ],
    "next_cursor": "eyJjYiI6MjE5NTMxMzMsInBpZCI6IjB4NGEyNGZjZjNjMWNiZWJkODBkMDk1MzdjN2FhMTVhZGYyZDIyOGFhMWI5YmExYjBlNWZiODJlNjZkYzk2YzBkMiJ9",
    "limit": 10
}

Response envelope

All list endpoints return a consistent response envelope:

  • indexed_to_block — highest indexed block included in the dataset
  • indexed_at — timestamp when indexing completed
  • items — array of result objects
  • next_cursor — pagination cursor (if more results exist)
  • limit — number of items requested

This structure is consistent across endpoints.

2.5 Pagination Basics

List endpoints support cursor-based pagination.

To retrieve additional results:

  1. Inspect the next_cursor field in the response.
  2. If not null, pass it as a query parameter in the next request.

Example:

curl "https://api.lp-intelligence.com/api/v1/uniswap-v4/pools?chain_id=1&limit=10&cursor=<next_cursor_from_previous_response>" \
  -H "Authorization: Bearer YOUR_API_KEY"

Use the exact next_cursor string from the previous response. Do not construct or parse cursor payloads manually — shape differs per endpoint (see §5).

Pagination guarantees:

  • Results are returned in deterministic order.
  • next_cursor ensures no overlap between pages.
  • If next_cursor is null, no additional results are available.

3. Authentication

LP Intelligence uses API key–based authentication for all requests.

Each request must include a valid API key in the Authorization header. API keys must be kept secret and should not be exposed in public client-side code.

API keys are long-lived, revocable, and scoped to a single account.

3.1 API Keys

Access to LP Intelligence is granted via API key.

Each account is issued a unique secret key during onboarding.

Example key format:

bf_live_7f4c9a2e3d1b4f0c8a6d9e2f1b3c4d5e

API keys:

  • Are account-scoped
  • Can be revoked or rotated
  • Should be kept secret
  • Must never be exposed in client-side code

Security recommendations

  • Store API keys in secure server-side environment variables.
  • Do not embed keys in frontend applications.
  • Rotate keys if you suspect compromise.

If a key is revoked, all subsequent requests using that key will return 401 Unauthorized.

3.2 Request Headers

All authenticated requests must include the Authorization header:

Authorization: Bearer YOUR_API_KEY

Example request:

curl https://api.lp-intelligence.com/api/v1/uniswap-v4/pools \
  -H "Authorization: Bearer bf_live_7f4c9a2e3d1b4f0c8a6d9e2f1b3c4d5e"

Requests without a valid API key will receive:

401 Unauthorized

If the key is valid but exceeds rate limits, the API will return:

429 Too Many Requests

3.3 Rate Limits

Rate limits are enforced per API key.

Limits are defined based on your access tier.

Rate limiting ensures:

  • Fair resource allocation
  • System stability
  • Predictable performance

When a rate limit is exceeded, the API responds with:

429 Too Many Requests

Example response:

{
  "error": "rate_limit_exceeded",
  "message": "Request rate limit exceeded. Please retry later."
}

Future versions may include rate limit headers such as:

  • X-RateLimit-Limit
  • X-RateLimit-Remaining
  • X-RateLimit-Reset

Rate limits may be adjusted during Public Beta.

3.4 Access Tiers

LP Intelligence is currently in Public Beta. There is a single access tier.

Public Beta

  • Read-only access
  • Historical indexing
  • Rate limits enforced per API key (limits may evolve during beta)
  • Access granted via request on the LP Intelligence page

Commercial tiers may be introduced after the beta period. Details will be published prior to any general availability release.

4. Core Concepts

This section defines the core data models used throughout LP Intelligence.

Rather than exposing raw contract events, the API provides structured, protocol-aware objects designed for backend and product integration.

4.1 Chains

A Chain represents a supported blockchain network.

Each chain is identified by a numeric chain_id, consistent with EVM standards.

Example:

  • 1 — Ethereum mainnet
  • (additional chains will be added in future phases)

Chain-level context determines:

  • Address namespace
  • Block height
  • Indexing boundaries
  • Protocol deployment addresses

All endpoints that return chain-specific data include a chain_id field.

4.2 Pools

A Pool represents a liquidity pool within a supported protocol.

Pools define:

  • pool_id — unique identifier
  • token0 and token1 — assets paired in the pool
  • fee — fee tier
  • tick_spacing — discrete price granularity
  • Protocol-specific metadata (e.g., hooks in Uniswap v4)

Pools are canonicalized in the API to provide:

  • Normalized token metadata
  • Structured fee configuration
  • Deterministic identification

Pools serve as the foundational market unit for swaps and broader liquidity models.

Hooks Support (Uniswap v4)

  • The hooks address is exposed as metadata when available.
  • LP Intelligence does not currently decode or model hook callback logic.
  • Indexed data reflects core protocol events and state; hook-driven behavioral adjustments are out of scope at this stage.
  • Hook-aware indexing and enriched semantics are planned in a future release.

4.3 Positions (account-owned NFT positions)

GET /api/v1/uniswap-v4/accounts/{address}/positions models a PositionManager ERC-721 position currently owned by the requested wallet. Ownership comes from the latest ERC-721 Transfer per token_id (not from tx.from on liquidity transactions).

Response items include identity and metadata: token_id (uint256 decimal string), position_manager, owner, pool (pool_id, tokens, fee, tick_spacing, hooks), tick_lower / tick_upper, salt, created_block, created_timestamp. Live liquidity, accrued fees, and current tick state are out of scope for this MVP endpoint.

For swap history attribution, use /accounts/{address}/swaps, which filters by transaction initiator (tx.from) — a different filter than ownership-based positions.

4.4 Swaps

A Swap represents a token exchange executed within a pool.

Swaps include:

  • Associated pool
  • Input and output tokens
  • Amounts
  • Block context
  • Transaction metadata

Swaps are indexed in deterministic block order and can be queried:

  • At the account level
  • At the pool level

Swap data enables:

  • Volume analytics
  • Strategy logic
  • Market activity monitoring

4.5 Liquidity Ranges (tick_lower / tick_upper)

Note: On the live GET .../accounts/{address}/positions endpoint, tick_lower and tick_upper describe the mint-time range from the position registry (identity). They do not imply that the API returns current in-range liquidity, accrued fees, or PnL — those depend on future live-state and analytics surfaces.

Liquidity in concentrated liquidity AMMs is allocated across a defined price range.

Each on-chain position specifies:

  • tick_lower — lower bound of price range
  • tick_upper — upper bound of price range

Liquidity is economically active only when the current pool price lies within this range. Ticks are discrete price intervals determined by the pool’s tick_spacing.

Full-range positions span the minimum and maximum tick boundaries supported by the protocol.

Understanding liquidity ranges is critical for:

  • LP profitability modeling
  • Impermanent loss estimation
  • Active liquidity calculations

These concepts support interpreting position identity in the live API and future analytics; the live positions endpoint does not yet expose full live-state LP metrics.

4.6 Indexing Metadata

All list endpoints return indexing metadata to allow clients to reason about data freshness and completeness.

Each response includes:

  • indexed_to_block — the highest block included in the dataset
  • indexed_at — timestamp when indexing completed

This metadata allows clients to:

  • Detect indexing lag
  • Build consistency guarantees
  • Implement freshness thresholds
  • Reconcile internal state with blockchain height

LP Intelligence prioritizes transparency in indexing boundaries rather than implying real-time guarantees.

5. Endpoints

All endpoints are versioned under:

/api/v1

All responses are returned as application/json.

List / collection endpoints:

  • Use cursor-based pagination where documented (not GET /chains or GET /tokens)
  • Return deterministically ordered results (ordering per endpoint — see §5)
  • Include indexing metadata where applicable (indexed_to_block / indexed_at)

For full request/response schemas and parameter details, see the API Reference.

👉 Full API Reference (OpenAPI / ReDoc)

Parameter types below match the FastAPI / Pydantic layer in api-engine (query names and defaults are authoritative).

5.1 GET /api/v1/chains

Path
Query

Returns a list of supported chains (items[]: chain_id, slug, name, native_currency, explorer_base_url, is_testnet). No pagination.


5.2 GET /api/v1/uniswap-v4/pools

ParameterInType / constraintsDefaultDescription
chain_idqueryinteger, >= 11EVM chain id (EIP-155).
limitqueryinteger, 150050Page size. The API fetches limit + 1 rows internally to set next_cursor.
cursorquerystring or omittednullOpaque pagination token from the previous response’s next_cursor. Payload (decoded): cb = pool created_block (int), pid = pool_id (bytes32 0x… hex string).
tokenquerystring or omittednullIf set, must be a checksummed or valid EVM address (0x + 20 bytes). Returns only pools where either token0 or token1 equals this address (byte-exact match after parsing). Invalid address → 400.

Order: created_block descending, then pool_id descending (see repository ordering).

Response envelope: indexed_to_block, indexed_at (Uniswap v4 pools registry watermark), items, next_cursor, limit.

Hooks (Uniswap v4): hooks is returned as metadata; hook callback logic is not interpreted in derived fields.


5.3 GET /api/v1/uniswap-v4/pools/{pool_id}/swaps

ParameterInType / constraintsDefaultDescription
pool_idpathstringrequiredUniswap v4 PoolId: 0x + 64 hex chars (32 bytes). Invalid length or hex → 400.
chain_idqueryinteger, >= 11EVM chain id.
limitqueryinteger, 150050Page size.
cursorquerystring or omittednullPayload: bn = block_number (int), ti = transaction_index (int), li = log_index (int) — canonical event ordering.
include_rawquerybooleanfalseIf true, swap token0 / token1 amount objects include raw integer strings; if false, raw is omitted.

Order: block_number DESC, transaction_index DESC, log_index DESC.

Watermark: indexed_to_block / indexed_at reflect swap events indexing for the chain (not the pools table).


5.4 GET /api/v1/uniswap-v4/tokens

ParameterInType / constraintsDefaultDescription
chain_idqueryinteger, >= 11EVM chain id.
qquerystring or omittednullSearch: case-insensitive (ILIKE) match on symbol or name from domain.tokens. If the value starts with 0x, the backend also attempts an exact address match on the pooled token set; malformed 0x input is ignored for the address branch (filter falls back to symbol/name only). Whitespace is trimmed; empty after trim = no filter.
limitqueryinteger, 11000200Max rows (no cursor; not paginated).

Coverage: only token addresses that appear as token0 or token1 in indexed Uniswap v4 pools on that chain.

Order: symbol ASC (nulls last), then token address ASC.

Watermark: same semantics as pools — pool registry watermark (indexed_to_block / indexed_at).


5.5 GET /api/v1/uniswap-v4/accounts/{address}/swaps

ParameterInType / constraintsDefaultDescription
addresspathstringrequiredWallet / contract address (0x…). Must parse as valid EVM address → else 400.
chain_idqueryinteger, >= 11EVM chain id.
protocolqueryenum stringuniswap_v4Only uniswap_v4 is supported; any other value → 400 (“Unsupported protocol”).
limitqueryinteger, 150050Page size.
cursorquerystring or omittednullSame shape as §5.3: bn, ti, li.

Filter: returns swaps where the account is the transaction initiator (tx.from), not the event sender. Response items include both initiator (tx.from) and sender (event arg) when present — they may differ (routers, meta-transactions, etc.).

Implementation note: the route always requests include_raw: true for the swap payload (raw integer strings included on token amounts).

Watermark: swap events watermark for the chain (same table family as §5.3).


5.6 GET /api/v1/uniswap-v4/accounts/{address}/positions

ParameterInType / constraintsDefaultDescription
addresspathstringrequiredWallet address; must be valid EVM address → else 400. Interpreted as current NFT owner (see below), not as tx.from.
chain_idqueryinteger, >= 11EVM chain id.
limitqueryinteger, 150050Page size.
cursorquerystring or omittednullPayload: cb = position created_block (int), tid = token_id as decimal string (uint256), not hex.

Semantics: returns positions whose PositionManager ERC-721 is currently owned by address, using the latest Transfer per token_id. Includes registry identity (token_id, ticks, salt, pool, …) and pool/token metadata — not live liquidity or fees.

Order: created_block DESC, token_id DESC.

Watermark: position NFT transfer indexing watermark (not swap or modify-liquidity watermarks).

6. Errors

LP Intelligence uses standard HTTP status codes to indicate success or failure of an API request.

Clients should always:

  • Inspect the HTTP status code
  • Parse the response body for structured error details
  • Implement retry logic where appropriate

6.1 HTTP Status Codes

The API uses the following status codes:

200 — OK

The request was successful.

400 — Bad Request

The request is malformed or contains invalid parameters.

401 — Unauthorized

Authentication credentials are missing or invalid.

403 — Forbidden

Authentication succeeded but the request is not permitted for the current API key or access tier.

404 — Not Found

The requested resource does not exist.

422 — Validation Error

The request parameters failed schema validation.

429 — Too Many Requests

Rate limit exceeded.

500 — Internal Server Error

Unexpected server-side error.

6.2 Error Response Format

Error responses are returned in JSON format.

For validation errors, the API follows a structured schema:

{
  "detail": [
    {
      "loc": ["query", "limit"],
      "msg": "ensure this value is less than or equal to 500",
      "type": "value_error.number.not_le"
    }
  ]
}

Fields:

  • loc — location of the invalid field (path, query, body)
  • msg — human-readable error message
  • type — machine-readable error classification

Clients should rely on:

  • HTTP status code for control flow
  • type for programmatic handling
  • msg for logging or debugging

6.3 Validation Errors (422)

A 422 Unprocessable Entity response is returned when request parameters fail validation.

Common causes:

  • Invalid address format
  • Exceeding limit constraints
  • Invalid enum value (e.g., unsupported protocol)

Example:

{
  "detail": [
    {
      "loc": ["query", "chain_id"],
      "msg": "field required",
      "type": "value_error.missing"
    }
  ]
}

Clients should treat validation errors as non-retryable unless request parameters are corrected.

6.4 Auth Errors (401/403)

401 Unauthorized

Returned when:

  • Authorization header is missing
  • API key is invalid
  • API key is revoked
{
  "error": "invalid_api_key",
  "message": "The provided API key is invalid."
}

403 Forbidden

Returned when:

  • API key is valid but lacks permission
  • Access tier does not allow requested resource
  • Chain or protocol not enabled for the key

Example:

{
  "error": "access_denied",
  "message": "Your API key does not have access to this resource."
}

Clients should not retry 401 or 403 errors without changing credentials or upgrading access.

6.5 Rate Limit Errors (429)

If a client exceeds the allowed request rate, the API returns:

429 Too Many Requests

Example:

{
  "error": "rate_limit_exceeded",
  "message": "You have exceeded your request limit. Please retry later."
}

Clients should implement exponential backoff when receiving 429 responses.

Recommended retry strategy:

  • Initial delay: 500–1000 ms
  • Exponential backoff with jitter
  • Maximum retry attempts: 3–5

Future versions may include rate limit headers such as:

  • X-RateLimit-Limit
  • X-RateLimit-Remaining
  • Retry-After

6.6 Idempotency / Retries guidance (even if you don’t support idempotency yet, retries matter)

All current endpoints are read-only (GET) and are therefore idempotent.

Safe to retry:

  • 429 (rate limit)
  • 500 (server error)
  • Network timeouts

Do not retry without modification:

  • 400 (bad request)
  • 401 (unauthorized)
  • 403 (forbidden)
  • 422 (validation error)

Recommended retry pattern:

  • Treat GET endpoints as safe to retry
  • Implement exponential backoff
  • Log request ID and error payload for diagnostics
  • Avoid aggressive retry loops under sustained 429 responses

7. Pagination & Filtering

Most list endpoints return potentially large result sets. LP Intelligence provides cursor-based pagination to keep responses fast, stable, and safe for production workloads.

Supported list endpoints use:

  • limit (page size)
  • cursor (opaque pointer to the next page)
  • next_cursor (returned by the API when more results are available)

7.1 limit

limit controls the maximum number of items returned in a single response.

  • Type: integer
  • Typical default: 50
  • Max values:
    • Most list endpoints: up to 500
    • Tokens search: up to 1000

Guidance:

  • Use smaller limit values for latency-sensitive UIs.
  • Use larger values for backfills/batch jobs, but expect larger payload sizes.

Example:

GET /api/v1/uniswap-v4/pools?chain_id=1&limit=100

7.2 cursor / next_cursor

cursor (request)

cursor is an opaque string used to request the next page of results. You should treat it as a black box (do not parse or generate it).

  • Type: string (nullable)
  • Provided by: next_cursor from the previous response

next_cursor (response)

If more results exist, the response includes a next_cursor. If you reached the end, next_cursor is null.

Example flow:

  1. First page (no cursor):
GET /api/v1/uniswap-v4/accounts/{address}/swaps?chain_id=1&limit=50
  1. Response includes:
{
  "items": [ /* ... */ ],
  "next_cursor": "eyJ2Ijo...opaque...",
  "limit": 50
}
  1. Next page:
GET /api/v1/uniswap-v4/accounts/{address}/swaps?chain_id=1&limit=50&cursor=eyJ2Ijo...opaque...

Important rules:

  • Always pass the same query parameters when paginating (same chain_id, filters, etc.).
  • Don’t reuse a cursor across different endpoints.
  • Don’t store cursors long-term for business logic; treat them as short-lived pagination pointers.

7.3 Ordering Guarantees

List endpoints return results in a consistent, deterministic order suitable for pagination.

What you can rely on:

  • Pagination is stable and consistent within a given endpoint and parameter set.
  • Cursor pagination is aligned with that ordering so you do not miss or duplicate items while paging.

What you should not assume:

  • Undocumented sort details are part of the public API contract.
  • Every endpoint returns newest-first or oldest-first unless that behavior is explicitly documented.

Practical guidance:

  • For UIs: assume “most relevant / most recent” unless the endpoint documentation states otherwise.
  • For ingestion jobs: page until next_cursor = null.

7.4 Deterministic Responses

LP Intelligence is an indexed data API, which means responses represent a snapshot at an indexing boundary, not necessarily the latest chain head.

To support deterministic integration behavior:

  • Many responses include indexing metadata (e.g., indexed_to_block, indexed_at), allowing you to detect when the underlying dataset advanced.
  • Pagination is designed to be consistent within an indexing window.

Responses include indexed_to_block, which indicates the highest indexed block included in the dataset. Clients performing large historical backfills may use this value to ensure consistency across paginated requests.

8. Data Freshness & Indexing

8.1 Historical Indexing Model

LP Intelligence currently operates on a historically indexed dataset.

The indexing pipeline processes on-chain events in strict block order, starting from the Uniswap v4 PoolManager deployment block. All data in the current beta reflects events that occurred before the current indexing boundary.

This means:

  • Responses represent a deterministic snapshot at an indexing boundary.
  • Data is not updated continuously or in near real time.
  • There may be a lag between the current chain head and the highest indexed block.

Near real-time ingestion is planned but not yet enabled in the current beta.

8.2 Current Freshness Window

The current dataset covers Ethereum mainnet from the Uniswap v4 PoolManager deployment through the current indexing boundary.

Indexing progress is reflected in the indexed_to_block and indexed_at fields returned in every list response.

As the indexing pipeline advances, these values will be updated. Clients may poll these fields to detect when new data becomes available.

8.3 How to Interpret indexed_to_block

Every list response includes two freshness fields:

  • indexed_to_block — the highest block number included in the dataset at the time of the response.
  • indexed_at — the UTC timestamp when indexing reached that block.

Practical guidance:

  • Use indexed_to_block to check whether the data you need is already included in the indexed dataset.
  • If you need multiple API responses to reflect the same indexed snapshot, compare indexed_to_block across those responses.
  • If indexed_to_block has not changed between requests, the indexed dataset has not moved forward to newer blocks.
  • Do not assume that indexed_to_block equals the current chain head.

Example:

{
  "indexed_to_block": 21955247,
  "indexed_at": "2025-03-01T23:16:47Z",
  "items": [ /* ... */ ]
}

8.4 Planned Near Real-Time Ingestion

Near real-time ingestion — continuously following the chain tip — is planned for a future phase.

When enabled, indexed_to_block will advance alongside the chain head with a short lag (measured in seconds or minutes rather than hours or days).

Until then, the beta dataset is updated periodically. The indexed_at field reflects the last update timestamp.

9. Versioning

All LP Intelligence API endpoints are versioned under a path prefix.

The current version is:

/api/v1

Example:

https://api.lp-intelligence.com/api/v1/uniswap-v4/pools

Versioning policy:

  • Non-breaking additions (new fields, new optional parameters) may be made within the current version without a version bump.
  • Breaking changes (removed fields, changed response structure, removed endpoints) will result in a new version path (e.g., /api/v2).
  • Old version paths will be supported with advance notice before deprecation.

During the public beta, the API is still evolving. Field additions are possible. Any breaking changes will be communicated to active API key holders before rollout.

10. Roadmap

This section summarizes the current state and direction of LP Intelligence.

Live — public beta

  • Uniswap v4 pools, pool swaps, account swaps, account positions (ownership + identity + metadata MVP), tokens, chains (see §1.4 if ReDoc omits some routes)
  • Cursor-based pagination where applicable
  • Indexing metadata on list responses where applicable
  • API key authentication

In progress

  • Position fee state (GET /api/v1/uniswap-v4/positions/{position_id}/fees) — implemented in codebase but router not mounted until release

Planned

  • Near real-time ingestion (continuous chain-tip following)
  • Impermanent loss and PnL analytics
  • Multi-protocol expansion (beyond Uniswap v4)
  • Access tiers and usage dashboards