---
title: "Run query"
method: POST
path: "/v1/query/run"
tags: ["Queries"]
---

# Run query

`POST /v1/query/run`

Run the query specified in the request body. Successful requests will return the data as a base64 encoded [Apache Arrow](https://arrow.apache.org/) table, allowing you to extract query results from Omni and use them elsewhere. For example, piping data to Google Sheets or leveraging data in a Python notebook.

## Query parameters

- `userId` string, uuid

## Request body

- object
  - `query` object, required — A JSON object representing the query to be run. To retrieve a query's JSON object from an Omni workbook: 1. Open a workbook in Omni. 2. Click the **bug icon** to toggle open the **Inspector** panel. For **Mac** use `Option + 9`; for **Windows**, use `Alt + 9`. 3. Locate the **Query structure** section. 4. Copy the query JSON.
    - `modelId` string, uuid, required — The ID of the model to execute the query against.
    - `table` string, required — The base table or topic name.
    - `fields` string[], required — The column names to include in the query results.
    - `limit` integer, nullable — Number of rows to return. Defaults to `1000` if not defined. Maximum is `75000`. - If `null`, unlimited results will be returned. **Note**: This is compatible with pivoted queries if `resultType` is `csv` or `xlsx`. - If set to a negative number, the API will return a `400` response.
    - `sorts` object[] — Sort specifications for the query results.
      - `column_name` string — The column to sort by
      - `sort_descending` boolean — If `true`, sort in descending order
      - `is_column_sort` boolean
      - `null_sort` string — How to handle nulls (e.g., `OMNI_DEFAULT`)
    - `filters` object — Filter conditions to apply to the query.
    - `pivots` object[] — Pivot configurations for the query.
    - `calculations` object[] — Custom calculations to include in the query.
    - `column_totals` object — Column total configuration.
    - `row_totals` object — Row total configuration.
    - `column_limit` integer — Column limit for pivoted queries.
    - `join_paths_from_topic_name` string — Topic name for join paths.
    - `join_via_map` object — Custom join path mappings.
    - `version` integer — Query version number.
    - `default_group_by` boolean — If `true`, enable default grouping behavior.
    - `dbtMode` boolean — If `true`, enable dbt mode.
    - `rewriteSql` boolean — If `true`, enable SQL mode.
    - `dimensionIndex` integer — The index of the last dimension in the list of fields in the query. Used internally to order and group fields in the UI.
    - `controls` object[] — Control configurations for the query.
    - `manualSort` boolean — If `true`, sorting was manually applied to the query instead of using Omni's default behavior.
    - `fill_fields` string[] — A list of dimensions that should have missing values filled with placeholder rows.
    - `userEditedSQL` string — User-edited SQL override.
    - `custom_summary_types` object — Custom summary type configurations.
  - `branchId` string, uuid — Optional ID of a model branch to execute the query against. When provided, the query runs against the specified branch instead of the shared model. The branch must belong to the same shared model specified in `query.modelId` and be within your organization.
  - `connectionEnvironmentId` string, uuid — Optional connection environment ID to override the session-derived connection environment for this query run. The requesting user must have access to the specified environment. When provided, the query runs against the specified connection environment instead of the user's session selection.
  - `userId` string, uuid — Executes the query as the specified user. Prefer passing `userId` as a query parameter instead of in the request body. Providing `userId` in both locations will return a `400` error. If not provided in either location, the API uses the user associated with the API token. The `userId` must belong to a user in your organization.
  - `cache` 'Standard' | 'SkipRequery' | 'SkipCache' — Optional cache policy to control how query caching behaves. Must be one of: - `Standard` - Uses standard caching behavior - `SkipRequery` - Uses cached results if available, but does not requery if not found (default) - `SkipCache` - Bypasses cache and always executes a fresh query
  - `resultType` 'csv' | 'json' | 'xlsx' — **Cannot be used with `planOnly`.** Specifies the format of query results exported by the API. If omitted, the API will return results in a base-64 encoded format.
  - `planOnly` boolean — **Cannot be used with `resultType`.** If `true`, the API will return the query execution plan without running the query. The response will include the generated SQL and query metadata.
  - `formatResults` boolean — **Applicable only if `resultType` is specified.** If `true`, formatting will be applied to numeric and currency values in the form of currency symbols and thousand separators.
  - `workbookUrl` boolean — **Cannot be combined with `planOnly`.** If `true`, creates an ephemeral workbook reproducing the query (preserving the run's `branchId` and timezone) and returns its URL in the `X-Omni-Workbook-Url` response header. The header works for all `resultType` modes and is delivered as a header to keep response bodies byte-identical. The header is best-effort: it will be silently omitted if the (target) user lacks the workbooks permission (`USE_WORKBOOKS`) on the query's model, or if workbook creation fails.

## Response `200`

Successful responses will contain the following:

- An object with a `jobs_submitted` property
- An object containing details about the job, such as `job_id`, `status`, and the provided query. **Note**: If `planOnly: true` was included in the request body, the status will be `PLANNED`.
- The job details object will also contain a `result` property, which contains the query results as a base64 encoded Apache Arrow table. You can use the [Omni Python SDK](https://github.com/exploreomni/omni-python-sdk) to decode and validate the results.

If the request times out, the response will include `remaining_job_ids`. Poll the `/api/v1/query/wait` endpoint with these IDs until `timed_out` is `false`.

- object
  - `jobs_submitted` object — Map of job IDs to client result IDs
  - `job_id` string, uuid — The unique identifier for the query job
  - `status` string — Job status (e.g., `COMPLETE`, `PLANNED`)
  - `client_result_id` string, uuid — Client-side result identifier
  - `summary` object — Query execution summary including SQL, stats, and field metadata
  - `cache_metadata` object — Cache information including TTL and data freshness
  - `query` object — The executed query details
  - `result` string — Base64 encoded Apache Arrow table containing query results
  - `stream_stats` object — Server-side streaming metrics
    - `server_stream` integer — Time in milliseconds to stream the result data from the server
  - `remaining_job_ids` string[] — IDs of the jobs still processing if the request timed out. Poll `/api/v1/query/wait` with these IDs.
  - `timed_out` string — Indicates if the request timed out. If `true`, use `remaining_job_ids` to poll for results.

## Other responses

- `400` — Bad Request. Possible causes: - `userId` provided in both the query parameter and request body - `formatResults` provided without `resultType` - `planOnly` and `resultType` both provided (incompatible) - `planOnly` and `workbookUrl` both provided (incompatible) - `workbookUrl` requested on a query containing `staticQueryReferences` - `query.limit` is a negative number - `branchId` provided when querying a schema model (schema models do not have branches) - `branchId` is not a valid UUID
- `403` — Forbidden. Possible causes: - A Personal Access Token (PAT) attempted to use `userId` to run the query as a different user. PATs can only run queries as their own user. - If including a `connectionEnvironmentId`, the requesting user must have access to the specified environment.
- `404` — Not Found. Possible causes: - The specified `userId` does not exist or does not belong to your organization - The specified model, topic, or view does not exist - The specified `branchId` does not exist, belongs to a different model, or is in a different organization - The branch has been soft-deleted
- `408` — Timeout
- `429` — Too Many Requests - Rate limit exceeded (60 requests/minute)

---

[API](https://skmtc.net/omni/apis/omni-api.md) · [All operations](https://skmtc.net/omni/apis/omni-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/omni/omni-api/revisions/6b02f7349d0e/schema)
