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 poolsGET /api/v1/uniswap-v4/pools/{pool_id}/swaps— swap history per poolGET /api/v1/uniswap-v4/accounts/{address}/swaps— swap history per account (filtered by transaction initiatortx.from)GET /api/v1/uniswap-v4/tokens— token metadata for tokens appearing in indexed poolsGET /api/v1/chains— supported chain metadataGET /api/v1/uniswap-v4/accounts/{address}/positions— live. Lists Uniswap v4 positions whose PositionManager ERC-721 is currently owned byaddress(latestTransferpertoken_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 datasetindexed_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, default1(Ethereum mainnet in the backend enum). Identifies the EVM chain for the query.limit— integer page size, default50, minimum1, maximum500.
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 datasetindexed_at— timestamp when indexing completeditems— array of result objectsnext_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:
- Inspect the
next_cursorfield in the response. - 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_cursorensures no overlap between pages.- If
next_cursorisnull, 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-LimitX-RateLimit-RemainingX-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 identifiertoken0andtoken1— assets paired in the poolfee— fee tiertick_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
hooksaddress 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}/positionsendpoint,tick_lowerandtick_upperdescribe 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 rangetick_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 datasetindexed_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 /chainsorGET /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
| Parameter | In | Type / constraints | Default | Description |
|---|---|---|---|---|
chain_id | query | integer, >= 1 | 1 | EVM chain id (EIP-155). |
limit | query | integer, 1–500 | 50 | Page size. The API fetches limit + 1 rows internally to set next_cursor. |
cursor | query | string or omitted | null | Opaque pagination token from the previous response’s next_cursor. Payload (decoded): cb = pool created_block (int), pid = pool_id (bytes32 0x… hex string). |
token | query | string or omitted | null | If 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):
hooksis returned as metadata; hook callback logic is not interpreted in derived fields.
5.3 GET /api/v1/uniswap-v4/pools/{pool_id}/swaps
| Parameter | In | Type / constraints | Default | Description |
|---|---|---|---|---|
pool_id | path | string | required | Uniswap v4 PoolId: 0x + 64 hex chars (32 bytes). Invalid length or hex → 400. |
chain_id | query | integer, >= 1 | 1 | EVM chain id. |
limit | query | integer, 1–500 | 50 | Page size. |
cursor | query | string or omitted | null | Payload: bn = block_number (int), ti = transaction_index (int), li = log_index (int) — canonical event ordering. |
include_raw | query | boolean | false | If 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
| Parameter | In | Type / constraints | Default | Description |
|---|---|---|---|---|
chain_id | query | integer, >= 1 | 1 | EVM chain id. |
q | query | string or omitted | null | Search: 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. |
limit | query | integer, 1–1000 | 200 | Max 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
| Parameter | In | Type / constraints | Default | Description |
|---|---|---|---|---|
address | path | string | required | Wallet / contract address (0x…). Must parse as valid EVM address → else 400. |
chain_id | query | integer, >= 1 | 1 | EVM chain id. |
protocol | query | enum string | uniswap_v4 | Only uniswap_v4 is supported; any other value → 400 (“Unsupported protocol”). |
limit | query | integer, 1–500 | 50 | Page size. |
cursor | query | string or omitted | null | Same 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
| Parameter | In | Type / constraints | Default | Description |
|---|---|---|---|---|
address | path | string | required | Wallet address; must be valid EVM address → else 400. Interpreted as current NFT owner (see below), not as tx.from. |
chain_id | query | integer, >= 1 | 1 | EVM chain id. |
limit | query | integer, 1–500 | 50 | Page size. |
cursor | query | string or omitted | null | Payload: 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 messagetype— machine-readable error classification
Clients should rely on:
- HTTP status code for control flow
typefor programmatic handlingmsgfor 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-LimitX-RateLimit-RemainingRetry-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_cursorfrom 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:
- First page (no cursor):
GET /api/v1/uniswap-v4/accounts/{address}/swaps?chain_id=1&limit=50
- Response includes:
{
"items": [ /* ... */ ],
"next_cursor": "eyJ2Ijo...opaque...",
"limit": 50
}
- 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_blockto 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_blockacross those responses. - If
indexed_to_blockhas not changed between requests, the indexed dataset has not moved forward to newer blocks. - Do not assume that
indexed_to_blockequals 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