Skip to content

Instantly share code, notes, and snippets.

@erinkcochran87
Last active January 22, 2026 21:40
Show Gist options
  • Select an option

  • Save erinkcochran87/95cbf0577065b914d3dc86d074e84566 to your computer and use it in GitHub Desktop.

Select an option

Save erinkcochran87/95cbf0577065b914d3dc86d074e84566 to your computer and use it in GitHub Desktop.
Omni OpenAPI spec
openapi: 3.1.0
info:
title: Omni API
description: |
The Omni REST API provides programmatic access to your Omni instance for managing users, documents, queries, schedules, and more.
version: 1.0.0
contact:
name: Omni Support
url: https://docs.omni.co
servers:
- url: https://{instance}.omniapp.co/api
description: Production
variables:
instance:
default: blobsrus
description: Your production Omni instance subdomain
- url: https://{instance}.playground.exploreomni.dev/api
description: Playground
variables:
instance:
default: blobsrus
description: Your playground Omni instance subdomain
security:
- bearerAuth: []
- orgApiKey: []
tags:
- name: AI
description: AI-powered query generation
- name: Connections
description: Manage database connections
- name: Schema refresh schedules
description: Manage automated schema refresh schedules for connections
- name: Connection environments
description: Manage connection environments database connections
- name: Content
description: Unified content retrieval (documents and folders)
- name: Content migration
description: Export and import dashboards
- name: Content validator
description: Validate content against models and perform find/replace operations
- name: Dashboard downloads
description: Download dashboards and tiles as PDF, PNG, XLSX, CSV, or JSON files
- name: Documents
description: Create, retrieve, and manage documents
- name: Document permissions
description: Manage document-level access
- name: Document labels
description: Apply and manage labels on documents
- name: Document favorites
description: Favorite and unfavorite documents
- name: Dashboard filters and controls
description: Read and update dashboard filter and control default values
- name: Labels
description: |
Manage labels in an organization. Labels can be applied to documents and folders to help organize and categorize content.
**Label types:**
- **Basic labels**: Can be created and managed by any user
- **Verified labels**: Indicate curated or officially sanctioned content. Admin-only.
- **Homepage labels**: Appear on the organization homepage. Admin-only.
- name: Folders
description: Create and organize content folders
- name: Folder permissions
description: Manage folder-level access
- name: Jobs
description: Check status of asynchronous jobs
- name: Models
description: Create and manage data models
- name: Model branches
description: Manage model branches and merge changes
- name: Model git configuration
description: Manage git configuration for shared models
- name: Queries
description: Execute workbook queries
- name: Schedules
description: Create and manage scheduled tasks
- name: Schedule recipients
description: Manage schedule recipients
- name: Topics
description: Retrieve topic information from models
- name: Users
description: Manage users
- name: User groups
description: Manage user groups
- name: User model roles
description: Manage model and connection role assignments for users
- name: User group model roles
description: Manage model and connection role assignments for user groups
paths:
/v1/ai/generate-query:
post:
tags:
- AI
summary: Generate a query
description: Generate a structured Omni query from natural language using AI
security:
- bearerAuth: []
operationId: generateQuery
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- modelId
- prompt
properties:
modelId:
type: string
format: uuid
description: The ID of the model to run the query against
currentTopicName:
type: string
description: Name of the base topic/table. If left empty, AI will automatically choose a topic based on the question.
prompt:
type: string
description: Natural language instruction describing the desired query output
workbookUrl:
type: boolean
description: When `true`, returns an Omni workbook URL that opens and runs the generated query
branchId:
type: string
description: The ID of the model branch to use to generate the query. If not provided, the `main` branch will be used.
contextQuery:
type: object
description: A query object to provide as context. Use this to reference previous queries or provide additional context for the generation.
structured:
type: boolean
description: When `true`, returns a more strictly structured query format. This is useful for applications that need to parse the query structure.
example:
modelId: "123e4567-e89b-12d3-a456-426614174000"
currentTopicName: "orders"
prompt: "Show me total revenue by product category for the last quarter"
responses:
'200':
description: Successfully generated query
content:
application/json:
schema:
type: object
properties:
query:
type: object
properties:
model_job:
type: object
description: A structured Omni query object that can be used with the [Query run API](/api/run-query)
properties:
model_id:
type: string
format: uuid
description: Model identifier
table:
type: string
description: Base table/topic name
fields:
type: array
items:
type: string
description: Array of field names to include in query
calculations:
type: array
items:
type: object
description: Custom calculations
filters:
type: object
description: Filter conditions
sorts:
type: array
items:
type: object
properties:
column_name:
type: string
sort_descending:
type: boolean
is_column_sort:
type: boolean
null_sort:
type: string
description: Sort specifications
limit:
oneOf:
- type: integer
- type: "null"
description: Result row limit
pivots:
type: array
items:
type: object
description: Pivot configurations
fill_fields:
type: array
items:
type: string
description: Fields to fill
column_totals:
type: object
description: Column totals configuration
row_totals:
type: object
description: Row totals configuration
column_limit:
type: integer
description: Column limit for pivots
default_group_by:
type: boolean
description: Enable default grouping
join_via_map:
type: object
description: Join configuration map
join_paths_from_topic_name:
type: string
description: Topic name for join paths
version:
type: integer
description: Query version
period_over_period_computations:
type: array
items:
type: object
description: Period over period calculations
query_references:
type: object
description: Query references
metadata:
type: object
description: Query metadata
custom_summary_types:
type: object
description: Custom summary type definitions
example:
query:
model_job:
model_id: "bcf0cffd-ec1b-44d5-945a-a261ebe407fc"
table: "order_items"
fields:
- "products.item_name"
- "order_items.total_sale_price"
calculations: []
filters: {}
sorts:
- column_name: "order_items.total_sale_price"
sort_descending: true
is_column_sort: false
null_sort: "OMNI_DEFAULT"
limit: 10
pivots: []
fill_fields: []
column_totals: {}
row_totals: {}
column_limit: 50
default_group_by: true
join_via_map: {}
join_paths_from_topic_name: "order_items"
version: 5
period_over_period_computations: []
query_references: {}
metadata: {}
custom_summary_types: {}
'400':
description: |
Bad Request
Possible error messages:
- `Invalid method`
- `Invalid JSON`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'403':
description: |
Forbidden
Possible error messages:
- `Feature not enabled`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
$ref: '#/components/responses/TooManyRequests'
'500':
$ref: '#/components/responses/InternalServerError'
/v1/connections:
post:
tags:
- Connections
summary: Create connection
x-mint:
content: |
Creates a new database connection. See below for a handful of example requests.
<Tabs>
<Tab title="BigQuery">
```bash title="Create a BigQuery connection"
curl -L -X POST 'https://{your-instance}.omniapp.co/api/v1/connections' \
-H 'Authorization: Bearer <TOKEN>' \
-H 'Content-Type: application/json' \
-d '{
"dialect": "bigquery",
"name": "My BigQuery Connection",
"region": "us",
"passwordUnencrypted": "<SERVICE_ACCOUNT_JSON_FILE>",
"defaultSchema": "my_dataset",
"includeSchemas": "dataset1,dataset2",
"includeOtherCatalogs": "other_project1,other_project2",
"maxBillingBytes": "1000000000"
}'
```
**Note**: For BigQuery, you must include a service account JSON file encoded as a string in the `passwordUnencrypted` field.
</Tab>
<Tab title="MySQL">
```bash title="Create a MySQL connection"
curl -L -X POST 'https://{your-instance}.omniapp.co/api/v1/connections' \
-H 'Authorization: Bearer <TOKEN>' \
-H 'Content-Type: application/json' \
-d '{
"dialect": "mysql",
"name": "My MySQL Connection",
"host": "mysql.example.com",
"port": 3306,
"database": "mydb",
"username": "dbuser",
"passwordUnencrypted": "mypassword",
"includeSchemas": "public,analytics",
"queryTimeoutSeconds": 900
}'
```
</Tab>
<Tab title="PostgreSQL">
```bash title="Create a PostgreSQL connection"
curl -L -X POST 'https://{your-instance}.omniapp.co/api/v1/connections' \
-H 'Authorization: Bearer <TOKEN>' \
-H 'Content-Type: application/json' \
-d '{
"dialect": "postgres",
"name": "My Postgres Connection",
"host": "postgres.example.com",
"port": 5432,
"database": "mydb",
"username": "dbuser",
"passwordUnencrypted": "mypassword",
"includeSchemas": "public,analytics",
"queryTimeoutSeconds": 900
}'
```
</Tab>
<Tab title="Snowflake">
```bash title="Create a Snowflake connection"
curl -L -X POST 'https://{your-instance}.omniapp.co/api/v1/connections' \
-H 'Authorization: Bearer <TOKEN>' \
-H 'Content-Type: application/json' \
-d '{
"dialect": "snowflake",
"name": "My Snowflake Connection",
"host": "myaccount",
"database": "MYDB",
"username": "dbuser",
"passwordUnencrypted": "mypassword",
"warehouse": "COMPUTE_WH",
"includeSchemas": "PUBLIC,ANALYTICS",
"includeOtherCatalogs": "OTHER_DB1,OTHER_DB2",
"queryTimeoutSeconds": 900
}'
```
</Tab>
</Tabs>
security:
- bearerAuth: []
operationId: createConnection
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- dialect
- name
- passwordUnencrypted
properties:
dialect:
$ref: '#/components/schemas/Dialect'
name:
type: string
description: A descriptive name for the connection
host:
type: string
description: |
The hostname or IP address of the database server.
- Not required for MotherDuck
- For Snowflake, provide only the account identifier (e.g., `myaccount` not `myaccount.snowflakecomputing.com`)
- For BigQuery, this is automatically determined from the service account
port:
type: integer
description: |
The port number for the database connection.
Not required for Snowflake, MotherDuck, BigQuery, Databricks, and Athena.
database:
type: string
description: |
The default database/catalog to connect to.
- For BigQuery, this is the project ID
- For Athena, this is the data catalog
username:
type: string
description: |
The username to authenticate with.
- Not required for MotherDuck
- For BigQuery, this is the client email from the service account
passwordUnencrypted:
type: string
description: |
The password to authenticate with.
- For BigQuery, this must be the JSON service account key file content
- For Snowflake with keypair authentication, this can be omitted
baseRole:
type: string
enum: [NO_ACCESS, VIEWER, RESTRICTED_QUERIER, QUERIER, MODELER, CONNECTION_ADMIN]
description: The default role for users accessing the connection
warehouse:
type: string
description: |
**Required for**:
- Snowflake - Specify the warehouse
- Databricks - Specify the HTTP path
includeSchemas:
type: string
description: Comma-separated list of schemas to include. Leave empty to include all schemas.
includeOtherCatalogs:
type: string
description: |
Comma-separated list of other catalogs/databases to include. **Only applicable for databases that support multi-catalog queries: BigQuery, Snowflake, MotherDuck, Databricks, Trino, Athena.**
defaultSchema:
type: string
description: The default schema to use. **Required for MSSQL.**
queryTimeoutSeconds:
type: integer
description: The timeout in seconds for queries. Maximum value is `3600` (1 hour). Only applicable for databases that support query timeouts.
maximum: 3600
default: 900
region:
type: string
description: |
**Required for BigQuery and Athena connections.**
- For BigQuery, specify a region like `us`
- For Athena, specify an AWS region like `us-east-1`
maxBillingBytes:
type: string
description: Maximum bytes that can be billed for a BigQuery query. **Applicable for BigQuery only.**
scratchSchema:
type: string
description: Schema to use for data input (upload) tables. If not specified, a suitable default will be chosen.
systemTimezone:
type: string
description: The timezone to use for the system.
default: "UTC"
queryTimezone:
type: string
description: The timezone to use for queries.
default: "NONE"
allowsUserSpecificTimezones:
type: boolean
description: Whether to allow users to specify their own timezones.
default: false
trustServerCertificate:
type: boolean
description: Whether to trust the server certificate. **Applicable for MSSQL, Exasol, and ClickHouse.**
default: false
privateKey:
type: string
description: An RSA key for keypair authentication. Omni will automatically add PEM headers if none are provided. **Applicable for Snowflake only.**
responses:
'201':
description: Connection created successfully
content:
application/json:
schema:
type: object
properties:
success:
type: boolean
data:
type: string
format: uuid
description: Connection ID
'400':
$ref: '#/components/responses/BadRequest'
'403':
$ref: '#/components/responses/Forbidden'
'429':
$ref: '#/components/responses/TooManyRequests'
get:
tags:
- Connections
summary: List connections
description: Retrieves a list of database connections with optional filtering and sorting
security:
- bearerAuth: []
operationId: listConnections
parameters:
- name: name
in: query
schema:
type: string
description: Filter connections by name (case-insensitive, partial matching)
- name: database
in: query
schema:
type: string
description: Filter connections by database name (case-insensitive, partial matching)
- name: dialect
in: query
schema:
$ref: '#/components/schemas/Dialect'
description: Filter connections by dialect(s). For multiple dialects, provide a comma-separated list (e.g., `postgres,mysql`).
- name: sortField
in: query
schema:
type: string
enum: [database, dialect, name]
description: Field to sort by
- $ref: '#/components/parameters/sortDirection'
- name: includeDeleted
in: query
schema:
type: boolean
description: When `true`, the response includes deleted connections. Defaults to `false`.
responses:
'200':
description: Returns a list of connections objects
content:
application/json:
schema:
type: object
properties:
connections:
type: array
items:
$ref: '#/components/schemas/Connection'
'400':
description: |
Bad Request
Possible error messages:
- `formErrors: Unrecognized key(s) in object: '<invalidParam>'`
- `sortField: Invalid enum value. Expected 'database' | 'dialect' | 'name', received '<invalidField>'`
- `Invalid dialect(s): <invalidDialect>`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
$ref: '#/components/responses/TooManyRequests'
/v1/connections/{connectionId}:
patch:
tags:
- Connections
summary: Update connection
description: Update connection properties
security:
- bearerAuth: []
operationId: updateConnection
parameters:
- name: connectionId
in: path
required: true
schema:
type: string
format: uuid
description: Connection ID
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
baseRole:
type: string
enum: [NO_ACCESS, VIEWER, RESTRICTED_QUERIER, QUERIER, MODELER, CONNECTION_ADMIN]
description: The default role for users accessing this connection
environmentUserAttribute:
oneOf:
- type: object
properties:
attributeName:
type: string
description: The name of the user attribute to use for environments
defaultValues:
type: array
items:
type: string
description: Array of default values for the user attribute
required:
- attributeName
- defaultValues
- type: "null"
description: Configuration for environment user attributes. Set to `null` to remove environment user attribute settings.
responses:
'200':
description: Connection updated successfully
content:
application/json:
schema:
type: object
properties:
success:
type: boolean
message:
type: string
'400':
$ref: '#/components/responses/BadRequest'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'429':
$ref: '#/components/responses/TooManyRequests'
/v1/connections/{connectionId}/schedules:
get:
tags:
- Schema refresh schedules
summary: List schema refresh schedules
description: |
Retrieves all schema refresh schedules configured for the specified connection. Each schedule uses a cron expression and timezone to define when the schema should be refreshed.
<Note>
This endpoint requires Connection Admin permissions for the connection.
</Note>
security:
- bearerAuth: []
operationId: listSchemaRefreshSchedules
parameters:
- name: connectionId
in: path
required: true
schema:
type: string
format: uuid
description: The unique identifier of the connection
responses:
'200':
description: Successfully retrieved schema refresh schedules
content:
application/json:
schema:
type: object
properties:
schedules:
type: array
items:
$ref: '#/components/schemas/SchemaRefreshSchedule'
example:
schedules:
- scheduleId: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
connectionId: "f47ac10b-58cc-4372-a567-0e02b2c3d479"
schedule: "00 09 * * ? *"
timezone: "America/New_York"
description: "At 09:00 AM EDT"
createdAt: "2025-01-15T10:30:00.000Z"
updatedAt: "2025-01-15T10:30:00.000Z"
disabledAt: null
'401':
description: Missing or invalid authentication
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'403':
description: |
Insufficient permissions. **Connection Admin** permissions for the connection are required.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
$ref: '#/components/responses/NotFound'
'429':
$ref: '#/components/responses/TooManyRequests'
post:
tags:
- Schema refresh schedules
summary: Create schema refresh schedule
description: |
Creates a new schema refresh schedule for the specified connection. Multiple schedules can be created for the same connection.
<Note>
This endpoint requires Connection Admin permissions for the connection.
</Note>
security:
- bearerAuth: []
operationId: createSchemaRefreshSchedule
parameters:
- name: connectionId
in: path
required: true
schema:
type: string
format: uuid
description: The unique identifier of the connection
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- schedule
- timezone
properties:
schedule:
type: string
description: |
A 6-field cron expression in AWS EventBridge format defining when the schema refresh should run, specified as:
```
minute hour day-of-month month day-of-week year
```
For example:
- `00 09 * * ? *` - Every day at 9:00 AM
- `00 18 ? * MON-FRI *` - Every weekday at 6:00 PM
- `30 08 1 * ? *` - First day of every month at 8:30 AM
timezone:
type: string
description: |
An IANA timezone identifier for when the schedule should run, such as `America/New_York`, `Europe/London`, `Asia/Tokyo`
example:
schedule: "00 09 * * ? *"
timezone: "America/New_York"
responses:
'201':
description: Schema refresh schedule created successfully
content:
application/json:
schema:
$ref: '#/components/schemas/SchemaRefreshSchedule'
example:
scheduleId: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
connectionId: "f47ac10b-58cc-4372-a567-0e02b2c3d479"
schedule: "00 09 * * ? *"
timezone: "America/New_York"
description: "At 09:00 AM EDT"
createdAt: "2025-01-15T10:30:00.000Z"
updatedAt: "2025-01-15T10:30:00.000Z"
disabledAt: null
'400':
description: |
Bad Request
Possible error messages:
- Invalid cron expression
- Invalid timezone
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'401':
description: Missing or invalid authentication
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'403':
description: |
Insufficient permissions. **Connection Admin** permissions for the connection are required.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
$ref: '#/components/responses/NotFound'
'429':
$ref: '#/components/responses/TooManyRequests'
/v1/connections/{connectionId}/schedules/{scheduleId}:
get:
tags:
- Schema refresh schedules
summary: Get schema refresh schedule
description: |
Retrieves the details of a connection's specific schema refresh schedule.
<Note>
This endpoint requires Connection Admin permissions for the connection.
</Note>
security:
- bearerAuth: []
operationId: getSchemaRefreshSchedule
parameters:
- name: connectionId
in: path
required: true
schema:
type: string
format: uuid
description: The unique identifier of the connection
- name: scheduleId
in: path
required: true
schema:
type: string
format: uuid
description: The unique identifier of the schema refresh schedule
responses:
'200':
description: Successfully retrieved schema refresh schedule
content:
application/json:
schema:
$ref: '#/components/schemas/SchemaRefreshSchedule'
example:
scheduleId: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
connectionId: "f47ac10b-58cc-4372-a567-0e02b2c3d479"
schedule: "00 09 * * ? *"
timezone: "America/New_York"
description: "At 09:00 AM EDT"
createdAt: "2025-01-15T10:30:00.000Z"
updatedAt: "2025-01-15T10:30:00.000Z"
disabledAt: null
'401':
description: Missing or invalid authentication
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'403':
description: |
Insufficient permissions. **Connection Admin** permissions for the connection are required.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: |
Not Found
Possible error messages:
- Schedule not found
- Schedule belongs to a different connection
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
$ref: '#/components/responses/TooManyRequests'
put:
tags:
- Schema refresh schedules
summary: Update schema refresh schedule
description: |
Updates the schedule and/or timezone for an existing schema refresh schedule.
<Note>
This endpoint requires Connection Admin permissions for the connection.
</Note>
security:
- bearerAuth: []
operationId: updateSchemaRefreshSchedule
parameters:
- name: connectionId
in: path
required: true
schema:
type: string
format: uuid
description: The unique identifier of the connection
- name: scheduleId
in: path
required: true
schema:
type: string
format: uuid
description: The unique identifier of the schema refresh schedule
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- schedule
- timezone
properties:
schedule:
type: string
description: |
A 6-field cron expression in AWS EventBridge format defining when the schema refresh should run, specified as:
```
minute hour day-of-month month day-of-week year
```
For example:
- `00 09 * * ? *` - Every day at 9:00 AM
- `00 18 ? * MON-FRI *` - Every weekday at 6:00 PM
- `30 08 1 * ? *` - First day of every month at 8:30 AM
timezone:
type: string
description: |
An IANA timezone identifier for when the schedule should run.
example:
schedule: "00 18 ? * * *"
timezone: "Europe/London"
responses:
'200':
description: Schema refresh schedule updated successfully
content:
application/json:
schema:
$ref: '#/components/schemas/SchemaRefreshSchedule'
example:
scheduleId: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
connectionId: "f47ac10b-58cc-4372-a567-0e02b2c3d479"
schedule: "00 18 ? * * *"
timezone: "Europe/London"
description: "At 06:00 PM GMT"
createdAt: "2025-01-15T10:30:00.000Z"
updatedAt: "2025-01-15T11:00:00.000Z"
disabledAt: null
'400':
description: |
Bad Request
Possible error messages:
- Invalid cron expression
- Invalid timezone
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'401':
description: Missing or invalid authentication
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'403':
description: |
Insufficient permissions. **Connection Admin** permissions for the connection are required.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: |
Not Found
Possible error messages:
- Schedule not found
- Connection not found
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
$ref: '#/components/responses/TooManyRequests'
delete:
tags:
- Schema refresh schedules
summary: Delete schema refresh schedule
description: |
Deletes a schema refresh schedule. This does not affect other schedules for the same connection.
<Note>
This endpoint requires Connection Admin permissions for the connection.
</Note>
security:
- bearerAuth: []
operationId: deleteSchemaRefreshSchedule
parameters:
- name: connectionId
in: path
required: true
schema:
type: string
format: uuid
description: The unique identifier of the connection
- name: scheduleId
in: path
required: true
schema:
type: string
format: uuid
description: The unique identifier of the schema refresh schedule
responses:
'200':
description: Schema refresh schedule deleted successfully
content:
application/json:
schema:
$ref: '#/components/schemas/SuccessResponse'
example:
success: true
'401':
description: Missing or invalid authentication
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'403':
description: |
Insufficient permissions. **Connection Admin** permissions for the connection are required.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: |
Not Found
Possible error messages:
- Schedule not found
- Connection not found
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
$ref: '#/components/responses/TooManyRequests'
/v1/connection-environments:
post:
tags:
- Connection environments
summary: Create connection environments
description: Creates connection environments by associating environment-specific connections with a base connection
security:
- bearerAuth: []
operationId: createConnectionEnvironments
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- baseConnectionId
- environmentConnectionIds
properties:
baseConnectionId:
type: string
format: uuid
description: The UUID of the base connection to associate environment connections with
environmentConnectionIds:
type: string
description: |
A comma-separated list of connection UUIDs to use as environment connections. All connection IDs must be valid UUIDs that:
- Exist in your organization
- Have the same dialect as the base connection
- Aren't already used as environment connections for the base connection
- Aren't the same as the base connection
example:
baseConnectionId: "123e4567-e89b-12d3-a456-426614174000"
environmentConnectionIds: "223e4567-e89b-12d3-a456-426614174001,323e4567-e89b-12d3-a456-426614174002"
responses:
'201':
description: Connection environment(s) created successfully
content:
application/json:
schema:
type: object
properties:
success:
type: boolean
data:
type: array
items:
type: object
properties:
id:
type: string
format: uuid
environmentConnectionId:
type: string
format: uuid
'400':
description: |
Bad Request
Possible error messages:
- `Invalid method`
- `Invalid JSON`
- `baseConnectionId: Base connection ID must be a valid UUID`
- `environmentConnectionIds: All environment connection IDs must be valid UUIDs`
- `The following environment connection IDs are not valid for this connection: <ids>`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'403':
$ref: '#/components/responses/Forbidden'
'404':
description: |
Not Found
Possible error messages:
- `Connection with id <baseConnectionId> does not exist`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
$ref: '#/components/responses/TooManyRequests'
/v1/connection-environments/{connectionEnvironmentId}:
put:
tags:
- Connection environments
summary: Update connection environment
description: |
Associates user attribute values with a specific connection environment, which will determine when it is used.
security:
- bearerAuth: []
x-mint:
content: |
<Note>
User attribute values for environment connections work in conjunction with the user attribute name and values set on the base connection, which can be defined using the [Update connection endpoint](/api/connections/update-connection).
The base connection specifies which user attribute to evaluate, while each environment connection specifies which values of that attribute will trigger its use.
</Note>
operationId: updateConnectionEnvironment
parameters:
- name: connectionEnvironmentId
in: path
required: true
schema:
type: string
format: uuid
description: The ID of the connection environment to update
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- userAttributeValues
properties:
userAttributeValues:
type: string
description: |
A comma-separated list of user attribute values to associate with the connection environment. For example: `"dev,staging"`
**Note**: User attribute values must be unique across all environments for a base connection.
responses:
'200':
description: Connection environment updated successfully
content:
application/json:
schema:
$ref: '#/components/schemas/SuccessResponse'
'400':
description: |
Bad Request
Possible error messages:
- `Invalid JSON`
- `Invalid method`
- `Invalid uuid`
- `User attribute value "<value>" is already in use`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'403':
$ref: '#/components/responses/Forbidden'
'404':
description: |
Not Found
Possible error messages:
- `Connection environment with id <id> does not exist`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
$ref: '#/components/responses/TooManyRequests'
/unstable/documents/{dashboardId}/export:
get:
tags:
- Content migration
summary: Export dashboard
description: Export dashboard for migration between Omni instances
x-mint:
content: |
<Warning>
This API is in beta and may have future breaking changes.
</Warning>
security:
- orgApiKey: []
operationId: exportDashboard
parameters:
- name: dashboardId
in: path
required: true
schema:
type: string
description: Dashboard identifier
responses:
'200':
description: Dashboard export data
content:
application/json:
schema:
type: object
properties:
dashboard:
type: object
description: Dashboard configuration
document:
type: object
description: Document metadata
exportVersion:
type: string
example: "0.1"
workbookModel:
type: object
description: Workbook model data
fileUploads:
type: array
description: Spreadsheet file data included in the export. Each item contains the file content and metadata needed to restore spreadsheet tiles during import.
items:
type: object
properties:
fileUploadId:
type: string
description: Unique identifier for the file upload
fileName:
type: string
description: Original file name
contentType:
type: string
description: MIME type of the file
data:
type: string
description: Base64-encoded file content
'404':
$ref: '#/components/responses/NotFound'
/unstable/documents/{documentId}/update-model:
put:
tags:
- Documents
summary: Update document model
description: |
Update the model associated with a document without recreating the document. This preserves all existing metadata such as owner information, view counts, and other document properties.
Both models must:
- Belong to the same organization
- Use the same database dialect
x-mint:
content: |
<Warning>
This API is in beta and may have future breaking changes.
</Warning>
security:
- bearerAuth: []
operationId: updateDocumentModel
parameters:
- name: documentId
in: path
required: true
schema:
type: string
description: |
The identifier of the document to update. To retrieve the identifier, navigate to **File > Document settings** in the document and then click **Settings**. The **Identifier** field contains the document identifier.
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- newModelId
properties:
newModelId:
type: string
format: uuid
description: The ID of the new model to associate with the document. The new model must belong to the same organization and use the same database dialect as the current model.
example:
newModelId: "95e44907-68d0-4b0a-aa3e-fb2b2d971d76"
responses:
'200':
description: Document model updated successfully
content:
application/json:
schema:
type: object
properties:
success:
type: boolean
example: true
message:
type: string
example: "Document updated successfully"
example:
success: true
message: "Document updated successfully"
'400':
description: |
Bad Request. Possible causes:
- `newModelId` is missing from the request body
- Models have incompatible dialects
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
examples:
missingModelId:
summary: Missing newModelId
value:
detail: "Bad Request: newModelId: Required"
incompatibleDialects:
summary: Incompatible dialects
value:
detail: "Models must have the same dialect"
'404':
description: |
Not Found. Possible causes:
- Document with the specified identifier does not exist
- Model with the specified ID does not exist
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
examples:
documentNotFound:
summary: Document not found
value:
detail: "Document with identifier \"a632aeb0\" not found"
modelNotFound:
summary: Model not found
value:
detail: "Model with id 95e44907-68d0-4b0a-aa3e-fb2b2d971d76 does not exist"
'429':
$ref: '#/components/responses/TooManyRequests'
/unstable/documents/import:
post:
tags:
- Content migration
summary: Import dashboard
description: Import dashboard to Omni instance
x-mint:
content: |
<Warning>
This API is in beta and may have future breaking changes.
</Warning>
security:
- orgApiKey: []
operationId: importDashboard
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- baseModelId
- dashboard
- document
- workbookModel
- exportVersion
properties:
baseModelId:
type: string
format: uuid
description: Target model ID
dashboard:
type: object
description: Dashboard configuration from export
document:
type: object
description: Document metadata from export
workbookModel:
type: object
description: Workbook model from export
exportVersion:
type: string
enum: ["0.1"]
description: Export format version (must be "0.1")
identifier:
type: string
description: Custom identifier for the imported dashboard
folderPath:
type: string
description: Destination folder path
fileUploads:
type: array
description: Spreadsheet file data to restore during import. Include the `fileUploads` array from the export response to restore spreadsheet tiles in the imported dashboard.
items:
type: object
properties:
fileUploadId:
type: string
description: Unique identifier for the file upload (from export)
fileName:
type: string
description: Original file name
contentType:
type: string
description: MIME type of the file
data:
type: string
description: Base64-encoded file content
responses:
'200':
description: Dashboard imported successfully
content:
application/json:
schema:
type: object
properties:
dashboard:
type: object
properties:
dashboardId:
type: string
format: uuid
miniUuidMap:
type: object
workbook:
type: object
'400':
$ref: '#/components/responses/BadRequest'
/v1/content:
get:
tags:
- Content
summary: Retrieve content
description: Retrieve paginated list of documents and folders
security:
- bearerAuth: []
operationId: getContent
parameters:
- name: labels
in: query
schema:
type: string
description: Filter content by labels. Provide as a comma-separated list (e.g., `finance,marketing`).
- name: scope
in: query
schema:
type: string
enum: [restricted, organization]
default: organization
description: Content scope filter
- name: sortField
in: query
schema:
type: string
enum: [favorites, name, updatedAt]
default: name
description: Field to sort by
- $ref: '#/components/parameters/sortDirection'
- name: include
in: query
schema:
type: string
description: |
Comma-separated list of additional fields to include in the response:
- `_count` - Adds count metrics (folders: document and favorite counts; documents: favorite and view counts)
- `labels` - Includes associated content labels
- name: folderId
in: query
schema:
type: string
format: uuid
description: Returns all content in the specified folder. **Cannot be used with `path`.**
- name: path
in: query
schema:
type: string
description: |
Filter content by path. **Cannot be used with `folderId`.** Examples:
- `/folder/subfolder` - Returns the folder and any content it contains
- `/folder/*` - Returns all folders and content recursively in the path
- `/` - Returns all content in the organization
- name: creatorId
in: query
schema:
type: string
format: uuid
description: UUID of organization membership. **Required when `scope` is `restricted`.**
- name: pageSize
in: query
schema:
type: integer
minimum: 1
maximum: 100
default: 20
description: Number of records per page (1-100)
- name: cursor
in: query
schema:
type: string
description: Pagination cursor from previous response
responses:
'200':
description: Paginated content list
content:
application/json:
schema:
$ref: '#/components/schemas/PaginatedResponse'
'400':
description: |
Bad Request
Possible error messages:
- `Page size must be at least 1`
- `Page size cannot exceed 100`
- `Invalid sort field`
- `creatorId required when scope is restricted`
- `Unrecognized query parameters`
- `folderId and path cannot be used together`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: |
Not Found
Possible error messages:
- `User with id <uuid> does not exist`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
$ref: '#/components/responses/TooManyRequests'
/v1/documents:
post:
tags:
- Documents
summary: Create document
description: Create a new document
security:
- bearerAuth: []
operationId: createDocument
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- modelId
- name
properties:
modelId:
type: string
format: uuid
description: The ID of the model to build the document on
name:
type: string
description: The name of the document
queryPresentations:
type: array
description: An array of query presentation objects, each representing a query in the document's workbook
items:
type: object
properties:
name:
type: string
description: The name of the query
description:
type: string
description: A description of the query
query:
type: object
description: The query definition object
visConfig:
type: object
description: Visualization configuration for the query
responses:
'200':
description: Document created successfully
content:
application/json:
schema:
type: object
properties:
dashboard:
type: object
properties:
id:
type: string
format: uuid
description: The dashboard ID
createdAt:
type: string
format: date-time
description: Timestamp when the dashboard was created
updatedAt:
type: string
format: date-time
description: Timestamp when the dashboard was last updated
metadata:
type: object
description: Dashboard metadata including layouts and tile settings
properties:
layouts:
type: object
description: Layout configurations for different screen sizes
textTiles:
type: array
items:
type: object
hiddenTiles:
type: array
items:
type: string
tileSettings:
type: object
tileFilterMap:
type: object
tileControlMap:
type: object
metadataVersion:
type: integer
description: Version of the metadata schema
refreshInterval:
type: integer
description: Auto-refresh interval in seconds
facetFilters:
type: boolean
description: Whether facet filters are enabled
organizationId:
type: string
format: uuid
description: The organization ID
workbookId:
type: string
format: uuid
description: The associated workbook ID
creatorId:
type: string
format: uuid
description: The ID of the user who created the dashboard
updaterId:
type: string
format: uuid
description: The ID of the user who last updated the dashboard
queryPresentationCollectionId:
type: string
format: uuid
description: The query presentation collection ID
dashboardId:
type: string
format: uuid
description: The dashboard ID (same as id)
workbook:
type: object
properties:
id:
type: string
format: uuid
description: The workbook ID
createdAt:
type: string
format: date-time
description: Timestamp when the workbook was created
updatedAt:
type: string
format: date-time
description: Timestamp when the workbook was last updated
deletedAt:
type: string
format: date-time
description: Timestamp when the workbook was deleted, if applicable
publishedAt:
type: string
format: date-time
description: Timestamp when the workbook was published
isDraft:
type: boolean
description: Whether the workbook is a draft
identifier:
type: string
description: The unique identifier for the document
name:
type: string
description: The name of the document
lastItemIndex:
type: integer
description: Index of the last item in the workbook
ephemeral:
type: string
description: Ephemeral state identifier
organizationRole:
type: string
description: Organization-level role for the document
organizationAccessBoost:
type: boolean
publicRole:
type: string
publicAccessBoost:
type: boolean
canAnalyze:
type: boolean
description: Whether users can analyze data in the document
canDownload:
type: boolean
description: Whether users can download data from the document
canDrill:
type: boolean
description: Whether users can drill into data in the document
canSchedule:
type: boolean
description: Whether users can create schedules in the document
canUpload:
type: boolean
description: Whether users can upload data in the document's workbook
canViewWorkbook:
type: boolean
description: Whether users can view the workbook in the document
organizationId:
type: string
format: uuid
description: The organization ID
ownerId:
type: string
format: uuid
description: The ID of the document owner
updaterId:
type: string
format: uuid
description: The ID of the user who last updated the document
folderId:
type: string
format: uuid
description: The folder ID, if the document is in a folder
originDocumentId:
type: string
format: uuid
description: The origin document ID, if duplicated
documentId:
type: string
format: uuid
description: The document ID
'400':
description: |
Bad Request
Possible error messages:
- `modelId: Required`
- `name: Required`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
$ref: '#/components/responses/TooManyRequests'
get:
tags:
- Documents
summary: List documents
description: List documents with pagination and filtering
security:
- bearerAuth: []
operationId: listDocuments
parameters:
- name: include
in: query
schema:
type: string
description: |
Comma-separated list of additional fields to include in the response:
- `_count` - Adds favorite and view count metrics
- `labels` - Includes associated document labels
- `includeDeleted` - Include deleted documents
- `onlyFavorites` - **Must be used with `userId`.** Include only documents that the specified user has favorited.
- name: labels
in: query
schema:
type: string
description: |
Comma-separated list of labels to filter results. For example: `finance,marketing`
- name: folderId
in: query
schema:
type: string
format: uuid
description: ID of the folder to filter results. Returns only documents within the specified folder.
- name: pageSize
in: query
schema:
type: integer
minimum: 1
maximum: 100
default: 20
description: Number of records per page
- name: sortField
in: query
schema:
type: string
enum: [favorites, name, updatedAt, visits]
default: name
description: |
Field to sort by:
- `favorites` - Sort by the number of favorites
- `name` - Sort by document name
- `updatedAt` - Sort by last update time
- `visits` - Sort by view count
- name: sortDirection
in: query
schema:
type: string
enum: [asc, desc]
default: desc
description: Sort direction (`asc` for ascending, `desc` for descending)
- name: cursor
in: query
schema:
type: string
description: Cursor for pagination. Used with `sortField`/`sortDirection` for relative positioning.
- name: userId
in: query
schema:
type: string
format: uuid
description: |
The ID of a standard or embed user to filter results, returning only documents the specified user can view based on their permissions.
**Required if `include=onlyFavorites` is specified.**
- name: creatorId
in: query
schema:
type: string
format: uuid
description: ID of the user who created the document(s), returning only documents that the specified user created.
responses:
'200':
description: Paginated document list
content:
application/json:
schema:
$ref: '#/components/schemas/PaginatedResponse'
'400':
description: |
Bad Request
Possible error messages:
- `pageSize: Page size must be at least 1`
- `pageSize: Page size cannot exceed 100`
- `sortField: Invalid enum value. Expected 'favorites' | 'name' | 'updatedAt' | 'visits', received '<invalidField>'`
- `creatorId: Invalid uuid`
- `userId: Invalid uuid`
- `formErrors: Unrecognized key(s) in object: '<unknownParameter>'`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: |
Not Found
Possible error messages:
- `User with id <uuid> does not exist`
**Note**: An invalid UUID format will result in a 400 error. This 404 error occurs when the provided ID is a valid UUID format but the user cannot be found.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
$ref: '#/components/responses/TooManyRequests'
/v1/documents/{documentId}/move:
put:
tags:
- Documents
summary: Move document
description: Move document to new folder or change scope
security:
- bearerAuth: []
operationId: moveDocument
parameters:
- name: documentId
in: path
required: true
schema:
type: string
description: |
The ID of the document to move. To retrieve the ID, navigate to **File > Document settings** in the document and then click **Settings**. The **Identifier** field contains the document ID.
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- folderPath
properties:
folderPath:
oneOf:
- type: string
- type: "null"
description: The path of the destination folder. Use `null` to move the document to the root level (no folder).
scope:
type: string
enum: [organization, restricted]
description: |
Optional sharing scope for the document:
- `organization` - Organization-wide access
- `restricted` - Limited access
If not provided, the scope will be computed based on the document or the destination folder.
**Note**: When providing a scope, it must match the destination folder's scope.
responses:
'200':
description: Document moved successfully
content:
application/json:
schema:
$ref: '#/components/schemas/SuccessResponse'
'400':
description: |
Bad Request
Possible error messages:
- `Scope "<scope>" and folder scope "<folderScope>" do not match`
- `Invalid method`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: |
Not Found
Possible error messages:
- `Document with identifier "<documentId>" not found`
- `Folder with path <path> does not exist`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
$ref: '#/components/responses/TooManyRequests'
/v1/documents/{documentId}/duplicate:
post:
tags:
- Documents
summary: Duplicate published document
x-mint:
content: |
<Warning>
Only published documents can be duplicated. Attempting to duplicate a draft document will return a 404 error.
</Warning>
Duplicate a published document.
security:
- bearerAuth: []
operationId: duplicateDocument
parameters:
- name: documentId
in: path
required: true
schema:
type: string
description: Document identifier
- name: userId
in: query
schema:
type: string
description: |
**Requires an Organization API key**. Optional user ID that attributes the action to the specified user.
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- name
properties:
name:
type: string
minLength: 1
maxLength: 255
description: The name for the duplicated document
folderPath:
oneOf:
- type: string
- type: "null"
description: Path to the destination folder. If not provided, the document will be duplicated to the root.
scope:
type: string
enum: [organization, restricted]
description: |
The visibility scope for the duplicated document.
If not provided, inherits from the destination folder or defaults to `restricted`.
example:
name: "My Dashboard Copy"
folderPath: "/reports/2024/q4"
scope: "organization"
responses:
'201':
description: Document duplicated successfully
content:
application/json:
schema:
type: object
properties:
dashboardId:
type: string
description: The dashboard ID, if the duplicated document has a dashboard
identifier:
type: string
description: Unique identifier for the newly created document
name:
type: string
description: The name of the duplicated document
workbookId:
type: string
description: The workbook ID of the duplicated document
example:
dashboardId: "abc123-dash-id"
identifier: "xyz789-new-identifier"
name: "My Dashboard Copy"
workbookId: "def456-workbook-id"
'400':
description: |
Bad Request. Possible error messages:
- `name: Name cannot be empty`
- `name: Name must be 255 characters or less`
- `Scope "organization" and folder scope "restricted" do not match`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'401':
description: Missing or invalid authentication
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'403':
description: |
Insufficient permissions. Possible error messages:
- `User does not have access to create content on the specified connection`
- `User-scoped API keys can only be used to act on behalf of the authenticated user.`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: |
Not Found. Possible error messages:
- `Document with identifier "<documentId>" not found`
- `Published document with id "<documentId>" does not exist`. This will surface when attempting to duplicate a draft.
- `Folder with path "<folderPath>" does not exist`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'405':
$ref: '#/components/responses/MethodNotAllowed'
'429':
$ref: '#/components/responses/TooManyRequests'
/v1/documents/{documentId}/transfer-ownership:
put:
tags:
- Documents
summary: Transfer document ownership
description: |
Transfer ownership of a document to another user in the organization.
To successfully transfer a document:
- The user performing the transfer must have `MANAGER` permissions or higher on the document
- The new owner must be a member of the organization AND have explicit access to the document
Upon success, the following occurs:
- Ownership of the document is updated to the new owner
- The previous owner is granted `MANAGER` permissions on the document
- Explicit permits for the new owner are revoked, as they now have owner access
- Content search index is updated
**Note:** Transferring to the current owner is a no-op and returns success.
security:
- bearerAuth: []
- orgApiKey: []
operationId: transferDocumentOwnership
parameters:
- name: documentId
in: path
required: true
schema:
type: string
description: |
The ID of the document to transfer. To retrieve the ID, navigate to **File > Document settings** in the document and then click **Settings**. The **Identifier** field contains the document ID.
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- userId
properties:
userId:
type: string
description: The membership ID of the user to transfer ownership to. This must be a valid organization member who has explicit permission on the document.
example:
userId: "9e8719d9-276a-4964-9395-a493189a247c"
responses:
'200':
description: |
Document ownership transferred successfully.
**Note:** This response is also returned when transferring to the current owner.
content:
application/json:
schema:
$ref: '#/components/schemas/SuccessResponse'
example:
success: true
'400':
description: |
Bad Request
Possible error messages:
- `Invalid JSON`
- `userId is required`
- `New owner must have explicit document permission`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
examples:
invalidJson:
summary: Invalid JSON body
value:
error: "Invalid JSON"
missingUserId:
summary: Missing userId field
value:
error: "userId is required"
noPermission:
summary: New owner lacks document permission
value:
error: "New owner must have explicit document permission"
'403':
description: |
Forbidden
Possible error messages:
- `Insufficient permissions` - Acting user does not have `MANAGER` or higher permissions on the document
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
error: "Insufficient permissions"
'404':
description: |
Not Found
Possible error messages:
- `Document with identifier "<documentId>" not found`
- `User not found`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
examples:
documentNotFound:
summary: Document not found
value:
error: "Document with identifier \"doc-123\" not found"
userNotFound:
summary: User not found
value:
error: "User not found"
'405':
$ref: '#/components/responses/MethodNotAllowed'
'429':
$ref: '#/components/responses/TooManyRequests'
/v1/documents/{documentId}:
get:
tags:
- Documents
summary: Get dashboard document
description: |
Retrieves dashboard document configuration in a format compatible with PUT for round-trip editing. This endpoint returns all fields needed to modify and update a dashboard document.
**Note:** This endpoint only supports dashboard documents. Workbook-only documents are not supported and will return a `400 Bad Request` error.
security:
- bearerAuth: []
operationId: getDocument
parameters:
- name: documentId
in: path
required: true
schema:
type: string
description: |
The document identifier. To retrieve the ID, navigate to **File > Document settings** in the document and then click **Settings**. The **Identifier** field contains the document ID.
responses:
'200':
description: Document retrieved successfully
content:
application/json:
schema:
type: object
properties:
name:
type: string
description: The name of the document
modelId:
type: string
format: uuid
description: The ID of the model the document is built on
facetFilters:
type: boolean
description: Whether facet filters are enabled for the document
refreshInterval:
type: integer
description: Auto-refresh interval in seconds
filterConfig:
type: object
description: Filter configuration for the document
filterOrder:
type: array
items:
type: string
description: Array of filter field names defining the order of filters
queryPresentations:
type: array
description: Array of query presentation objects representing tabs in the document's workbook
items:
type: object
properties:
name:
type: string
description: Name of the query tab
query:
type: object
description: Full OmniQuery object with all query fields
properties:
fields:
type: array
items:
type: string
description: Array of field names to include in the query
table:
type: string
description: The table to query from
limit:
type: integer
description: Maximum number of rows to return
filters:
type: object
description: Filter conditions for the query
sorts:
type: array
items:
type: object
description: Sort order for the query results
modelId:
type: string
format: uuid
description: The model ID for the query
chartType:
type: string
description: Chart type (e.g., "bar", "line", "area", "table")
visualization:
type: object
description: Visualization configuration
properties:
visType:
type: string
description: The visualization type (e.g., "basic")
config:
type: object
description: Visualization-specific configuration
fields:
type: array
items:
type: string
description: Fields used in the visualization
prefersChart:
type: boolean
description: Whether the query prefers chart view over table view
id:
type: string
format: uuid
description: Query presentation ID
queryIdentifierMapKey:
type: string
description: Query identifier map key
description:
type: string
description: Description of the query (if set)
subTitle:
type: string
description: Subtitle for the query (if set)
topicName:
type: string
description: Topic name associated with the query (if set)
aiConfig:
type: object
description: AI configuration for the query
resultConfig:
type: object
description: Result table configuration
example:
name: "Sales Dashboard"
modelId: "abc123de-f456-7890-abcd-ef1234567890"
facetFilters: true
refreshInterval: 300
filterConfig:
date_range:
type: "date"
defaultValue: "last_7_days"
filterOrder:
- "date_range"
- "region"
queryPresentations:
- name: "Revenue by Region"
query:
fields:
- "order_items.total_revenue"
- "orders.region"
table: "order_items"
limit: 1000
filters: {}
sorts: []
modelId: "abc123de-f456-7890-abcd-ef1234567890"
chartType: "bar"
prefersChart: true
visualization:
visType: "basic"
config:
xAxis: "orders.region"
yAxis: "order_items.total_revenue"
fields:
- "order_items.total_revenue"
- "orders.region"
id: "cd54494d-318f-4105-af1c-10af59e62b2e"
queryIdentifierMapKey: "1"
aiConfig: {}
resultConfig: {}
'400':
description: |
Bad Request
Possible error messages:
- `Analysis documents are not supported`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
detail: "Analysis documents are not supported"
status: 400
'403':
description: |
Forbidden. User does not have permission to view the document.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
detail: "User does not have permission to view this document"
status: 403
'404':
description: |
Not Found
Possible error messages:
- `Document with identifier "<documentId>" not found`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
detail: "Document with identifier \"054518c8\" not found"
status: 404
'429':
$ref: '#/components/responses/TooManyRequests'
delete:
tags:
- Documents
summary: Delete document
description: Delete document (moves to Trash)
security:
- bearerAuth: []
operationId: deleteDocument
parameters:
- name: documentId
in: path
required: true
schema:
type: string
description: |
The ID of the document to delete. To retrieve the ID, navigate to **File > Document settings** in the document and then click **Settings**. The **Identifier** field contains the document ID.
responses:
'200':
description: Document deleted successfully
content:
application/json:
schema:
$ref: '#/components/schemas/SuccessResponse'
'404':
description: |
Not Found
Possible error messages:
- `Document with identifier "<documentId>" not found`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
$ref: '#/components/responses/TooManyRequests'
patch:
tags:
- Documents
summary: Rename document
description: |
Rename a document. The rename operation follows the app's draft/publish workflow:
| Document Type | Behavior |
|---------------|----------|
| **Draft** | Renamed directly |
| **Published (no existing draft)** | Creates draft > Renames draft > Publishes draft |
| **Published (existing draft, `clearExistingDraft: true`)** | Discards existing draft > Creates new draft > Renames > Publishes |
| **Published (existing draft, `clearExistingDraft` not set)** | Returns `409 Conflict` |
security:
- bearerAuth: []
operationId: renameDocument
parameters:
- name: documentId
in: path
required: true
schema:
type: string
description: Document identifier
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- name
properties:
name:
type: string
minLength: 1
maxLength: 255
description: New name for the document
clearExistingDraft:
type: boolean
description: |
If `true`, discards any existing draft before renaming.
**Note**: This parameter is required when a draft exists for the document.
responses:
'200':
description: Document renamed successfully
content:
application/json:
schema:
type: object
properties:
identifier:
type: string
description: The document identifier
name:
type: string
description: The new document name
example:
identifier: "doc-123"
name: "New Document Name"
'400':
description: |
Bad Request. Possible causes:
- Name is empty
- Name exceeds 255 characters
- Name field is missing
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'403':
description: User has insufficient permissions to update document
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: Document not found
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'405':
$ref: '#/components/responses/MethodNotAllowed'
'409':
description: |
Conflict. Published document has an existing draft and `clearExistingDraft` is not set to `true`.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
$ref: '#/components/responses/TooManyRequests'
put:
tags:
- Documents
summary: Update document
x-mint:
content: |
<Warning>
This endpoint only works with dashboard documents. Workbook-only documents are not supported.
</Warning>
Update a dashboard document. The update operation follows the Omni's [draft/publish workflow](/content/develop):
| Document Type | Behavior |
|---------------|----------|
| **Draft** | Updated directly |
| **Published (no existing draft)** | Creates draft > Updates draft > Publishes draft |
| **Published (existing draft, `clearExistingDraft: true`)** | Discards existing draft > Creates new draft > Updates > Publishes |
| **Published (existing draft, `clearExistingDraft` not set)** | Returns `409 Conflict` |
security:
- bearerAuth: []
operationId: updateDocument
parameters:
- name: documentId
in: path
required: true
schema:
type: string
description: Document identifier
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- modelId
- name
- facetFilters
- refreshInterval
- filterConfig
- filterOrder
- queryPresentations
properties:
modelId:
type: string
description: Model ID for query transformation
name:
type: string
minLength: 1
maxLength: 254
description: Document name
facetFilters:
type: boolean
description: When `true`, enable facet filters on the dashboard
refreshInterval:
oneOf:
- type: integer
minimum: 60
- type: "null"
description: Auto-refresh interval in seconds. Minimum value must be `60`. Use `null` to disable.
filterConfig:
type: object
description: |
Dashboard filter configuration. Pass `{}` for no filters.
Each key is a field name and the value is a filter definition object.
additionalProperties:
type: object
properties:
type:
type: string
description: Field type (e.g., "string", "number")
kind:
type: string
description: Filter kind (e.g., "EQUALS", "GREATER_THAN")
values:
type: array
items: {}
description: Filter values
is_negative:
type: boolean
description: When `true`, negate the filter condition
filterOrder:
type: array
items:
type: string
description: Order of filters in the filter bar. Pass `[]` if no filters.
queryPresentations:
type: array
minItems: 1
description: Array of query presentations (at least one required)
items:
type: object
required:
- name
- query
properties:
name:
type: string
description: Name of the query tab
query:
type: object
required:
- fields
- table
properties:
fields:
type: array
items:
type: string
description: Array of field names to include in the query
table:
type: string
description: Table name for the query
description: Query definition
description:
type: string
description: Query description
subTitle:
type: string
description: Subtitle for the query
prefersChart:
type: boolean
description: When `true`, show chart by default
topicName:
type: string
description: Topic name for the query
chartType:
oneOf:
- type: string
- type: "null"
description: Chart type (line, bar, etc.)
visConfig:
type: object
description: Full visualization configuration
resultConfig:
type: object
description: Result display configuration
aiConfig:
type: object
description: AI configuration
documentMetadata:
type: object
description: Document metadata for feature flags and presentation settings
properties:
presentation:
type: object
properties:
filters:
type: object
properties:
collapsible:
type: boolean
description: Whether filters are collapsible
defaultExpanded:
type: boolean
description: Whether filters are expanded by default
clearExistingDraft:
type: boolean
description: |
If `true`, discards any existing draft before updating.
**Note**: This parameter is required when a draft exists for the document.
example:
modelId: "abc123"
name: "Monthly Sales Dashboard"
facetFilters: true
refreshInterval: null
filterConfig:
order_items.category:
type: "string"
kind: "EQUALS"
values:
- "Electronics"
is_negative: false
filterOrder:
- "order_items.category"
queryPresentations:
- name: "Sales Trend"
description: "Monthly sales over time"
prefersChart: true
topicName: "order_items"
query:
fields:
- "order_items.created_at[month]"
- "order_items.sale_price_sum"
table: "order_items"
visConfig:
visType: "basic"
spec:
mark:
type: "line"
documentMetadata:
presentation:
filters:
collapsible: true
defaultExpanded: false
responses:
'200':
description: Document updated successfully
content:
application/json:
schema:
type: object
properties:
identifier:
type: string
description: The document identifier
name:
type: string
description: The updated document name
example:
identifier: "my-dashboard"
name: "Q4 Sales Dashboard"
'400':
description: |
Bad Request. Possible causes:
- Missing required fields (`modelId`, `name`, `facetFilters`, `refreshInterval`, `filterConfig`, `filterOrder`, `queryPresentations`)
- Invalid field values (`name` too long, `refreshInterval` less than `60`)
- Empty `queryPresentations` array (at least one required)
- Document has no dashboard (workbook-only document)
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'403':
description: User has insufficient permissions to update document
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: Document not found
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'409':
description: |
Conflict. Published document has an existing draft and `clearExistingDraft` is not set to `true`.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
$ref: '#/components/responses/TooManyRequests'
/v1/documents/{documentId}/draft:
delete:
tags:
- Documents
summary: Archive draft
description: |
Archives the current draft of the specified document. Archived drafts will be placed in the in the [**Archived** section of the **Drafts** drawer](/content/develop/drafts#archiving-drafts) in the document's workbook and retained for 30 days.
If a branch is specified, the current draft on the branch is archived.
security:
- bearerAuth: []
operationId: archiveDraft
parameters:
- name: documentId
in: path
required: true
schema:
type: string
description: |
The ID of the document to archive the draft from. To retrieve the ID, navigate to **File > Document settings** in the document and then click **Settings**. The **Identifier** field contains the document ID.
requestBody:
content:
application/json:
schema:
type: object
properties:
branchId:
type: string
format: uuid
description: The UUID of the branch the draft is attached to.
responses:
'200':
description: Draft archived successfully
content:
application/json:
schema:
type: object
properties:
message:
type: string
example: "Draft deleted successfully"
'404':
description: |
Not Found
Possible error messages:
- `Document with identifier <documentId> not found`
- `Draft with id <documentId> does not exist`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
$ref: '#/components/responses/TooManyRequests'
/v1/documents/{documentId}/queries:
get:
tags:
- Documents
summary: Get document queries
description: Retrieves queries associated with a document by its identifier.
x-mint:
content: |
<Tip>
Check out the [Running document queries with APIs guide](/guides/run-document-queries) to learn how to programmatically run the queries you retrieve with this API.
</Tip>
security:
- bearerAuth: []
operationId: getDocumentQueries
parameters:
- name: documentId
in: path
required: true
schema:
type: string
description: |
The unique identifier of the document. This can be retrieved by:
- **Opening the document settings**: Navigate to **File > Document settings** and click **Settings**. The **Identifier** field contains the document ID.
- **Using the dashboard's URL**: The string after `/dashboards/` is the identifier (e.g., `https://myorg.omniapp.co/dashboards/12db1a0a`)
responses:
'200':
description: Queries retrieved successfully
content:
application/json:
schema:
type: object
properties:
queries:
type: array
description: An array of queries used in the document
items:
type: object
properties:
id:
type: string
format: uuid
description: The UUID of the query
name:
type: string
description: The name of the query
query:
type: object
description: The query JSON structure that can be used with the Query API
'403':
description: |
Forbidden
Possible error messages:
- `User cannot view document`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: |
Not Found
Possible error messages:
- `Document with id <identifier> does not exist`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
$ref: '#/components/responses/TooManyRequests'
/v1/documents/{documentId}/permissions:
post:
tags:
- Document permissions
summary: Grant document permissions
description: Grant document permissions to users or groups
security:
- bearerAuth: []
operationId: grantDocumentPermissions
parameters:
- name: documentId
in: path
required: true
schema:
type: string
description: |
The document identifier. To retrieve the ID, navigate to **File > Document settings** in the document and then click **Settings**. The **Identifier** field contains the document ID.
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- role
properties:
role:
type: string
enum: [NO_ACCESS, VIEWER, EXPLORER, EDITOR, MANAGER]
description: |
The content role to assign. Must be one of:
- `NO_ACCESS` - No access. Document won't appear in content system or search results.
- `VIEWER` - View dashboard
- `EXPLORER` - View and explore dashboard and workbook
- `EDITOR` - Edit dashboard and workbook
- `MANAGER` - Edit dashboard and workbook and manage permissions
accessBoost:
type: boolean
default: false
description: If `true`, AccessBoost will be enabled for the document.
userIds:
type: array
items:
type: string
format: uuid
description: |
The list of user IDs to assign permissions to. Use the [List users](/api/users/list-users) and [List embed users](/api/users/list-embedded-users) endpoints to retrieve user IDs. **Either `userIds` or `userGroupIds` is required.**
userGroupIds:
type: array
items:
type: string
description: |
The list of user group IDs to assign permissions to. Use the [List user groups](/api/user-groups/list-user-groups) endpoint to retrieve user group IDs. **Either `userIds` or `userGroupIds` is required.**
responses:
'200':
description: Permissions granted successfully
content:
application/json:
schema:
$ref: '#/components/schemas/SuccessResponse'
'400':
description: |
Bad Request. Possible causes:
- Missing `userIds` or `userGroupIds` parameter
- Invalid `userId` value
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
examples:
missingIds:
summary: Missing userIds or userGroupIds
value:
detail: "userIds.userGroupIds: userIds or userGroupIds must be provided"
status: 400
invalidUuid:
summary: Invalid userId value
value:
detail: "userIds.0: Invalid uuid"
status: 400
'403':
description: |
Forbidden. The user sending the API request must have **Manager** permissions for the document.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
detail: "User does not have permission to manage document permissions"
status: 403
'404':
description: Document not found
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
detail: "Document with identifier \"<documentId>\" not found"
status: 404
'429':
$ref: '#/components/responses/TooManyRequests'
patch:
tags:
- Document permissions
summary: Update document permissions
description: Update existing document permissions for users or groups
security:
- bearerAuth: []
operationId: updateDocumentPermissions
parameters:
- name: documentId
in: path
required: true
schema:
type: string
description: |
The document identifier. To retrieve the ID, navigate to **File > Document settings** in the document and then click **Settings**. The **Identifier** field contains the document ID.
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- role
properties:
role:
type: string
enum: [NO_ACCESS, VIEWER, EXPLORER, EDITOR, MANAGER]
description: |
The content role to assign. Must be one of:
- `NO_ACCESS` - No access. Document won't appear in content system or search results.
- `VIEWER` - View dashboard
- `EXPLORER` - View and explore dashboard and workbook
- `EDITOR` - Edit dashboard and workbook
- `MANAGER` - Edit dashboard and workbook and manage permissions
accessBoost:
type: boolean
default: false
description: If `true`, AccessBoost will be enabled for the document.
userIds:
type: array
items:
type: string
format: uuid
description: |
The list of user IDs to update permissions for. Use the [List users](/api/users/list-users) and [List embed users](/api/users/list-embedded-users) endpoints to retrieve user IDs. **Either `userIds` or `userGroupIds` is required.**
userGroupIds:
type: array
items:
type: string
description: |
The list of user group IDs to update permissions for. Use the [List user groups](/api/user-groups/list-user-groups) endpoint to retrieve user group IDs. **Either `userIds` or `userGroupIds` is required.**
responses:
'200':
description: Permissions updated successfully
content:
application/json:
schema:
$ref: '#/components/schemas/SuccessResponse'
'400':
description: |
Bad Request. Possible causes:
- Missing `userIds` or `userGroupIds` parameter
- Invalid `userId` value
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
examples:
missingIds:
summary: Missing userIds or userGroupIds
value:
detail: "userIds.userGroupIds: userIds or userGroupIds must be provided"
status: 400
invalidUuid:
summary: Invalid userId value
value:
detail: "userIds.0: Invalid uuid"
status: 400
'403':
description: |
Forbidden. The user sending the API request must have **Manager** permissions for the document.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
detail: "User does not have permission to manage document permissions"
status: 403
'404':
description: Document not found
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
detail: "Document with identifier \"<documentId>\" not found"
status: 404
'429':
$ref: '#/components/responses/TooManyRequests'
put:
tags:
- Document permissions
summary: Update document permission settings
description: |
Updates the permission and [interactivity settings](/share#controlling-document-interactivity) for a document. For example, the ability to allow users to schedule or download the document's content.
security:
- bearerAuth: []
operationId: updateDocumentSettings
parameters:
- name: documentId
in: path
required: true
schema:
type: string
description: |
The document identifier. To retrieve the ID, navigate to **File > Document settings** in the document and then click **Settings**. The **Identifier** field contains the document ID.
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
organizationRole:
type: string
enum: [NO_ACCESS, VIEWER, EXPLORER, EDITOR, MANAGER]
description: |
The default content role for the organization. Must be one of:
- `NO_ACCESS` - No access. Document won't appear in content system or search results.
- `VIEWER` - View dashboard
- `EXPLORER` - View and explore dashboard and workbook
- `EDITOR` - Edit dashboard and workbook
- `MANAGER` - Edit dashboard and workbook and manage permissions
canDownload:
type: boolean
description: If `true`, users with required permissions will be able to [download the document's query results](/analyze-explore/querying#downloading-results) or [dashboards](/visualize-present/dashboards/download). In the UI, this is the **Download** setting in the document's settings.
canDrill:
type: boolean
description: If `true`, users with required permissions will be able to drill into data points in the document's content. In the UI, this is the **Drill** setting in the document's settings.
canSchedule:
type: boolean
description: If `true`, users with required permissions will be able to create [deliveries (schedules and alerts)](/share/deliveries) on the document. In the UI, this is the **Schedule** setting in the document's settings.
canUpload:
type: boolean
description: |
If `true`, users with required permissions can [upload data](/analyze-explore/data-input-csvs) (ex: CSVs) into the document to create data input tables. In the UI, this is the **Upload data** setting in the document's settings.
canViewWorkbook:
type: boolean
description: If `true`, users with required permissions can view a read-only version of the workbook. In the UI, this is the **Viewers can see workbook** setting in the document's settings.
responses:
'200':
description: Settings updated successfully
content:
application/json:
schema:
$ref: '#/components/schemas/SuccessResponse'
'400':
description: |
Bad Request. Possible causes:
- Invalid parameter value
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
detail: "<parameter>: Invalid <parameter>"
status: 400
'403':
description: |
Forbidden. The user sending the API request must have **Manager** permissions for the document.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
detail: "User does not have permission to manage document permissions"
status: 403
'404':
description: Document not found
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
detail: "Document with identifier \"<documentId>\" not found"
status: 404
'429':
$ref: '#/components/responses/TooManyRequests'
get:
tags:
- Document permissions
summary: Retrieve document permissions for a user
description: Retrieves the document permissions for a specific user.
security:
- bearerAuth: []
operationId: getDocumentPermissions
parameters:
- name: documentId
in: path
required: true
schema:
type: string
description: |
The document identifier. To retrieve the ID, navigate to **File > Document settings** in the document and then click **Settings**. The **Identifier** field contains the document ID.
- name: userId
in: query
required: true
schema:
type: string
format: uuid
description: |
ID of the user to retrieve document permissions for. Use the [List users](/api/users/list-users) and [List embed users](/api/users/list-embedded-users) endpoints to retrieve user IDs.
responses:
'200':
description: Document permissions for the user
content:
application/json:
schema:
type: object
properties:
permits:
type: array
items:
type: object
properties:
description:
type: string
description: Description of the permission type. For example, `Organization`
id:
type: string
description: ID of the user
name:
type: string
description: Name of the user
type:
type: string
description: The type of the permission holder (e.g., "user")
direct:
type: object
description: Direct permissions assigned to the user
properties:
accessBoost:
type: boolean
description: If `true`, AccessBoost is enabled for the user
isOwner:
type: boolean
description: If `true`, the user is the owner of the document
role:
type: string
description: The content role assigned to the user
folder:
type: object
description: Permissions inherited from a folder
properties:
accessBoost:
type: boolean
description: If `true`, AccessBoost is enabled via folder permissions
isOwner:
type: boolean
description: If `true`, the user is the owner via folder permissions
role:
type: string
description: The content role inherited from folder permissions
example:
permits:
- description: "Organization"
direct:
accessBoost: false
isOwner: false
role: "VIEWER"
id: "df290ed4-b721-4efe-914b-95d30ce1c5f2"
name: "Organization"
type: "user"
- description: "Organization"
folder:
accessBoost: false
isOwner: false
role: "VIEWER"
id: "df290ed4-b721-4efe-914b-95d30ce1c5f2"
name: "Organization"
type: "user"
'400':
description: |
Bad Request. Possible causes:
- Missing `userId` parameter
- Invalid `userId` value
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
examples:
missingUserId:
summary: Missing userId parameter
value:
detail: "userId: userId must be provided"
status: 400
invalidUserId:
summary: Invalid userId value
value:
detail: "userId: Invalid userId"
status: 400
'403':
description: |
Forbidden. The user sending the API request must have **Manager** permissions for the document.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
detail: "User does not have permission to manage document permissions"
status: 403
'404':
description: Document not found
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
detail: "Document with identifier \"<documentId>\" not found"
status: 404
'429':
$ref: '#/components/responses/TooManyRequests'
delete:
tags:
- Document permissions
summary: Revoke document permissions
description: Revokes document permissions for users or user groups.
security:
- bearerAuth: []
operationId: revokeDocumentPermissions
parameters:
- name: documentId
in: path
required: true
schema:
type: string
description: |
The document identifier. To retrieve the ID, navigate to **File > Document settings** in the document and then click **Settings**. The **Identifier** field contains the document ID.
requestBody:
content:
application/json:
schema:
type: object
properties:
userIds:
type: array
items:
type: string
format: uuid
description: |
The list of user IDs to revoke permissions from. Use the [List users](/api/users/list-users) and [List embed users](/api/users/list-embedded-users) endpoints to retrieve user IDs. **Either `userIds` or `userGroupIds` is required.**
userGroupIds:
type: array
items:
type: string
description: |
The list of user group IDs to revoke permissions from. Use the [List user groups](/api/user-groups/list-user-groups) endpoint to retrieve user group IDs. **Either `userIds` or `userGroupIds` is required.**
responses:
'200':
description: Permissions revoked successfully
content:
application/json:
schema:
$ref: '#/components/schemas/SuccessResponse'
'400':
description: |
Bad Request. Possible causes:
- Missing `userIds` or `userGroupIds` parameter
- Invalid `userId` value
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
examples:
missingIds:
summary: Missing userIds or userGroupIds
value:
detail: "userId: userId must be provided"
status: 400
invalidUserId:
summary: Invalid userId value
value:
detail: "userId: Invalid userId"
status: 400
'403':
description: |
Forbidden. The user sending the API request must have **Manager** permissions for the document.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
detail: "User does not have permission to manage document permissions"
status: 403
'404':
description: Document not found
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
detail: "Document with identifier \"<documentId>\" not found"
status: 404
'429':
$ref: '#/components/responses/TooManyRequests'
/v1/documents/{documentId}/access-list:
get:
tags:
- Document permissions
summary: List all users and groups with document access
description: |
Returns all users and groups with access to a document in a single paginated call.
The response includes a list of `principal` objects, where each entry represents a distinct access grant with its own role and settings. A `principal` may appear twice in the response if they have both `direct` access and `folder`-based access to the same document.
security:
- bearerAuth: []
operationId: listDocumentAccessList
parameters:
- name: documentId
in: path
required: true
schema:
type: string
description: |
The document identifier. To retrieve the ID, navigate to **File > Document settings** in the document and then click **Settings**. The **Identifier** field contains the document ID.
- name: pageSize
in: query
required: false
schema:
type: integer
minimum: 1
maximum: 100
default: 20
description: Number of results per page (1-100).
- name: cursor
in: query
required: false
schema:
type: string
description: Pagination cursor from a previous response's `pageInfo.nextCursor`.
- name: sortField
in: query
required: false
schema:
type: string
enum: [name, email, role]
default: name
description: Field to sort results by.
- name: sortDirection
in: query
required: false
schema:
type: string
enum: [asc, desc]
default: asc
description: Sort order.
- name: accessSource
in: query
required: false
schema:
type: string
enum: [direct, folder]
description: |
Filter by how access was granted:
- `direct` — Only principals with explicit document permissions
- `folder` — Only principals with inherited folder permissions
- name: type
in: query
required: false
schema:
type: string
enum: [user, userGroup]
description: |
Filter by principal type:
- `user` — Only individual users
- `userGroup` — Only user groups
responses:
'200':
description: Successfully retrieved access list
content:
application/json:
schema:
type: object
properties:
principals:
type: array
items:
$ref: '#/components/schemas/DocumentAccessPrincipal'
pageInfo:
$ref: '#/components/schemas/PageInfo'
example:
principals:
- id: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
name: "Jane Smith"
email: "jane@example.com"
type: "user"
role: "EDITOR"
accessBoost: false
accessSource: "direct"
isOwner: false
- id: "b2c3d4e5-f6a7-8901-bcde-f23456789012"
name: "John Doe"
email: "john@example.com"
type: "user"
role: "VIEWER"
accessBoost: false
accessSource: "folder"
isOwner: false
folderInfo:
id: "c3d4e5f6-a7b8-9012-cdef-345678901234"
name: "Marketing Reports"
path: "/Shared/Marketing Reports"
- id: "d4e5f6a7-b8c9-0123-def0-456789012345"
name: "Data Analysts"
type: "userGroup"
role: "VIEWER"
accessBoost: false
accessSource: "direct"
pageInfo:
hasNextPage: true
nextCursor: "eyJuYW1lIjoiSm9obiIsImlkIjoiMTIzIn0="
pageSize: 20
totalRecords: 47
'400':
description: |
Bad Request. Possible causes:
- Invalid `pageSize` value (must be 1-100)
- Invalid `sortField` value
- Invalid `sortDirection` value
- Invalid `accessSource` value
- Invalid `type` value
- Invalid `cursor` value
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
examples:
invalidPageSize:
summary: Invalid pageSize value
value:
detail: "pageSize: Must be between 1 and 100"
status: 400
invalidSortField:
summary: Invalid sortField value
value:
detail: "sortField: Must be one of: name, email, role"
status: 400
'403':
description: |
Forbidden. The user sending the API request must have **Manager** permissions for the document.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
detail: "User does not have permission to manage document permissions"
status: 403
'404':
description: Document not found
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
detail: "Document with identifier \"<documentId>\" not found"
status: 404
'429':
$ref: '#/components/responses/TooManyRequests'
/v1/documents/{documentId}/labels:
patch:
tags:
- Document labels
summary: Bulk update document labels
x-mint:
content: |
Add and/or remove multiple labels from a document in a single atomic operation.
When using this endpoint, keep in mind that:
- **All changes succeed or fail together.** No partial updates occur.
- **Label matching is case-insensitive**.
- **Requests must have at least one operation.** Either `add` or `remove` must contain at least one label.
- **Labels must already exist to be added to or removed from a document.** Create labels via the [Create label API](/api/labels/create-label).
- **Labels cannot be included in both `add` and `remove` in the same request.**
- **Organization Admin permissions are required to**:
- Add or remove **Verified** labels
- Add or remove **Homepage** labels
security:
- bearerAuth: []
- orgApiKey: []
operationId: bulkUpdateDocumentLabels
parameters:
- name: documentId
in: path
required: true
schema:
type: string
format: uuid
description: The document identifier (UUID)
- name: userId
in: query
required: false
schema:
type: string
description: |
**Requires an Organization API key**. Optional user ID that attributes the action to the specified user.
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
add:
type: array
items:
type: string
minLength: 2
maxLength: 25
default: []
description: Label names to add to the document
remove:
type: array
items:
type: string
minLength: 2
maxLength: 25
default: []
description: Label names to remove from the document
examples:
addLabels:
summary: Add labels
value:
add:
- production
- reviewed
removeLabels:
summary: Remove labels
value:
remove:
- draft
- needs-review
addAndRemove:
summary: Add and remove labels
value:
add:
- approved
remove:
- pending-review
responses:
'200':
description: Labels updated successfully
content:
application/json:
schema:
type: object
properties:
labels:
type: array
items:
type: string
description: The updated list of labels on the document
example:
labels:
- label-one
- label-two
- new-label
'400':
description: |
Bad Request. Possible causes:
- Empty request - Neither `add` nor `remove` contains any labels
- Label appears in both `add` and `remove` arrays
- Invalid label name (less than 2 or more than 25 characters)
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
examples:
emptyRequest:
summary: Empty request
value:
detail: "Bad Request: At least one label must be specified in add or remove"
status: 400
title: Bad Request
conflictingLabels:
summary: Label in both arrays
value:
detail: "Bad Request: Labels cannot appear in both add and remove arrays"
status: 400
title: Bad Request
'403':
description: |
Forbidden. Possible causes:
- User does not have `canLabel` permission on the document
- User lacks Organization Admin permissions to modify Verified labels
- User lacks Organization Admin permissions to modify Homepage labels
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
examples:
permissionDenied:
summary: Permission denied
value:
detail: You do not have permission to modify labels on this document.
status: 403
title: Forbidden
verifiedLabelDenied:
summary: Verified label permission denied
value:
detail: You do not have permission to modify Verified labels on this document
status: 403
title: Forbidden
'404':
description: |
Not Found. Possible causes:
- Document does not exist
- Label does not exist globally. Create the label first with the [Create label API](/api/labels/create-label).
- Label in `remove` array does not exist on the document
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
examples:
documentNotFound:
summary: Document not found
value:
detail: Document with identifier "abc123" not found
status: 404
title: Not Found
labelNotFound:
summary: Label not found globally
value:
detail: Label "my-label" not found
status: 404
title: Not Found
labelNotOnDocument:
summary: Label not on document
value:
detail: |
Labels not found on this document: "label-one", "label-two"
status: 404
title: Not Found
'429':
$ref: '#/components/responses/TooManyRequests'
/v1/documents/{documentId}/labels/{labelName}:
put:
tags:
- Document labels
summary: Apply label to document
description: |
Apply an existing label to a document. Labels must be created first via the [Create label](/api/labels/create-label) endpoint.
Documents can have multiple labels. When a new label is applied using this endpoint, the API adds it to the document's existing labels. Labels are not replaced.
security:
- bearerAuth: []
operationId: applyLabelToDocument
parameters:
- name: documentId
in: path
required: true
schema:
type: string
description: The document identifier
- name: labelName
in: path
required: true
schema:
type: string
minLength: 2
maxLength: 25
description: |
The label name to apply:
- Must be 2-25 characters
- Labels are **case insensitive**. For example, adding `BlobSales` when `blobsales` exists will be treated as a duplicate.
- Special characters must be URL-encoded (e.g., `Q1%202024` for "Q1 2024").
Additionally, adding **Verified** or **Homepage** labels require Organization Admin permissions.
- name: userId
in: query
required: false
schema:
type: string
description: |
**Requires an Organization API key**. Optional user ID that attributes the action to the specified user.
responses:
'204':
description: |
Label applied successfully. No response body.
This response is returned whether the label was newly applied or already existed on the document.
'400':
description: |
Bad Request. Possible causes:
- Label name too short (less than 2 characters)
- Label name too long (more than 25 characters)
- Invalid HTTP method
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'403':
description: |
Forbidden. Possible causes:
- User does not have Manager role on the specified document
- User lacks Organization Admin permissions for Verified labels
- User lacks Organization Admin permissions for Homepage labels
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: |
Not Found. Possible causes:
- Document does not exist
- Label does not exist. Must be created first via the [Create label](/api/labels/create-label).
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
$ref: '#/components/responses/TooManyRequests'
delete:
tags:
- Document labels
summary: Remove label from document
x-mint:
content: |
Remove a label from a document.
<Note>
This endpoint is not idempotent. If the label does not exist on the document, the API returns a `404` error.
</Note>
security:
- bearerAuth: []
operationId: removeLabelFromDocument
parameters:
- name: documentId
in: path
required: true
schema:
type: string
description: The document identifier
- name: labelName
in: path
required: true
schema:
type: string
minLength: 2
maxLength: 25
description: |
The label name to remove:
- Must be 2-25 characters
- Labels are **case insensitive**. For example, removing `BlobSales` will remove `blobsales` if it exists on the document.
- Special characters must be URL-encoded (e.g., `Q1%202024` for "Q1 2024").
- name: userId
in: query
required: false
schema:
type: string
description: |
**Requires an Organization API key**. Optional user ID that attributes the action to the specified user.
responses:
'204':
description: Label removed successfully. No response body.
'403':
description: |
Forbidden. User does not have permission to modify labels on this document.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: |
Not Found. Possible causes:
- Document does not exist
- Label does not exist on this document
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
detail: Label "production" not found on this document
status: 404
title: Not Found
'429':
$ref: '#/components/responses/TooManyRequests'
/v1/documents/{documentId}/favorite:
put:
tags:
- Document favorites
summary: Favorite document
description: |
Add a document to a user's favorites. Only published documents can be favorited.
**Note**: Successful requests will return `204` regardless of whether the document is newly favorited or already in the user's favorites.
security:
- bearerAuth: []
operationId: favoriteDocument
parameters:
- name: documentId
in: path
required: true
schema:
type: string
description: The document identifier
- name: userId
in: query
required: false
schema:
type: string
description: |
**Requires an Organization API key**. Membership ID of the user to favorite the document on behalf of.
Personal Access Tokens (PATs) cannot use this parameter to act on behalf of other users.
responses:
'204':
description: |
Document favorited successfully. No response body.
This response is returned whether the document was newly favorited or already in favorites.
'403':
description: |
Forbidden. Possible causes:
- Personal Access Token attempted to act on behalf of another user. PATs cannot use the `userId` parameter.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: |
Not Found. Possible causes:
- Document does not exist
- Document is not published
- Specified `userId` not found
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'405':
$ref: '#/components/responses/MethodNotAllowed'
'429':
$ref: '#/components/responses/TooManyRequests'
delete:
tags:
- Document favorites
summary: Unfavorite document
description: |
Remove a document from a user's favorites. Only published documents can be unfavorited.
**Note**: Successful requests will return `204` regardless of whether the document was previously favorited or not.
security:
- bearerAuth: []
operationId: unfavoriteDocument
parameters:
- name: documentId
in: path
required: true
schema:
type: string
description: The document identifier
- name: userId
in: query
required: false
schema:
type: string
description: |
**Requires an Organization API key**. Membership ID of the user to unfavorite the document on behalf of.
Personal Access Tokens (PATs) cannot use this parameter to act on behalf of other users.
responses:
'204':
description: |
Document unfavorited successfully. No response body.
This response is returned whether the document was previously favorited or not.
'400':
description: Invalid HTTP method
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'403':
description: |
Forbidden. Possible causes:
- Personal Access Token attempted to act on behalf of another user
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: |
Not Found. Possible causes:
- Document does not exist
- Document is not published
- Specified `userId` not found
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'405':
$ref: '#/components/responses/MethodNotAllowed'
'429':
$ref: '#/components/responses/TooManyRequests'
/v1/dashboards/{dashboardId}/download:
post:
tags:
- Dashboard downloads
summary: Initiate download
x-mint:
content: |
Starts an asynchronous download job for a dashboard or single tile.
This API supports multiple output formats and provides an asynchronous workflow: initiate a download, poll for completion, then retrieve the file.
<Note>
Only one download per dashboard per user is allowed at a time. If a download is already in progress for the specified dashboard, the request will return a `409 Conflict` response with the existing job ID.
</Note>
security:
- bearerAuth: []
operationId: initiateDashboardDownload
parameters:
- name: dashboardId
in: path
required: true
schema:
type: string
description: The dashboard identifier (ID or document UUID)
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- format
properties:
format:
type: string
enum: [pdf, png, csv, xlsx, json]
description: |
Output format:
| Format | Full dashboard | Single tile | Notes |
|--------|----------------|-------------|-------|
| PDF | Yes | Yes | |
| PNG | Yes | Yes | |
| XLSX | Yes | Yes | |
| CSV | Yes (as ZIP) | Yes | For full dashboards, delivery will be a zip file containing one CSV per tile |
| JSON | No | Yes | Only single tile is supported. Requires `queryIdentifierMapKey` to be specified |
filename:
type: string
maxLength: 255
description: Custom filename for the downloaded file. Defaults to the dashboard name.
queryIdentifierMapKey:
type: string
description: Tile identifier to download a single tile instead of the full dashboard
filterConfig:
type: object
description: Dashboard filter values to apply before rendering
paperFormat:
type: string
enum: [fit_page, letter, legal, tabloid, a3, a4]
default: fit_page
description: |
**Applicable to PDF and PNG formats**. Page size.
paperOrientation:
type: string
enum: [portrait, landscape]
description: |
**Applicable to PDF and PNG formats**. Page orientation.
hideTitle:
type: boolean
default: false
description: |
**Applicable to PDF and PNG formats**. If `true`, hide the dashboard title in the output.
showFilters:
type: boolean
default: true
description: |
**Applicable to PDF and PNG formats**. If `true`, display applied filter values in the output.
expandTablesToShowAllRows:
type: boolean
description: |
**Applicable to PDF and PNG formats**. If `true`, expand table tiles to display all rows.
singleColumnLayout:
type: boolean
description: |
**Applicable to PDF and PNG formats**. If `true`, render tiles in a single column layout.
enableFormatting:
type: boolean
default: false
description: |
**Applicable to CSV, XLSX, and JSON formats**. If `true`, apply number and date formatting to values.
hideHiddenFields:
type: boolean
default: false
description: |
**Applicable to CSV, XLSX, and JSON formats**. If `true`, exclude hidden fields from the output.
overrideRowLimit:
type: boolean
default: false
description: |
**Applicable to CSV, XLSX, and JSON formats**. If `true`, remove the default row limit.
maxRowLimit:
type: integer
minimum: 1
maximum: 1000000
description: |
**Applicable to CSV, XLSX, and JSON formats**. Maximum number of rows to export.
examples:
fullDashboardPdf:
summary: Download full dashboard as PDF
value:
format: pdf
paperFormat: letter
paperOrientation: landscape
singleTileJson:
summary: Download single tile as JSON
value:
format: json
queryIdentifierMapKey: "1"
csvWithOptions:
summary: Download as CSV with formatting
value:
format: csv
enableFormatting: true
overrideRowLimit: true
maxRowLimit: 50000
responses:
'200':
description: Download initiated successfully
content:
application/json:
schema:
type: object
properties:
job_id:
type: string
format: uuid
description: The job ID to use for checking status and downloading the file
message:
type: string
description: Success message
example:
job_id: "550e8400-e29b-41d4-a716-446655440000"
message: "Download initiated successfully"
'400':
description: |
Bad Request. Possible causes:
- Missing required `format` field
- Invalid format value
- Invalid options for the specified format
- Malformed JSON body
- Invalid UUID format
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'403':
description: Insufficient permissions to download the specified dashboard
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: Dashboard not found
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'405':
$ref: '#/components/responses/MethodNotAllowed'
'409':
description: A download is already in progress for the specified dashboard
content:
application/json:
schema:
type: object
properties:
detail:
type: string
description: Error message
existing_job_id:
type: string
format: uuid
description: The ID of the existing in-progress job
status:
type: string
description: The status of the existing job
example:
detail: "A download is already in progress for this dashboard. Please wait for it to complete or check its status."
existing_job_id: "550e8400-e29b-41d4-a716-446655440000"
status: "EXECUTING"
'429':
$ref: '#/components/responses/TooManyRequests'
/v1/dashboards/{dashboardId}/download/{jobId}/status:
get:
tags:
- Dashboard downloads
summary: Check download status
x-mint:
content: |
Retrieves the current status of a dashboard download job. Poll this endpoint to determine when the file is ready.
The response will contain one of the following statuses:
| Status | Description | Next Step |
|---------------|------------------------------------------------|----------------------------------|
| `in_progress` | Job is still processing | Continue polling |
| `complete` | File is ready | Call the [Download endpoint](/api/dashboard-downloads/download-file) |
| `error` | Job failed - see `error` field for details | Review error and retry if needed |
<Tip>
We recommend the following when polling:
- Use a reasonable polling interval (2-5 seconds)
- Avoid polling more frequently than once per second
</Tip>
security:
- bearerAuth: []
operationId: getDashboardDownloadStatus
parameters:
- name: dashboardId
in: path
required: true
schema:
type: string
description: The dashboard identifier. This must match the ID of the original download request.
- name: jobId
in: path
required: true
schema:
type: string
format: uuid
description: The job ID returned from the [Initiate dashboard download endpoint](/api/dashboard-downloads/initiate-download)
responses:
'200':
description: Job status retrieved successfully
content:
application/json:
schema:
type: object
properties:
job_id:
type: string
format: uuid
description: The job ID
status:
type: string
enum: [in_progress, complete, error]
description: Current status of the download job
format:
type: string
enum: [pdf, png, csv, xlsx, json]
description: The requested output format
created_at:
type: string
format: date-time
description: When the job was created
error:
type: string
description: Error message. Only present when status is `error`.
examples:
inProgress:
summary: Job in progress
value:
job_id: "550e8400-e29b-41d4-a716-446655440000"
status: "in_progress"
format: "pdf"
created_at: "2024-01-15T10:30:00Z"
complete:
summary: Job complete
value:
job_id: "550e8400-e29b-41d4-a716-446655440000"
status: "complete"
format: "pdf"
created_at: "2024-01-15T10:30:00Z"
error:
summary: Job failed
value:
job_id: "550e8400-e29b-41d4-a716-446655440000"
status: "error"
format: "pdf"
created_at: "2024-01-15T10:30:00Z"
error: "All queries failed."
'400':
description: Invalid job ID format
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'403':
description: Insufficient permissions
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: Job not found or does not belong to the specified dashboard
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'405':
$ref: '#/components/responses/MethodNotAllowed'
'429':
$ref: '#/components/responses/TooManyRequests'
/v1/dashboards/{dashboardId}/download/{jobId}:
get:
tags:
- Dashboard downloads
summary: Download file
x-mint:
content: |
<Note>
Only call this endpoint when the [Check download status endpoint](/api/dashboard-downloads/check-download-status) returns a `complete` status.
</Note>
Retrieves the completed dashboard download file.
The response will include appropriate headers for the file type:
- `Content-Type` - MIME type based on format (e.g., `application/pdf`)
- `Content-Disposition` - Attachment with filename (e.g., `attachment; filename="Dashboard Name.pdf"`)
- `Content-Length` - File size in bytes (when available)
security:
- bearerAuth: []
operationId: downloadDashboardFile
parameters:
- name: dashboardId
in: path
required: true
schema:
type: string
description: The dashboard identifier. This must match the ID of the original download request.
- name: jobId
in: path
required: true
schema:
type: string
format: uuid
description: The job ID returned from the [Initiate dashboard download endpoint](/api/dashboard-downloads/initiate-download)
responses:
'200':
description: File download successful
content:
application/pdf:
schema:
type: string
format: binary
image/png:
schema:
type: string
format: binary
text/csv:
schema:
type: string
format: binary
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet:
schema:
type: string
format: binary
application/json:
schema:
type: object
description: Query result data
application/zip:
schema:
type: string
format: binary
description: |
**Applicable to full dashboard downloads in CSV format.** ZIP file containing CSV files.
'202':
description: Job still in progress. Poll the [Check download status endpoint](/api/dashboard-downloads/check-download-status) first.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'400':
description: Invalid job ID format
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'403':
description: Insufficient permissions
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: Job not found or does not belong to the specified dashboard
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'405':
$ref: '#/components/responses/MethodNotAllowed'
'410':
description: Job failed. Call the [Check download status endpoint](/api/dashboard-downloads/check-download-status) for error details.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
$ref: '#/components/responses/TooManyRequests'
/v1/dashboards/{dashboardId}/filters:
get:
tags:
- Dashboard filters
summary: Get dashboard filters and controls
description: |
Returns the filter and control configuration for a dashboard, including IDs, types, current default values, and metadata.
security:
- bearerAuth: []
operationId: getDashboardFilters
parameters:
- name: dashboardId
in: path
required: true
schema:
type: string
description: The dashboard identifier
- name: userId
in: query
required: false
schema:
type: string
description: |
**Requires an Organization API key**. Optional user ID that attributes the action to the specified user.
Personal Access Tokens (PATs) cannot use this parameter.
responses:
'200':
description: Dashboard filter and control configuration
content:
application/json:
schema:
$ref: '#/components/schemas/DashboardFiltersResponse'
example:
identifier: "abc123"
filters:
order_status:
type: "string"
kind: "EQUALS"
values: ["completed", "pending"]
label: "Order Status"
description: "Filter by order status"
required: false
hidden: false
order_date:
type: "date"
kind: "WITHIN_RANGE"
left_side: "2024-01-01"
right_side: "2024-12-31"
label: "Order Date"
controls:
- id: "field_selector"
type: "FIELD_SELECTION"
kind: "FIELD"
label: "Metric Selector"
field: "orders.revenue"
options:
- label: "Revenue"
value: "orders.revenue"
- label: "Quantity"
value: "orders.quantity"
filterOrder: ["order_status", "order_date", "field_selector"]
'401':
description: Missing or invalid authentication
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'403':
description: Insufficient permissions to view the specified dashboard
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: Dashboard not found
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
$ref: '#/components/responses/TooManyRequests'
patch:
tags:
- Dashboard filters
summary: Update dashboard filters/controls
x-mint:
content: |
Updates filter and/or control values on a dashboard. Allows setting or resetting values for specific filters/controls by ID.
<Note>
Updates to published dashboards go through a [draft/publish workflow](/content/develop). If a draft already exists for the dashboard, you must set `clearExistingDraft: true` to discard it and proceed with the update.
</Note>
security:
- bearerAuth: []
operationId: updateDashboardFilters
parameters:
- name: dashboardId
in: path
required: true
schema:
type: string
description: The dashboard identifier
- name: userId
in: query
required: false
schema:
type: string
description: |
**Requires an Organization API key**. Membership ID to act on behalf of.
Personal Access Tokens (PATs) cannot use this parameter.
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/DashboardFiltersUpdateRequest'
examples:
updateFilterValues:
summary: Update filter values
value:
filters:
order_status:
values: ["shipped", "delivered"]
updateWithClearDraft:
summary: Update with existing draft (clear draft)
value:
clearExistingDraft: true
filters:
order_status:
values: ["shipped"]
updateControlLabel:
summary: Update control label
value:
controls:
field_selector:
label: "Choose Metric"
updateDisplayOrder:
summary: Update display order
value:
filterOrder: ["order_date", "field_selector", "order_status"]
responses:
'200':
description: Updated filter and control configuration
content:
application/json:
schema:
$ref: '#/components/schemas/DashboardFiltersResponse'
'400':
description: |
Bad Request. Possible error messages:
- `Invalid filter IDs: <ids>. Available filter IDs: <ids>`
- `Invalid control IDs: <ids>. Available control IDs: <ids>`
- `Invalid IDs in filterOrder: <ids>. Available IDs: <ids>`
- `Invalid filter update for <id>: <validation error>`
- `Invalid control update for <id>: <validation error>`
- `Request must include at least one filter, control, or filterOrder to update`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'401':
description: Missing or invalid authentication
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'403':
description: Insufficient permissions to edit the specified dashboard
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: Dashboard not found
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'405':
$ref: '#/components/responses/MethodNotAllowed'
'409':
description: A draft already exists for this document. Set `clearExistingDraft` to `true` to discard and proceed.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
$ref: '#/components/responses/TooManyRequests'
/v1/folders:
post:
tags:
- Folders
summary: Create folder
description: |
Create a new folder. Folders can be nested up to 7 levels.
Folder paths are automatically generated based on hierarchy. Child folder paths include the paths of their parents.
security:
- bearerAuth: []
operationId: createFolder
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- name
properties:
name:
type: string
description: Name of the folder.
parentFolderId:
type: string
format: uuid
description: |
ID of the parent folder. Use the [List folders](/api/folders/list-folders) endpoint to retrieve folder IDs.
Maximum nesting depth is 7 levels. A `400` error is returned when the limit is reached.
scope:
type: string
enum: [organization, restricted]
default: organization
description: |
Scope of the folder.
- If no scope is provided and no parent folder exists, defaults to `organization`
- If no scope is provided but a parent folder exists, inherits the parent folder's scope
- Child folder scope must match the parent folder's scope
userId:
type: string
format: uuid
description: ID of the folder owner. Use the [List users](/api/users/list-users) or [List embed users](/api/users/list-embedded-users) endpoints to retrieve user IDs.
responses:
'201':
description: Folder created successfully
content:
application/json:
schema:
$ref: '#/components/schemas/Folder'
'400':
description: |
Bad Request
Possible error messages:
- `Bad Request: Invalid JSON`
- `Bad Request: name: Required`
- `Bad Request: Maximum folder nesting depth reached`
- `Bad Request: Child folder scope must match parent folder scope`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: |
Not Found
Possible error messages:
- `Parent folder with id <parentFolderId> does not exist`
- `User with id <userId> does not exist`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
$ref: '#/components/responses/TooManyRequests'
get:
tags:
- Folders
summary: List folders
description: Retrieve a paginated list of folders within an organization. Supports filtering, sorting, and cursor-based pagination.
security:
- bearerAuth: []
operationId: listFolders
parameters:
- name: include
in: query
schema:
type: string
description: |
Comma-separated list of additional fields to include:
- `_count` - Include document and favorite counts
- `labels` - Include folder labels
- name: path
in: query
schema:
type: string
description: |
Filter folders by path. Wildcards are supported and must appear at the end of the path:
- `*` - Include direct children only (e.g., `blob-sales/*`)
- `**` - Include all descendants recursively (e.g., `blob-sales/**`)
- name: labels
in: query
schema:
type: array
items:
type: string
description: Comma-separated list of labels to filter by.
- name: scope
in: query
schema:
type: string
enum: [organization, restricted]
default: organization
description: |
Scope of folders to retrieve.
When set to `restricted`, the `ownerId` parameter is required.
- name: sortField
in: query
schema:
type: string
enum: [favorites, name, path]
default: name
description: |
Field to sort by:
- `favorites` - Sort by number of favorites
- `name` - Sort by folder name
- `path` - Sort by folder path
- name: sortDirection
in: query
schema:
type: string
enum: [asc, desc]
default: desc
description: Sort direction.
- name: cursor
in: query
schema:
type: string
description: Cursor for pagination positioning.
- name: pageSize
in: query
schema:
type: integer
minimum: 1
default: 20
description: Number of items per page.
- name: ownerId
in: query
schema:
type: string
format: uuid
description: |
UUID of organization membership.
**Required when `scope` is `restricted`**.
responses:
'200':
description: Paginated folder list
content:
application/json:
schema:
type: object
properties:
records:
type: array
description: Array of folder objects matching the query.
items:
$ref: '#/components/schemas/Folder'
pageInfo:
$ref: '#/components/schemas/PageInfo'
example:
records:
- id: "21db26b3-466c-4791-90e7-b9ce9375426d"
name: "Blob Sales"
path: "/blob-sales"
scope: "organization"
owner:
id: "f4df8d6e-7f69-4d54-b23b-7abfe5c4da74"
name: "Blob Ross"
labels:
- "important"
- "archived"
_count:
documents: 15
favorites: 3
pageInfo:
hasNextPage: true
nextCursor: "eyJpZCI6ImZvbGRlcjEyMyJ9"
pageSize: 20
totalRecords: 45
'400':
description: |
Bad Request
Possible error messages:
- `Bad Request: pageSize: Page size must be at least 1`
- `Bad Request: ownerId: ownerId is required when scope is 'restricted'`
- `Bad Request: sortField: Invalid enum value. Expected 'name' | 'path', received '<invalidField>'`
- `Bad Request: include: Invalid value. Expected: _count, labels, received '<invalidValue>'`
- `Bad Request: Invalid path pattern. Only a single wildcard (*) is allowed at the end of the pattern`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: |
Not Found
Possible error messages:
- `Folder with path <path> does not exist`
- `User membership not found`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
$ref: '#/components/responses/TooManyRequests'
/v1/folders/{folderId}:
delete:
tags:
- Folders
summary: Delete folder
description: Delete an empty folder. This operation only succeeds if the folder has no documents or subfolders.
security:
- bearerAuth: []
operationId: deleteFolder
parameters:
- name: folderId
in: path
required: true
schema:
type: string
format: uuid
description: The UUID of the folder to delete. Use the [List folders](/api/folders/list-folders) endpoint to retrieve folder IDs.
responses:
'200':
description: Folder deleted successfully
content:
application/json:
schema:
$ref: '#/components/schemas/SuccessResponse'
'400':
description: |
Bad Request
Possible error messages:
- `Folders with documents cannot be deleted`
- `Only empty folders can be deleted`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: |
Not Found
Possible error messages:
- `Folder with id <folderId> does not exist`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
$ref: '#/components/responses/TooManyRequests'
/v1/folders/{folderId}/permissions:
post:
tags:
- Folder permissions
summary: Grant folder permissions
description: Grant folder permissions to users or groups
security:
- bearerAuth: []
operationId: grantFolderPermissions
parameters:
- name: folderId
in: path
required: true
schema:
type: string
format: uuid
description: The UUID of the folder. Use the [List folders](/api/folders/list-folders) endpoint to retrieve folder IDs.
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- role
properties:
role:
type: string
enum: [NO_ACCESS, VIEWER, EXPLORER, EDITOR, MANAGER]
description: The content role to assign to the specified users or user groups.
accessBoost:
type: boolean
default: false
description: If `true`, [AccessBoost](/share#boosting-permissions-with-accessboost) is enabled for the folder.
userIds:
type: array
items:
type: string
format: uuid
description: |
The list of user IDs to grant permissions to. Use the [List users](/api/users/list-users) or [List embed users](/api/users/list-embedded-users) endpoints to retrieve user IDs.
Either `userIds` or `userGroupIds` is required.
userGroupIds:
type: array
items:
type: string
description: |
The list of user group IDs to grant permissions to. Use the [List user groups](/api/user-groups/list-user-groups) endpoint to retrieve user group IDs.
Either `userIds` or `userGroupIds` is required.
responses:
'200':
description: Permissions granted successfully
content:
application/json:
schema:
$ref: '#/components/schemas/SuccessResponse'
'400':
description: |
Bad Request
Possible error messages:
- `userIds.userGroupIds: userIds or userGroupIds must be provided`
- `userIds.0: Invalid uuid`
- `userGroupIds.0: Invalid uuid`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'403':
description: |
Forbidden
Possible error messages:
- `User does not have permission to manage folder permissions` - The user sending the API request must have **Manager** permissions for the folder.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: |
Not Found
Possible error messages:
- `Folder with identifier "<folderId>" not found`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
$ref: '#/components/responses/TooManyRequests'
patch:
tags:
- Folder permissions
summary: Update folder permissions
description: Update existing folder permissions for users or groups
security:
- bearerAuth: []
operationId: updateFolderPermissions
parameters:
- name: folderId
in: path
required: true
schema:
type: string
format: uuid
description: The UUID of the folder. Use the [List folders](/api/folders/list-folders) endpoint to retrieve folder IDs.
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- role
properties:
role:
type: string
enum: [NO_ACCESS, VIEWER, EXPLORER, EDITOR, MANAGER]
description: The content role to assign to the specified users or user groups.
accessBoost:
type: boolean
default: false
description: If `true`, [AccessBoost](/share#boosting-permissions-with-accessboost) is enabled for the folder.
userIds:
type: array
items:
type: string
format: uuid
description: |
The list of user IDs to update permissions for. Use the [List users](/api/users/list-users) or [List embed users](/api/users/list-embedded-users) endpoints to retrieve user IDs.
Either `userIds` or `userGroupIds` is required.
userGroupIds:
type: array
items:
type: string
description: |
The list of user group IDs to update permissions for. Use the [List user groups](/api/user-groups/list-user-groups) endpoint to retrieve user group IDs.
Either `userIds` or `userGroupIds` is required.
responses:
'200':
description: Permissions updated successfully
content:
application/json:
schema:
$ref: '#/components/schemas/SuccessResponse'
'400':
description: |
Bad Request
Possible error messages:
- `userIds.userGroupIds: userIds or userGroupIds must be provided`
- `userIds.0: Invalid uuid`
- `userGroupIds.0: Invalid uuid`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'403':
description: |
Forbidden
Possible error messages:
- `User does not have permission to manage folder permissions` - The user sending the API request must have **Manager** permissions for the folder.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: |
Not Found
Possible error messages:
- `Folder with identifier "<folderId>" not found`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
$ref: '#/components/responses/TooManyRequests'
get:
tags:
- Folder permissions
summary: Get folder permissions
description: Retrieve folder permissions for a user
security:
- bearerAuth: []
operationId: getFolderPermissions
parameters:
- name: folderId
in: path
required: true
schema:
type: string
format: uuid
description: The UUID of the folder. Use the [List folders](/api/folders/list-folders) endpoint to retrieve folder IDs.
- name: userId
in: query
required: true
schema:
type: string
format: uuid
description: The ID of the user to retrieve folder permissions for. Use the [List users](/api/users/list-users) or [List embed users](/api/users/list-embedded-users) endpoints to retrieve user IDs.
responses:
'200':
description: Folder permissions object
content:
application/json:
schema:
type: object
properties:
permits:
type: array
items:
$ref: '#/components/schemas/FolderPermission'
'400':
description: |
Bad Request
Possible error messages:
- `userId: userId must be provided`
- `userId: Invalid userId`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'403':
description: |
Forbidden
Possible error messages:
- `User does not have permission to manage folder permissions` - The user sending the API request must have **Manager** permissions for the folder.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: |
Not Found
Possible error messages:
- `Folder with identifier "<folderId>" not found`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
$ref: '#/components/responses/TooManyRequests'
delete:
tags:
- Folder permissions
summary: Revoke folder permissions
description: Revoke folder permissions from users or groups
security:
- bearerAuth: []
operationId: revokeFolderPermissions
parameters:
- name: folderId
in: path
required: true
schema:
type: string
format: uuid
description: The UUID of the folder. Use the [List folders](/api/folders/list-folders) endpoint to retrieve folder IDs.
requestBody:
content:
application/json:
schema:
type: object
properties:
userIds:
type: array
items:
type: string
format: uuid
description: |
The list of user IDs to revoke permissions from. Use the [List users](/api/users/list-users) or [List embed users](/api/users/list-embedded-users) endpoints to retrieve user IDs.
Either `userIds` or `userGroupIds` is required.
userGroupIds:
type: array
items:
type: string
description: |
The list of user group IDs to revoke permissions from. Use the [List user groups](/api/user-groups/list-user-groups) endpoint to retrieve user group IDs.
Either `userIds` or `userGroupIds` is required.
responses:
'200':
description: Permissions revoked successfully
content:
application/json:
schema:
$ref: '#/components/schemas/SuccessResponse'
'400':
description: |
Bad Request
Possible error messages:
- `userIds.userGroupIds: userIds or userGroupIds must be provided`
- `userIds.0: Invalid uuid`
- `userGroupIds.0: Invalid uuid`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'403':
description: |
Forbidden
Possible error messages:
- `User does not have permission to manage folder permissions` - The user sending the API request must have **Manager** permissions for the folder.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: |
Not Found
Possible error messages:
- `Folder with identifier "<folderId>" not found`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
$ref: '#/components/responses/TooManyRequests'
/v1/jobs/{jobId}/status:
get:
tags:
- Jobs
summary: Get job status
description: |
<Note>
Currently, this endpoint only supports schema refresh jobs. Job IDs from other job types will return an error.
</Note>
Retrieves the current status of an asynchronous job. The user authenticating the request must have **read** permissions on the connection.
This endpoint is used to check the status of jobs initiated by other API calls, such as schema refreshes. Poll this endpoint to determine when the job has completed.
x-mint:
content: |
The response will contain one of the following statuses:
| Status | Description |
|-------------|-------------------------|
| `RUNNING` | Job is currently executing |
| `COMPLETED` | Job finished successfully |
| `FAILED` | Job failed |
<Tip>
We recommend the following when polling:
- Use a reasonable polling interval (2-5 seconds)
- Avoid polling more frequently than once per second
</Tip>
security:
- bearerAuth: []
operationId: getJobStatus
parameters:
- name: jobId
in: path
required: true
schema:
type: string
format: uuid
description: The job ID returned from an asynchronous operation such as [Refresh schema](/api/models/refresh-schema)
responses:
'200':
description: Job status retrieved successfully
content:
application/json:
schema:
type: object
properties:
job_type:
type: string
description: The type of job
example: "refresh_schema"
job_id:
type: string
format: uuid
description: The unique identifier of the job
status:
type: string
enum: [RUNNING, COMPLETED, FAILED]
description: Current status of the job
examples:
running:
summary: Job running
value:
job_type: "refresh_schema"
job_id: "4e6953a9-a71b-4c0b-8b63-a9ea308f6aaf"
status: "RUNNING"
completed:
summary: Job completed
value:
job_type: "refresh_schema"
job_id: "4e6953a9-a71b-4c0b-8b63-a9ea308f6aaf"
status: "COMPLETED"
failed:
summary: Job failed
value:
job_type: "refresh_schema"
job_id: "4e6953a9-a71b-4c0b-8b63-a9ea308f6aaf"
status: "FAILED"
'400':
description: |
Bad Request
Possible error messages:
- `Bad Request: jobId: Invalid uuid`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'401':
description: Unauthorized - Invalid or missing API key
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'403':
description: |
Forbidden
Possible error messages:
- `Job type not supported for status checks`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: Job not found
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
$ref: '#/components/responses/TooManyRequests'
/v1/labels:
post:
tags:
- Labels
summary: Create label
description: |
Create a new label in the organization.
Any user can create basic labels, but **Organization Admin** permissions are required to:
- Create **Verified** labels (`verified: true`)
- Create **Homepage** labels (`homepage: true`)
security:
- bearerAuth: []
operationId: createLabel
parameters:
- name: userId
in: query
required: false
schema:
type: string
description: |
**Requires an Organization API key**. Optional user ID that attributes the action to the specified user.
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- name
properties:
name:
type: string
minLength: 2
maxLength: 25
description: |
Label name. Must be 2-25 characters.
Names are case-insensitive: `"Production"` and `"production"` are considered the same.
verified:
type: boolean
default: false
description: |
**Requires Organization Admin permissions**. If `true`, documents with this label will be marked as verified/curated.
homepage:
type: boolean
default: false
description: |
**Requires Organization Admin permissions**. If `true`, documents with this label will display on the instance's Homepage.
example:
name: "Production"
responses:
'201':
description: Label created successfully
content:
application/json:
schema:
$ref: '#/components/schemas/Label'
example:
name: "Production"
verified: true
homepage: true
usage_count: 0
'400':
description: |
Bad Request. Possible causes:
- Label name too short (less than 2 characters)
- Label name too long (more than 25 characters)
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'403':
description: |
Forbidden. Possible causes:
- User lacks **Organization Admin** permissions, which are required to create Verified and Homepage labels
- User lacks the permissions required to manage labels
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'409':
description: |
Conflict. A label with this name already exists (case-insensitive).
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
$ref: '#/components/responses/TooManyRequests'
get:
tags:
- Labels
summary: List labels
description: Retrieve all labels in the organization.
security:
- bearerAuth: []
operationId: listLabels
responses:
'200':
description: List of all labels in the organization
content:
application/json:
schema:
type: object
properties:
labels:
type: array
items:
$ref: '#/components/schemas/Label'
example:
labels:
- name: "Production"
verified: true
homepage: true
usage_count: 12
- name: "In Review"
verified: true
homepage: false
usage_count: 5
- name: "Draft"
verified: false
homepage: false
usage_count: 3
'429':
$ref: '#/components/responses/TooManyRequests'
/v1/labels/{labelName}:
get:
tags:
- Labels
summary: Get label
description: Retrieve a single label by name.
security:
- bearerAuth: []
operationId: getLabel
parameters:
- name: labelName
in: path
required: true
schema:
type: string
description: |
The label name. Lookup is case-insensitive.
URL-encode special characters (e.g., `In%20Review` for "In Review").
responses:
'200':
description: Label details
content:
application/json:
schema:
$ref: '#/components/schemas/Label'
example:
name: "Production"
verified: true
homepage: true
usage_count: 12
'404':
description: Label not found
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
$ref: '#/components/responses/TooManyRequests'
put:
tags:
- Labels
summary: Update label
description: |
Update an existing label, including renaming, changing **Verified** status, or adding/removing it from the **Homepage**.
Users can update basic labels they created. **Organization Admin** permissions are required to modify **Verified** or **Homepage** labels, including making a label `verified` or visible on the `homepage`.
security:
- bearerAuth: []
operationId: updateLabel
parameters:
- name: name
in: path
required: true
schema:
type: string
description: |
The name of the label to update. Lookup is case-insensitive.
URL-encode special characters.
- name: userId
in: query
required: false
schema:
type: string
description: |
**Requires an Organization API key**. Optional user ID that attributes the action to the specified user.
requestBody:
description: |
Only include the fields you want to update when submitting requests.
required: true
content:
application/json:
schema:
type: object
properties:
name:
type: string
minLength: 2
maxLength: 25
description: The new name of the label.
verified:
type: boolean
description: |
**Organization Admin permissions required**. If `true`, documents with the label will be marked as **Verified**.
homepage:
type: boolean
description: |
**Organization Admin permissions required**. If `true`, documents with the label will be visible on the **Homepage**.
example:
name: "Ready for Review"
responses:
'200':
description: Label updated successfully
content:
application/json:
schema:
$ref: '#/components/schemas/Label'
example:
name: "Ready for Review"
verified: true
homepage: false
usage_count: 3
'400':
description: |
Bad Request. Possible causes:
- Name too short or too long
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'403':
description: |
Forbidden. Possible causes:
- User lacks permission to manage labels
- User lacks **Organization Admin** permissions, which are required to modify **Verified** labels
- User lacks **Organization Admin** permissions, which are required to modify **Homepage** labels
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: Label not found
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'409':
description: |
Conflict. The new label name already exists (case-insensitive).
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
$ref: '#/components/responses/TooManyRequests'
x-codeSamples:
- lang: bash
label: Rename label
source: |
curl -X PUT "https://{instance}.omniapp.co/api/v1/labels/Draft" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "Ready for Review"}'
- lang: bash
label: Set verified (admin)
source: |
curl -X PUT "https://{instance}.omniapp.co/api/v1/labels/Production" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"verified": true, "homepage": true}'
delete:
tags:
- Labels
summary: Delete label
x-mint:
content: |
<Warning>
Labels that are currently applied to documents cannot be deleted. You must first remove the label from all documents.
</Warning>
description: |
Delete a label from the organization.
Any user can delete basic labels, but **Organization Admin** permissions are required to delete **Verified** and **Homepage** labels.
security:
- bearerAuth: []
operationId: deleteLabel
parameters:
- name: name
in: path
required: true
schema:
type: string
description: |
The name of the label to delete. Lookup is case-insensitive.
URL-encode special characters.
- name: userId
in: query
required: false
schema:
type: string
description: |
**Requires an Organization API key**. Optional user ID that attributes the action to the specified user.
responses:
'204':
description: Label deleted successfully. No response body.
'403':
description: |
Forbidden. Possible causes:
- User lacks permission to manage labels
- User lacks **Organization Admin** permissions, which are required to delete **Verified** labels
- User lacks **Organization Admin** permissions, which are required to delete **Homepage** labels
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: Label not found
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'409':
description: |
Conflict. The label is currently applied to documents and cannot be deleted.
Remove the label from all documents first.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
$ref: '#/components/responses/TooManyRequests'
/v1/models:
post:
tags:
- Models
summary: Create model
description: |
Create a new model. The typical workflow for using this endpoint is:
1. Create a schema model using this endpoint
2. Use the [Refresh schema](/api/models/refresh-schema) endpoint to load the schema for the created model
3. Create shared models based on the schema model
security:
- bearerAuth: []
operationId: createModel
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- connectionId
properties:
connectionId:
type: string
format: uuid
description: ID of the connection the model is based on.
modelKind:
type: string
enum: [SCHEMA, SHARED, SHARED_EXTENSION, BRANCH]
default: SCHEMA
description: |
Type of model.
- `SCHEMA` - Mirrors the database structure
- `SHARED` - Represents the universal, governed data model that workbooks are based on
- `SHARED_EXTENSION` - Represents an extension to the `SHARED` model. Can be used to dynamically extend the `SHARED` model based on user attributes, or as a model that workbooks are based on in a departmental use case.
- `BRANCH` - A model layer that is used to develop modifications to the production shared model
For more information, see the [Modeling documentation](/modeling).
modelName:
type: string
description: Name of the model.
accessGrants:
type: array
default: []
description: List of [access grants](/modeling/develop/data-access-control) for the model.
items:
type: object
properties:
name:
type: string
description: Name of the access grant.
accessBoostable:
type: boolean
description: If `true`, the access grant can be boosted.
allowAsWorkbookBase:
type: boolean
default: false
description: |
**Only applicable to `SHARED_EXTENSION` models**. If `true`, allows the model to be selected as a base model when creating workbooks.
responses:
'200':
description: Model created successfully
content:
application/json:
schema:
$ref: '#/components/schemas/Model'
'400':
description: |
Bad Request
Possible error messages:
- `Bad Request: Invalid parameter value`
- `Bad Request: Schema model already exists for the connection`
- `Bad Request: Schema model does not exist when creating a non-schema model`
- `Bad Request: Shared model cannot be created when branch schema refresh is enabled`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'403':
description: |
Forbidden
Possible error messages:
- `Forbidden`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
$ref: '#/components/responses/TooManyRequests'
get:
tags:
- Models
summary: List models
description: Retrieves a paginated list of models with their metadata.
security:
- bearerAuth: []
operationId: listModels
parameters:
- name: baseModelId
in: query
required: false
schema:
type: string
description: |
Filter models by base model ID.
- name: connectionId
in: query
required: false
schema:
type: string
description: |
Filter models by connection ID.
- name: includeDeleted
in: query
required: false
schema:
type: boolean
description: |
If `true`, include deleted models.
- name: modelId
in: query
required: false
schema:
type: string
description: |
Filter models by a specific model ID.
- name: modelKind
in: query
required: false
schema:
type: string
enum: [SCHEMA, SHARED, SHARED_EXTENSION, WORKBOOK, BRANCH, QUERY, TOPIC, FIELD_PICKER_TOPIC]
description: |
Filter by model kind.
- name: name
in: query
required: false
schema:
type: string
description: |
Filter models by name.
- name: pageSize
in: query
schema:
type: integer
default: 20
description: Specifies the number of records per page.
- name: cursor
in: query
schema:
type: string
description: Pagination cursor
- name: sortDirection
in: query
required: false
schema:
type: string
default: desc
enum: [asc, desc]
description: |
Sort direction.
- name: sortField
in: query
required: false
schema:
type: string
default: updatedAt
enum: [name, modelKind, connectionId, baseModelId, createdAt, updatedAt]
description: |
Field to sort by.
- name: include
in: query
schema:
type: string
enum: [activeBranches]
description: |
Comma-separated list of additional fields to include in the response.
- `activeBranches` - Include active branches for each model
responses:
'200':
description: Paginated model list
content:
application/json:
schema:
type: object
properties:
pageInfo:
$ref: '#/components/schemas/PageInfo'
records:
type: array
description: List of model records.
items:
allOf:
- $ref: '#/components/schemas/Model'
- type: object
properties:
branches:
type: array
description: List of branch models. Only included when `include=activeBranches`.
items:
$ref: '#/components/schemas/Model'
'400':
$ref: '#/components/responses/BadRequest'
'403':
$ref: '#/components/responses/Forbidden'
'429':
$ref: '#/components/responses/TooManyRequests'
/v1/models/{modelId}/branch/{branchName}:
delete:
tags:
- Models
summary: Delete branch
description: Deletes a branch associated with the specified shared model.
security:
- bearerAuth: []
operationId: deleteModelBranch
parameters:
- name: modelId
in: path
required: true
schema:
type: string
format: uuid
description: ID of the shared model.
- name: branchName
in: path
required: true
schema:
type: string
description: Name of the branch to delete.
responses:
'200':
description: Branch deleted successfully
content:
application/json:
schema:
$ref: '#/components/schemas/SuccessResponse'
'400':
description: |
Bad Request
Possible error messages:
- `Bad Request: Invalid modelId format`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'403':
$ref: '#/components/responses/Forbidden'
'404':
description: |
Not Found
Possible error messages:
- `Shared model or branch model does not exist`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'405':
$ref: '#/components/responses/MethodNotAllowed'
'429':
$ref: '#/components/responses/TooManyRequests'
/v1/models/{modelId}/refresh:
post:
tags:
- Models
summary: Refresh schema
description: |
Refreshes the schema of the specified model. This will cause the model to reflect the latest changes to schemas, views, and fields from the data source.
<Note>
This will remove structures that are no longer present in the source, but not anything created by users.
</Note>
security:
- bearerAuth: []
operationId: refreshSchema
parameters:
- name: modelId
in: path
required: true
schema:
type: string
format: uuid
description: The ID of the model to be refreshed.
responses:
'200':
description: Model refresh started
content:
application/json:
schema:
type: object
properties:
modelId:
type: string
format: uuid
description: ID of the model.
status:
type: string
example: "running"
description: Status of the schema refresh. This value will be `running` to indicate that the refresh has started.
'400':
description: |
Bad Request
Possible error messages:
- `Bad Request: modelId: Invalid uuid`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'403':
$ref: '#/components/responses/Forbidden'
'429':
$ref: '#/components/responses/TooManyRequests'
/v1/models/{modelId}/cache_reset/{cachePolicyName}:
post:
tags:
- Models
summary: Reset cache
description: |
Resets the cache for the specified cache policy.
<Note>
`cachePolicyName` values are not validated against existing policies. Verify that the values you provide are exact matches to policies in the model.
</Note>
security:
- bearerAuth: []
operationId: resetModelCache
parameters:
- name: modelId
in: path
required: true
schema:
type: string
format: uuid
description: The ID of the model associated with the cache policy.
- name: cachePolicyName
in: path
required: true
schema:
type: string
description: The name of the cache policy to reset.
requestBody:
content:
application/json:
schema:
type: object
properties:
resetAt:
type: string
format: date-time
description: |
An ISO-8601 date string that sets the time the cache should be reset (invalidated). When set, cache entries created between this value and the current time will still be considered valid. Cannot be a future date. Defaults to now.
responses:
'200':
description: Cache reset successfully
content:
application/json:
schema:
type: object
properties:
cache_reset:
type: object
description: The cache reset details.
properties:
id:
type: string
format: uuid
description: ID of the cache reset record.
model_id:
type: string
format: uuid
description: ID of the model.
policy_name:
type: string
description: Name of the cache policy.
created_at:
type: string
format: date-time
description: Timestamp when the cache reset record was created.
updated_at:
type: string
format: date-time
description: Timestamp when the cache reset record was last updated.
reset_at:
type: string
format: date-time
description: Timestamp when the cache was reset.
success:
type: boolean
description: Indicates the request was successful.
'400':
description: |
Bad Request
Possible error messages:
- `Model with id <modelId> does not exist`
- `resetAt cannot be future dated`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: |
Not Found
Possible error messages:
- `Model with id <modelId> does not exist`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
$ref: '#/components/responses/TooManyRequests'
/unstable/models/{modelId}/yaml:
post:
tags:
- Models
summary: Create or update YAML files
description: |
Creates or overwrites a YAML file for a model. The file can be a special file (`model` or `relationships`) or a YAML file ending in `.topic` or `.view`.
The following models cannot be edited using this endpoint:
- Schema models
- Models using git follower mode
x-mint:
content: |
<Warning>
This API is in beta and may have future breaking changes.
</Warning>
security:
- bearerAuth: []
operationId: updateModelYaml
parameters:
- name: modelId
in: path
required: true
schema:
type: string
format: uuid
description: The ID of the model.
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- fileName
- yaml
- mode
properties:
branchId:
type: string
format: uuid
description: |
**Required if git pull requests are required for the model.** The ID of the branch to create or update.
fileName:
type: string
description: |
The name of the YAML file. Valid values are:
- `model` - [Model file](/modeling/models)
- `relationships` - [Relationships file](/modeling/relationships)
- `<topic_name>.topic` - [Topic file](/modeling/topics/parameters)
- `<view_name>.view` - [View file](/modeling/views)
yaml:
type: string
description: |
The YAML contents of the file. This can be empty, in which case:
- If empty and used with `mode: extension` the file will be removed from the model
- If empty and used with `mode: combined`, the file will be ignored in the model
mode:
type: string
default: combined
enum: [combined, extension, staged]
description: |
The mode to use when creating or overwriting the YAML file.
**Note**: Workbook models must use `combined` mode if there is a `branchId`.
commitMessage:
type: string
description: |
**Required for [git-enabled models](/integrations/git).** Commit message describing the change.
previousChecksum:
type: string
description: |
Checksum of the file when fetched, for conflict detection. Obtain this value from the [Get model YAML endpoint](/api/models/get-model-yaml) by including the `includeChecksums` parameter.
If the file has been modified since you fetched it, the request will fail with a `File has been modified since it was fetched` error.
responses:
'200':
description: YAML file updated successfully
content:
application/json:
schema:
type: object
properties:
fileName:
type: string
description: The name of the file that was created or updated.
success:
type: boolean
description: Indicates the request was successful.
'400':
description: |
Bad Request
Possible error messages:
- `<parameter>: <parameter> is required`
- `modelId: Invalid uuid`
- `branchId: Invalid uuid`
- `<parameter>: Invalid value <description>`
- `File has been modified since it was fetched`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'403':
description: |
Forbidden
Possible error messages:
- `Permission denied`
- `Feature not enabled`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: |
Not Found
Possible error messages:
- `Model with id <modelId> does not exist`
- `Branch does not exist`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'405':
$ref: '#/components/responses/MethodNotAllowed'
'429':
$ref: '#/components/responses/TooManyRequests'
get:
tags:
- Models
summary: Get model YAML
description: Retrieves the YAML representation of a model with optional filtering and mode selection.
x-mint:
content: |
<Warning>
This API is in beta and may have future breaking changes.
</Warning>
security:
- bearerAuth: []
operationId: getModelYaml
parameters:
- name: modelId
in: path
required: true
schema:
type: string
format: uuid
description: The unique identifier of the model.
- name: branchId
in: query
schema:
type: string
format: uuid
description: The ID of the branch to retrieve YAML from. Only valid for shared models in `combined` mode.
- name: fileName
in: query
schema:
type: string
description: Filter YAML files by name. Can be a string or a regex pattern.
- name: mode
in: query
schema:
type: string
default: combined
enum: [extension, staged, combined]
description: |
The mode to use when retrieving YAML.
- `extension` - Returns extension-only format
- `staged` - Returns staged changes
- `combined` - Returns combined YAML
- name: includeChecksums
in: query
schema:
type: boolean
default: false
description: |
If `true`, the response will include file checksums for concurrency control.
A file's checksum can be passed as a query parameter in the [Create or update YAML endpoint](/api/models/create-or-update-yaml-files) to ensure changes made by another user aren't overwritten.
responses:
'200':
description: Model YAML specification
content:
application/json:
schema:
type: object
properties:
files:
type: object
additionalProperties:
type: string
description: Map of file paths to YAML content.
version:
type: integer
description: Version of the YAML.
viewNames:
type: object
description: Map of view names to their definitions.
checksums:
type: object
description: Map of file paths to their checksums.
example:
files:
model.yaml: "name: Test Model\ntype: model"
views/customers.yaml: "name: Customers\nfields: []"
views/orders.yaml: "name: Orders\nfields: []"
version: 1
viewNames: {}
'400':
description: |
Bad Request
Possible error messages:
- `Schema models do not have branches`
- `Branches are not valid for workbook models with mode=extension, staged`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'403':
description: |
Forbidden
Possible error messages:
- `Permission denied`
- `Feature not enabled`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: |
Not Found
Possible error messages:
- `Model with id <modelId> does not exist`
- `Branch does not exist`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'405':
$ref: '#/components/responses/MethodNotAllowed'
'429':
$ref: '#/components/responses/TooManyRequests'
'500':
description: |
Internal Server Error
Possible error messages:
- `Failed to get model YAML`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/unstable/models/{modelId}/branch/{branchName}/merge:
post:
tags:
- Model branches
summary: Merge a branch
description: |
<Warning>
This API is in beta and may have future breaking changes.
</Warning>
Merges a model branch into the shared model.
x-mint:
content: |
For PR-required and [git follower](/integrations/git/follower-mode) models, direct merges via API are rejected by default as they would bypass the intended git workflow. You can use the `force_override_git_settings` flag to override this check when necessary, but git will not be synced to avoid force-pushing to `main`.
| Model Configuration | Default Behavior | With `force_override_git_settings: true` |
|---------------------|------------------|------------------------------------------|
| No git | Merge succeeds, no git sync | N/A |
| Git enabled (no PR required) | Merge succeeds, syncs to git | N/A |
| Git + PR required | Rejected with 400 error | Merge succeeds, no git sync |
| Git + git follower | Rejected with 400 error | Merge succeeds, no git sync |
security:
- bearerAuth: []
operationId: mergeBranch
parameters:
- name: modelId
in: path
required: true
schema:
type: string
format: uuid
description: The unique identifier of the model
example: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
- name: branchName
in: path
required: true
schema:
type: string
description: The name of the branch to merge
example: "feature/add-revenue-metrics"
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
delete_branch:
type: boolean
default: false
description: Delete the branch after merging
publish_drafts:
type: boolean
default: true
description: When enabled, publish branch-attached drafts when merging
commit_message:
type: string
description: Custom commit message for git sync. Defaults to `"branch <name> merged via API"`
example: "Merged revenue metrics branch via CI/CD pipeline"
force_override_git_settings:
type: boolean
default: false
description: |
Allow merge for PR-required or git-follower models.
When enabled, the merge will succeed but git will not be synced to avoid force-pushing to main.
example:
delete_branch: true
publish_drafts: true
commit_message: "Merged revenue metrics branch via CI/CD pipeline"
force_override_git_settings: false
responses:
'200':
description: Branch merged successfully
content:
application/json:
schema:
type: object
properties:
success:
type: boolean
description: Whether the merge was successful
example: true
published_drafts_count:
type: integer
description: Number of drafts that were published during the merge
example: 2
failed_drafts_count:
type: integer
description: Number of drafts that failed to publish
example: 0
git_synced:
type: boolean
description: Whether the changes were synced to git
example: true
example:
success: true
published_drafts_count: 2
failed_drafts_count: 0
git_synced: true
'400':
description: Bad Request - Merge not allowed for this model configuration
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
examples:
prRequired:
summary: PR-required model without override
value:
error: "Cannot merge branch directly. This model requires pull requests for changes. Use force_override_git_settings: true to bypass."
gitFollower:
summary: Git-follower model without override
value:
error: "Cannot merge branch directly. This model follows git as source of truth. Use force_override_git_settings: true to bypass."
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'405':
description: Invalid HTTP method
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
$ref: '#/components/responses/TooManyRequests'
'500':
$ref: '#/components/responses/InternalServerError'
/v1/models/{modelId}/validate:
get:
tags:
- Models
summary: Validate model
description: Retrieves validation issues for a model and its branches.
security:
- bearerAuth: []
operationId: validateModel
parameters:
- name: modelId
in: path
required: true
schema:
type: string
format: uuid
description: The ID of the model.
- name: branchId
in: query
schema:
type: string
format: uuid
description: |
The ID of the branch to validate. The branch must exist for the model. If not provided, the model is validated directly.
**Note**: Schema models do not support branches.
responses:
'200':
description: A list of validation issues.
content:
application/json:
schema:
type: array
items:
type: object
properties:
message:
type: string
description: The validation issue message.
is_warning:
type: boolean
description: If `true`, the issue is a warning. If `false`, the issue is an error.
yaml_path:
type: string
description: The path to the YAML file containing the issue.
auto_fix:
type: object
description: Information about automatic fixes available for the issue.
properties:
description_short:
type: string
description: A short description of the auto-fix.
description_unique:
type: string
description: A unique description of the auto-fix.
example:
- message: "No view \"blob_sales\". Set base_view to a valid, existing view."
is_warning: false
yaml_path: "blob_sales.topic"
auto_fix:
description_short: "Delete topic \"blob_sales\""
description_unique: "Delete topic \"blob_sales\""
'400':
description: |
Bad Request
Possible error messages:
- `modelId: Invalid uuid`
- `Schema models do not have branches`
- `Unrecognized key(s) in object: '<invalidParameter>'`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: |
Not Found
Possible error messages:
- `Model with id <modelId> does not exist`
- `Branch model with id <branchId> does not exist`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'405':
$ref: '#/components/responses/MethodNotAllowed'
'429':
$ref: '#/components/responses/TooManyRequests'
'500':
description: |
Internal Server Error
Possible error messages:
- `Model service error`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v1/models/{modelId}/content-validator:
get:
tags:
- Content validator
summary: Validate content
description: |
Validates all content against the model and returns documents with queries and any validation issues.
This endpoint scans all documents associated with the model and identifies any fields, views, or other model elements referenced in queries that are no longer valid.
security:
- bearerAuth: []
operationId: validateContent
parameters:
- name: modelId
in: path
required: true
schema:
type: string
format: uuid
description: The ID of the model to validate content against.
- name: branch_id
in: query
schema:
type: string
format: uuid
description: The ID of the branch to validate against. If not provided, validates against the main model.
- name: userId
in: query
schema:
type: string
format: uuid
description: |
The user ID to act on behalf of. Only valid when using an organization API key.
User-scoped API keys cannot use this parameter and will receive a 403 error if provided.
- name: include_personal_folders
in: query
schema:
type: boolean
description: When enabled, include personal folders in the search.
responses:
'200':
description: Content validation results
content:
application/json:
schema:
type: object
properties:
model_id:
type: string
format: uuid
description: The ID of the model that was validated.
branch:
type: object
nullable: true
description: Branch information if a branch was specified, null otherwise.
properties:
id:
type: string
format: uuid
description: The branch ID.
name:
type: string
description: The branch name.
content:
type: array
description: List of documents with their validation results.
items:
type: object
properties:
document_id:
type: string
description: The document ID.
identifier:
type: string
description: The document identifier (slug).
name:
type: string
description: The document name.
type:
type: string
description: The document type (e.g., "Published").
updated_at:
type: string
format: date-time
description: When the document was last updated.
folder:
type: object
nullable: true
description: Folder information if the document is in a folder.
properties:
name:
type: string
description: The folder name.
path:
type: string
description: The full folder path.
owner:
type: object
description: Information about the document owner.
properties:
email:
type: string
format: email
description: The owner's email address.
name:
type: string
description: The owner's display name.
require_pull_request_to_publish:
type: boolean
description: Whether the document requires a pull request to publish changes.
queries_and_issues:
type: array
description: List of queries and their validation issues.
items:
type: object
properties:
query_name:
type: string
description: The name of the query.
query_presentation_id:
type: string
description: The query presentation ID.
query_id_map_key:
type: string
description: The query ID map key.
issues:
type: array
items:
type: string
description: List of validation issue messages for this query.
dashboard_filter_issues:
type: array
items:
type: string
description: List of validation issues for dashboard filters.
example:
model_id: "550e8400-e29b-41d4-a716-446655440000"
branch: null
content:
- document_id: "abc123"
identifier: "dashboard-1"
name: "Sales Dashboard"
type: "Published"
updated_at: "2025-01-15T10:00:00Z"
folder:
name: "Reports"
path: "/Reports"
owner:
email: "user@example.com"
name: "Jane Doe"
require_pull_request_to_publish: false
queries_and_issues:
- query_name: "Total Revenue"
query_presentation_id: "qp-123"
query_id_map_key: "1"
issues:
- "Field 'orders.old_field' not found in model"
dashboard_filter_issues: []
'400':
description: |
Bad Request
Possible error messages:
- `modelId: Invalid UUID`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
detail: "Bad Request: modelId: Invalid UUID"
status: 400
'403':
description: |
Forbidden
Possible error messages:
- `User-scoped API keys cannot act on behalf of other users`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
detail: "User-scoped API keys cannot act on behalf of other users"
status: 403
'404':
description: |
Not Found
Possible error messages:
- `Shared model with id <modelId> does not exist`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
detail: "Shared model with id 550e8400-e29b-41d4-a716-446655440000 does not exist"
status: 404
'405':
$ref: '#/components/responses/MethodNotAllowed'
'429':
$ref: '#/components/responses/TooManyRequests'
post:
tags:
- Content validator
summary: Find and replace content
description: |
Performs find/replace operations on content using the specified model.
This endpoint allows you to replace views or fields across all documents associated with the model. This is useful when renaming model elements and need to update all references.
security:
- bearerAuth: []
operationId: findReplaceContent
parameters:
- name: modelId
in: path
required: true
schema:
type: string
format: uuid
description: The ID of the model to perform find/replace against.
- name: userId
in: query
schema:
type: string
format: uuid
description: |
The user ID to act on behalf of. Only valid when using an organization API key.
User-scoped API keys cannot use this parameter and will receive a 403 error if provided.
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- find
- replacement
- find_or_replace_type
properties:
find:
type: string
description: |
The value to find. Used with `find_or_replace_type` to scope the search:
- `VIEW` - The name of the view to find
- `FIELD` - The fully qualified name of the field to find, specified as `view_name.field_name`
- `TOPIC` - The name of the topic to find
replacement:
type: string
description: |
The replacement value.
- `VIEW` - The name of the replacement view
- `FIELD` - The fully qualified name of the replacement field, specified as `view_name.field_name`
- `TOPIC` - The name of the replacement topic
find_or_replace_type:
type: string
enum:
- VIEW
- FIELD
- TOPIC
description: |
The type of find/replace operation.
- `VIEW` - Replace view references
- `FIELD` - Replace field references. `find` and `replacement` values must be the fully qualified name of the field, e.g. `view_name.field_name`.
- `TOPIC` - Replace topic references
branch_id:
type: string
format: uuid
description: The branch ID to perform the operation on. If not provided, operates on the main model.
include_personal_folders:
type: boolean
description: When enabled, include personal folders.
only_in_workbook_id:
type: string
description: A workbook ID. When provided, the find/replace action will be limited only to the specified workbook.
examples:
replaceView:
summary: Replace a view
value:
find: "old_view"
replacement: "new_view"
find_or_replace_type: "VIEW"
replaceField:
summary: Replace a field
value:
find: "orders.old_field"
replacement: "orders.new_field"
find_or_replace_type: "FIELD"
replaceViewInBranch:
summary: Replace a view in a branch
value:
find: "old_view"
replacement: "new_view"
find_or_replace_type: "VIEW"
branch_id: "550e8400-e29b-41d4-a716-446655440001"
responses:
'200':
description: Find/replace operation completed successfully
content:
application/json:
schema:
type: object
properties:
replaced_queries_count:
type: integer
description: The number of queries that had replacements made.
replaced_documents_count:
type: integer
description: The number of documents that had replacements made.
replaced_workbook_models_count:
type: integer
description: The number of workbook models that had replacements made.
replaced_dashboard_filters_count:
type: integer
description: The number of dashboard filters that had replacements made.
skipped_pr_required_count:
type: integer
description: The number of documents skipped because they require a pull request to publish.
example:
replaced_queries_count: 15
replaced_documents_count: 5
replaced_workbook_models_count: 3
replaced_dashboard_filters_count: 2
skipped_pr_required_count: 0
'400':
description: |
Bad Request
Possible error messages:
- `modelId: Invalid UUID`
- `Find field must be scoped by view name.`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
examples:
invalidModelId:
summary: Invalid model ID
value:
detail: "Bad Request: modelId: Invalid UUID"
status: 400
fieldNotScoped:
summary: Field not scoped by view name
value:
detail: "Find field must be scoped by view name."
status: 400
'403':
description: |
Forbidden
Possible error messages:
- `User-scoped API keys cannot act on behalf of other users`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
detail: "User-scoped API keys cannot act on behalf of other users"
status: 403
'404':
description: |
Not Found
Possible error messages:
- `Shared model with id <modelId> does not exist`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
detail: "Shared model with id 550e8400-e29b-41d4-a716-446655440000 does not exist"
status: 404
'405':
$ref: '#/components/responses/MethodNotAllowed'
'429':
$ref: '#/components/responses/TooManyRequests'
/v1/models/{modelId}/git:
get:
tags:
- Model git configuration
summary: Get git configuration
description: |
Retrieves the git configuration for a shared model.
security:
- bearerAuth: []
operationId: getModelGitConfig
parameters:
- name: modelId
in: path
required: true
schema:
type: string
format: uuid
description: The unique identifier of the shared model.
- name: include
in: query
required: false
schema:
type: string
enum: [webhookSecret]
description: |
Comma-separated list of additional fields to include in the response.
- `webhookSecret` - Include the webhook secret in the response
responses:
'200':
description: Git configuration retrieved successfully
content:
application/json:
schema:
$ref: '#/components/schemas/ModelGitConfig'
example:
baseBranch: "main"
branchPerPullRequest: false
gitFollower: false
gitServiceProvider: "github"
modelPath: "omni/blobs_r_us"
publicKey: "ssh-ed25519 AAAA..."
requirePullRequest: "users-only"
sshUrl: "git@github.com:org/repo.git"
webUrl: "https://github.com/org/repo"
webhookUrl: "https://app.omni.co/api/webhooks/model/..."
'400':
description: |
Bad Request
Possible error messages:
- `Bad Request: modelId: Invalid uuid`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'401':
description: Missing or invalid authentication
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'403':
description: |
Forbidden
Possible error messages:
- `Forbidden: Requires MANAGE_MODEL permission`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: |
Not Found
Possible error messages:
- `Not Found: Model does not exist`
- `Not Found: Git configuration not found for this model`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
$ref: '#/components/responses/TooManyRequests'
post:
tags:
- Model git configuration
summary: Create git configuration
description: |
Creates a new git configuration for a shared model.
security:
- bearerAuth: []
operationId: createModelGitConfig
parameters:
- name: modelId
in: path
required: true
schema:
type: string
format: uuid
description: The unique identifier of the shared model.
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- sshUrl
properties:
sshUrl:
type: string
description: The SSH URL of the git repository.
example: "git@github.com:org/repo.git"
baseBranch:
type: string
default: "main"
description: The target branch for Omni pull requests.
example: "main"
branchPerPullRequest:
type: boolean
default: false
description: If `true`, all pull requests will create a branch in Omni, even those created outside of the tool.
example: false
gitFollower:
type: boolean
default: false
description: If `true`, the shared model is read-only and can only be updated by merging pull requests to the `baseBranch`.
example: false
gitServiceProvider:
type: string
enum: [auto, github, gitlab, azure_devops, bitbucket]
default: "auto"
description: |
The git provider type. Use `auto` for automatic detection based on the SSH URL.
- `auto` - Automatically detect the provider
- `github` - GitHub
- `gitlab` - GitLab
- `azure_devops` - Azure DevOps
- `bitbucket` - Bitbucket
example: "github"
modelPath:
type: string
description: Path to model files within the repository.
example: "omni/blobs_r_us"
requirePullRequest:
type: string
enum: [always, users-only, never]
default: "never"
description: |
Controls when pull requests are required for changes:
- `always` - Required for all changes
- `users-only` - Required only for user-initiated changes
- `never` - Never required
example: "users-only"
webUrl:
type: string
description: Custom web URL override for the git repository. If not provided, it will be inferred from the SSH URL.
example: "https://github.com/org/repo"
example:
sshUrl: "git@github.com:org/repo.git"
baseBranch: "main"
gitServiceProvider: "github"
modelPath: "omni/blobs_r_us"
requirePullRequest: "users-only"
responses:
'200':
description: Git configuration created successfully
content:
application/json:
schema:
$ref: '#/components/schemas/ModelGitConfig'
example:
baseBranch: "main"
branchPerPullRequest: false
gitFollower: false
gitServiceProvider: "github"
modelPath: "omni/my_model"
publicKey: "ssh-ed25519 AAAA..."
requirePullRequest: "users-only"
sshUrl: "git@github.com:org/repo.git"
webUrl: "https://github.com/org/repo"
webhookSecret: "whsec_abc123xyz789"
webhookUrl: "https://app.omni.co/api/webhooks/model/..."
'400':
description: |
Bad Request
Possible error messages:
- `Bad Request: modelId: Invalid uuid`
- `Bad Request: sshUrl is required`
- `Bad Request: Invalid sshUrl format`
- `Bad Request: Invalid requirePullRequest value`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'401':
description: Missing or invalid authentication
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'403':
description: |
Forbidden
Possible error messages:
- `Forbidden: Requires MANAGE_MODEL permission`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: |
Not Found
Possible error messages:
- `Not Found: Model does not exist`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'409':
description: |
Conflict
Possible error messages:
- `Conflict: Git configuration already exists for this model`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
$ref: '#/components/responses/TooManyRequests'
patch:
tags:
- Model git configuration
summary: Update git configuration
description: Updates the git configuration for a shared model. Oly provided fields will be updated.
security:
- bearerAuth: []
operationId: updateModelGitConfig
parameters:
- name: modelId
in: path
required: true
schema:
type: string
format: uuid
description: The unique identifier of the shared model.
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
sshUrl:
type: string
description: The SSH URL of the git repository.
example: "git@github.com:org/repo.git"
baseBranch:
type: string
description: The target branch for Omni pull requests.
example: "main"
branchPerPullRequest:
type: boolean
description: If `true`, all pull requests will create a branch in Omni, even those created outside of the tool.
example: false
gitFollower:
type: boolean
description: If `true`, the shared model is read-only and can only be updated by merging pull requests to the `baseBranch`.
example: false
gitServiceProvider:
type: string
enum: [auto, github, gitlab, azure_devops, bitbucket]
description: |
The git provider type. Use `auto` for automatic detection based on the SSH URL.
- `auto` - Automatically detect the provider
- `github` - GitHub
- `gitlab` - GitLab
- `azure_devops` - Azure DevOps
- `bitbucket` - Bitbucket
example: "github"
modelPath:
type: string
description: Path to model files within the repository.
example: "omni/blobs_r_us"
requirePullRequest:
type: string
enum: [always, users-only, never]
description: |
Controls when pull requests are required for changes:
- `always` - Pull requests are required for all changes
- `users-only` - Pull requests are required only for user-initiated changes
- `never` - Pull requests are never required
example: "users-only"
webUrl:
type: string
description: Custom web URL override for the git repository.
example: "https://github.com/org/repo"
example:
baseBranch: "develop"
requirePullRequest: "always"
responses:
'200':
description: Git configuration updated successfully
content:
application/json:
schema:
$ref: '#/components/schemas/ModelGitConfig'
example:
baseBranch: "develop"
branchPerPullRequest: false
gitFollower: false
gitServiceProvider: "github"
modelPath: "omni/my_model"
publicKey: "ssh-ed25519 AAAA..."
requirePullRequest: "always"
sshUrl: "git@github.com:org/repo.git"
webUrl: "https://github.com/org/repo"
webhookUrl: "https://app.omni.co/api/webhooks/model/..."
'400':
description: |
Bad Request
Possible error messages:
- `Bad Request: modelId: Invalid uuid`
- `Bad Request: Invalid sshUrl format`
- `Bad Request: Invalid requirePullRequest value`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'401':
description: Missing or invalid authentication
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'403':
description: |
Forbidden
Possible error messages:
- `Forbidden: Requires MANAGE_MODEL permission`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: |
Not Found
Possible error messages:
- `Not Found: Model does not exist`
- `Not Found: Git configuration not found for this model`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
$ref: '#/components/responses/TooManyRequests'
delete:
tags:
- Model git configuration
summary: Delete git configuration
description: Removes the git configuration from a shared model.
security:
- bearerAuth: []
operationId: deleteModelGitConfig
parameters:
- name: modelId
in: path
required: true
schema:
type: string
format: uuid
description: The unique identifier of the shared model.
responses:
'200':
description: Git configuration deleted successfully
content:
application/json:
schema:
$ref: '#/components/schemas/SuccessResponse'
'400':
description: |
Bad Request
Possible error messages:
- `Bad Request: modelId: Invalid uuid`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'401':
description: Missing or invalid authentication
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'403':
description: |
Forbidden
Possible error messages:
- `Forbidden: Requires MANAGE_MODEL permission`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: |
Not Found
Possible error messages:
- `Not Found: Model does not exist`
- `Not Found: Git configuration not found for this model`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
$ref: '#/components/responses/TooManyRequests'
/v1/models/{modelId}/git/sync:
post:
tags:
- Model git configuration
summary: Sync model with git repository
description: |
Triggers a sync operation between the model and its configured git repository.
This will pull the latest changes from the repository and apply them to the model.
security:
- bearerAuth: []
operationId: syncModelWithGit
parameters:
- name: modelId
in: path
required: true
schema:
type: string
format: uuid
description: The unique identifier of the shared model.
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
commitMessage:
type: string
description: Optional commit message to use when pushing changes to the repository.
example: "Updated model configuration"
example:
commitMessage: "Updated model configuration"
responses:
'200':
description: Sync operation completed successfully
content:
application/json:
schema:
type: object
properties:
didSync:
type: boolean
description: Whether a sync was performed. `false` if the model was already in sync.
example: true
gitSha:
type: string
nullable: true
description: The git SHA after the sync operation, or null if no sync was performed.
example: "abc123def456"
inSync:
type: boolean
description: Whether the model is currently in sync with the git repository.
example: true
message:
type: string
description: Human-readable status message describing the sync result.
example: "Model synced successfully"
example:
didSync: true
gitSha: "abc123def456"
inSync: true
message: "Model synced successfully"
'400':
description: |
Bad Request
Possible error messages:
- `Bad Request: modelId: Invalid uuid`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'401':
description: Missing or invalid authentication
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'403':
description: |
Forbidden
Possible error messages:
- `Forbidden: Requires MANAGE_MODEL permission`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: |
Not Found
Possible error messages:
- `Not Found: Model does not exist`
- `Not Found: Git configuration not found for this model`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
$ref: '#/components/responses/TooManyRequests'
/v1/models/{modelId}/topic/{topicName}:
get:
tags:
- Topics
summary: Retrieve a topic
description: Retrieves a topic in a model by name.
security:
- bearerAuth: []
operationId: getTopic
parameters:
- name: modelId
in: path
required: true
schema:
type: string
format: uuid
description: The unique identifier of the model that contains the topic.
- name: topicName
in: path
required: true
schema:
type: string
description: The name of the topic.
responses:
'200':
description: ""
content:
application/json:
schema:
type: object
properties:
success:
type: boolean
description: Indicates the request was successful
topic:
type: object
description: Details about the topic. The properties included in the response will typically mirror the [IDE parameters](/modeling/topics/parameters) for topic files.
properties:
name:
type: string
description: The name of the topic
base_view_name:
type: string
description: The name of the base view for the topic
label:
type: string
description: The display label for the topic
default_filters:
type: object
description: Default filters applied to the topic
join_via_map:
type: object
description: Join path mappings for the topic. Keys are view names, values are arrays of view names representing the join path.
additionalProperties:
type: array
items:
type: string
join_via_map_key_order:
type: array
items:
type: string
description: Order of join path keys
ignored_props:
type: array
items:
type: string
description: Properties to ignore
always_where_filters:
type: object
description: |
Filters that applied to all rows in a query. In the model IDE, this is the [`always_where_filters`](/modeling/topics/parameters/always-where-filters) parameter.
extension_model_id:
type: string
format: uuid
description: The ID of the extension model
has_frozen_join_via_map:
type: boolean
description: Whether the join via map is frozen
relationships:
type: array
description: Relationships defined in the topic. The properties in each object will typically mirror the [IDE parameters](/modeling/relationships/parameters) used in a model's `relationships` file.
items:
type: object
properties:
left_view_name:
type: string
description: The left view in the relationship
right_view_name:
type: string
description: The right view in the relationship
join_type:
type: string
description: The type of join (e.g., ALWAYS_LEFT)
on:
type: object
description: The join condition expression
properties:
type:
type: string
operator:
type: string
operands:
type: array
items:
type: object
distinct:
type: boolean
sql:
type: string
description: The SQL expression for the join
id:
type: string
description: Unique identifier for the relationship
type:
type: string
description: The relationship type (e.g., `ONE_TO_MANY`)
ignored:
type: boolean
description: Whether the relationship is ignored
bidirectional:
type: boolean
description: Whether the relationship is bidirectional
original_on_sql:
type: string
description: The original SQL for the join condition
yaml_path_prefix:
type: string
description: The YAML path prefix for the relationship
ide_file_name:
type: string
description: The file name for the topic in the IDE
views:
type: array
description: A list of views included in the topic. The properties in each object will mirror the [IDE parameters](/modeling/views/parameters) available for views.
items:
type: object
properties:
name:
type: string
description: The name of the view
label:
type: string
description: The display label for the view
table_name:
type: string
description: The underlying database table name
schema:
type: string
description: The database schema
schema_label:
type: string
description: The display label for the schema
extension_model_id:
type: string
format: uuid
ide_file_name:
type: string
description: The name of the IDE file for the view
yaml_path:
type: string
description: The YAML file path for the view
filter_only_fields:
type: array
items:
type: string
is_pseudo_display_view:
type: boolean
primary_key:
type: array
description: Primary key fields for the view
items:
type: object
properties:
type:
type: string
field_name:
type: string
dimensions:
type: array
description: A list of dimensions defined in the view. The properties in each object will mirror the [IDE parameters](/modeling/dimensions/parameters) for `dimensions.`
items:
type: object
properties:
field_name:
type: string
view_name:
type: string
data_type:
type: string
description: Data type (e.g., STRING, NUMBER, TIMESTAMP)
format:
type: string
description: Display format (e.g., ID)
label:
type: string
description: Display label for the dimension
description:
type: string
description: Description of the dimension
view_label:
type: string
extension_model_id:
type: string
format: uuid
is_dimension:
type: boolean
fully_qualified_name:
type: string
time_frames:
type: array
description: Available time frames for date dimensions
items:
type: string
date_type:
type: string
description: Date granularity (e.g., DATE, WEEK, MONTH, QUARTER, YEAR)
drill_fields:
type: array
description: Fields available for drilling
items:
type: string
parent_field:
type: string
description: Parent field name for grouped dimensions
parent_label:
type: string
description: Parent field label
group_label:
type: string
description: Group label for the dimension
is_group_parent_field:
type: boolean
description: Whether this is a parent field in a group
data_type_metadata:
type: object
description: Additional metadata about the data type
properties:
is_date_type:
type: boolean
ai_context:
type: string
description: Context hints for AI usage
measures:
type: array
description: Measures defined in the view. The properties in each object will mirror the [IDE parameters](/modeling/measures/parameters) for `measures.`
items:
type: object
properties:
type:
type: string
description: Measure type (e.g., aggregation)
field_name:
type: string
view_name:
type: string
aggregate_type:
type: string
description: Aggregation type (e.g., COUNT, SUM, AVG)
data_type:
type: string
label:
type: string
format:
type: string
view_label:
type: string
ignored:
type: boolean
description: Whether the measure is ignored
display_sql:
type: string
description: SQL displayed in the UI
dialect_sql:
type: string
description: SQL specific to the database dialect
fully_qualified_name:
type: string
filters:
type: object
description: Filters applied to the measure
example:
success: true
topic:
name: "Customers"
base_view_name: "main__customers"
label: "Customers"
default_filters: {}
join_via_map:
main__orders: []
main__order_items:
- "main__orders"
join_via_map_key_order:
- "main__orders"
- "main__order_items"
ignored_props: []
always_where_filters: {}
extension_model_id: "5da4e30e-45e2-4693-b87d-51c39d69963f"
has_frozen_join_via_map: true
relationships:
- left_view_name: "main__orders"
right_view_name: "main__customers"
join_type: "ALWAYS_LEFT"
sql: "${main__orders.customer_id} = ${main__customers.id}"
id: "main__orders_main__customers"
type: "ASSUMED_MANY_TO_ONE"
ignored: false
bidirectional: false
ide_file_name: "Customers.topic"
views:
- name: "main__customers"
label: "Customers"
table_name: "customers"
schema: "main"
schema_label: "Main"
extension_model_id: "5da4e30e-45e2-4693-b87d-51c39d69963f"
ide_file_name: "main/customers.view"
yaml_path: "main__customers.view"
filter_only_fields: []
is_pseudo_display_view: false
primary_key:
- type: "field"
field_name: "main__customers.id"
dimensions:
- field_name: "country"
view_name: "main__customers"
data_type: "STRING"
description: "User's country"
view_label: "Customers"
is_dimension: true
fully_qualified_name: "main__customers.country"
- field_name: "created_date"
view_name: "main__customers"
data_type: "TIMESTAMP"
time_frames:
- null
- "DATE"
- "WEEK"
- "MONTH"
- "QUARTER"
- "YEAR"
date_type: "DATE"
description: "Date of user creation"
parent_field: "created_date"
parent_label: "Created Date"
view_label: "Customers"
group_label: "Created Date"
is_dimension: true
is_group_parent_field: true
fully_qualified_name: "main__customers.created_date"
measures:
- type: "aggregation"
field_name: "count"
view_name: "main__customers"
aggregate_type: "COUNT"
data_type: "NUMBER"
ignored: false
label: "Customers Count"
format: "NUMBER_0"
view_label: "Customers"
display_sql: "COUNT(*)"
dialect_sql: "COUNT(*)"
fully_qualified_name: "main__customers.count"
'400':
description: |
Bad Request. Possible causes:
- Invalid model UUID
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
detail: "Model with id <modelId> does not exist"
status: 400
'404':
description: |
Not Found. Possible causes:
- Model not found
- Topic not found or access not permitted
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
examples:
modelNotFound:
summary: Model not found
value:
detail: "Model with id <modelId> does not exist"
status: 404
topicNotFound:
summary: Topic not found
value:
detail: "No such topic \"<topicName>\" or access not permitted"
status: 404
'429':
$ref: '#/components/responses/TooManyRequests'
/v1/query/run:
post:
tags:
- Queries
summary: Run query
description: |
Runs 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.
x-mint:
content: |
**Encountering timeouts?** If a request takes too long, the response will include a `remaining_job_ids` property. When this occurs, poll the [Wait for query results](/api/queries/wait-for-query-results) endpoint until the `timed_out` property is `false`.
security:
- bearerAuth: []
operationId: runQuery
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- query
properties:
query:
type: object
description: |
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.
required:
- modelId
- table
- fields
properties:
modelId:
type: string
format: uuid
description: The ID of the model to execute the query against.
table:
type: string
description: The base table or topic name.
fields:
type: array
items:
type: string
description: The column names to include in the query results.
limit:
oneOf:
- type: integer
maximum: 75000
default: 1000
- type: "null"
description: |
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:
type: array
items:
type: object
properties:
column_name:
type: string
description: The column to sort by
sort_descending:
type: boolean
description: If `true`, sort in descending order
is_column_sort:
type: boolean
null_sort:
type: string
description: How to handle nulls (e.g., `OMNI_DEFAULT`)
description: Sort specifications for the query results.
filters:
type: object
description: Filter conditions to apply to the query.
pivots:
type: array
items:
type: object
description: Pivot configurations for the query.
calculations:
type: array
items:
type: object
description: Custom calculations to include in the query.
column_totals:
type: object
description: Column total configuration.
row_totals:
type: object
description: Row total configuration.
column_limit:
type: integer
description: Column limit for pivoted queries.
join_paths_from_topic_name:
type: string
description: Topic name for join paths.
join_via_map:
type: object
description: Custom join path mappings.
version:
type: integer
description: Query version number.
default_group_by:
type: boolean
description: If `true`, enable default grouping behavior.
dbtMode:
type: boolean
description: If `true`, enable dbt mode.
rewriteSql:
type: boolean
description: If `true`, enable SQL mode.
dimensionIndex:
type: integer
description: 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:
type: array
items:
type: object
description: Control configurations for the query.
manualSort:
type: boolean
description: If `true`, sorting was manually applied to the query instead of using Omni's default behavior.
fill_fields:
type: array
items:
type: string
description: A list of dimensions that should have missing values filled with placeholder rows.
userEditedSQL:
type: string
description: User-edited SQL override.
custom_summary_types:
type: object
description: Custom summary type configurations.
userId:
type: string
format: uuid
description: Executes the query as the specified user. If not provided, the API uses the user associated with the API token. The `userId` must belong to a user in your organization.
cache:
type: string
default: SkipRequery
enum: [ Standard, SkipRequery, SkipCache ]
description: |
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:
type: string
enum: [ csv, json, xlsx ]
description: |
**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:
type: boolean
description: |
**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:
type: boolean
default: true
description: |
**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.
example:
query:
modelId: "bcf0cffd-ec1b-44d5-945a-a261ebe407fc"
table: "order_items"
fields:
- "inventory_items.product_department"
- "inventory_items.product_category"
- "inventory_items.count"
limit: 10
sorts:
- column_name: "inventory_items.product_department"
sort_descending: false
join_paths_from_topic_name: "order_items"
responses:
'200':
description: |
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`.
content:
application/json:
schema:
type: object
properties:
jobs_submitted:
type: object
description: Map of job IDs to client result IDs
job_id:
type: string
format: uuid
description: The unique identifier for the query job
status:
type: string
description: Job status (e.g., `COMPLETE`, `PLANNED`)
client_result_id:
type: string
format: uuid
description: Client-side result identifier
summary:
type: object
description: Query execution summary including SQL, stats, and field metadata
cache_metadata:
type: object
description: Cache information including TTL and data freshness
query:
type: object
description: The executed query details
result:
type: string
description: Base64 encoded Apache Arrow table containing query results
stream_stats:
type: object
description: Server-side streaming metrics
properties:
server_stream:
description: Time in milliseconds to stream the result data from the server
type: integer
remaining_job_ids:
type: array
items:
type: string
format: uuid
description: IDs of the jobs still processing if the request timed out. Poll `/api/v1/query/wait` with these IDs.
timed_out:
type: string
description: Indicates if the request timed out. If `true`, use `remaining_job_ids` to poll for results.
'400':
description: |
Bad Request. Possible causes:
- `formatResults` provided without `resultType`
- `planOnly` and `resultType` both provided (incompatible)
- `query.limit` is a negative number
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
examples:
formatResultsWithoutResultType:
summary: formatResults without resultType
value:
detail: "formatResults cannot be provided without resultType"
status: 400
planOnlyWithResultType:
summary: planOnly and resultType both provided
value:
detail: "planOnly and resultType cannot both be provided"
status: 400
negativeLimitValue:
summary: Negative limit value
value:
detail: "query.limit: Too small: expected number to be >0"
status: 400
'429':
$ref: '#/components/responses/TooManyRequests'
/v1/query/wait:
get:
tags:
- Queries
summary: Wait for query results
description: |
Polls for the results of one or more query jobs. Use this endpoint when a request to the [Run query endpoint](/api/queries/run-query) times out and returns `remaining_job_ids` in the response.
This endpoint will wait for the specified jobs to complete and return their results. If the jobs are still processing when the request times out, the response will include the remaining job IDs to poll again.
security:
- bearerAuth: []
operationId: waitForQuery
parameters:
- name: job_ids
in: query
required: true
schema:
type: array
items:
type: string
format: uuid
description: |
An array of job IDs to poll for results. These IDs are returned in the `remaining_job_ids` property when a request to the [Run query endpoint](/api/queries/run-query) times out.
Format the parameter as a JSON array (e.g., `?job_ids=["job-id-1","job-id-2"]`).
responses:
'200':
description: |
Successful response containing the query results for completed jobs.
If all jobs have completed, `timed_out` will be `false` and the response will include the full query results.
If some jobs are still processing when this request times out, `timed_out` will be `true` and `remaining_job_ids` will contain the IDs of jobs that are still running. Continue polling with these IDs until all jobs complete.
content:
application/json:
schema:
type: object
properties:
job_id:
type: string
format: uuid
description: The unique identifier for the query job
status:
type: string
description: Job status (e.g., `COMPLETE`, `PLANNED`)
client_result_id:
type: string
format: uuid
description: Client-side result identifier
summary:
type: object
description: Query execution summary including SQL, stats, and field metadata
cache_metadata:
type: object
description: Cache information including TTL and data freshness
query:
type: object
description: The executed query details
result:
type: string
description: Base64 encoded Apache Arrow table containing query results
stream_stats:
type: object
description: Server-side streaming metrics
properties:
server_stream:
description: Time in milliseconds to stream the result data from the server
type: integer
remaining_job_ids:
type: array
items:
type: string
format: uuid
description: IDs of jobs still processing if this request timed out. Continue polling with these IDs.
timed_out:
type: boolean
description: Indicates if the request timed out. If `true`, use `remaining_job_ids` to poll again.
examples:
completedJob:
summary: Job completed successfully
value:
job_id: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
status: "COMPLETE"
client_result_id: "b2c3d4e5-f6a7-8901-bcde-f12345678901"
summary:
sql: "SELECT * FROM order_items LIMIT 10"
total_rows: 10
execution_time_ms: 245
result: "QVJST1cxAAD/////..."
timed_out: false
timedOut:
summary: Request timed out with remaining jobs
value:
timed_out: true
remaining_job_ids:
- "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
- "b2c3d4e5-f6a7-8901-bcde-f12345678901"
'400':
description: |
Bad Request. Possible causes:
- Missing or invalid `job_ids` parameter
- `job_ids` is not a valid JSON array
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
examples:
missingJobIds:
summary: Missing job_ids parameter
value:
detail: "job_ids parameter is required"
status: 400
invalidJobIds:
summary: Invalid job_ids format
value:
detail: "job_ids must be a valid JSON array of UUIDs"
status: 400
'401':
description: Missing or invalid authentication
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: |
Not Found. Possible causes:
- One or more job IDs do not exist
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
examples:
jobNotFound:
summary: Job not found
value:
detail: "Job with id <jobId> does not exist"
status: 404
'429':
$ref: '#/components/responses/TooManyRequests'
/v1/schedules:
post:
tags:
- Schedules
summary: Create schedule
description: |
Creates a scheduled task for the specified dashboard. Supports applying filters and formatting, creating alert conditions, and triggering test deliveries.
<Note>
Currently, only [email](/sharing-and-sending/email), [SFTP](/sharing-and-sending/SFTP), and [webhook](/sharing-and-sending/webhooks) destinations are supported.
</Note>
security:
- bearerAuth: []
operationId: createSchedule
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- identifier
- name
- schedule
- timezone
- format
- destinationType
properties:
identifier:
type: string
description: |
The ID of the dashboard where the task will be created. This can be retrieved by:
- **Opening the dashboard settings** - Navigate to **File > Document settings** in the dashboard and then click **Settings**. The **Identifier** field contains the dashboard ID.
- **Using the dashboard's URL** - The string after `/dashboards` is the dashboard's ID; for example: `https://myorg.omniapp.co/dashboards/12db1a0a`
name:
type: string
description: The name of the task.
schedule:
type: string
description: |
A cron expression defining when the schedule will run, in [Amazon Web Services (AWS) Cloudwatch syntax](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-scheduled-rule-pattern.html).
timezone:
type: string
description: |
The IANA timezone where the task should run, such as `Asia/Dubai`. Refer to the [`TZ` column in this IANA.org timezone description file](https://data.iana.org/time-zones/tzdb-2021a/zone1970.tab) for a list of accepted values.
format:
type: string
enum: [csv, link_only, json, pdf, png, xlsx]
description: |
The output format of the schedule.
destinationType:
type: string
enum: [webhook, email, sftp]
description: |
The destination where the task's output should be delivered.
filterConfig:
type: object
description: |
An object specifying the filter conditions to apply to the task. The filter key specified must already exist in the dashboard. If the dashboard doesn't have any filters configured, filters can't be used in the task.
Use the [Get dashboard filters and controls endpoint](/api/dashboard-filters/get-dashboard-filters-and-controls) to retrieve filter configuration objects.
**Note**: Filter keys are case-sensitive and must match exactly.
conditionType:
type: string
enum: [RESULTS_PRESENT, RESULTS_CHANGED, RESULTS_MISSING, RESULTS_UNCHANGED]
description: |
**Required if `conditionQueryMapKey` is provided.** Defines the type of condition to use for alerts.
conditionQueryMapKey:
type: string
description: |
**Required if `conditionType` is provided.** The ID of the query to monitor for triggering an alert. Must reference a valid query in the dashboard.
queryIdentifierMapKey:
type: string
description: |
The ID of the query to include in a single tile task. Must reference a valid query in the dashboard.
**Required for:**
- `format: json` with `enableFormatting: true`
- `format: xlsx` with `overrideRowLimit: true`
killJobsOnFailure:
type: boolean
default: false
description: |
If `true`, stop the entire job if any queries included in the task fail.
testNow:
type: boolean
default: false
description: |
If `true`, run the task immediately instead of scheduling.
Not supported for `RESULTS_CHANGED` alert conditions.
hideTitle:
type: boolean
default: false
description: |
**Compatible with `pdf` and `png` formats.** If `true`, the content's title will be hidden in the task's output.
hideHiddenFields:
type: boolean
default: false
description: |
**Compatible with `csv` and `xlsx` formats.** If `true`, fields marked as `hidden` won't be displayed in the task's output.
enableFormatting:
type: boolean
default: false
description: |
**Compatible with `csv` and `json` formats.** If `true`, formatting will be enabled in the task's output.
If `true` for `json` format, `queryIdentifierMapKey` is required.
overrideRowLimit:
type: boolean
default: false
description: |
**Compatible with `csv`, `json`, and `xlsx` formats.** If `true`, the default row limit will be overridden.
If `true` for `json` and `xlsx` formats, a `queryIdentifierMapKey` is required.
maxRowLimit:
type: integer
description: |
**Compatible with `csv`, `json`, and `xlsx` formats.** Used with `overrideRowLimit`. Specifies the maximum number of rows.
showContentLink:
type: boolean
default: true
description: |
**Compatible with all formats except `link_only`.** If `true`, a link to the content will be shown in the task's output.
showFilters:
type: boolean
default: true
description: |
**Compatible with all formats except `link_only` and `csv`.** If `true`, filters will be shown in the task's output.
expandTablesToShowAllRows:
type: boolean
default: false
description: |
**Compatible with `pdf` and `png` formats.** If `true`, up to 1,000 rows in table visualizations will be included in the delivery.
This parameter cannot be used when `paperFormat: fit_page`.
paperFormat:
type: string
enum: [a3, a4, letter, legal, fit_page, tabloid]
description: |
**Compatible with `pdf` format.** Defines the paper format (size) of the resulting PDF.
The `fit_page` option cannot be used if `expandTablesToShowAllRows: true`.
paperOrientation:
type: string
enum: [portrait, landscape]
description: |
**Compatible with `pdf` format.** Defines the paper orientation of the resulting PDF.
singleColumnLayout:
type: boolean
default: false
description: |
**Compatible with `pdf` and `png` formats.** If `true`, dashboard tiles will be arranged into a single vertical column.
url:
type: string
description: |
**Required if `destinationType: webhook`.** A webhook URL. Must be a valid HTTP/HTTPS URL.
recipients:
type: array
items:
type: string
description: |
**Required if `destinationType: email`.** An array of strings, each specifying a valid email address.
subject:
type: string
description: |
**Required if `destinationType: email`.** Email subject line.
textBody:
type: string
description: |
**Applicable to email destinations.** Custom email body text.
fanOut:
type: boolean
default: false
description: |
**Applicable to email destinations.** If `true`, send individual emails to each recipient.
address:
type: string
description: |
**Required if `destinationType: sftp`.** SFTP server address.
port:
type: integer
description: |
**Required if `destinationType: sftp`.** SFTP port.
username:
type: string
description: |
**Required if `destinationType: sftp`.** SFTP username.
path:
type: string
description: |
**Required if `destinationType: sftp`.** Remote file path.
passwordUnencrypted:
type: string
description: |
**Applicable to SFTP destinations.** SFTP password.
examples:
'Webhook':
summary: Webhook destination
value:
identifier: "12db1a0a"
name: "My Webhook schedule"
schedule: "0 9 ? * * *"
timezone: "UTC"
format: "json"
destinationType: "webhook"
url: "https://webhooksrus.com/1234566"
'Email':
summary: Email destination
value:
identifier: "12db1a0a"
name: "My Email schedule"
schedule: "0 9 ? * * *"
timezone: "UTC"
format: "pdf"
destinationType: "email"
paperFormat: "legal"
expandTablesToShowAllRows: true
paperOrientation: "landscape"
recipients:
- "user1@example.com"
- "user2@example.com"
subject: "Daily Sales report"
textBody: "Here are the daily sales!"
fanOut: false
'SFTP':
summary: SFTP destination
value:
identifier: "12db1a0a"
name: "My SFTP schedule"
schedule: "0 9 ? * * *"
timezone: "UTC"
format: "xlsx"
destinationType: "sftp"
address: "sftp.example.com"
port: 22
username: "sftpuser"
passwordUnencrypted: "password123"
'Filters and formatting':
summary: Filters and formatting
value:
identifier: "dashboard-abc123"
name: "Weekly Regional Report"
schedule: "0 0 ? * MON *"
timezone: "UTC"
format: "pdf"
destinationType: "email"
recipients:
- "iamagoodblob@blobsrus.com"
- "managerblob@blobsrus.com"
subject: "Weekly Regional Report"
filterConfig:
region:
kind: "EQ"
left_side: "US"
type: "string"
hideTitle: true
'Alert condition':
summary: Alert condition
value:
identifier: "dashboard-abc123"
name: "Data Alert Webhook"
schedule: "0 */6 * * ? *"
timezone: "UTC"
format: "json"
destinationType: "webhook"
url: "https://api.example.com/webhook"
conditionType: "RESULTS_PRESENT"
conditionQueryMapKey: "1"
queryIdentifierMapKey: "1"
overrideRowLimit: true
maxRowLimit: 1000
'Test delivery':
summary: Test delivery
value:
identifier: "dashboard-abc123"
name: "Test Delivery"
schedule: "0 0 1 1 ? 2099"
timezone: "UTC"
format: "pdf"
destinationType: "email"
recipients:
- "iamagoodblob@blobsrus.com"
subject: "Test Delivery"
testNow: true
responses:
'200':
description: Schedule created successfully
content:
application/json:
schema:
type: object
properties:
id:
type: string
format: uuid
description: The ID of the created schedule.
message:
type: string
example: "Successfully created schedule"
description: A success message.
'400':
description: |
Bad Request
Possible error messages:
- `Analyses do not support dashboards.`
- `Document does not have a dashboard`
- `schedule: Schedule is an invalid cron expression`
- `timezone: Time zone must be IANA valid.`
- `hideTitle can only be used with PDF or PNG formats`
- `Invalid filter keys found in schedule configuration: <filterKey>. Available dashboard filter keys are: <key1>, <key2>, ....`
- `Test delivery not supported for condition type RESULTS_CHANGED`
- `Print options are not supported for this format`
- `Single column layout and table expansion options are not supported for FIT_PAGE format.`
- `Must provide both a trigger query and an alert condition type`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: |
Not Found
Possible error messages:
- `Document with identifier "<dashboardId>" not found`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'405':
$ref: '#/components/responses/MethodNotAllowed'
'429':
$ref: '#/components/responses/TooManyRequests'
'500':
$ref: '#/components/responses/InternalServerError'
get:
tags:
- Schedules
summary: List schedules
description: |
Retrieves scheduled tasks. This endpoint supports filtering, sorting, and cursor-based pagination.
To retrieve the recipients for a schedule, use the [List schedule recipients](/api/schedule-recipients/list-schedule-recipients) endpoint.
security:
- bearerAuth: []
operationId: listSchedules
parameters:
- name: q
in: query
schema:
type: string
description: |
Search term for filtering schedules by name, dashboard name, or owner name (case-insensitive).
- name: status
in: query
schema:
type: string
enum: [success, error, canceled, none]
description: Filter schedules by delivery status.
- name: destination
in: query
schema:
type: string
enum: [email, slack, webhook, sftp]
description: Filter schedules by destination type.
- name: scheduleType
in: query
schema:
type: string
enum: [alert, schedule]
description: Filter by schedule type.
- name: contentType
in: query
schema:
type: string
enum: [dashboard, single tile]
description: Filter schedules by content type.
- name: sortField
in: query
schema:
type: string
default: scheduleName
enum: [scheduleName, dashboardName, ownerName, lastRun, lastRunStatus]
description: The field to sort results by.
- name: sortDirection
in: query
schema:
type: string
default: desc
enum: [asc, desc]
description: The direction to sort results.
- name: cursor
in: query
schema:
type: integer
default: 1
description: The page number for offset-based pagination.
- name: pageSize
in: query
schema:
type: integer
minimum: 1
maximum: 100
default: 20
description: The number of results to include on each page.
- name: ownerId
in: query
schema:
type: string
format: uuid
description: |
Filter schedules by the owner's user ID. Use the [List users](/api/users/list-users) endpoint to retrieve user IDs.
- name: embedEntity
in: query
schema:
type: string
description: |
Filter schedules by embed entity:
- If used as the only filter, list all schedules in the embed entity
- If used with `ownerId`, list only schedules for the specified user if they are associated with the `embedEntity`. The response will be empty if the specified `ownerId` doesn't have the entity.
- Can be combined with other filters for more specific results
- name: identifier
in: query
schema:
type: string
description: |
Filter schedules by dashboard ID. This can be retrieved by:
- **Opening the dashboard settings** - Navigate to **File > Document settings** in the dashboard and then click **Settings**. The **Identifier** field contains the dashboard ID.
- **Using the dashboard's URL** - The string after `/dashboards` is the dashboard's ID; for example: `https://myorg.omniapp.co/dashboards/12db1a0a`
responses:
'200':
description: Paginated schedule list
content:
application/json:
schema:
type: object
properties:
pageInfo:
$ref: '#/components/schemas/PageInfo'
records:
type: array
description: List of schedule records.
items:
type: object
properties:
id:
type: string
format: uuid
description: The schedule ID.
schedule:
type: string
description: The cron expression for the schedule.
disabledAt:
type: string
format: date-time
nullable: true
description: Timestamp when the schedule was paused, if applicable.
name:
type: string
description: The name of the schedule.
timezone:
type: string
description: The IANA timezone for the schedule.
identifier:
type: string
description: The ID of the dashboard associated with the schedule.
dashboardName:
type: string
description: The name of the dashboard associated with the schedule.
ownerName:
type: string
description: The name of the schedule owner.
lastCompletedAt:
type: string
format: date-time
nullable: true
description: Timestamp of the last completed run.
lastStatus:
type: string
nullable: true
description: Status of the last run (e.g., `COMPLETE`, `ERROR_DELIVERED`).
destinationType:
type: string
description: The destination type (e.g., `email`, `webhook`, `sftp`, `slack`).
format:
type: string
description: The output format of the schedule. (e.g., `CSV`, `JSON`)
recipientCount:
type: integer
description: Number of recipients. Returns `-1` for webhook destinations.
content:
type: string
description: Content type (`dashboard` or `single tile`).
slackRecipientType:
type: string
nullable: true
description: Slack recipient type, if applicable.
systemDisabledAt:
type: string
format: date-time
nullable: true
description: Timestamp when the schedule was system-disabled, if applicable.
systemDisabledReason:
type: string
nullable: true
description: Reason for system disabling, if applicable.
alert:
type: string
nullable: true
description: Alert configuration, if applicable.
'400':
description: |
Bad Request
Possible error messages:
- `Invalid enum value`
- `ownerId: Invalid uuid`
- `Page size cannot exceed 100`
- `Invalid page number. The last valid page is <number>.`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: |
Not Found
Possible error messages:
- `User with id <id> does not exist`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'405':
$ref: '#/components/responses/MethodNotAllowed'
'429':
$ref: '#/components/responses/TooManyRequests'
/v1/schedules/{scheduleId}:
put:
tags:
- Schedules
summary: Update schedule
x-mint:
content: |
Updates the specified task. Changes to the schedule will be applied to future runs. Currently running jobs are not affected.
<Note>
Only properties included in the request will be updated. Omitted properties will retain their current values.
</Note>
security:
- bearerAuth: []
operationId: updateSchedule
parameters:
- name: scheduleId
in: path
required: true
schema:
type: string
format: uuid
description: |
The ID of the schedule. To find a schedule's ID:
1. Navigate to the dashboard of a document.
2. Click **File > Deliveries & Alerts**.
3. Next to a schedule, click **Edit**.
The schedule's ID is in the page's URL, after `/schedules/`. For example, the schedule ID in this URL is `123e4567-e89b-12d3-a456-426614174000`:
```markdown
https://blobsrus.omniapp.co/dashboards/e23ebaa0/schedules/123e4567-e89b-12d3-a456-426614174000
requestBody:
content:
application/json:
schema:
type: object
description: |
Same properties as [Create schedule](/api/schedules/create-schedule). All properties are optional - only included properties will be updated.
example:
name: "Weekly Sales Report"
schedule: "0 9 * * MON"
timezone: "America/New_York"
format: "pdf"
destinationType: "email"
recipients:
- "blob.ross@blobsrus.com"
subject: "Weekly Sales Dashboard"
paperFormat: "letter"
paperOrientation: "landscape"
responses:
'200':
description: Schedule updated successfully
content:
application/json:
schema:
type: object
properties:
success:
type: boolean
description: Indicates the request was successful.
scheduledTaskId:
type: string
format: uuid
description: The ID of the updated schedule.
'400':
description: |
Bad Request
Possible error messages:
- `Bad Request: scheduleId: Invalid uuid`
- `Invalid method`
- `Bad Request: name: name is required, schedule: schedule is required, timezone: timezone is required, destinationType: Invalid discriminator value. Expected email | webhook | sftp`
- `schedule: Schedule is an invalid cron expression`
- `timezone: Time zone must be IANA valid.`
- `hideTitle can only be used with PDF or PNG formats`
- `Invalid filter keys found in schedule configuration: <filterKey>. Available dashboard filter keys are: <key1>, <key2>, ....`
- `Print options are not supported for this format`
- `Single column layout and table expansion options are not supported for FIT_PAGE format.`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: |
Not Found
Possible error messages:
- `Scheduled task with id <scheduleId> does not exist`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'405':
$ref: '#/components/responses/MethodNotAllowed'
'429':
$ref: '#/components/responses/TooManyRequests'
'500':
$ref: '#/components/responses/InternalServerError'
delete:
tags:
- Schedules
summary: Delete schedule
description: Deletes a schedule.
security:
- bearerAuth: []
operationId: deleteSchedule
parameters:
- name: scheduleId
in: path
required: true
schema:
type: string
format: uuid
description: |
The ID of the schedule. To find a schedule's ID:
1. Navigate to the dashboard of a document.
2. Click **File > Deliveries & Alerts**.
3. Next to a schedule, click **Edit**.
The schedule's ID is in the page's URL, after `/schedules/`. For example, the schedule ID in this URL is `123e4567-e89b-12d3-a456-426614174000`:
```markdown
https://blobsrus.omniapp.co/dashboards/e23ebaa0/schedules/123e4567-e89b-12d3-a456-426614174000
```
responses:
'200':
description: Schedule deleted successfully
content:
application/json:
schema:
$ref: '#/components/schemas/SuccessResponse'
'400':
description: |
Bad Request
Possible error messages:
- `scheduleId: Invalid uuid`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: |
Not Found
Possible error messages:
- `Scheduled task with id <scheduleId> does not exist`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'405':
$ref: '#/components/responses/MethodNotAllowed'
'429':
$ref: '#/components/responses/TooManyRequests'
/v1/schedules/{scheduleId}/trigger:
post:
tags:
- Schedules
summary: Trigger schedule
description: Triggers the execution of a schedule on demand, outside of its regular schedule.
security:
- bearerAuth: []
operationId: triggerSchedule
parameters:
- name: scheduleId
in: path
required: true
schema:
type: string
format: uuid
description: |
The ID of the schedule. To find a schedule's ID:
1. Navigate to the dashboard of a document.
2. Click **File > Deliveries & Alerts**.
3. Next to a schedule, click **Edit**.
The schedule's ID is in the page's URL, after `/schedules/`. For example, the schedule ID in this URL is `123e4567-e89b-12d3-a456-426614174000`:
```markdown
https://blobsrus.omniapp.co/dashboards/e23ebaa0/schedules/123e4567-e89b-12d3-a456-426614174000
```
responses:
'200':
description: Schedule triggered successfully
content:
application/json:
schema:
$ref: '#/components/schemas/SuccessResponse'
'400':
description: |
Bad Request
Possible error messages:
- `Bad Request: scheduleId: Invalid uuid`
- `Invalid method`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: |
Not Found
Possible error messages:
- `Scheduled task with id <scheduleId> does not exist`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'405':
$ref: '#/components/responses/MethodNotAllowed'
'409':
description: |
409 Conflict
Possible error messages:
- `Cannot trigger schedule while another execution is in progress` - Occurs when an `EMAIL` schedule has more than 50 recipients, has `fanOut: true`, and is currently in progress
'429':
$ref: '#/components/responses/TooManyRequests'
'500':
description: |
Internal Server Error
Possible error messages:
- Various error messages related to dispatch failures
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v1/schedules/{scheduleId}/pause:
put:
tags:
- Schedules
summary: Pause schedule
description: Pauses a schedule.
security:
- bearerAuth: []
operationId: pauseSchedule
parameters:
- name: scheduleId
in: path
required: true
schema:
type: string
format: uuid
description: |
The ID of the schedule. To find a schedule's ID:
1. Navigate to the dashboard of a document.
2. Click **File > Deliveries & Alerts**.
3. Next to a schedule, click **Edit**.
The schedule's ID is in the page's URL, after `/schedules/`. For example, the schedule ID in this URL is `123e4567-e89b-12d3-a456-426614174000`:
```markdown
https://blobsrus.omniapp.co/dashboards/e23ebaa0/schedules/123e4567-e89b-12d3-a456-426614174000
```
responses:
'200':
description: Schedule paused successfully
content:
application/json:
schema:
$ref: '#/components/schemas/SuccessResponse'
'400':
description: |
Bad Request
Possible error messages:
- `Schedule is system disabled`
- `Schedule is already paused`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: |
Not Found
Possible error messages:
- `Scheduled task with id <scheduleId> does not exist`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'405':
$ref: '#/components/responses/MethodNotAllowed'
'429':
$ref: '#/components/responses/TooManyRequests'
/v1/schedules/{scheduleId}/resume:
put:
tags:
- Schedules
summary: Resume schedule
description: Resumes a schedule.
security:
- bearerAuth: []
operationId: resumeSchedule
parameters:
- name: scheduleId
in: path
required: true
schema:
type: string
format: uuid
description: |
The ID of the schedule. To find a schedule's ID:
1. Navigate to the dashboard of a document.
2. Click **File > Deliveries & Alerts**.
3. Next to a schedule, click **Edit**.
The schedule's ID is in the page's URL, after `/schedules/`. For example, the schedule ID in this URL is `123e4567-e89b-12d3-a456-426614174000`:
```markdown
https://blobsrus.omniapp.co/dashboards/e23ebaa0/schedules/123e4567-e89b-12d3-a456-426614174000
responses:
'200':
description: Schedule resumed successfully
content:
application/json:
schema:
type: object
properties:
success:
type: boolean
description: Indicates the schedule has been resumed successfully.
'400':
description: |
Bad Request
Possible error messages:
- `Schedule is system disabled`
- `Schedule is already resumed`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: |
Not Found
Possible error messages:
- `Scheduled task with id <scheduleId> does not exist`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'405':
$ref: '#/components/responses/MethodNotAllowed'
'429':
$ref: '#/components/responses/TooManyRequests'
/v1/schedules/{scheduleId}/transfer-ownership:
put:
tags:
- Schedules
summary: Transfer schedule ownership
x-mint:
content: |
Transfers ownership of a schedule from one user to another user in the same organization. New ownership will be immediate and can't be reversed using this endpoint.
How ownership transfer affects schedule execution depends on the type of destination the schedule uses, and for email destinations, whether the **Personalize delivery with the recipient's user attributes** is enabled:
| | Slack, SFTP, &amp; Webhooks | Email without personalization | Email with personalization |
|---------------------------------------------------------------------|-----------------------------|-------------------------------|----------------------------|
| **Future jobs are executed by...** | New owner | New owner | Each recipient |
| **Permissions, data access, &amp; user attributes are based on...** | New owner | New owner | Each recipient |
| **Output is generated using...** | New owner access | New owner access | Recipient access |
security:
- bearerAuth: []
operationId: transferScheduleOwnership
parameters:
- name: scheduleId
in: path
required: true
schema:
type: string
format: uuid
description: |
The ID of the schedule. To find a schedule's ID:
1. Navigate to the dashboard of a document.
2. Click **File > Deliveries & Alerts**.
3. Next to a schedule, click **Edit**.
The schedule's ID is in the page's URL, after `/schedules/`. For example, the schedule ID in this URL is `123e4567-e89b-12d3-a456-426614174000`:
```markdown
https://blobsrus.omniapp.co/dashboards/e23ebaa0/schedules/123e4567-e89b-12d3-a456-426614174000
```
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- userId
properties:
userId:
type: string
format: uuid
description: |
The ID of the user to transfer schedule ownership to. Use the [List users](/api/users/list-users) endpoint to retrieve user IDs.
The new owner must:
- Be a member of the same organization
- Not be the current owner
- Have permission to view the dashboard associated with the schedule
responses:
'200':
description: Ownership transferred successfully
content:
application/json:
schema:
$ref: '#/components/schemas/SuccessResponse'
'400':
description: |
Bad Request
Possible error messages:
- `userId: Invalid uuid`
- `userId is a required field`
- `User already owns the schedule`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'403':
description: |
Forbidden
Possible error messages:
- `New owner does not have permission to view the dashboard`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: |
Not Found
Possible error messages:
- `Scheduled task with id <scheduleId> does not exist`
- `New owner is not a member of the organization`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'405':
$ref: '#/components/responses/MethodNotAllowed'
'429':
$ref: '#/components/responses/TooManyRequests'
/v1/schedules/{scheduleId}/recipients:
get:
tags:
- Schedule recipients
summary: List schedule recipients
description: |
Retrieves the list of recipients for the specified schedule. Successful responses will include the recipients and details about the schedule's destination type.
To retrieve a schedule's full configuration, use the [List schedules](/api/schedules#list-schedules) endpoint.
security:
- bearerAuth: []
operationId: listScheduleRecipients
parameters:
- name: scheduleId
in: path
required: true
schema:
type: string
format: uuid
description: |
The ID of the schedule. To find a schedule's ID:
1. Navigate to the dashboard of a document.
2. Click **File > Deliveries & Alerts**.
3. Next to a schedule, click **Edit**.
The schedule's ID is in the page's URL, after `/schedules/`. For example, the schedule ID in this URL is `123e4567-e89b-12d3-a456-426614174000`:
```markdown
https://blobsrus.omniapp.co/dashboards/e23ebaa0/schedules/123e4567-e89b-12d3-a456-426614174000
responses:
'200':
description: |
Successful requests return a `200 OK` status and response body specific to the schedule's destination type.
content:
application/json:
schema:
oneOf:
- $ref: '#/components/schemas/ScheduleRecipientsEmail'
- $ref: '#/components/schemas/ScheduleRecipientsSftp'
- $ref: '#/components/schemas/ScheduleRecipientsSlack'
- $ref: '#/components/schemas/ScheduleRecipientsWebhook'
examples:
email:
summary: Email destination
value:
recipients:
- email: "blobby@blobsrus.com"
emailOnly: false
id: "3e7c4152-cdac-42ce-8749-fe3b81d5d8ab"
name: "blobby@blobsrus.com"
type: "email"
sftp:
summary: SFTP destination
value:
type: "sftp"
address: "sftp.example.com"
port: 22
username: "username"
slackChannel:
summary: Slack destination with channel recipients
value:
type: "slack"
recipients:
- recipientType: "channel"
slackId: "C123456789"
slackUser:
summary: Slack destination with user recipients
value:
type: "slack"
recipients:
- recipientType: "users"
slackId: "U123456789"
webhook:
summary: Webhook destination
value:
type: "webhook"
url: "https://example.com/webhook"
'400':
description: |
Bad Request. Possible error messages include:
- `Bad Request: scheduleId: Invalid uuid`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: |
Not Found. Possible error messages include:
- `Scheduled task with id {scheduleId} does not exist`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'405':
$ref: '#/components/responses/MethodNotAllowed'
'429':
$ref: '#/components/responses/TooManyRequests'
/v1/schedules/{scheduleId}/add-recipients:
put:
tags:
- Schedule recipients
summary: Add schedule recipients
x-mint:
content: |
Adds one or more recipients to an existing scheduled email task. Recipients can be specified by email address or user ID.
<Note>
This endpoint only works with schedules that have [email destinations](/share/deliveries/email).
</Note>
security:
- bearerAuth: []
operationId: addScheduleRecipients
parameters:
- name: scheduleId
in: path
required: true
schema:
type: string
format: uuid
description: |
The ID of the schedule to add recipients to. To find a schedule's ID:
1. Navigate to the dashboard of a document.
2. Click **File > Deliveries & Alerts**.
3. Next to a schedule, click **Edit**.
The schedule's ID is in the page's URL, after `/schedules/`. For example, the schedule ID in this URL is `123e4567-e89b-12d3-a456-426614174000`:
```markdown
https://blobsrus.omniapp.co/dashboards/e23ebaa0/schedules/123e4567-e89b-12d3-a456-426614174000
requestBody:
content:
application/json:
schema:
type: object
properties:
emails:
type: array
items:
type: string
format: email
description: |
**At least one email or user ID must be provided.** Array of email addresses to add as recipients.
userIds:
type: array
items:
type: string
format: uuid
description: |
**At least one email or user ID must be provided.** Array of user UUIDs to add as recipients. Use the [List users](/api/users#list-users) and [List embed users](/api/users#list-embed-users) endpoints to retrieve user IDs.
responses:
'200':
description: Recipients added successfully.
content:
application/json:
schema:
type: object
properties:
addedRecipientsCount:
type: integer
description: The number of recipients added to the schedule.
success:
type: boolean
description: Indicates whether the operation was successful.
example:
addedRecipientsCount: 2
success: true
'400':
description: |
Bad Request. Possible error messages include:
- `userIds: Invalid uuid`
- `emails: Invalid email address`
- `Please provide either valid email addresses, valid user IDs, or both`
- `At least one recipient must be provided`
- `{parameter}: Array must contain at least 1 element(s)`
- `Invalid recipient(s): The following members do not exist or do not have access to this organization: {userId}`
- `Cannot add recipients to destination type {destinationType}`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: |
Not Found. Possible error messages include:
- `Scheduled task with id {scheduleId} does not exist`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'405':
$ref: '#/components/responses/MethodNotAllowed'
'429':
$ref: '#/components/responses/TooManyRequests'
/v1/schedules/{scheduleId}/remove-recipients:
put:
tags:
- Schedule recipients
summary: Remove schedule recipients
x-mint:
content: |
Removes one or more recipients from an existing scheduled email task. Recipients can be specified by email address or user ID.
<Note>This endpoint only works with schedules that have [email destinations](/share/deliveries/email).</Note>
security:
- bearerAuth: []
operationId: removeScheduleRecipients
parameters:
- name: scheduleId
in: path
required: true
schema:
type: string
format: uuid
description: |
The ID of the schedule to remove recipients from. To find a schedule's ID:
1. Navigate to the dashboard of a document.
2. Click **File > Deliveries & Alerts**.
3. Next to a schedule, click **Edit**.
The schedule's ID is in the page's URL, after `/schedules/`. For example, the schedule ID in this URL is `123e4567-e89b-12d3-a456-426614174000`:
```markdown
https://blobsrus.omniapp.co/dashboards/e23ebaa0/schedules/123e4567-e89b-12d3-a456-426614174000
requestBody:
content:
application/json:
schema:
type: object
properties:
emails:
type: array
items:
type: string
format: email
description: |
**At least one email or user ID must be provided.** Array of recipient email addresses to remove from the scheduled task.
userIds:
type: array
items:
type: string
format: uuid
description: |
**At least one email or user ID must be provided.** Array of recipient user UUIDs to remove from the scheduled task. Use the [List users](/api/users#list-users) and [List embed users](/api/users#list-embed-users) endpoints to retrieve user IDs.
responses:
'200':
description: Recipients removed successfully.
content:
application/json:
schema:
type: object
properties:
removedRecipientsCount:
type: integer
description: The number of recipients removed from the schedule.
success:
type: boolean
description: Indicates whether the operation was successful.
example:
removedRecipientsCount: 2
success: true
'400':
description: |
Bad Request. Possible error messages include:
- `Bad Request: userIds: Invalid uuid`
- `Bad Request: emails: Invalid email address`
- `Please provide either valid email addresses, valid user IDs, or both`
- `At least one recipient must be provided`
- `{parameter}: Array must contain at least 1 element(s)`
- `Invalid recipient(s): The following members do not exist or do not have access to this organization: {userId}`
- `Cannot change recipients on a scheduled task destination of type {destinationType}`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: |
Not Found. Possible error messages include:
- `Scheduled task with id {scheduleId} does not exist`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'405':
$ref: '#/components/responses/MethodNotAllowed'
'429':
$ref: '#/components/responses/TooManyRequests'
/v1/users/email-only:
get:
tags:
- Users
summary: List email-only users
description: Retrieve email-only users with their user attributes, with support for cursor-based pagination and filtering
security:
- bearerAuth: []
operationId: listEmailOnlyUsers
parameters:
- name: email
in: query
schema:
type: string
description: Filter users by email (partial match, case-insensitive)
- name: cursor
in: query
schema:
type: string
description: Pagination cursor from previous response
- name: pageSize
in: query
schema:
type: integer
default: 20
maximum: 20
description: Results per page
- name: sortDirection
in: query
schema:
type: string
enum: [asc, desc]
default: desc
description: |
Sort order:
- `asc` - Ascending order (A-Z)
- `desc` - Descending order (Z-A)
responses:
'200':
description: Paginated list of email-only users
content:
application/json:
schema:
type: object
properties:
pageInfo:
$ref: '#/components/schemas/PageInfo'
records:
type: array
items:
type: object
properties:
email:
type: string
format: email
description: User's email address
user_id:
type: string
format: uuid
description: User's membership ID
user_attributes:
type: object
description: Key-value map of user attributes, including system attributes like `omni_user_email`, `omni_user_name`, `omni_user_id`, `omni_is_org_admin`, plus any custom attributes.
additionalProperties:
type: string
example:
pageInfo:
hasNextPage: true
nextCursor: "bob@example.com"
pageSize: 20
totalRecords: 50
records:
- email: "alice@example.com"
user_id: "550e8400-e29b-41d4-a716-446655440000"
user_attributes:
omni_user_email: "alice@example.com"
omni_user_name: "alice@example.com"
omni_user_id: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
omni_is_org_admin: "false"
omni_user_timezone: "America/New_York"
department: "Engineering"
- email: "bob@example.com"
user_id: "550e8400-e29b-41d4-a716-446655440001"
user_attributes:
omni_user_email: "bob@example.com"
omni_user_name: "bob@example.com"
omni_user_id: "b2c3d4e5-f6a7-8901-bcde-f23456789012"
omni_is_org_admin: "false"
omni_user_timezone: "Europe/London"
'400':
$ref: '#/components/responses/BadRequest'
'401':
description: Unauthorized - Invalid or missing API key
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'403':
$ref: '#/components/responses/Forbidden'
'500':
$ref: '#/components/responses/InternalServerError'
post:
tags:
- Schedule recipients
summary: Manage email-only user
x-mint:
content: |
Creates or updates an [email-only user](/share/deliveries/email). An email-only user is a recipient of a delivery that isn't associated with an Omni account.
If Omni matches the provided email to an existing email-only user, the user will be updated according to the `userAttributes` in the request body.
<Tip>
Need to include multiple email-only users? Use the [Create or update multiple email-only users](/api/schedule-recipients/bulk-manage-email-only-users) endpoint.
</Tip>
security:
- orgApiKey: []
operationId: manageEmailOnlyUser
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- email
properties:
email:
type: string
format: email
description: The user's email address.
userAttributes:
type: object
description: |
An object defining the user's [user attributes](/administration/users/attributes). Attributes are represented as key/value pairs, where the keys map to the IDs of user attributes (the **Reference** column in the **User attributes** page) defined in Omni.
When providing user attributes, note that:
- `omni_user_timezone` is the only supported system attribute
- **Values must match the user attribute's specified type**. For example, `number` attribute values must be numbers such as `1`, `10`, etc.
- **Multi-value attributes should be provided using arrays**. For example: `["US","EU"]` or `[1, 10]`
To unset attributes:
- `null` values
- `""` - Empty strings for string attributes
- `[]` - Empty arrays for multi-value attributes
examples:
basic:
summary: Basic request
value:
email: "iamagoodblob@blobsrus.co"
withAttributes:
summary: Set user attributes
value:
email: "iamagoodblob@blobsrus.co"
userAttributes:
region: ["US", "EU"]
omni_user_timezone: "America/New_York"
is_admin: 0
is_sales_team: 1
unsetAttributes:
summary: Unset user attributes
value:
email: "iamagoodblob@blobsrus.co"
userAttributes:
is_admin: null
is_sales_team: ""
region: []
responses:
'200':
description: Email-only user created or updated successfully.
content:
application/json:
schema:
type: object
properties:
email:
type: string
format: email
description: The email address of the created or updated user.
userId:
type: string
format: uuid
description: The unique identifier of the email-only user.
example:
email: "iamagoodblob@blobsrus.co"
userId: "9e8719d9-276a-4964-9395-a493189a247c"
'400':
description: |
Bad Request. Possible error messages include:
- `Invalid JSON`
- `email: email is required`
- `email: Invalid email address`
- `The provided user attributes: "<attribute>" do not match the names of existing user attributes.`
- `User Attribute <attribute> is type number, but passed-in value <value> is not a number.`
- `The timezone <invalidTimezone> is not supported. Please see the connection page or user profile page for the list of valid timezones. Use e.g. "America/New_York" instead of "EST"`
- `User Attribute <attribute> has multiple values enabled, but the passed-in value is not an array. If passing a single value for a user attribute with multiple values enabled, please wrap the value in an array [x].`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'405':
$ref: '#/components/responses/MethodNotAllowed'
'429':
$ref: '#/components/responses/TooManyRequests'
/v1/users/email-only/bulk:
post:
tags:
- Schedule recipients
summary: Bulk manage email-only users
description: |
Creates or updates up to 20 [email-only users](/share/deliveries/email). An email-only user is a recipient of a delivery that isn't associated with an Omni account.
If Omni matches a provided email to an existing email-only user, the user will be updated according to the `userAttributes` in the request body.
security:
- orgApiKey: []
operationId: bulkManageEmailOnlyUsers
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- users
properties:
users:
type: array
maxItems: 20
description: |
An array of user objects, which includes `email` and `userAttributes` properties. Up to 20 users can be included in each request.
items:
type: object
required:
- email
properties:
email:
type: string
format: email
description: The user's email address.
userAttributes:
type: object
description: |
An object defining the user's [user attributes](/administration/users/attributes). Attributes are represented as key/value pairs, where the keys map to the IDs of user attributes (the **Reference** column in the **User attributes** page) defined in Omni.
When providing user attributes, note that:
- `omni_user_timezone` is the only supported system attribute
- **Values must match the user attribute's specified type**. For example, `number` attribute values must be numbers such as `1`, `10`, etc.
- **Multi-value attributes should be provided using arrays**. For example: `["US","EU"]` or `[1, 10]`
To unset attributes:
- `null` values
- `""` - Empty strings for string attributes
- `[]` - Empty arrays for multi-value attributes
examples:
basic:
summary: Basic request
value:
users:
- email: "iamagoodblob@blobsrus.co"
- email: "blobmanager@blobsrus.co"
withAttributes:
summary: Set user attributes
value:
users:
- email: "iamagoodblob@blobsrus.co"
userAttributes:
region: ["US", "EU"]
omni_user_timezone: "America/New_York"
is_admin: 0
is_sales_team: 1
- email: "blobmanager@blobsrus.co"
userAttributes:
region: ["US"]
omni_user_timezone: "America/New_York"
is_admin: 1
is_sales_team: 0
unsetAttributes:
summary: Unset user attributes
value:
users:
- email: "iamagoodblob@blobsrus.co"
userAttributes:
region: []
omni_user_timezone: ""
is_admin: null
responses:
'200':
description: Email-only users created or updated successfully.
content:
application/json:
schema:
type: object
properties:
results:
type: array
description: An array of created or updated email-only users.
items:
type: object
properties:
email:
type: string
format: email
description: The email address of the created or updated user.
userId:
type: string
format: uuid
description: The unique identifier of the email-only user.
example:
results:
- email: "iamagoodblob@blobsrus.co"
userId: "1e23dadc-961b-4a21-b36b-17168130fc3f"
- email: "blobmanager@blobsrus.co"
userId: "e9d19f71-0b59-4f8e-8343-a75d30576d28"
'400':
description: |
Bad Request. Possible error messages include:
- `Invalid JSON`
- `users: Maximum of 20 users can be processed in a single request`
- `users: users is required`
- `email: email is required`
- `email: Invalid email address`
- `The provided user attributes: "<attribute>" do not match the names of existing user attributes.`
- `User Attribute <attribute> is type number, but passed-in value <value> is not a number.`
- `The timezone <invalidTimezone> is not supported. Please see the connection page or user profile page for the list of valid timezones. Use e.g. "America/New_York" instead of "EST"`
- `User Attribute <attribute> has multiple values enabled, but the passed-in value is not an array. If passing a single value for a user attribute with multiple values enabled, please wrap the value in an array [x].`
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'405':
$ref: '#/components/responses/MethodNotAllowed'
'429':
$ref: '#/components/responses/TooManyRequests'
/scim/v2/users:
post:
tags:
- Users
summary: Create user
description: Creates a user. To manage model and connection role assignments for users, see the [User model role APIs](/api/user-model-roles).
security:
- orgApiKey: []
operationId: createUser
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- displayName
- userName
properties:
displayName:
type: string
description: The user's display name
example: Blob Ross
userName:
type: string
format: email
description: The user's email address
example: blob.ross@blobsrus.com
urn:omni:params:1.0:UserAttribute:
type: object
description: |
[User attributes](/administration/users/attributes) as key/value pairs, where keys map to the IDs of user attributes defined in Omni. This is the **Reference** column in the **User attributes** page.
example:
good_blob: true
responses:
'201':
description: User created successfully
content:
application/json:
schema:
$ref: '#/components/schemas/ScimUser'
example:
active: true
displayName: Blob Ross
emails:
- primary: true
value: blob.ross@blobsrus.co
groups: []
id: 9e8719d9-276a-4964-9395-a493189a247c
meta:
created: "2024-12-03T23:13:14.109Z"
lastModified: "2024-12-03T23:13:14.109Z"
resourceType: User
schemas:
- "urn:ietf:params:scim:schemas:core:2.0:User"
userName: blob.ross@blobsrus.co
urn:omni:params:1.0:UserAttribute:
good_blob: "yes"
'429':
$ref: '#/components/responses/TooManyRequests'
get:
tags:
- Users
summary: List users
description: |
Returns a list of users, sorted by creation time. Use the [List embed users](/api/list-embed-users) endpoint to retrieve embed users.
security:
- orgApiKey: []
operationId: listUsers
parameters:
- name: filter
in: query
schema:
type: string
description: |
Filter to return a specific user using the `userName` field. Format: `userName eq "<email>"`.
Usernames should be URL-encoded when passed as filters. For example, `userName eq "user@example.com"` will become `userName%20eq%20%22user%40example.com%22` when encoded.
example: userName eq "blob.ross@blobsrus.co"
- name: count
in: query
schema:
type: integer
default: 100
description: The number of users to return per page
example: 50
- name: startIndex
in: query
schema:
type: integer
default: 1
description: An integer index that determines the starting point of the sorted result list
example: 1
responses:
'200':
description: List of users
content:
application/json:
schema:
type: object
properties:
Resources:
type: array
description: The list of users
items:
$ref: '#/components/schemas/ScimUser'
schemas:
type: array
description: SCIM schema information for the response
items:
type: string
itemsPerPage:
type: integer
description: The number of users returned in the current page
totalResults:
type: integer
description: The total number of users matching the query
startIndex:
type: integer
description: The starting index of the current page in the result set
example:
Resources:
- active: true
displayName: Blob Ross
emails:
- primary: true
value: blob.ross@blobsrus.co
groups: []
id: 9e8719d9-276a-4964-9395-a493189a247c
meta:
created: "2024-11-04T16:01:47.015Z"
lastModified: "2024-11-04T16:05:45.356Z"
resourceType: User
schemas:
- "urn:ietf:params:scim:schemas:core:2.0:User"
- "urn:omni:params:1.0:UserAttribute"
- "urn:omni:params:scim:schemas:extension:user:2.0"
userName: blob.ross@blobsrus.co
urn:omni:params:scim:schemas:extension:user:2.0:
lastLogin: "2024-01-03T00:00:00.000Z"
itemsPerPage: 1
schemas:
- "urn:ietf:params:scim:api:messages:2.0:ListResponse"
startIndex: 1
totalResults: 1
'429':
$ref: '#/components/responses/TooManyRequests'
/scim/v2/users/{userId}:
get:
tags:
- Users
summary: Retrieve user
description: Retrieves a user using their unique ID
security:
- orgApiKey: []
operationId: getUser
parameters:
- name: userId
in: path
required: true
schema:
type: string
description: The ID of the user to be retrieved
example: 9e8719d9-276a-4964-9395-a493189a247c
responses:
'200':
description: User details
content:
application/json:
schema:
$ref: '#/components/schemas/ScimUser'
example:
active: true
displayName: Blob Ross
emails:
- primary: true
value: blob.ross@blobsrus.co
groups: []
id: 9e8719d9-276a-4964-9395-a493189a247c
meta:
created: "2024-12-03T23:13:14.109Z"
lastModified: "2024-12-03T23:13:14.109Z"
resourceType: User
schemas:
- "urn:ietf:params:scim:schemas:core:2.0:User"
- "urn:omni:params:1.0:UserAttribute"
- "urn:omni:params:scim:schemas:extension:user:2.0"
userName: blob.ross@blobsrus.co
urn:omni:params:1.0:UserAttribute:
good_blob: "yes"
urn:omni:params:scim:schemas:extension:user:2.0:
lastLogin: "2024-01-03T00:00:00.000Z"
'429':
$ref: '#/components/responses/TooManyRequests'
put:
tags:
- Users
summary: Update user
description: Updates the specified user by setting the values of the parameters provided and leaving all other properties of the user unchanged.
security:
- orgApiKey: []
operationId: updateUser
parameters:
- name: userId
in: path
required: true
schema:
type: string
description: The ID of the user to be updated
example: 9e8719d9-276a-4964-9395-a493189a247c
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- userName
properties:
displayName:
type: string
description: The user's display name
example: Blob Ross
userName:
type: string
format: email
description: The user's email address. Must match the user's existing email address and cannot be changed.
example: blob.ross@blobsrus.co
urn:omni:params:1.0:UserAttribute:
type: object
description: |
[User attributes](/administration/users/attributes) as key/value pairs, where keys map to the IDs of user attributes defined in Omni. This is the **Reference** column in the **User attributes** page.
example:
good_blob: "yes"
responses:
'200':
description: User updated successfully
content:
application/json:
schema:
$ref: '#/components/schemas/ScimUser'
example:
active: true
displayName: Blob Ross
emails:
- primary: true
value: blob.ross@blobsrus.co
groups: []
id: 9e8719d9-276a-4964-9395-a493189a247c
meta:
created: "2024-12-03T23:13:14.109Z"
lastModified: "2024-12-03T23:13:14.109Z"
resourceType: User
schemas:
- "urn:ietf:params:scim:schemas:core:2.0:User"
userName: blob.ross@blobsrus.co
urn:omni:params:1.0:UserAttribute:
good_blob: "yes"
'429':
$ref: '#/components/responses/TooManyRequests'
delete:
tags:
- Users
summary: Delete user
description: Deletes the specified user. Use the [Delete embed user](/api/delete-embed-user) endpoint to delete embed users.
security:
- orgApiKey: []
operationId: deleteUser
parameters:
- name: userId
in: path
required: true
schema:
type: string
description: The ID of the user to be deleted
example: 9e8719d9-276a-4964-9395-a493189a247c
responses:
'204':
description: User deleted successfully
'429':
$ref: '#/components/responses/TooManyRequests'
/scim/v2/embed/users:
get:
tags:
- Users
summary: List embed users
description: |
Returns a list of embed users, sorted by creation time. Use the [List users](/api/list-users) endpoint to retrieve standard users.
security:
- orgApiKey: []
operationId: listEmbeddedUsers
parameters:
- name: filter
in: query
schema:
type: string
description: |
Filter to return a specific user using the `userName` or `embedExternalId` field. Format: `<fieldName> eq "<value>"`.
Usernames should be URL-encoded when passed as filters. For example, `userName eq "user@example.com"` will become `userName%20eq%20%22user%40example.com%22` when encoded.
example: embedExternalId eq "102"
- name: count
in: query
schema:
type: integer
default: 100
description: The number of users to return
example: 50
- name: startIndex
in: query
schema:
type: integer
default: 1
description: An integer index that determines the starting point of the sorted result list
example: 1
responses:
'200':
description: List of embed users
content:
application/json:
schema:
type: object
properties:
Resources:
type: array
description: The list of embed users
items:
$ref: '#/components/schemas/ScimEmbedUser'
schemas:
type: array
description: SCIM schema information for the response
items:
type: string
itemsPerPage:
type: integer
description: The number of embed users returned in the current page
totalResults:
type: integer
description: The total number of embed users matching the query
startIndex:
type: integer
description: The starting index of the current page in the result set
example:
Resources:
- active: true
displayName: Blobby
emails:
- primary: true
value: embed-user-i_4TrNwyVTu34bZaC35VJVD3-pknp4YF7V8_Bi4TMdw@blobsrus.embed-exploreomni.co
groups:
- display: All Embed Users
value: 4GcvQ2D9
- display: Omni
value: nqGuU_uh
id: 2212aecf-a2ba-4d99-b23b-f615bc4c6522
meta:
created: "2024-09-30T20:25:01.822Z"
lastModified: "2024-09-30T20:51:47.558Z"
resourceType: User
schemas:
- "urn:ietf:params:scim:schemas:core:2.0:User"
userName: embed-user-i_4TrNwyVTu34bZaC35VJVD3-pknp4YF7V8_Bi4TMdw@blobsrus.embed-exploreomni.co
embedEmail: null
embedEntity: omni
embedExternalId: blobby-manager
itemsPerPage: 1
schemas:
- "urn:ietf:params:scim:api:messages:2.0:ListResponse"
startIndex: 1
totalResults: 1
'429':
$ref: '#/components/responses/TooManyRequests'
/scim/v2/embed/users/{userId}:
get:
tags:
- Users
summary: Retrieve embed user
description: Retrieves an embed user using their unique ID. Use the [Retrieve user](/api/retrieve-user) endpoint to retrieve standard users.
security:
- orgApiKey: []
operationId: getEmbeddedUser
parameters:
- name: userId
in: path
required: true
schema:
type: string
description: The ID of the embed user to be retrieved
example: 2212aecf-a2ba-4d99-b23b-f615bc4c6522
responses:
'200':
description: Embed user details
content:
application/json:
schema:
$ref: '#/components/schemas/ScimEmbedUser'
example:
active: true
displayName: Blobby
emails:
- primary: true
value: embed-user-i_4TrNwyVTu34bZaC35VJVD3-pknp4YF7V8_Bi4TMdw@blobsrus.embed-exploreomni.co
groups:
- display: All Embed Users
value: 4GcvQ2D9
- display: Omni
value: nqGuU_uh
id: 2212aecf-a2ba-4d99-b23b-f615bc4c6522
meta:
created: "2024-09-30T20:25:01.822Z"
lastModified: "2024-09-30T20:51:47.558Z"
resourceType: User
schemas:
- "urn:ietf:params:scim:schemas:core:2.0:User"
userName: embed-user-i_4TrNwyVTu34bZaC35VJVD3-pknp4YF7V8_Bi4TMdw@blobsrus.embed-exploreomni.co
embedEmail: null
embedEntity: omni
embedExternalId: blobby-manager
'404':
$ref: '#/components/responses/NotFound'
'429':
$ref: '#/components/responses/TooManyRequests'
delete:
tags:
- Users
summary: Delete embed user
description: Deletes the specified embed user. Use the [Delete user](/api/delete-user) endpoint to delete standard users.
security:
- orgApiKey: []
operationId: deleteEmbeddedUser
parameters:
- name: userId
in: path
required: true
schema:
type: string
description: The ID of the embed user to be deleted
example: 2212aecf-a2ba-4d99-b23b-f615bc4c6522
responses:
'204':
description: Embed user deleted successfully
'429':
$ref: '#/components/responses/TooManyRequests'
/scim/v2/groups:
post:
tags:
- User groups
summary: Create user group
description: |
Creates a [user group](/administration/users/groups). To manage model and connection role assignments for user groups, see the [User group model role APIs](/api/user-group-model-roles).
security:
- orgApiKey: []
operationId: createUserGroup
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- displayName
properties:
displayName:
type: string
description: The name of the group
example: Blob Sales
members:
type: array
description: A list of users to add as group members. Each member should be specified as an object containing a user ID.
items:
type: object
properties:
value:
type: string
description: The user's unique identifier
example:
- value: 9e8719d9-276a-4964-9395-a493189a247c
responses:
'201':
description: Group created successfully
content:
application/json:
schema:
$ref: '#/components/schemas/ScimGroup'
example:
displayName: Blob Sales
id: mEhXj6ZI
meta:
created: "2024-12-04T00:08:03.250Z"
lastModified: "2024-12-04T00:08:03.250Z"
resourceType: Group
schemas:
- "urn:ietf:params:scim:schemas:core:2.0:Group"
members:
- display: blob.ross@blobsrus.co
value: 9e8719d9-276a-4964-9395-a493189a247c
'429':
$ref: '#/components/responses/TooManyRequests'
get:
tags:
- User groups
summary: List user groups
description: Returns a list of user groups, sorted by creation time.
security:
- orgApiKey: []
operationId: listUserGroups
parameters:
- name: count
in: query
schema:
type: integer
default: 100
description: The number of groups to return
example: 50
- name: startIndex
in: query
schema:
type: integer
default: 1
description: An integer index that determines the starting point of the sorted result list
example: 1
responses:
'200':
description: List of user groups
content:
application/json:
schema:
type: object
properties:
Resources:
type: array
description: The list of user groups
items:
$ref: '#/components/schemas/ScimGroup'
schemas:
type: array
description: SCIM schema information for the response
items:
type: string
itemsPerPage:
type: integer
description: The number of groups returned in the current page
startIndex:
type: integer
description: The starting index of the current page in the result set
totalResults:
type: integer
description: The total number of groups matching the query
example:
Resources:
- displayName: Blob Sales
id: mEhXj6ZI
meta:
created: "2024-08-29T20:33:36.626Z"
lastModified: "2024-08-29T20:33:36.626Z"
resourceType: Group
schemas:
- "urn:ietf:params:scim:schemas:core:2.0:Group"
members:
- display: blob.ross@blobsrus.co
value: 9e8719d9-276a-4964-9395-a493189a247c
itemsPerPage: 1
schemas:
- "urn:ietf:params:scim:api:messages:2.0:ListResponse"
startIndex: 1
totalResults: 1
'429':
$ref: '#/components/responses/TooManyRequests'
/scim/v2/groups/{userGroupId}:
get:
tags:
- User groups
summary: Retrieve user group
description: Retrieves a user group using its unique ID.
security:
- orgApiKey: []
operationId: getUserGroup
parameters:
- name: userGroupId
in: path
required: true
schema:
type: string
description: The ID of the group to be retrieved
example: mEhXj6ZI
responses:
'200':
description: User group details
content:
application/json:
schema:
$ref: '#/components/schemas/ScimGroup'
example:
displayName: Blob Sales
id: mEhXj6ZI
meta:
created: "2024-08-29T20:33:36.626Z"
lastModified: "2024-08-29T20:33:36.626Z"
resourceType: Group
schemas:
- "urn:ietf:params:scim:schemas:core:2.0:Group"
members:
- display: blob.ross@blobsrus.co
value: 9e8719d9-276a-4964-9395-a493189a247c
'429':
$ref: '#/components/responses/TooManyRequests'
put:
tags:
- User groups
summary: Update user group
description: Updates the specified user group by setting the values of the parameters provided and leaving all other properties unchanged.
security:
- orgApiKey: []
operationId: updateUserGroup
parameters:
- name: userGroupId
in: path
required: true
schema:
type: string
description: The ID of the group to be updated
example: mEhXj6ZI
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- displayName
- members
properties:
displayName:
type: string
description: The name of the group
example: Blob SEs
members:
type: array
description: |
A list of users that defines the group membership. **Note**: This will overwrite the existing membership. Include existing members to retain their membership.
items:
type: object
properties:
display:
type: string
description: The user's email address
value:
type: string
description: The user's unique identifier
example:
- display: blob.ross@blobsrus.co
value: 9e8719d9-276a-4964-9395-a493189a247c
responses:
'200':
description: Group updated successfully
content:
application/json:
schema:
$ref: '#/components/schemas/ScimGroup'
example:
displayName: Blob SEs
id: mEhXj6ZI
meta:
created: "2024-12-04T00:08:03.250Z"
lastModified: "2024-12-04T00:20:47.346Z"
resourceType: Group
schemas:
- "urn:ietf:params:scim:schemas:core:2.0:Group"
members:
- display: blob.ross@blobsrus.co
value: 9e8719d9-276a-4964-9395-a493189a247c
'429':
$ref: '#/components/responses/TooManyRequests'
delete:
tags:
- User groups
summary: Delete user group
description: Deletes the specified user group.
security:
- orgApiKey: []
operationId: deleteUserGroup
parameters:
- name: userGroupId
in: path
required: true
schema:
type: string
description: The ID of the group to be deleted
example: mEhXj6ZI
responses:
'204':
description: Group deleted successfully
'429':
$ref: '#/components/responses/TooManyRequests'
/v1/users/{userId}/model-roles:
post:
tags:
- User model roles
summary: Assign or update user model role
description: |
Assigns or updates a model role for a user. If the user already has a role for the specified model, this endpoint will update it to the new role.
Model roles control what actions a user can perform on models and connections. To manage users, see the [User APIs](/api/users).
security:
- bearerAuth: []
operationId: assignUserModelRole
parameters:
- name: userId
in: path
required: true
schema:
type: string
format: uuid
description: The ID of the user to assign or update a model role for.
example: 9e8719d9-276a-4964-9395-a493189a247c
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- roleName
properties:
connectionId:
type: string
format: uuid
description: |
The ID of the connection that the model belongs to:
- **Required** if `modelId` is not provided
- **Optional** if `modelId` is provided, in which case it will be inferred from the model
modelId:
type: string
format: uuid
description: |
The ID of the model to assign the role for:
- **Optional** when assigning `CONNECTION_ADMIN` or custom roles with `CONNECTION_ADMIN` as the base role
- **Required** for other role types
roleName:
type: string
description: |
The role to assign. Available roles include:
- `VIEWER` - Can view the model
- `QUERIER` - Can view and query the model
- `QUERY_TOPICS` - Can query specific topics. Equivalent to **Restricted Querier**.
- `MODELER` - Can edit and model the data
- `CONNECTION_ADMIN` - Full administrative access to the connection
- `NO_ACCESS` - No access to the model
- Custom roles defined for your organization
example:
connectionId: bc1f9c9f-208d-48a2-9ae3-ff80f2c79fed
modelId: 7d3e4f5a-6b7c-8d9e-0f1a-2b3c4d5e6f7a
roleName: QUERIER
responses:
'200':
description: Model role assigned or updated successfully.
content:
application/json:
schema:
type: object
properties:
userId:
type: string
format: uuid
description: The ID of the user.
connectionId:
type: string
format: uuid
description: The ID of the connection.
modelId:
type: string
format: uuid
description: The ID of the model.
roleName:
type: string
description: The assigned role name.
example:
userId: 9e8719d9-276a-4964-9395-a493189a247c
connectionId: bc1f9c9f-208d-48a2-9ae3-ff80f2c79fed
modelId: 7d3e4f5a-6b7c-8d9e-0f1a-2b3c4d5e6f7a
roleName: QUERIER
'400':
description: |
Bad Request. Possible error messages include:
- `Invalid JSON`
- `Invalid model ID`
- `Invalid connection ID`
- `Method not allowed`
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorWithStatus'
'404':
description: |
Not Found. Possible error messages include:
- `User not found in organization`
- `Model does not exist`
- `Connection does not exist`
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorWithStatus'
'422':
description: |
Unprocessable Entity. Possible error messages include:
- `Invalid role`
- `Model does not belong to connection`
- `Only shared and shared_extension models can be assigned model roles`
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorWithStatus'
'429':
$ref: '#/components/responses/TooManyRequests'
get:
tags:
- User model roles
summary: Retrieve user model roles
description: |
Retrieves the model role assignments for a user. This includes both direct role assignments and roles inherited from user group memberships.
security:
- bearerAuth: []
operationId: getUserModelRoles
parameters:
- name: userId
in: path
required: true
schema:
type: string
format: uuid
description: The ID of the user to retrieve model roles for.
example: 9e8719d9-276a-4964-9395-a493189a247c
- name: modelId
in: query
schema:
type: string
format: uuid
description: Filter results to a specific model ID. If not provided, returns roles for all models the user has access to.
example: 7d3e4f5a-6b7c-8d9e-0f1a-2b3c4d5e6f7a
- name: connectionId
in: query
schema:
type: string
format: uuid
description: Filter results to models from a specific connection. If not provided, returns roles for all connections.
example: bc1f9c9f-208d-48a2-9ae3-ff80f2c79fed
responses:
'200':
description: User model roles retrieved successfully.
content:
application/json:
schema:
type: object
properties:
membershipId:
type: string
format: uuid
description: The ID of the user's membership in the organization.
results:
type: array
description: Array of all role assignments for the user, including direct assignments, roles inherited from user groups, and connection base roles.
items:
type: object
properties:
modelId:
type: string
format: uuid
description: The ID of the model.
connectionId:
type: string
format: uuid
description: The ID of the connection.
roleName:
type: string
description: The role name for this assignment.
baseRole:
type: string
description: The base role for this assignment.
priority:
type: integer
description: The priority of this role assignment. Higher values take precedence.
resolved:
type: boolean
description: If `true`, this is the highest priority role for the model. This is the role that will be used when determining the user's effective permissions.
from:
type: object
description: Information about where this role assignment comes from.
properties:
type:
type: string
description: |
The type of role assignment:
- `User Role` - Direct role assignment to the user
- `Group Role` - Role inherited from a user group
- `Connection Base Role` - Default role from the connection
miniUuid:
type: string
description: The short ID of the user group. Only present for `Group Role` type.
name:
type: string
description: The name of the user group. Only present for `Group Role` type.
depth:
type: integer
description: The depth of group nesting. Only present for `Group Role` type.
example:
membershipId: 9633bd79-7bdf-4773-8952-8fdd4098e51c
results:
- baseRole: MODELER
from:
type: User Role
priority: 350
resolved: true
roleName: MODELER
connectionId: 8a464dc9-1f0e-4a9e-86fa-e1e6d970157c
modelId: 5fb90312-67b1-4cca-823a-9a341d549320
- baseRole: QUERIER
from:
depth: 0
miniUuid: PgjffoEu
name: Super Group
type: Group Role
priority: 250
resolved: false
roleName: QUERIER
connectionId: 8a464dc9-1f0e-4a9e-86fa-e1e6d970157c
modelId: 5fb90312-67b1-4cca-823a-9a341d549320
- baseRole: VIEWER
from:
type: Connection Base Role
priority: 50
resolved: false
roleName: VIEWER
connectionId: 8a464dc9-1f0e-4a9e-86fa-e1e6d970157c
modelId: 5fb90312-67b1-4cca-823a-9a341d549320
'404':
description: User not found in organization.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorWithStatus'
example:
detail: User not found in organization
status: 404
'429':
$ref: '#/components/responses/TooManyRequests'
/v1/user-groups/{userGroupId}/model-roles:
post:
tags:
- User group model roles
summary: Assign or update user group model role
description: |
Assigns or updates a model role for a user group. If the user group already has a role for the specified model, this endpoint will update it to the new role. All members of the user group will inherit this role.
Model roles control what actions user group members can perform on models and connections. To manage user groups, see the [User group APIs](/api/user-groups).
security:
- bearerAuth: []
operationId: assignUserGroupModelRole
parameters:
- name: userGroupId
in: path
required: true
schema:
type: string
description: The ID of the user group to assign or update a model role for.
example: mEhXj6ZI
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- roleName
properties:
connectionId:
type: string
format: uuid
description: |
The ID of the connection that the model belongs to:
- **Required** if `modelId` is not provided
- **Optional** if `modelId` is provided, as it will be inferred from the model
modelId:
type: string
format: uuid
description: |
The ID of the model to assign the role for:
- **Optional** when assigning `CONNECTION_ADMIN` or custom roles with `CONNECTION_ADMIN` as the base role
- **Required** for other role types
roleName:
type: string
description: |
The role to assign. Available roles include:
- `VIEWER` - Can view the model
- `QUERIER` - Can view and query the model
- `QUERY_TOPICS` - Can query specific topics. Equivalent to **Restricted Querier.**
- `MODELER` - Can edit and model the data
- `CONNECTION_ADMIN` - Full administrative access to the connection
- `NO_ACCESS` - No access to the model
- Custom roles defined for your organization
example:
connectionId: bc1f9c9f-208d-48a2-9ae3-ff80f2c79fed
modelId: 7d3e4f5a-6b7c-8d9e-0f1a-2b3c4d5e6f7a
roleName: QUERIER
responses:
'200':
description: Model role assigned or updated successfully.
content:
application/json:
schema:
type: object
properties:
userGroupId:
type: string
description: The ID of the user group.
connectionId:
type: string
format: uuid
description: The ID of the connection.
modelId:
type: string
format: uuid
description: The ID of the model.
roleName:
type: string
description: The assigned role name.
example:
userGroupId: mEhXj6ZI
connectionId: bc1f9c9f-208d-48a2-9ae3-ff80f2c79fed
modelId: 7d3e4f5a-6b7c-8d9e-0f1a-2b3c4d5e6f7a
roleName: QUERIER
'400':
description: |
Bad Request. Possible error messages include:
- `Invalid JSON`
- `Invalid model ID`
- `Invalid connection ID`
- `Method not allowed`
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorWithStatus'
'404':
description: |
Not Found. Possible error messages include:
- `User group not found in organization`
- `Model does not exist`
- `Connection does not exist`
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorWithStatus'
'422':
description: |
Unprocessable Entity. Possible error messages include:
- `Invalid role`
- `Model does not belong to connection`
- `Only shared and shared_extension models can be assigned model roles`
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorWithStatus'
'429':
$ref: '#/components/responses/TooManyRequests'
get:
tags:
- User group model roles
summary: Retrieve user group model roles
description: |
Retrieves the model role assignments for a user group.
security:
- bearerAuth: []
operationId: getUserGroupModelRoles
parameters:
- name: userGroupId
in: path
required: true
schema:
type: string
description: The ID of the user group to retrieve model roles for.
example: mEhXj6ZI
- name: modelId
in: query
schema:
type: string
format: uuid
description: Filter results to a specific model ID. If not provided, returns roles for all models the user group has access to.
example: 7d3e4f5a-6b7c-8d9e-0f1a-2b3c4d5e6f7a
- name: connectionId
in: query
schema:
type: string
format: uuid
description: Filter results to models from a specific connection. If not provided, returns roles for all connections.
example: bc1f9c9f-208d-48a2-9ae3-ff80f2c79fed
responses:
'200':
description: User group model roles retrieved successfully.
content:
application/json:
schema:
type: object
properties:
userGroupId:
type: string
description: The ID of the user group.
results:
type: array
description: Array of role assignments for the user group.
items:
type: object
properties:
modelId:
type: string
format: uuid
description: The ID of the model.
connectionId:
type: string
format: uuid
description: The ID of the connection.
roleName:
type: string
description: The role assigned to the user group for this model.
baseRole:
type: string
description: The base role assigned to the user group.
example:
userGroupId: mEhXj6ZI
results:
- baseRole: QUERIER
roleName: QUERIER
connectionId: bc1f9c9f-208d-48a2-9ae3-ff80f2c79fed
modelId: 7d3e4f5a-6b7c-8d9e-0f1a-2b3c4d5e6f7a
'404':
description: User group not found in organization.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorWithStatus'
example:
detail: User group not found in organization
status: 404
'429':
$ref: '#/components/responses/TooManyRequests'
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
description: |
Can be either an [Organization API Key](/api/authentication#organization-api-keys) or [Personal Access Token (PAT)](/api/authentication#personal-access-tokens-pat).
Include in the `Authorization` header as: `Bearer YOUR_TOKEN`
orgApiKey:
type: http
scheme: bearer
bearerFormat: JWT
description: |
Requires an [Organization API Key](/api/authentication#organization-api-keys). Personal Access Tokens (PATs) are not supported for this endpoint.
Include in the `Authorization` header as: `Bearer ORGANIZATION_API_KEY`
parameters:
sortDirection:
name: sortDirection
in: query
schema:
type: string
enum: [asc, desc]
description: |
Direction for sorting:
- `asc` - Ascending order (A-Z, 0-9)
- `desc` - Descending order (Z-A, 9-0)
schemas:
Dialect:
type: string
description: |
The database dialect.
enum:
- athena
- bigquery
- clickhouse
- databricks
- exasol
- mariadb
- motherduck
- mssql
- mysql
- postgres
- redshift
- snowflake
- starrocks
- trino
SuccessResponse:
type: object
properties:
success:
type: boolean
example: true
SchemaRefreshSchedule:
type: object
properties:
scheduleId:
type: string
format: uuid
description: The unique identifier of the schema refresh schedule
connectionId:
type: string
format: uuid
description: The unique identifier of the connection this schedule belongs to
schedule:
type: string
description: |
A 6-field cron expression in AWS EventBridge format defining when the schema refresh should run.
Format: `minute hour day-of-month month day-of-week year`
timezone:
type: string
description: The IANA timezone identifier for when the schedule should run
description:
type: string
description: A human-readable description of the schedule, automatically generated from the cron expression and timezone
createdAt:
type: string
format: date-time
description: The timestamp when the schedule was created
updatedAt:
type: string
format: date-time
description: The timestamp when the schedule was last updated
disabledAt:
type: string
format: date-time
nullable: true
description: The timestamp when the schedule was disabled, or `null` if active
Error:
type: object
properties:
error:
type: string
description: HTTP response code for the error
example: "<response_code>"
message:
type: string
description: Detailed error description
example: "<error_reason>"
ErrorWithStatus:
type: object
properties:
detail:
type: string
description: Detailed error description
example: "<error_reason>"
status:
type: integer
description: HTTP status code
example: 400
ScheduleRecipientsEmail:
type: object
description: Response for schedules with email destinations.
properties:
type:
type: string
enum: [email]
description: The destination type.
recipients:
type: array
items:
type: object
properties:
email:
type: string
format: email
description: The recipient's email address.
emailOnly:
type: boolean
description: Indicates whether the recipient is an email-only user.
id:
type: string
format: uuid
description: The recipient's unique identifier.
name:
type: string
description: The recipient's name.
ScheduleRecipientsSftp:
type: object
description: Response for schedules with SFTP destinations.
properties:
type:
type: string
enum: [sftp]
description: The destination type.
address:
type: string
description: The SFTP server address.
port:
type: integer
description: The SFTP server port.
username:
type: string
description: The SFTP username.
ScheduleRecipientsSlack:
type: object
description: Response for schedules with Slack destinations.
properties:
type:
type: string
enum: [slack]
description: The destination type.
recipients:
type: array
items:
type: object
properties:
recipientType:
type: string
enum: [channel, users]
description: |
The type of Slack recipient:
- `channel` - A Slack channel
- `users` - A Slack user
slackId:
type: string
description: The Slack channel or user ID.
ScheduleRecipientsWebhook:
type: object
description: Response for schedules with webhook destinations.
properties:
type:
type: string
enum: [webhook]
description: The destination type.
url:
type: string
format: uri
description: The webhook URL.
DashboardFiltersResponse:
type: object
properties:
identifier:
type: string
description: The dashboard identifier
filters:
type: object
description: Map of filter ID to filter configuration
additionalProperties:
$ref: '#/components/schemas/DashboardFilter'
controls:
type: array
description: Array of control configurations
items:
$ref: '#/components/schemas/DashboardControl'
filterOrder:
type: array
description: Ordered list of filter and control IDs for display
items:
type: string
DashboardFilter:
type: object
description: |
Filter configuration.
properties:
type:
type: string
description: |
The filter data type.
- `string`: Text-based filters (equals, contains, etc.)
- `number`: Numeric filters (equals, between, etc.)
- `date`: Date range filters
- `boolean`: True/false filters
- `null`: Null check filters
- `by_query`: Query-based dynamic filters
- `user_attribute`: Filters based on user attributes
- `composite`: Combined filters
enum:
- string
- number
- date
- boolean
- "null"
- by_query
- user_attribute
- composite
kind:
type: string
description: The filter operation kind (e.g., `EQUALS`, `WITHIN_RANGE`)
values:
type: array
description: Default values for string/number filters
items:
type: string
left_side:
type: string
description: Start value for date range filters
right_side:
type: string
description: End value for date range filters
label:
type: string
description: Display label
description:
type: string
description: Help text description
required:
type: boolean
description: Whether the filter is required
hidden:
type: boolean
description: Whether the filter is hidden
DashboardControl:
type: object
description: |
Control configuration.
properties:
id:
type: string
description: Control identifier
type:
type: string
description: |
The control type:
- `FIELD_SELECTION`: Single field selector dropdown
- `MULTI_FIELD_SELECTION`: Parent control for grouping child controls
- `FIELD_PICKER`: Multi-select field picker
- `PERIOD_OVER_PERIOD`: Time comparison control
enum:
- FIELD_SELECTION
- MULTI_FIELD_SELECTION
- FIELD_PICKER
- PERIOD_OVER_PERIOD
kind:
type: string
description: |
The control kind, ex: `FIELD`
label:
type: string
description: Display label
description:
type: string
description: Help text description
hidden:
type: boolean
description: Whether the control is hidden
field:
type: string
description: |
**Applicable to `FIELD_SELECTION` controls.** The currently selected field.
options:
type: array
description: Available options for field selection
items:
type: object
properties:
label:
type: string
description: Option display label
value:
type: string
description: Option value
DashboardFiltersUpdateRequest:
type: object
description: Request body for updating dashboard filters and controls. At least one of `filters`, `controls`, or `filterOrder` must be provided with at least one entry.
properties:
clearExistingDraft:
type: boolean
default: false
description: When `true`, discards any existing draft before applying updates
filters:
type: object
description: Map of filter ID to partial update
additionalProperties:
$ref: '#/components/schemas/DashboardFilterUpdate'
controls:
type: object
description: Map of control ID to partial update
additionalProperties:
$ref: '#/components/schemas/DashboardControlUpdate'
filterOrder:
type: array
description: New display order (filter and control IDs)
items:
type: string
DashboardFilterUpdate:
type: object
description: Partial update for a dashboard filter
properties:
values:
type: array
description: New default values for string/number filters
items:
type: string
left_side:
type: string
description: New start value for date filters
right_side:
type: string
description: New end value for date filters
label:
type: string
description: Display label
description:
type: string
description: Help text description
required:
type: boolean
description: Whether the filter is required
hidden:
type: boolean
description: Whether to hide the filter
DashboardControlUpdate:
type: object
description: Partial update for a dashboard control
properties:
label:
type: string
description: Display label
description:
type: string
description: Help text description
hidden:
type: boolean
description: Whether to hide the control
PageInfo:
type: object
description: Pagination information for paginated responses.
properties:
hasNextPage:
type: boolean
description: Indicates if there are more records available.
nextCursor:
type: string
nullable: true
description: Cursor for the next page of results. `null` if no more results.
pageSize:
type: integer
description: Number of records per page.
totalRecords:
type: integer
description: Total number of records matching the query.
PaginatedResponse:
type: object
properties:
records:
type: array
items:
type: object
pageInfo:
$ref: '#/components/schemas/PageInfo'
Connection:
type: object
properties:
id:
type: string
format: uuid
example: "c0f12353-4817-4398-bcc0-d501e6dd2f64"
name:
type: string
example: "Production Database"
dialect:
type: string
example: "postgres"
database:
type: string
example: "prod_db"
baseRole:
type: string
example: "NO_ACCESS"
deletedAt:
type: string
format: date-time
example: null
userAttributeNameForConnectionEnvironments:
type: string
example: "environment"
userAttributeValuesForDefaultEnvironment:
type: string
branchConnectionEnvironmentOverridesUserAttr:
type: boolean
example: "false"
environmentConnectionSwitchesSchemaModel:
type: boolean
example: "false"
defaultSchema:
type: string
example: "public"
Folder:
type: object
description: Represents a folder in Omni.
properties:
id:
type: string
format: uuid
description: Unique identifier for the folder.
name:
type: string
description: Display name of the folder.
path:
type: string
description: Full path to the folder.
scope:
type: string
enum: [organization, restricted]
description: |
Visibility scope of the folder.
- `organization` - Organization-wide access
- `restricted` - Limited access
owner:
type: object
description: Information about the folder owner.
properties:
id:
type: string
description: ID of the folder owner.
name:
type: string
description: Display name of the owner.
labels:
type: array
items:
type: string
description: List of labels associated with the folder. Only included when requested via the `include` parameter.
_count:
type: object
description: Contains count information. Only included when requested via the `include` parameter.
properties:
documents:
type: integer
description: Number of documents contained in the folder.
favorites:
type: integer
description: Number of users who favorited this folder.
createdAt:
type: string
format: date-time
description: Timestamp when the folder was created.
updatedAt:
type: string
format: date-time
description: Timestamp when the folder was last updated.
Label:
type: object
description: A label for organizing and categorizing documents and folders
properties:
name:
type: string
description: |
The label name (2-25 characters).
Names are case-insensitive: `"Production"` and `"production"` are considered the same.
example: "Production"
verified:
type: boolean
description: Whether the label is verified/curated
example: true
homepage:
type: boolean
description: Whether the label appears on the organization homepage
example: false
usage_count:
type: integer
description: Total number of documents and folders using this label
example: 12
Model:
type: object
properties:
id:
type: string
format: uuid
description: ID of the model.
baseModelId:
type: string
format: uuid
nullable: true
description: ID of the base model, if applicable.
connectionId:
type: string
format: uuid
nullable: true
description: ID of the connection the model is based on.
modelKind:
type: string
nullable: true
description: The type of model.
name:
type: string
nullable: true
description: The name of the model.
createdAt:
type: string
format: date-time
description: The time the model was created.
updatedAt:
type: string
format: date-time
description: The time the model was last updated.
deletedAt:
type: string
format: date-time
nullable: true
description: The time the model was deleted, if applicable.
ModelGitConfig:
type: object
properties:
baseBranch:
type: string
description: The target branch for Omni pull requests.
example: "main"
branchPerPullRequest:
type: boolean
description: If `true`, all pull requests will create a branch in Omni, even those created outside of the tool.
example: false
gitFollower:
type: boolean
description: If `true`, the shared model is read-only and can only be updated by merging pull requests to the base branch.
example: false
gitServiceProvider:
type: string
enum: [github, gitlab, azure_devops, bitbucket]
description: |
The git provider type.
- `github` - GitHub
- `gitlab` - GitLab
- `azure_devops` - Azure DevOps
- `bitbucket` - Bitbucket
example: "github"
modelPath:
type: string
nullable: true
description: Path to model files in the repository.
example: "omni/blobs_r_us"
publicKey:
type: string
description: SSH public key for repository access (deploy key).
example: "ssh-ed25519 AAAA..."
requirePullRequest:
type: string
enum: [always, users-only, never]
description: |
Controls when pull requests are required for changes:
- `always` - Required for all changes
- `users-only` - Required only for user-initiated changes
- `never` - Never required
example: "users-only"
sshUrl:
type: string
description: SSH URL of the git repository.
example: "git@github.com:org/repo.git"
webUrl:
type: string
nullable: true
description: Custom web URL for the git repository, or null if not set.
example: "https://github.com/org/repo"
webhookSecret:
type: string
description: Webhook secret for signature verification. Only included if requested via `?include=webhookSecret`.
webhookUrl:
type: string
description: Webhook URL to configure in your git provider.
example: "https://app.omni.co/api/webhooks/model/..."
Permission:
type: object
properties:
role:
type: string
enum: [VIEWER, EDITOR, MANAGER]
accessBoost:
type: boolean
direct:
type: boolean
inherited:
type: boolean
FolderPermission:
type: object
description: Represents a folder permission in Omni.
properties:
id:
type: string
description: The ID of the user or user group.
name:
type: string
description: The name of the user or user group.
description:
type: string
description: Description of the permission source.
type:
type: string
description: The type of the permission holder.
enum: [user, userGroup]
direct:
type: object
description: Direct permission details for this folder.
properties:
accessBoost:
type: boolean
description: If `true`, [AccessBoost](/share#boosting-permissions-with-accessboost) is enabled for the user.
isOwner:
type: boolean
description: If `true`, the user is the owner of the folder.
role:
type: string
description: The content role associated with the user.
enum: [NO_ACCESS, VIEWER, EXPLORER, EDITOR, MANAGER]
DocumentAccessPrincipal:
type: object
description: Represents a user or group with access to a document.
properties:
id:
type: string
description: The ID of the user or user group.
name:
type: string
description: Display name of the user or user group.
email:
type: string
description: Email address. Only present for users, not user groups.
type:
type: string
enum: [user, userGroup]
description: The type of principal.
role:
type: string
enum: [VIEWER, INTERACTOR, EDITOR, MANAGER]
description: Permission level assigned to this principal.
accessBoost:
type: boolean
description: Whether elevated access is enabled for this principal.
accessSource:
type: string
enum: [direct, folder]
description: |
How access was granted:
- `direct` — Explicit document permissions
- `folder` — Inherited from folder permissions
isOwner:
type: boolean
description: Whether this user owns the document. Only present for users, not user groups.
folderInfo:
type: object
description: Information about the folder that grants access. Only present when `accessSource` is `folder`.
properties:
id:
type: string
description: The ID of the folder.
name:
type: string
description: The name of the folder.
path:
type: string
description: The full path of the folder.
ScimGroup:
type: object
properties:
id:
type: string
description: Unique identifier for the group
displayName:
type: string
description: The name of the group
members:
type: array
description: The list of users in the group
items:
type: object
properties:
value:
type: string
description: The user's unique identifier
display:
type: string
description: The user's email address
meta:
type: object
description: Metadata about the group resource
properties:
resourceType:
type: string
example: "Group"
description: The type of resource. This will be `Group`.
created:
type: string
format: date-time
description: The time the group was created
lastModified:
type: string
format: date-time
description: The time the group was last updated
schemas:
type: array
description: SCIM schema information for the group
items:
type: string
ScimUser:
type: object
properties:
id:
type: string
description: Unique identifier for the user
userName:
type: string
description: The user's email address
displayName:
type: string
description: The user's display name
active:
type: boolean
description: Whether the user is active
emails:
type: array
description: The user's email addresses
items:
type: object
properties:
primary:
type: boolean
description: Whether this is the user's primary email
value:
type: string
description: The email address
groups:
type: array
description: User groups that the user belongs to
items:
type: object
properties:
display:
type: string
description: The group's display name
value:
type: string
description: The group's unique identifier
meta:
type: object
properties:
resourceType:
type: string
example: "User"
description: The resource type. This will be `User`.
created:
type: string
format: date-time
description: The time the user was created
lastModified:
type: string
format: date-time
description: The time the user was last updated
schemas:
type: array
items:
type: string
description: |
SCIM information about the type of schemas used in the API. For example, `urn:ietf:params:scim:schemas:core:2.0:User`
urn:omni:params:1.0:UserAttribute:
type: object
description: |
[User attributes](/administration/users/attributes) as key/value pairs, where keys map to the IDs of user attributes defined in Omni. This is the **Reference** column in the **User attributes** page.
urn:omni:params:scim:schemas:extension:user:2.0:
type: object
description: Omni SCIM extension schema containing additional user metadata
properties:
lastLogin:
type: string
format: date-time
nullable: true
description: The timestamp of the user's last login. Will be `null` if the user has never logged in.
ScimEmbedUser:
type: object
description: An embed user object (SCIM 2.0)
properties:
id:
type: string
description: Unique identifier for the user
userName:
type: string
description: The user's email address
displayName:
type: string
description: The user's display name
active:
type: boolean
description: Whether the user is active
emails:
type: array
description: The user's email addresses
items:
type: object
properties:
primary:
type: boolean
description: Whether this is the user's primary email
value:
type: string
description: The email address
groups:
type: array
description: User groups that the user belongs to
items:
type: object
properties:
display:
type: string
description: The group's display name
value:
type: string
description: The group's unique identifier
meta:
type: object
properties:
resourceType:
type: string
example: "User"
description: The type of resource. This will be `User`.
created:
type: string
format: date-time
description: The time the user was created
lastModified:
type: string
format: date-time
description: The time the user was last uodated
schemas:
type: array
items:
type: string
description: |
SCIM information about the type of schemas used in the API. For example, `urn:ietf:params:scim:schemas:core:2.0:User`
embedEmail:
type: string
nullable: true
description: The embed user's email address
embedEntity:
type: string
description: The embed entity identifier
embedExternalId:
type: string
description: The external ID for the embed user
responses:
BadRequest:
description: Bad Request - Invalid parameters or request body
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
Forbidden:
description: Forbidden - Insufficient permissions
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
NotFound:
description: Not Found - Resource does not exist
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
TooManyRequests:
description: Too Many Requests - Rate limit exceeded (60 requests/minute)
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
MethodNotAllowed:
description: Method Not Allowed - Invalid HTTP method for this endpoint
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
InternalServerError:
description: Internal Server Error
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment