> ## Documentation Index
> Fetch the complete documentation index at: https://takeprofit.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# List historical volume footprint profiles

> Provide `exchange`, `symbol`, and `timeframe`. Nothing else is required: the
window defaults to the 100 timeframe periods before now.

- With `from` the window starts there and runs forward, ending at `to` or after
  `period` seconds (100 timeframe periods by default).
- Without `from` the window ends at `to` (now by default) and runs backwards over
  `period` seconds or the 100 timeframe periods before it.
- The default is measured in wall-clock time, so on an exchange with trading sessions
  it holds fewer than 100 profiles, and none while the market has been closed for the
  whole window (a 1m frame outside trading hours); pass `from` or `period` to reach
  back further.
- `period` cannot be added to an explicit `from`+`to` window.
- The requested range is limited to at most 1000 profiles, and `rowSize` (price row
  height in ticks, 0 enables automatic detection) is bounded, so a single request cannot
  ask for an unbounded number of price levels.
- Every profile in one response shares the same `rowSize` and every row price is a whole
  multiple of it. That grid is resolved from the requested range, so a different range
  can answer on a different grid; pass `rowSizeValue` to pin it.
- History depth is limited per timeframe, counted back from the security's newest candle
  (from now while it trades): by default 30 days for minute frames below 5m, rising with
  the timeframe to 3 years for 1w and above. A `from` older than that limit is trimmed to
  it rather than rejected, so the response may start later than `from` (the first
  `profileStart` is the effective start) and a range ending before the limit is empty.

**Cost:** 10 credits per returned profile, at least 1000 credits per request.




## OpenAPI

````yaml /platform-api/specs/openapi.yaml get /api/v1/marketdata/footprint
openapi: 3.0.3
info:
  title: TakeProfit API (REST)
  version: 0.6.0
  contact:
    email: support@takeprofit.com
  description: |
    Historical marketdata and the security catalog over REST. Live streams
    (candles, volume footprint, order books) are served over WebSocket and
    described by the AsyncAPI document at
    `https://public-api.takeprofit.com/api/v1/marketdata/asyncapi.yaml`.
    Guides (getting an API key, credits and quota, errors) live at
    [takeprofit.com/docs](https://takeprofit.com/docs).

    ## Requests

    - Base URL: `https://public-api.takeprofit.com`.
    - Every endpoint answers `GET` only.
    - Authenticate with the `x-api-key` header; exactly one header value is
      required.
    - Unknown query parameters and repeated scalar parameters are rejected
      with 400.
    - Identify securities with `exchange` and `symbol` as returned by the
      catalog endpoints; internal ids and GUIDs are not accepted (search
      additionally accepts an ISIN as a lookup key).

    ## Credits and quota

    Requests are metered in credits against a fixed quota window of 100000
    credits per 60 seconds, shared by all API keys of the account. Each
    operation states its price; every billed request costs at least 1000
    credits, so an account makes at most 100 requests per minute. Every
    authenticated response carries the window state:

    - `X-RateLimit-Limit` - credits per window;
    - `X-RateLimit-Remaining` - credits still available after this request;
    - `X-RateLimit-Reset` - epoch second the window resets at.

    A request the remaining credits cannot cover is rejected with 429 and
    `Retry-After` (seconds until the window resets); the rejection itself is
    free.

    ## Errors

    Every error response is `{"error": {"code": "<stable code>", "message":
    "<human-readable text>"}}`. The statuses listed on each operation (400,
    401, 403, 404, 429) are the outcomes a client handles explicitly. A 400
    is either `invalid_argument` (a malformed request) or `too_much_data`: the
    request produces more data than can be served in one response, and only a
    narrower window fixes it - it is never a rate limit. In
    addition, any operation can answer 502 (`bad_gateway`), 503
    (`unavailable`) or 504 (`deadline_exceeded`) while the gateway or an
    upstream is unavailable or slow; these are transient - retry with
    exponential backoff.
servers:
  - url: https://public-api.takeprofit.com
    description: Production
security: []
paths:
  /api/v1/marketdata/footprint:
    get:
      tags:
        - Footprint
      summary: List historical volume footprint profiles
      description: >
        Provide `exchange`, `symbol`, and `timeframe`. Nothing else is required:
        the

        window defaults to the 100 timeframe periods before now.


        - With `from` the window starts there and runs forward, ending at `to`
        or after
          `period` seconds (100 timeframe periods by default).
        - Without `from` the window ends at `to` (now by default) and runs
        backwards over
          `period` seconds or the 100 timeframe periods before it.
        - The default is measured in wall-clock time, so on an exchange with
        trading sessions
          it holds fewer than 100 profiles, and none while the market has been closed for the
          whole window (a 1m frame outside trading hours); pass `from` or `period` to reach
          back further.
        - `period` cannot be added to an explicit `from`+`to` window.

        - The requested range is limited to at most 1000 profiles, and `rowSize`
        (price row
          height in ticks, 0 enables automatic detection) is bounded, so a single request cannot
          ask for an unbounded number of price levels.
        - Every profile in one response shares the same `rowSize` and every row
        price is a whole
          multiple of it. That grid is resolved from the requested range, so a different range
          can answer on a different grid; pass `rowSizeValue` to pin it.
        - History depth is limited per timeframe, counted back from the
        security's newest candle
          (from now while it trades): by default 30 days for minute frames below 5m, rising with
          the timeframe to 3 years for 1w and above. A `from` older than that limit is trimmed to
          it rather than rejected, so the response may start later than `from` (the first
          `profileStart` is the effective start) and a range ending before the limit is empty.

        **Cost:** 10 credits per returned profile, at least 1000 credits per
        request.
      operationId: listFootprint
      parameters:
        - name: exchange
          in: query
          required: true
          schema:
            $ref: '#/components/schemas/ExchangeCode'
        - name: symbol
          in: query
          required: true
          description: >-
            Public security symbol returned by
            /api/v1/marketdata/exchanges/{exchange}/securities.
          schema:
            $ref: '#/components/schemas/SecuritySymbol'
        - name: timeframe
          in: query
          required: true
          description: >-
            Minute (1m..59m), hour (1h..24h), day (1d..31d), week (1w..4w), or
            month (1M) timeframe id.
          schema:
            $ref: '#/components/schemas/TimeframeId'
        - name: from
          in: query
          required: false
          description: >-
            Range start as Unix seconds or RFC3339 timestamp. Without it the
            window is measured backwards from to.
          schema:
            $ref: '#/components/schemas/TimestampQuery'
        - name: to
          in: query
          required: false
          description: >-
            Range end as Unix seconds or RFC3339 timestamp, greater than from.
            Defaults to now when from is omitted.
          schema:
            $ref: '#/components/schemas/TimestampQuery'
        - name: period
          in: query
          required: false
          description: >-
            Range duration in seconds, counted forward from from or backwards
            from to.
          schema:
            $ref: '#/components/schemas/PositiveSeconds'
        - name: rowSize
          in: query
          required: false
          description: >-
            Price row height in tick size. 0 (or omitted) enables automatic row
            size detection. When rowSizeValue is set it takes precedence, but
            rowSize is still validated.
          schema:
            type: integer
            minimum: 0
            maximum: 1000000
          example: 0
        - name: rowSizeValue
          in: query
          required: false
          description: >-
            Absolute price row height in quote currency units, echoed back from
            the rowSize a previous response returned. Takes precedence over
            rowSize and pins this request to the same price grid, so a chart
            that loads history and then opens the footprint websocket stream
            keeps one price axis. A resolved row size is not always a whole
            number of ticks, so rowSize cannot always reproduce it. The server
            may still coarsen the pinned value onto the stored price grid or to
            respect its row limit, so read the rowSize actually returned.
          schema:
            type: string
          example: '0.5'
        - name: sessionType
          in: query
          required: false
          description: >-
            Optional session filter. Repeat this parameter or pass
            comma-separated values.
          style: form
          explode: true
          schema:
            type: array
            items:
              $ref: '#/components/schemas/SessionType'
      responses:
        '200':
          description: Volume footprint response.
          headers:
            X-RateLimit-Limit:
              $ref: '#/components/headers/RateLimitLimit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/RateLimitRemaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/RateLimitReset'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FootprintResponse'
        '400':
          $ref: '#/components/responses/InvalidRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/RateLimited'
      security:
        - ApiKeyAuth: []
components:
  schemas:
    ExchangeCode:
      type: string
      description: TakeProfit exchange code as returned by /api/v1/marketdata/exchanges.
      example: BATS
    SecuritySymbol:
      type: string
      description: >-
        TakeProfit security symbol as returned by
        /api/v1/marketdata/exchanges/{exchange}/securities. In a path segment a
        slash must be percent-encoded (BTC/USDT is requested as BTC%2FUSDT).
      example: AAPL
    TimeframeId:
      type: string
      description: >-
        Timeframe id returned by /api/v1/marketdata/timeframes. Canonical
        suffixes include M for months and Q for quarters.
      example: 1h
    TimestampQuery:
      type: string
      description: Unix seconds (for example 1790000000) or RFC3339 timestamp.
    PositiveSeconds:
      type: integer
      minimum: 1
    SessionType:
      type: string
      enum:
        - MAINSESSION
        - PRE_MARKET
        - POST_MARKET
    FootprintResponse:
      type: object
      required:
        - meta
        - profiles
      properties:
        meta:
          $ref: '#/components/schemas/CandlesMeta'
        profiles:
          type: array
          items:
            $ref: '#/components/schemas/FootprintProfile'
      example:
        meta:
          exchange: CXBNCE
          symbol: BTC/USDT
          timeframe: 1h
        profiles:
          - profileStart: '2026-09-21T10:00:00Z'
            profileEnd: '2026-09-21T11:00:00Z'
            sessionType: MAINSESSION
            rowSize: '100'
            rows:
              - - '84100'
                - '66.32422'
                - '63.42842'
                - 8305
                - 6430
              - - '84200'
                - '185.50922'
                - '151.98043'
                - 25221
                - 22635
              - - '84300'
                - '103.05549'
                - '75.71044'
                - 13722
                - 12348
              - - '84400'
                - '67.85132'
                - '72.35893'
                - 10385
                - 10509
              - - '84500'
                - '349.05247'
                - '260.16653'
                - 34101
                - 27199
              - - '84600'
                - '108.17618'
                - '98.62807'
                - 13821
                - 13449
              - - '84700'
                - '55.2806'
                - '34.94816'
                - 5132
                - 4522
              - - '84800'
                - '1.75602'
                - '2.40955'
                - 229
                - 186
            totalVolumeSell: '759.63053'
            totalVolumeBuy: '937.00552'
            totalTradesCountSell: 97278
            totalTradesCountBuy: 110916
    CandlesMeta:
      type: object
      required:
        - exchange
        - symbol
        - timeframe
      properties:
        exchange:
          $ref: '#/components/schemas/ExchangeCode'
        symbol:
          $ref: '#/components/schemas/SecuritySymbol'
        timeframe:
          $ref: '#/components/schemas/TimeframeId'
    FootprintProfile:
      type: object
      required:
        - profileStart
        - sessionType
        - rowSize
        - rows
        - totalVolumeSell
        - totalVolumeBuy
        - totalTradesCountSell
        - totalTradesCountBuy
      properties:
        profileStart:
          type: string
          format: date-time
        profileEnd:
          type: string
          format: date-time
        sessionType:
          $ref: '#/components/schemas/SessionType'
        rowSize:
          type: string
          description: >-
            Price increment per row, in quote currency units. Identical for
            every profile of one response, and every row price is a whole
            multiple of it. Echo this value back as the rowSizeValue query
            parameter to pin a follow-up request to the same grid.
        rows:
          type: array
          description: Price rows ordered from lowest to highest price.
          items:
            $ref: '#/components/schemas/FootprintRow'
        totalVolumeSell:
          type: string
        totalVolumeBuy:
          type: string
        totalTradesCountSell:
          type: integer
          format: int64
        totalTradesCountBuy:
          type: integer
          format: int64
    ErrorResponse:
      type: object
      required:
        - error
      properties:
        error:
          type: object
          required:
            - code
            - message
          properties:
            code:
              type: string
              description: Stable public error code.
            message:
              type: string
              description: Human-readable public error message.
      example:
        error:
          code: unauthenticated
          message: authentication failed
    FootprintRow:
      type: array
      description: >-
        One price row as the positional array [price, volumeBuy, volumeSell,
        tradesCountBuy, tradesCountSell]. price is the lower bound of the
        half-open interval [price, price + rowSize); price and volumes are
        decimal strings, trade counts are integers. Future fields extend the
        array, so clients must ignore extra trailing elements.
      minItems: 5
      items: {}
      example:
        - '84500'
        - '349.05247'
        - '260.16653'
        - 34101
        - 27199
  headers:
    RateLimitLimit:
      description: Credits allowed per quota window.
      schema:
        type: integer
    RateLimitRemaining:
      description: Credits still available in the current quota window after this request.
      schema:
        type: integer
    RateLimitReset:
      description: Epoch second at which the current quota window resets.
      schema:
        type: integer
        format: int64
    RetryAfter:
      description: Seconds until the quota window resets and the request can be retried.
      schema:
        type: integer
  responses:
    InvalidRequest:
      description: >-
        Invalid request (`invalid_argument`), or a request producing more data
        than can be served (`too_much_data`).
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error:
              code: invalid_argument
              message: query parameter "exchange" is required
    Unauthorized:
      description: Authentication failed.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error:
              code: unauthenticated
              message: authentication failed
    Forbidden:
      description: Permission denied.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error:
              code: permission_denied
              message: permission denied
    NotFound:
      description: The exchange or the security is not served.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error:
              code: not_found
              message: security not found
    RateLimited:
      description: >-
        The remaining credits of the quota window cannot cover this request;
        retry after the window resets.
      headers:
        X-RateLimit-Limit:
          $ref: '#/components/headers/RateLimitLimit'
        X-RateLimit-Remaining:
          $ref: '#/components/headers/RateLimitRemaining'
        X-RateLimit-Reset:
          $ref: '#/components/headers/RateLimitReset'
        Retry-After:
          $ref: '#/components/headers/RetryAfter'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error:
              code: rate_limited
              message: rate limit exceeded
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key

````