Envelop Managers API
The Managers API from Envelop — 3 operation(s) for managers.
The Managers API from Envelop — 3 operation(s) for managers.
Every API here is available over the APIs.io API and to AI agents over MCP.
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
find_apisBrowse and filter every API in the catalog.get_api_artifactsOne API's artifacts, grouped by type.get_openapiThe primary OpenAPI for this API.find_similar_apisAPIs that look like this one.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.curl "https://apis.io/api/v1/apis/envelop-is:envelop-is-managers-api"
curl "https://apis.io/api/v1/apis?limit=25"
Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.
Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
title: Fast Managers API
version: 0.1.0
tags:
- name: Managers
paths:
/v2/managers/{user_address}:
get:
summary: 'EnvelopV2: manager proxies owned by an EOA (public)'
description: 'List every EnvelopV2 proxy owned by an EOA, across all indexed chains.
Public endpoint - no `Authorization` header required.
Covers every proxy an EnvelopV2 factory has deployed, which includes the
StableLP/VolatileLP managers of the `LPManagerFactory` stack (oracle types 3000 and
3001) as well as the older v2 smart wallets (type 2002). Each one is itself a v2
wNFT that mints token id 1 to its owner, so "owned by" means the current holder of
that token.
All filters are optional: `chain_id` restricts to one chain, `implementation` to one
implementation address, `oracle_type` to one kind of contract (e.g. 3000 for
StableLP managers only). By default every chain carrying EnvelopV2 data is queried.
Paginated with `page` (from 1) and `size`. The default of 100 is larger than the
house default of 10 on purpose: this endpoint answers "everything this EOA owns",
and today only 3 of 69 owners hold more than 100 proxies, so one call is normally
enough. Ordering is stable (chain_id, created_block, manager_address), and a page
shorter than `size` is the last one.
Each row: `chain_id`, `manager_address`, `implementation`, `oracle_type`,
`manager_type`, `created_block`, `create_tx`, `owner`.
Sources: `public.raw_envelopv2` (EnvelopV2Deployment logs - proxy, implementation and
oracle type), `chain_.token_721` (current owner of token 1) and
`public.dict_contract_types` (manager_type).'
operationId: v2_managers_by_owner
parameters:
- name: user_address
in: path
required: true
schema:
type: string
title: User Address
- name: page
in: query
required: false
schema:
type: integer
default: 1
title: Page
- name: size
in: query
required: false
schema:
type: integer
default: 100
title: Size
- name: chain_id
in: query
required: false
schema:
anyOf:
- type: integer
- type: 'null'
title: Chain Id
- name: implementation
in: query
required: false
schema:
anyOf:
- type: string
- type: 'null'
title: Implementation
- name: oracle_type
in: query
required: false
schema:
anyOf:
- type: integer
- type: 'null'
title: Oracle Type
responses:
'200':
description: Successful Response
content:
application/json:
schema: {}
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
tags:
- Managers
/v2/managers/{chain_id}/{manager_address}/history:
get:
summary: 'EnvelopV2: LP position history of one manager (public)'
description: 'Indexed history of an EnvelopV2 LP manager''s Uniswap v4 positions.
Public endpoint - no `Authorization` header required.
One entry per position, where a position is a `salt`. Pass `?salt=` to get just one.
The granularity is the manager rather than the position because a manager card shows
several positions at once; per position it would be N requests per screen.
Each entry: `chain_id`, `manager_address`, `salt`, `pool_id`, `opened_at`,
`entry_amount0/1`, `lifetime_fees0/1`, `lives` and `events`.
**A salt can be opened more than once.** When its liquidity returns to zero the manager
deletes the position, and the same salt can be opened again (on a Stable manager salt =
poolId, so every "withdraw all, allocate again" into one pool does it). The per-salt fields
above sum every opening. `lives` cuts them apart, oldest first: `opened_block`,
`opened_at`, `closed_block` / `closed_at` (null while open), `pool_id` (a Volatile salt can
be reopened in another pool), `entry_amount0/1` and `lifetime_fees0/1` of that opening
alone. `lives` is null when the index cannot cut the salt (no position rows, or rows that
do not add up) - then treat the salt as one record, as before. Event kinds are `open`, `fees`,
`reinvest` and `recenter`, ordered by `(block, log index)`; `fees` events carry
`fees0`/`fees1`, `recenter` events carry `tick_lower`/`tick_upper`.
**Token amounts are decimal strings in base units** (uint256 does not survive a JSON
number), and `null` where the amount is genuinely unknown - `entry_amount0/1` are null
when the price to split the liquidity by was unavailable at that block, which is not
the same as zero. `lifetime_fees0/1` are never null: no fee events means exactly zero.
Times are unix seconds and are nullable, because they are interpolated from
`public.chain_time`, which today has a feed only for chains 1 and 42161.
**Three answers, not two.** `200` with an empty `events` list, or an empty array, is a
real answer: the manager is known and the index has nothing for it - do not fall back
to scanning logs. Every error is the other state, "the index cannot answer, go scan":
`400` for a chain whose LP handlers are not switched on (the response lists the ones
that are), `404` for an address that is not a known LP manager or a `salt` this
manager has no position under, `500` for anything else. A non-integer `chain_id`,
`page` or `size` is answered by FastAPI itself with `422` and a list in `detail`.
`entry_amount0/1` are the amounts the allocate and moveLiquidity transactions actually
added to the position (a move opens its destination salt with no allocate), not the
`amount*Desired` upper bounds from their calldata, so they read lower than a client
computing the same figure from calldata. There is no reorg handling in this pipeline:
an event that was reorged out stays indexed, which can only inflate `lifetime_fees0/1`.
Sources: `public.lp_positions` (Uniswap v4 ModifyLiquidity of this manager - salt,
pool_id, exact amounts), `public.lp_events` (decoding view over
`public.raw_lp_manager` - FeesCollected / Reinvested / Recentered / Allocated),
`public.dict_contracts` (LP manager registry, oracle types 3000/3001/3002),
`public.event_state` (which chains are indexed) and
`public.get_estimate_date_for_block` / `public.chain_time` (block timestamps).'
operationId: v2_manager_position_history
parameters:
- name: chain_id
in: path
required: true
schema:
type: integer
title: Chain Id
- name: manager_address
in: path
required: true
schema:
type: string
title: Manager Address
- name: salt
in: query
required: false
schema:
anyOf:
- type: string
- type: 'null'
title: Salt
- name: page
in: query
required: false
schema:
type: integer
default: 1
title: Page
- name: size
in: query
required: false
schema:
type: integer
default: 20
title: Size
responses:
'200':
description: Successful Response
content:
application/json:
schema: {}
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
tags:
- Managers
/v2/managers/{chain_id}/{manager_address}/operators:
get:
summary: 'EnvelopV2: active operators of one LP manager (public)'
description: 'Addresses that are operators of an EnvelopV2 LP manager right now.
Public endpoint - no `Authorization` header required.
Returns an object, not a bare list:
```json
{
"chain_id": 42161,
"manager_address": "0x60723973abf3bbc2ce7eb4400b728390d55e264b",
"indexed_to_block": 487466603,
"operators": [
{"operator": "0xd5228c94...", "allowed_since_block": 487466603}
]
}
```
**`indexed_to_block` is the point of the wrapper.** Operator status is not a stored
field anywhere - on-chain it is a last-write-wins fold over `OperatorSet(address
indexed operator, bool allowed)`, and a fold is only as true as the log it saw. A
client rebuilding it from `eth_getLogs` that loses a span to a throttling provider
loses the revoking `OperatorSet(op, false)` with it, leaves the earlier
`OperatorSet(op, true)` as the last word, and shows a revoked operator as active.
Answering with a list and no block would move exactly that failure onto the server, so
the block the fold is current to travels with the list. Compare it to the head of the
chain to decide whether the answer is fresh enough for what you are about to do.
`allowed_since_block` is the block of the grant that is currently in force; a re-grant
moves it forward. Not paginated: this is the operator set of one manager.
Enumerating operators on-chain is not an alternative. `operatorCount()` /
`operatorList(i)` exist in the sources, but the deployed managers are non-upgradeable
EIP-1167 clones of an older implementation and the call reverts on every live one, so
the index is the only source that can answer at all.
**Three answers, not two**, as in `/history`. `200` with an empty `operators` list is a
real answer - the manager is known and has no active operator, do not fall back to
scanning logs. Every error means "the index cannot answer, go scan": `400` for a chain
whose LP handlers are not switched on (the response lists the ones that are), `404` for
an address that is not a known LP manager, `500` for anything else, including the case
where the index cannot state how far it has walked.
Sources: `public.lp_events` (decoding view over `public.raw_lp_manager` - the
OperatorSet logs), `public.dict_contracts` (LP manager registry, oracle types
3000/3001/3002) and `public.event_state` (which chains are indexed, and how far).'
operationId: v2_manager_operators
parameters:
- name: chain_id
in: path
required: true
schema:
type: integer
title: Chain Id
- name: manager_address
in: path
required: true
schema:
type: string
title: Manager Address
responses:
'200':
description: Successful Response
content:
application/json:
schema: {}
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
tags:
- Managers
components:
schemas:
HTTPValidationError:
properties:
detail:
items:
$ref: '#/components/schemas/ValidationError'
type: array
title: Detail
type: object
title: HTTPValidationError
ValidationError:
properties:
loc:
items:
anyOf:
- type: string
- type: integer
type: array
title: Location
msg:
type: string
title: Message
type:
type: string
title: Error Type
type: object
required:
- loc
- msg
- type
title: ValidationError
securitySchemes:
APIKeyHeader:
type: apiKey
in: header
name: Authorization
JwtAccessBearer:
type: http
scheme: bearer
HTTPBasic:
type: http
scheme: basic