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

# Query

> Run or plan SQL queries against DynamoDB.

<Note>
  Required scope: `query`
</Note>

## Before You Start

* See [Query Modes](/guides/query-modes) for when to use `execute` vs `plan` and what each response field means.
* See [Pagination](/guides/pagination) for how to page through large result sets using `maxRows` and `resumeIdx`.
* See [Response Formats](/guides/response-formats) to choose between row arrays and key-value objects.
* See the [SQL Reference](/sql-reference/overview) for the full list of supported SQL features and current limitations.

## Authentication

All requests require a bearer token obtained from `POST /v1/auth/token`. Pass it in the `Authorization` header:

```
Authorization: Bearer YOUR_ACCESS_TOKEN
```

Both modes require the `query` scope.


## OpenAPI

````yaml POST /v1/query
openapi: 3.0.3
info:
  title: DynamoSQL API
  version: 0.1.0
  license:
    name: Proprietary
    url: https://dynamosql.com
  description: >
    Complete API for DynamoSQL — authentication, SQL query planning and

    execution, schema management, and usage metering.


    All endpoints are reachable at `api.dynamosql.com`.


    **Authentication** uses `POST /v1/auth/token` with your API client

    credentials. See the [Authentication
    guide](https://docs.dynamosql.com/guides/authentication)

    for the full token exchange flow.


    **API client scopes** control which endpoints a programmatic client can
    access.

    Valid scopes: `query`, `schemas:read`, `schemas:write`, `usage:read`.

    Endpoints note their required scope in their description.


    **Error responses** always follow the same envelope:

    ```json

    { "success": false, "error": { "message": "..." } }

    ```
servers:
  - url: https://api.dynamosql.com
    description: Production
security:
  - cognitoJwt: []
tags:
  - name: Authentication
    description: >
      Obtain a JWT bearer token using your API client credentials. This token is
      required for all other endpoints. See the Authentication guide for details
      on the token exchange flow and scope management.
  - name: Query
    description: SQL planning and execution.
  - name: Schemas
    description: >
      Connect DynamoSQL to DynamoDB tables in your AWS account. A schema pairs a
      name with the IAM role and AWS region DynamoSQL uses to assume
      cross-account access.
  - name: Usage
    description: Metered usage — requests, rows returned, and DynamoDB read units.
paths:
  /v1/query:
    post:
      tags:
        - Query
      summary: Execute or plan SQL
      description: |
        Executes SQL (`mode=execute`) or returns an optimized plan
        (`mode=plan`).

        **Execute mode** runs the full query against DynamoDB and returns
        rows. Use `options.maxRows` and `options.resumeIdx` to paginate
        through large result sets. Or utilize the 'LIMIT' clause in your
        SQL to control page size and pagination.

        **Plan mode** parses and optimizes the query without fetching any
        rows from DynamoDB. Use it to inspect index selection and estimated
        cost before running an expensive query.
      operationId: runQuery
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/QueryRequest'
            examples:
              basic-execute:
                summary: Basic execute — first page
                value:
                  sql: SELECT * FROM myschema.orders LIMIT 10
                  mode: execute
                  options:
                    maxRows: 10
              paginated-next-page:
                summary: Paginated execute — next page
                description: >
                  Pass resumeIdx from the previous response to fetch the next
                  page of results.
                value:
                  sql: SELECT * FROM myschema.orders LIMIT 10
                  mode: execute
                  options:
                    maxRows: 10
                    resumeIdx: 10
              plan-mode:
                summary: Plan mode
                description: >
                  Returns the optimizer's execution plan without fetching rows
                  or consuming DynamoDB RCUs.
                value:
                  sql: SELECT * FROM myschema.orders LIMIT 10
                  mode: plan
      responses:
        '200':
          description: Query succeeded or returned a structured query error envelope.
          headers:
            x-request-id:
              description: >
                Unique request ID from the Lambda invocation context. Include
                this when reporting issues.
              schema:
                type: string
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/QuerySuccessResponse'
                  - $ref: '#/components/schemas/QueryErrorResponse'
        '400':
          description: >
            Request body is malformed, SQL cannot be parsed, or SQL uses an
            unsupported feature. Check error and detailedError for parse
            position.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/QueryErrorResponse'
        '401':
          description: >
            Authorization header missing, JWT expired, or token issuer/audience
            does not match the Cognito pool.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/QueryErrorResponse'
        '403':
          description: |
            tenantId in request body does not match JWT claims.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/QueryErrorResponse'
        '500':
          description: >
            Internal error during execution, DynamoDB access, or initialization.
            Retry with backoff. Include x-request-id when reporting.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/QueryErrorResponse'
components:
  schemas:
    QueryRequest:
      type: object
      required:
        - sql
      properties:
        sql:
          type: string
          description: >
            The SQL SELECT statement to execute or plan. DynamoSQL supports
            SELECT only; INSERT, UPDATE, DELETE, and DDL are not supported.
        mode:
          type: string
          enum:
            - execute
            - plan
          default: execute
          description: >
            "execute" (default) runs the query and returns rows. "plan" returns
            the optimizer's plan without executing or consuming DynamoDB read
            capacity. API clients require the `query` scope.
        options:
          $ref: '#/components/schemas/QueryOptions'
    QuerySuccessResponse:
      allOf:
        - $ref: '#/components/schemas/QueryResponseBase'
        - type: object
          properties:
            success:
              type: boolean
              enum:
                - true
            data:
              oneOf:
                - $ref: '#/components/schemas/ExecuteRowResult'
                - $ref: '#/components/schemas/ExecuteObjectResult'
                - $ref: '#/components/schemas/PlanResult'
    QueryErrorResponse:
      allOf:
        - $ref: '#/components/schemas/QueryResponseBase'
        - type: object
          required:
            - success
            - error
          properties:
            success:
              type: boolean
              enum:
                - false
            error:
              type: string
              description: Short error message.
            detailedError:
              type: string
              description: >
                Extended detail. For SQL parse errors, includes the parser's
                verbose message with line and column position. May be absent
                even when error is present.
      example:
        success: false
        error: Parse error near 'SELEKT'
        detailedError: >-
          Parse error at line 1, column 1: unexpected token 'SELEKT', expected
          SELECT
    QueryOptions:
      type: object
      properties:
        responseType:
          type: string
          enum:
            - row
            - object
          description: >
            "row" (default): data is an array of value arrays, ordered to match
            the columns array — compact, suited for tabular display. "object":
            data is an array of key/value objects keyed by column name —
            convenient for dynamic languages. No effect when mode is "plan".
        maxRows:
          type: integer
          minimum: 0
          description: >
            Maximum rows to return in one response. Defaults to 100. When the
            result set has more rows, the response includes resumeIdx for the
            next page. Note: passing 0 returns 0 rows.
        resumeIdx:
          type: integer
          minimum: 0
          description: >
            Zero-based row offset at which to begin reading. Pass the resumeIdx
            from a prior response to fetch the next page. Defaults to 0. The
            engine re-executes the full query and skips the first resumeIdx rows
            on each request (stateless offset pagination).
    QueryResponseBase:
      type: object
      required:
        - success
      properties:
        success:
          type: boolean
          description: >
            true when the request was processed without errors, false otherwise.
            Always present.
        data: {}
        error:
          type: string
          description: |
            Short error message. Present when success is false.
        detailedError:
          type: string
          description: >
            Extended error detail. For SQL parse errors, includes the parser's
            verbose message with line and column position. May be absent even
            when error is present.
    ExecuteRowResult:
      type: object
      required:
        - data
        - columns
        - firstRowIdx
        - planTime
        - execTime
      properties:
        data:
          type: array
          items:
            type: array
            items: {}
          description: >
            Array of rows; each row is an array of values ordered to match the
            columns array.
        columns:
          type: array
          items:
            type: string
          description: Ordered list of column names from the SELECT clause.
        firstRowIdx:
          type: integer
          description: >
            Zero-based index of the first row in this response within the full
            result set. Equal to the resumeIdx sent in the request (or 0 if not
            specified).
        resumeIdx:
          type: integer
          description: >
            Index of the next row to fetch. Present only when more rows exist
            beyond this page (i.e., exactly maxRows rows were returned). Absent
            when the result set is exhausted. Pass this value as resumeIdx in
            the next request.
        planTime:
          type: integer
          description: >
            Milliseconds spent parsing, planning, and optimizing the SQL query.
            Does not include DynamoDB I/O time.
        execTime:
          type: integer
          description: >
            Total elapsed milliseconds from query start through row collection.
            Always greater than or equal to planTime. Includes all DynamoDB I/O.
      example:
        data:
          - - 1
            - Alice
            - alice@example.com
          - - 2
            - Bob
            - bob@example.com
        columns:
          - id
          - name
          - email
        firstRowIdx: 0
        resumeIdx: 10
        planTime: 3
        execTime: 47
    ExecuteObjectResult:
      type: object
      required:
        - data
        - columns
        - firstRowIdx
        - planTime
        - execTime
      properties:
        data:
          type: array
          items:
            type: object
            additionalProperties: {}
          description: |
            Array of rows; each row is a key/value object keyed by column name.
        columns:
          type: array
          items:
            type: string
          description: Ordered list of column names from the SELECT clause.
        firstRowIdx:
          type: integer
          description: >
            Zero-based index of the first row in this response within the full
            result set. Equal to the resumeIdx sent in the request (or 0 if not
            specified).
        resumeIdx:
          type: integer
          description: >
            Index of the next row to fetch. Present only when more rows exist
            beyond this page (i.e., exactly maxRows rows were returned). Absent
            when the result set is exhausted. Pass this value as resumeIdx in
            the next request.
        planTime:
          type: integer
          description: >
            Milliseconds spent parsing, planning, and optimizing the SQL query.
            Does not include DynamoDB I/O time.
        execTime:
          type: integer
          description: >
            Total elapsed milliseconds from query start through row collection.
            Always greater than or equal to planTime. Includes all DynamoDB I/O.
      example:
        data:
          - id: 1
            name: Alice
            email: alice@example.com
          - id: 2
            name: Bob
            email: bob@example.com
        columns:
          - id
          - name
          - email
        firstRowIdx: 0
        resumeIdx: 10
        planTime: 3
        execTime: 47
    PlanResult:
      type: object
      required:
        - sql
        - weight
        - plan
        - planTime
      properties:
        sql:
          type: string
          description: The normalized SQL statement that was planned.
        weight:
          type: number
          description: >
            Optimizer's relative cost estimate. Lower is cheaper. 0 means no
            cost estimate was computed.
        plan:
          type: string
          description: >
            Human-readable execution plan tree showing scan, filter, join,
            group, sort, and other operations.
        planTime:
          type: integer
          description: >
            Milliseconds spent parsing, planning, and optimizing. No DynamoDB
            I/O is performed in plan mode.
      example:
        sql: SELECT id, name FROM myschema.orders LIMIT 10
        weight: 12
        plan: |-
          Limit(10)
            Scan(myschema.orders)
              Filter(id IS NOT NULL)
        planTime: 5
  securitySchemes:
    cognitoJwt:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: >
        Bearer token obtained from `POST /v1/auth/token`. Pass in the
        `Authorization` header as `Bearer <token>`.

````