Skip to main content
Integrating Omni with metadata catalogs like OpenMetadata or DataHub allows you to visualize how data flows from raw database tables into Omni dashboards. By using the Omni REST API, you can construct a complete, queryable lineage graph that gives you a picture of how data is consumed across your organization. The lineage will follow this structure: The approach in this guide is read-only and relies on endpoints that retrieve information from your Omni instance:
EntityEndpointPurpose
FoldersGET /v1/foldersLists all top-level and nested folders.
DocumentsGET /v1/documentsLists dashboards and workbooks within a folder.
QueriesGET /v1/documents/:id/queriesRetrieves the underlying queries (tiles) for a document.
Model YAMLGET /v1/models/:id/yamlRetrieves the view definitions and SQL mappings.
TopicsGET /v1/models/:id/topicsLists the available entry points for exploration.

Requirements

To follow the steps in this guide, you’ll need:
  • Modeler or Connection Admin permissions on the Omni model you want to work with
  • A Personal Access Token for the Omni API

Steps

Remember to update example placeholders! Throughout this guide, you’ll see variables like {your-omni-instance} in code examples. These are placeholders that you’ll need to replace with real values when you run the code yourself.
1

Retrieve a list of folders

Folders serve as the top-level nodes of your lineage graph. Use the List folders endpoint to retrieve all folders in your organization.
GET /api/v1/folders
curl --request GET \
--url 'https://{your-omni-instance}.omniapp.co/api/v1/folders' \
--header 'Authorization: Bearer {your-omni-token}'
The response from this endpoint uses cursor-based pagination. Loop until pageInfo.hasNextPage is false.Then, store the following fields:
  • id - Used to filter documents in the next step
  • name - The human-readable folder name
  • url - A direct link to the folder in Omni
2

List documents per folder

Next, you’ll retrieve the documents in each folder.For every folder id you retrieved in the previous step, call the List documents endpoint. Replace {folder_id} with the id of a folder:
GET /api/v1/documents?folderId={folder_id}
curl --request GET \
--url 'https://{your-omni-instance}.omniapp.co/api/v1/documents?folderId={folder_id}' \
--header 'Authorization: Bearer {your-omni-token}'
Then, store the following fields from the response - you’ll use them to identify content items in a later step:
  • identifier - The document ID used in subsequent calls
  • name - The human-readable document name
  • url - A direct deep-link to the dashboard or workbook
  • hasDashboard - Indicates if the document contains tiles
  • type - Usually document for workbooks and dashboards
3

List queries per document

Next, you’ll retrieve the queries in each document. Each tile on a dashboard corresponds to a workbook query.For every document identifier you retrieved in the previous step, call the Get document queries endpoint. Replace {documentId} with the identifier of a document:
GET /api/v1/documents/{documentId}/queries
curl --request GET \
--url 'https://{your-omni-instance}.omniapp.co/api/v1/documents/{documentId}/queries' \
--header 'Authorization: Bearer {your-omni-token}'
The response will include a top-level queries object, which will contain a list of queries. For example:
Example response from the List document queries endpoint
{
  "queries": [
    {
      "id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
      "name": "Blobtastic Dashboard",
      "url": "https://{your-omni-org}.omni.co/w/abc123?key=1",
      "query": {...}
    }
  ]
}
The full query object isn’t included here due to length, but you’ll need to store the following fields from the response:
  • url - A direct deep-link to the specific tile/query
  • query.table - The Omni view reference in schema__viewname format (e.g., ecomm__order_items)
  • query.fields - Array of field references (e.g., schema__viewname.field_name)
  • query.join_paths_from_topic_name - The topic label (e.g., “Orders”). Identifies which topic the tile belongs to.
  • query.modelId - Use this ID when calling the Get model YAML endpoint in the next step
4

Resolve topics and views from model YAML

In this step, you’ll map Omni objects to raw database tables using the model’s underlying configuration.
  • Topics define the join graph and are the entry point for exploration
  • Views map to a database table or query.
The join_paths_from_topic_name field identifies the topic, which usually shares the name of the base view.Because model logic is often split across multiple files, you’ll start by finding the correct file path for a specific view.
  1. Retrieve the view map. Use the modelId from the previous step to call the Get model YAML endpoint as follows:
    GET /api/v1/models/{modelId}/yaml
    curl --request GET \
    --url 'https://{your-omni-instance}.omniapp.co/api/v1/models/{modelId}/yaml' \
    --header 'Authorization: Bearer {your-omni-token}'
    
    The response will contain a viewNames map that indexes every view file path by its internal schema__viewname reference.
  2. Locate the file in the map. Search the map for the view name provided in the query (e.g., ecomm__order_items).
    Omni supports two types of views. Standard views map to physical tables, while query views are promoted from saved queries. Check the viewNames map to determine if you need to request a .view or .query.view file.
  3. Fetch the YAML for the file. After you find the file name, use it in the fileName parameter to retrieve the file’s YAML:
    GET /api/v1/models/{modelId}/yaml?fileName={schema_name}/{view_name}.view
    curl --request GET \
    --url 'https://{your-omni-instance}.omniapp.co/api/v1/models/{modelId}/yaml?fileName={SCHEMA_NAME}/{view_name}.view' \
    --header 'Authorization: Bearer {your-omni-token}'
    
    The fileName parameter is case-sensitive and requires the schema portion to be uppercase to resolve correctly (e.g., ECOMM/order_items.view).
Once you have the specific YAML content, extract these fields from the response to complete the mapping from Omni to your database:
  • table_name - The physical table name in your database
  • schema - The database schema where the table resides
  • dimensions and measures - These blocks contain a sql property that defines which database columns are used for that field
5

Assemble the lineage graph

Once all data is collected, you can assemble the lineage graph:
  1. Add deep links to the catalog. Use the url fields returned directly in the response payloads to provide deep-links in your catalog:
    • Folders - https://{your-omni-instance}.omniapp.co/f/{folder_id}
    • Documents - https://{your-omni-instance}.omniapp.co/dashboards/{document_id}
    • Tiles/Queries - https://{your-omni-instance}.omniapp.co/w/{document_id}?key={tile_key}
    While URLs can be constructed manually, it’s best practice to use the url property returned by the API as it handles the correct routing for different document types.
  2. Create the graph. Use the following diagram to assemble your graph. Each arrow represents a foreign-key relationship established through the API traversal you completed in previous steps. By parsing the query.fields array and comparing it to the dimensions and measures in your YAML, you can identify exactly which database columns drive each dashboard tile.
    When building your graph, use the identifier or id fields as unique keys for each node to ensure updates or deletions in Omni are correctly reflected.

Troubleshooting

Personal Access Tokens have the same permissions as the user that created the token.If you can’t access a model or you see folders missing in API responses, the user making the requests may not have permissions to those objects in Omni. Verify that the owner of the token has the correct permissions.
If you receive a 429 too many requests error from the API, you’ll need to implement exponential backoff to avoid hitting the rate limit.
The List folders and List documents endpoints use pagination in their responses, which means only a specific number of folders or documents are included per ‘page’.If it seems like the response is incomplete, check the value of pageInfo.hasNextPage in the response. If true, you’ll need to make subsequent requests and pass the nextCursor value as the cursor parameter to retrieve the next page of results.

Next steps

  • Explore the API reference - Review the full API reference for endpoints used in this guide
  • Drafts and publishing - Learn how to use drafts to stage model changes before deploying