Gauntlet Users API

The Users API from Gauntlet — 4 operation(s) for users.

OpenAPI Specification

gauntlet-users-api-openapi.yml Raw ↑
openapi: 3.1.0
info:
  title: Gauntlet Prices Users API
  description: Gauntlet vault data, user positions, and event analytics API.
  contact:
    name: Gauntlet
    url: https://gauntlet.xyz
  license:
    name: ''
  version: 1.0.0
tags:
- name: Users
paths:
  /v1/users/{wallet_address}/activity:
    get:
      tags:
      - Users
      summary: Get user wallet activity (deposits, withdrawals, transfers)
      description: "Immutable log of on-chain events that affected the wallet's vault position. Each row is a frozen-in-time record; rows never mutate after emission. \n\n`?vault_id=` narrows to one vault; omitted = activity across every vault the wallet has touched. Each row echoes its `vault_id` so wallet-wide consumers can distinguish per-vault activity. \n\nAsync deposit/redeem lifecycles emit multiple rows (one at request time with `status=pending`, a later one with `status=settled` or `refunded`). Consumers correlate them via `request_hash` to follow a single action across rows. Sync flows emit one row directly in the settled state. \n\nPagination is cursor-only. Default order is `desc` (newest first). Default page size 100, max 1000."
      operationId: get_user_activity
      parameters:
      - name: wallet_address
        in: path
        description: Ethereum wallet address
        required: true
        schema:
          type: string
      - name: vault_id
        in: query
        description: CAIP-10 vault identifier. Optional — omit for wallet-wide activity across every vault the wallet has touched.
        required: false
        schema:
          type: string
      - name: next
        in: query
        description: Opaque cursor from previous `meta.next_cursor`.
        required: false
        schema:
          type: string
      - name: limit
        in: query
        description: Page size (1–1000, default 100).
        required: false
        schema:
          type: integer
          format: int64
      - name: order
        in: query
        description: 'Sort direction: `desc` (default) or `asc`.'
        required: false
        schema:
          type: string
      responses:
        '200':
          description: User wallet activity
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserActivityResponse'
        '401':
          description: Missing or invalid auth
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Invalid cursor
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /v1/users/{wallet_address}/positions:
    get:
      tags:
      - Users
      summary: Get all current positions for a wallet
      description: 'Returns every vault position the wallet currently holds or has pending exposure in (pending deposit or redeem). Fully-exited positions (zero shares, no pending escrow) are excluded.


        All monetary metrics include a `usd` field (null when pricing is unavailable). `value.usd` and `pending_deposit_assets.usd` use the current spot price. `cost_basis.usd` and `pnl.realized.usd` are computed by replaying on-chain events against the token''s historical price series — the same method used by `GET /v1/users/{wallet}/positions/{vault_id}`. `pnl.unrealized.usd`, `pnl.total.usd`, and `roi_pct.usd` are derived from those.


        Cursor-paginated on internal position ID. Default page size 100, max 500.'
      operationId: get_user_all_positions
      parameters:
      - name: wallet_address
        in: path
        description: Ethereum wallet address
        required: true
        schema:
          type: string
      - name: next
        in: query
        description: Opaque cursor from previous `meta.next_cursor`.
        required: false
        schema:
          type: string
      - name: limit
        in: query
        description: Page size (1–500, default 100).
        required: false
        schema:
          type: integer
          format: int64
      responses:
        '200':
          description: All wallet positions
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserAllPositionsResponse'
        '401':
          description: Missing or invalid auth
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Invalid cursor
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /v1/users/{wallet_address}/positions/{vault_id}:
    get:
      tags:
      - Users
      summary: Get user position in a specific vault
      description: Returns the current position snapshot for a wallet in a single vault. Historical points live on `/positions/{vault_id}/timeseries`.
      operationId: get_user_vault_position
      parameters:
      - name: wallet_address
        in: path
        description: Ethereum wallet address
        required: true
        schema:
          type: string
      - name: vault_id
        in: path
        description: Vault identifier
        required: true
        schema:
          type: string
      responses:
        '200':
          description: Single vault position
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserPositionLatestResponse'
        '401':
          description: Missing or invalid auth
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Position not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /v1/users/{wallet_address}/positions/{vault_id}/timeseries:
    get:
      tags:
      - Users
      summary: Get user position timeseries for a specific vault
      description: Returns historical value, cost basis, grouped PnL, and ROI data for a single vault position. Default order is `asc` (oldest first, chart-friendly); pass `?order=desc` for newest-first list views. Cursor-paginated — pass `meta.next_cursor` back as `?next=` for the next page (cursor is bound to the order it was created with). Defaults to `granularity=day` (one UTC-midnight snapshot per day); `week` returns Monday 00:00 UTC snapshots, `month` returns first-of-month 00:00 UTC snapshots, and `hour` returns the raw hourly cadence. Default page size is 1000.
      operationId: get_user_vault_position_timeseries
      parameters:
      - name: wallet_address
        in: path
        description: Ethereum wallet address
        required: true
        schema:
          type: string
      - name: vault_id
        in: path
        description: Vault identifier
        required: true
        schema:
          type: string
      - name: start
        in: query
        description: 'Window start: ISO 8601 date (`2026-01-01`, read as 00:00:00 UTC) or RFC 3339 timestamp (`2026-01-01T00:00:00Z`).'
        required: false
        schema:
          type: string
      - name: end
        in: query
        description: 'Window end: ISO 8601 date (`2026-01-01`, read as 00:00:00 UTC) or RFC 3339 timestamp (`2026-01-01T00:00:00Z`).'
        required: false
        schema:
          type: string
      - name: next
        in: query
        description: Opaque cursor from previous `meta.next_cursor`.
        required: false
        schema:
          type: string
      - name: limit
        in: query
        description: Page size (1–10000, default 1000).
        required: false
        schema:
          type: integer
          format: int64
      - name: order
        in: query
        description: 'Sort direction: `asc` (default) or `desc`.'
        required: false
        schema:
          type: string
      - name: granularity
        in: query
        description: 'Sampling granularity: `day` (default), `hour`, `week`, or `month`. Day/week/month buckets start at 00:00 UTC; weeks start Monday and months start on the 1st.'
        required: false
        schema:
          type: string
      responses:
        '200':
          description: Position timeseries
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserPositionsTimeseriesResponse'
        '401':
          description: Missing or invalid auth
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Invalid cursor
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
components:
  schemas:
    UserPositionsTimeseriesResponse:
      type: object
      required:
      - meta
      - data
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/PositionTimeseriesPoint'
        meta:
          $ref: '#/components/schemas/TimeseriesMeta'
    UserActivity:
      type: object
      description: 'One immutable entry in the wallet''s activity log.


        Each row represents a single on-chain event that affected the

        wallet''s vault position. Async deposit/redeem lifecycles emit

        multiple rows (one per lifecycle event — request, solve, refund);

        each row is frozen at emission time and never mutates. To follow

        an async action across rows, correlate via `request_hash`.'
      required:
      - block_timestamp
      - type
      - vault_id
      - tx_hash
      - block_number
      - block_hash
      - shares_delta
      - assets_delta
      properties:
        assets_delta:
          $ref: '#/components/schemas/AssetDelta'
          description: "Signed asset delta in the row's asset-token units, using a\ndeposit-ledger sign convention (NOT wallet-flow direction):\n- Positive = a deposit-direction action (`deposit`,\n  `deposit_pending`, `transfer_in`).\n- Negative = a withdraw-direction action (`withdraw`,\n  `deposit_refunded`, `transfer_out`).\n- `0` = no asset movement at this event\n  (`deposit` on Aera async solve, `withdraw_pending`,\n  `withdraw_refunded`).\n\nNote: under this convention `deposit_refunded` is negative\n(a deposit was unwound) even though tokens flow back INTO the\nwallet, and async `withdraw` (Aera redeem_solved) is negative\neven though tokens flow back INTO the wallet — the sign tracks\nthe deposit-ledger direction, not the user's wallet balance.\n\nSumming across rows for a single async lifecycle gives the net\nsigned asset movement of that lifecycle (no double-counting).\n`assets_delta.token` identifies the asset token when known. Emitted\nas a struct (`{ native: \"...\", token: { address, symbol } }`) so\nderived denominations (e.g. usd) can be added later without breaking\nthe response shape."
        block_hash:
          type: string
          description: 'Block hash — 1:1 identifier for the block this event was mined

            in. Consumers needing to detect reorgs should key off this rather

            than `block_number` (multiple blocks can share a number across a

            reorg).'
        block_number:
          type: integer
          format: int64
          description: 'Block number — kept alongside `block_timestamp` for on-chain

            reconciliation / explorer linking.'
        block_timestamp:
          type: integer
          format: int64
          description: Unix seconds, block time (`block.timestamp` from the chain).
        request_hash:
          type:
          - string
          - 'null'
          description: 'Aera async-flow correlation hash. Links a `*_pending` row to

            its later terminal row (bare `deposit`/`withdraw` for settled,

            or `*_refunded`) of the same lifecycle. Emitted only on rows

            that participate in an async flow; omitted on sync rows and on

            secondary-market transfers.'
        shares_delta:
          type: string
          description: "Signed share delta in 18-decimal units, reported at the event\nwhere the shares actually moved. Conventions by row type:\n- `deposit` — positive (shares minted to the wallet).\n- `deposit_pending` / `deposit_refunded` — `0` (no share\n  movement; deposit requests touch assets only).\n- `withdraw_pending` — negative for Aera async redeems (shares\n  leave the wallet at request time, escrowed to the Provisioner).\n- `withdraw` — negative for sync (Morpho) withdraws (shares\n  burn on the same row that pays out assets); `0` for Aera\n  async redeems (the share movement is recorded on the paired\n  `withdraw_pending` row).\n- `withdraw_refunded` — positive (escrowed shares return).\n- `transfer_in` — positive; `transfer_out` — negative.\n\nSumming across rows for a single async lifecycle gives the net\nshare movement of that lifecycle — there is no double-counting."
        tx_hash:
          type: string
          description: Transaction hash of the on-chain event.
        type:
          type: string
          description: 'What happened. One of:

            - `deposit` — settled deposit (sync vault flow or async terminal solve).

            - `deposit_pending` — async deposit request submitted; awaiting solver.

            - `deposit_refunded` — async deposit returned without settling; assets bounced back.

            - `withdraw` — settled withdrawal (sync vault flow or async terminal solve).

            - `withdraw_pending` — async redeem request submitted; awaiting solver.

            - `withdraw_refunded` — async redeem returned without settling; shares bounced back.

            - `transfer_in` — vault shares received from another EOA (secondary market).

            - `transfer_out` — vault shares sent to another EOA.


            Async deposit/redeem lifecycles emit two rows (a `*_pending` at

            request time, then a separate terminal row — bare `deposit` or

            `_refunded` — at solve time). Rows are immutable; the pending

            row never mutates. Correlate the pair via `request_hash`.'
        vault_id:
          type: string
          description: CAIP-10 vault identifier this row belongs to. Always emitted.
    UserActivityResponse:
      type: object
      required:
      - meta
      - data
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/UserActivity'
        meta:
          $ref: '#/components/schemas/TimeseriesMeta'
    BasicMeta:
      type: object
      required:
      - request_id
      - refreshed_at
      properties:
        refreshed_at:
          type: string
          format: date-time
        request_id:
          type: string
    UserPositionMetrics:
      type: object
      required:
      - pending_deposit_assets
      - shares_owned
      - pending_redeem_shares
      - value
      - cost_basis
      - pnl
      - roi_pct
      properties:
        cost_basis:
          $ref: '#/components/schemas/AmountPair'
          description: Cumulative cost of currently-held shares.
        pending_deposit_assets:
          $ref: '#/components/schemas/AmountPair'
          description: 'Assets escrowed at the Aera Provisioner pending share mint

            (`native` = numeraire-token units, `usd` = `native` × current USD price).'
        pending_redeem_shares:
          type: string
          description: Shares escrowed at the Aera Provisioner pending asset return.
        pnl:
          $ref: '#/components/schemas/PnlBreakdown'
          description: Profit and loss grouped by total, unrealized, and realized values.
        roi_pct:
          $ref: '#/components/schemas/RatioPair'
          description: Time-weighted ROI from user deposit/redeem history.
        shares_owned:
          type: string
          description: Shares currently held by the wallet.
        value:
          $ref: '#/components/schemas/AmountPair'
          description: 'Current market value of held shares (`native` = numeraire-token

            units, `usd` = `native` × current USD price).'
    PnlBreakdown:
      type: object
      required:
      - total
      - unrealized
      - realized
      properties:
        realized:
          $ref: '#/components/schemas/AmountPair'
          description: Locked-in PnL from past disposals.
        total:
          $ref: '#/components/schemas/AmountPair'
          description: '`unrealized` + `realized`.'
        unrealized:
          $ref: '#/components/schemas/AmountPair'
          description: '`value` − `cost_basis`.'
    PartialResponseError:
      type: object
      required:
      - code
      - message
      properties:
        code:
          type: string
          description: Machine-readable error code for the isolated item failure.
        message:
          type: string
          description: Human-readable error message.
        resource_id:
          type:
          - string
          - 'null'
          description: Resource that failed inside the aggregate response, when known.
    ErrorResponse:
      type: object
      description: Standard error response envelope returned on 4xx/5xx
      required:
      - error
      properties:
        error:
          $ref: '#/components/schemas/ErrorBody'
    PositionTimeseriesPoint:
      type: object
      required:
      - timestamp
      - shares_owned
      - value
      - cost_basis
      - pnl
      - roi_pct
      properties:
        cost_basis:
          $ref: '#/components/schemas/AmountPair'
          description: Cumulative cost of held shares (`usd` uses per-event historical pricing).
        pnl:
          $ref: '#/components/schemas/PnlBreakdown'
          description: Profit and loss grouped by total, unrealized, and realized values.
        roi_pct:
          $ref: '#/components/schemas/RatioPair'
          description: ROI ratio (`native` is in-kind; `usd` is null when pricing unavailable).
        shares_owned:
          type: string
          description: Shares currently held by the wallet at this timestamp.
        timestamp:
          type: string
          format: date-time
        value:
          $ref: '#/components/schemas/AmountPair'
          description: 'Position value at this timestamp (`native` = numeraire-token units,

            `usd` = `native` × historical USD price; null when unavailable).'
    UserPosition:
      type: object
      required:
      - vault_id
      - wallet_address
      - metrics
      properties:
        metrics:
          $ref: '#/components/schemas/UserPositionMetrics'
        numeraire_token:
          oneOf:
          - type: 'null'
          - $ref: '#/components/schemas/TokenRef'
        vault_id:
          type: string
        wallet_address:
          type: string
    AssetDelta:
      type: object
      description: 'Asset-delta envelope on user activity rows. `native` is always present;

        `token` is present when the indexer knows the row''s asset token.

        The struct shape is kept stable so derived denominations (usd,

        numeraire token) can be added later without breaking integrators.'
      required:
      - native
      properties:
        native:
          type: string
        token:
          oneOf:
          - type: 'null'
          - $ref: '#/components/schemas/TokenRef'
    RatioPair:
      type: object
      description: 'JSON-number ratio paired across native (in-kind) and USD denominations.

        Null when event history is unavailable or cannot support ROI replay.'
      properties:
        native:
          type:
          - number
          - 'null'
          format: double
        usd:
          type:
          - number
          - 'null'
          format: double
    AmountPair:
      type: object
      description: 'Decimal-string metric paired across native (numeraire-token) and USD.

        `native` is always present; `usd` is JSON null when pricing is unavailable.'
      required:
      - native
      properties:
        native:
          type: string
        usd:
          type:
          - string
          - 'null'
    UserAllPositionsResponse:
      type: object
      required:
      - meta
      - data
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/UserPosition'
        meta:
          $ref: '#/components/schemas/TimeseriesMeta'
    ErrorBody:
      type: object
      required:
      - code
      - message
      properties:
        code:
          type: string
          description: Machine-readable error code (e.g. `NOT_FOUND`, `UNAUTHORIZED`)
        details: {}
        message:
          type: string
          description: Human-readable error message
    UserPositionLatestResponse:
      type: object
      required:
      - meta
      - data
      properties:
        data:
          $ref: '#/components/schemas/UserPosition'
        meta:
          $ref: '#/components/schemas/BasicMeta'
    TokenRef:
      type: object
      required:
      - address
      properties:
        address:
          type: string
        decimals:
          type:
          - integer
          - 'null'
          format: int32
        symbol:
          type:
          - string
          - 'null'
    TimeseriesMeta:
      type: object
      required:
      - request_id
      - refreshed_at
      - count
      - limit
      properties:
        count:
          type: integer
          format: int64
          description: Number of points in this response.
        end:
          type:
          - string
          - 'null'
          format: date-time
        limit:
          type: integer
          format: int64
          description: Page-size cap actually applied.
        next_cursor:
          type:
          - string
          - 'null'
          description: Set when more pages exist; pass back as `?next=`.
        partial_errors:
          type:
          - array
          - 'null'
          items:
            $ref: '#/components/schemas/PartialResponseError'
          description: Item-scoped failures isolated from an aggregate response.
        refreshed_at:
          type: string
          format: date-time
        request_id:
          type: string
        start:
          type:
          - string
          - 'null'
          format: date-time
          description: Window bounds the response covers (echoes the request when set).