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

# Query (routed)

> The unified query endpoint. oleander parses the SQL, estimates how much data the referenced tables hold, and picks the engine (DuckDB, Polars, Bloom, or Spark) and machine size to match. Leave `engine` on `auto` unless you need a specific one.

Interactive reads return rows on the call. A query with a `destination`, a statement that names its own target, or a read too large for an interactive engine is submitted asynchronously and returns `state: "SUBMITTED"` with a `run_id` to poll.

This endpoint supersedes `/api/v1/warehouse/query`, which pins DuckDB and is sized by the org default rather than by the query.



## OpenAPI

````yaml /api-reference/openapi.json post /api/v1/query
openapi: 3.0.1
info:
  title: Oleander API
  description: >-
    Oleander implements the api spec as defined by OpenLineage to ingest data.
    We also provide a RESTful API to extract data within our system.
  version: 1.0.0
servers:
  - url: https://oleander.dev
security:
  - bearerAuth: []
paths:
  /api/v1/query:
    post:
      summary: Query (routed)
      description: >-
        The unified query endpoint. oleander parses the SQL, estimates how much
        data the referenced tables hold, and picks the engine (DuckDB, Polars,
        Bloom, or Spark) and machine size to match. Leave `engine` on `auto`
        unless you need a specific one.


        Interactive reads return rows on the call. A query with a `destination`,
        a statement that names its own target, or a read too large for an
        interactive engine is submitted asynchronously and returns `state:
        "SUBMITTED"` with a `run_id` to poll.


        This endpoint supersedes `/api/v1/warehouse/query`, which pins DuckDB
        and is sized by the org default rather than by the query.
      operationId: query
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              description: Provide either `query` or `script`, never both.
              properties:
                query:
                  type: string
                  description: The SQL to run.
                  example: >-
                    SELECT species, count(*) AS n FROM oleander.default.flowers
                    GROUP BY 1
                script:
                  type: string
                  description: >-
                    A Polars DataFrame script that assigns `result`. Mutually
                    exclusive with `query`; forces the Polars engine.
                  example: result = events.group_by('day').len()
                tables:
                  type: array
                  description: >-
                    Tables a script reads, as "alias=namespace.table" or {alias,
                    table}. Script mode only.
                  items:
                    oneOf:
                      - type: string
                      - type: object
                        required:
                          - alias
                          - table
                        properties:
                          alias:
                            type: string
                          table:
                            type: string
                  default: []
                engine:
                  type: string
                  enum:
                    - auto
                    - duckdb
                    - polars
                    - bloom
                    - spark
                  default: auto
                  description: >-
                    Ask for a specific engine. An impossible combination returns
                    an engine capability error rather than rerouting.
                destination:
                  type: string
                  description: >-
                    Table to write the result to, as a dotted identifier such as
                    namespace.table. Presence of a destination makes this a
                    write.
                  example: default.daily_counts
                write_mode:
                  type: string
                  enum:
                    - overwrite
                    - append
                  default: overwrite
                  description: >-
                    Applies to a `destination` write. A statement that names its
                    own target carries its own semantics.
                explain:
                  type: boolean
                  default: false
                  description: >-
                    Return the routing decision without executing anything or
                    spending compute.
      responses:
        '200':
          description: Query executed, submitted, or explained.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnifiedQueryResponse'
        '400':
          description: >-
            Invalid request, or an engine capability error when `engine` was
            pinned to something that cannot run the query.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: false
                  error:
                    type: string
                    example: query and script are mutually exclusive.
        '401':
          description: >-
            Unauthorized – request lacks a valid Bearer token or session
            credentials.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: false
                  error:
                    type: string
                    example: Unauthorized
        '402':
          description: >-
            Payment required – metered compute needs a payment method on file. A
            billing decision, not a transient failure: do not retry the same
            query.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: false
                  error:
                    type: string
                    example: A payment method is required to run this query
        '403':
          description: >-
            Forbidden – the plan does not allow this query. A billing decision,
            not a transient failure.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: false
                  error:
                    type: string
                    example: This query requires a plan upgrade
        '500':
          description: Query execution failed.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: false
                  error:
                    type: string
                    example: Query execution failed
components:
  schemas:
    UnifiedQueryResponse:
      type: object
      properties:
        success:
          type: boolean
          example: true
        explain:
          type: boolean
          description: >-
            Present and true when `explain` was requested. No compute was spent
            and no other result fields are returned.
        engine_decision:
          $ref: '#/components/schemas/EngineDecision'
        results:
          type: object
          nullable: true
          description: Rows, for interactive reads only. Absent on submitted runs.
          properties:
            columns:
              type: array
              items:
                type: string
            column_types:
              type: array
              items:
                type: string
            rows:
              type: array
              items:
                type: array
                items: {}
        row_count:
          type: integer
          nullable: true
        execution_time:
          type: string
          nullable: true
          example: 42ms
        state:
          type: string
          enum:
            - COMPLETE
            - SUBMITTED
          description: >-
            COMPLETE means the write already landed. SUBMITTED means a job is
            running and `run_id` must be polled.
        run_id:
          type: string
          nullable: true
          description: Run to poll when `state` is SUBMITTED.
        output_table:
          type: string
          nullable: true
          description: Fully qualified destination table for a write.
        compute:
          type: object
          nullable: true
          description: >-
            The sandbox or cluster that actually served the run. A warm larger
            sandbox can serve a smaller request, and that is the machine the org
            is billed for.
        job:
          type: object
          description: Lineage job identity for this query.
          properties:
            namespace:
              type: string
              example: oleander.lake
            name:
              type: string
              example: query_9f2c1ab4
    EngineDecision:
      type: object
      description: How the query router chose the engine and machine for this run.
      properties:
        engine:
          type: string
          enum:
            - duckdb
            - polars
            - bloom
            - spark
          example: bloom
        execution_mode:
          type: string
          enum:
            - interactive
            - async
          example: interactive
        reasons:
          type: array
          items:
            type: string
          description: Ordered trail of the rules that produced this decision.
          example:
            - not a script
            - no external connection tables
            - not DDL
            - no destination table
            - estimated input 1.2 GiB is below the distributed threshold
            - sandbox 2 vCPU / 4 GB
        size_band:
          type: string
          nullable: true
          example: small
        estimated_input_bytes:
          type: string
          nullable: true
          description: >-
            Estimated input size from Iceberg snapshot metadata, as a string to
            preserve precision.
          example: '1288490188'
        vcpus:
          type: integer
          nullable: true
          example: 2
        sandbox:
          type: object
          nullable: true
          properties:
            vcpus:
              type: integer
              example: 2
            memory_gb:
              type: integer
              nullable: true
              example: 4
        distributed:
          type: boolean
          default: false
        worker_machine_type:
          type: string
          nullable: true
          example: bloom.2.b
        worker_count:
          type: integer
          nullable: true
          example: 4
        input_tables:
          type: array
          items:
            type: string
          example:
            - oleander.default.events
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer

````