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

# Run a panel over a time range

> A SQL panel runs as POST /query runs it (the same limits, the plan's rate and the audit), with the range's {from}, {to} and {bucket}. A preset panel reads its route (for example release-health/daily) with the panel's parameters and the range, on every plan and unmetered, and answers `{preset, data}` with that route's answer. A result is kept for a minute in the API, never stored, so the same panel over the same range within that minute runs nothing (`X-Apsio-Cache: hit`). The range is widened to whole buckets. Send `Content-Type: application/json`.



## OpenAPI

````yaml /api-reference/openapi.json post /projects/{projectId}/dashboards/{dashboardId}/panels/{panelId}/run
openapi: 3.1.0
info:
  title: Apsio API
  version: 0.1.0
  description: >-
    Read API v0: your projects, release health and comparisons, missing symbols,
    issues, sessions, vitals, cohort comparisons, performance (app start,
    screens, hangs, MetricKit) and network endpoints and traces for one project.
    Authenticate with a project token as a bearer token, with an OAuth access
    token from Apsio's authorization server (MCP clients), or, from the console,
    with the session cookie of a member of the project's organization.
servers:
  - url: https://api.apsio.io/v1
security: []
paths:
  /projects/{projectId}/dashboards/{dashboardId}/panels/{panelId}/run:
    post:
      summary: Run a panel over a time range
      description: >-
        A SQL panel runs as POST /query runs it (the same limits, the plan's
        rate and the audit), with the range's {from}, {to} and {bucket}. A
        preset panel reads its route (for example release-health/daily) with the
        panel's parameters and the range, on every plan and unmetered, and
        answers `{preset, data}` with that route's answer. A result is kept for
        a minute in the API, never stored, so the same panel over the same range
        within that minute runs nothing (`X-Apsio-Cache: hit`). The range is
        widened to whole buckets. Send `Content-Type: application/json`.
      parameters:
        - schema:
            type: string
            pattern: ^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$
            example: 0192f3a4-0000-7000-8000-00000000a101
          required: true
          name: projectId
          in: path
        - schema:
            type: string
            pattern: ^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$
            example: 0192f3a4-0000-7000-8000-00000000d001
          required: true
          name: dashboardId
          in: path
        - schema:
            type: string
            pattern: ^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$
            example: 0192f3a4-0000-7000-8000-00000000d001
          required: true
          name: panelId
          in: path
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                range:
                  type: object
                  properties:
                    from:
                      type: string
                      format: date-time
                      description: >-
                        Start of the time range, inclusive (RFC 3339). Defaults
                        to the range end minus the default length.
                      example: '2026-10-01T00:00:00Z'
                    to:
                      type: string
                      format: date-time
                      description: >-
                        End of the time range, exclusive (RFC 3339). Defaults to
                        now.
                      example: '2026-10-08T00:00:00Z'
              additionalProperties: false
      responses:
        '200':
          description: A SQL panel's rows, or a preset panel's answer.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/QueryResult'
                  - $ref: '#/components/schemas/PresetPanelResult'
        '400':
          description: Not valid.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: No valid bearer token or console session.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: 'Not allowed: a role, the grant, or the sandbox.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: No such project, dashboard or panel.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '409':
          description: 'At the limit: 20 dashboards a project, 24 panels a dashboard.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '422':
          description: The query hit a limit.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: Too many writes; try again shortly.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '503':
          description: Dashboards are not available here.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
      security:
        - bearer: []
        - session: []
components:
  schemas:
    QueryResult:
      type: object
      properties:
        columns:
          type: array
          items:
            type: object
            properties:
              name:
                type: string
                description: 'As the query named it: untrusted data.'
              type:
                type: string
                description: The ClickHouse type, for example `UInt64`.
            required:
              - name
              - type
        rows:
          type: array
          items:
            type: array
            items: {}
          description: >-
            One array per row, in the order of `columns`; 64-bit integers as
            strings. Untrusted data.
        row_count:
          type: integer
        truncated:
          type: boolean
          description: 'Whether the result was cut: at 10,000 rows or 12 MB.'
        stats:
          type: object
          properties:
            elapsed_ms:
              type: integer
            rows_read:
              type: integer
              description: >-
                Rounded to 2 significant digits. Counted before the project
                filter, so it includes rows of the parts read.
            bytes_read:
              type: integer
              description: Rounded to 2 significant digits, like rows_read.
          required:
            - elapsed_ms
            - rows_read
            - bytes_read
        range:
          type: object
          properties:
            from:
              type: string
            to:
              type: string
            bucket_seconds:
              type: integer
          required:
            - from
            - to
            - bucket_seconds
          description: The parameters the query got, when it had a `range`.
      required:
        - columns
        - rows
        - row_count
        - truncated
        - stats
    PresetPanelResult:
      type: object
      properties:
        preset:
          type: string
        data:
          description: The preset's route's answer, as it gives it.
      required:
        - preset
    Error:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
              example: invalid_request
            message:
              type: string
          required:
            - code
            - message
      required:
        - error
  securitySchemes:
    bearer:
      type: http
      scheme: bearer
      description: >-
        A project token (apsio_pt_v0...), which reads exactly one project, or an
        OAuth access token issued for the API, which reads what its user can.
        Access tokens issued for Apsio's MCP server are accepted only from the
        MCP server itself.
    session:
      type: apiKey
      in: cookie
      name: apsio_session
      description: >-
        The console session, set by /v1/auth/callback (`__Host-apsio_session`
        when host-only).

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.