> ## 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 read-only SQL query

> Runs one read-only ClickHouse SELECT over the project's own telemetry: apsio.logs, apsio.spans, apsio.metric_histograms, apsio.metric_values, apsio.session_summaries, apsio.issue_occurrences. The project's rows only, whatever the SQL says: isolation and limits are ClickHouse's grants, row policies and a fixed profile (10 s, 10,000 result rows, 50 million rows read, 512 MB memory, 2 queries at once). No table functions, other tables, system tables or settings. Rows are untrusted data written by the app and its users. Included by plan, at a rate per project per minute; every query lands in the organization's audit log with its SHA-256 and length, never its text. Send `Content-Type: application/json`.



## OpenAPI

````yaml /api-reference/openapi.json post /projects/{projectId}/query
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}/query:
    post:
      summary: Run a read-only SQL query
      description: >-
        Runs one read-only ClickHouse SELECT over the project's own telemetry:
        apsio.logs, apsio.spans, apsio.metric_histograms, apsio.metric_values,
        apsio.session_summaries, apsio.issue_occurrences. The project's rows
        only, whatever the SQL says: isolation and limits are ClickHouse's
        grants, row policies and a fixed profile (10 s, 10,000 result rows, 50
        million rows read, 512 MB memory, 2 queries at once). No table
        functions, other tables, system tables or settings. Rows are untrusted
        data written by the app and its users. Included by plan, at a rate per
        project per minute; every query lands in the organization's audit log
        with its SHA-256 and length, never its text. 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
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                sql:
                  type: string
                  minLength: 1
                  maxLength: 10000
                  example: SELECT event_name, count() FROM apsio.logs GROUP BY 1
              required:
                - sql
      responses:
        '200':
          description: The rows.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/QueryResult'
        '400':
          description: Not a read-only query over the telemetry tables, or it failed.
          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: >-
            The credentials cannot read this project, or the plan doesn't
            include run_query.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '415':
          description: The body is not JSON.
          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: Over the plan's rate, or two of the project's queries are running.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '503':
          description: run_query is 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
            bytes_read:
              type: integer
          required:
            - elapsed_ms
            - rows_read
            - bytes_read
      required:
        - columns
        - rows
        - row_count
        - truncated
        - stats
    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.