Envelop Managers API

The Managers API from Envelop — 3 operation(s) for managers.

GitHub OpenAPI

Operations 3

GET /v2/managers/{user_address} EnvelopV2: manager proxies owned by an EOA (public) #
GET /v2/managers/{chain_id}/{manager_address}/history EnvelopV2: LP position history of one manager (public) #
GET /v2/managers/{chain_id}/{manager_address}/operators EnvelopV2: active operators of one LP manager (public) #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • 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.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/envelop-is:envelop-is-managers-api"
All apis
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.

Get an API 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 Specification

envelop-is-managers-api-openapi.yml Raw ↑
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