Use the Genie Agents API

Integrate Genie Agents into your own chatbot, agent, or application with the Genie Agents API. The API provides Chat mode APIs for stateful natural-language data querying (with follow-up questions and history) and Management APIs for CI/CD workflows that create, configure, and deploy Genie Agents across workspaces.

Note

Genie Agents were formerly known as Genie Spaces.

Overview

The Genie API provides the following types of capabilities:

  • Chat mode APIs: Enable natural language data querying in applications, chatbots, and agent frameworks. These APIs support stateful conversations created in Chat mode where users can ask follow-up questions and explore data naturally over time.
  • Agent mode APIs: Enable developers to programmatically send prompts in Agent mode, stream the reasoning and SQL results, and receive final reports with citations.
  • Management APIs: Enable programmatic creation, configuration, and deployment of Genie Agents across workspaces. Use these APIs for CI/CD pipelines, version control, and automated agent management.

This page explains how to prepare a well-curated Genie Agent and manage agents across workspaces so that the API returns reliable results. The agent provides the context that Genie uses to interpret questions and generate answers. If the agent is incomplete or untested, users might still receive incorrect results even with a correct API integration. For the runtime endpoints, request formats, and response formats, see the REST API reference linked in Genie API reference.

The setup examples on this page use the REST API directly. You can also call these APIs using the Azure Databricks SDKs. See Databricks SDKs.

Prerequisites

To use the Genie API, you must have:

  • Access to a Azure Databricks workspace with the Databricks SQL entitlement.
  • At least CAN USE privileges on a SQL pro or serverless SQL warehouse.

Getting started

Configure Azure Databricks authentication

For production use cases where a user with access to a browser is present, use OAuth for users (OAuth U2M). In situations where browser-based authentication is not possible, use a service principal to authenticate with the API. See OAuth for service principals (OAuth M2M). Service principals must have permissions to access the required data and SQL warehouses.

Gather details

  • Workspace instance name: Find and copy your workspace instance name from your Databricks workspace URL. For details about the workspace identifiers in your URL, see Get identifiers for workspace objects.

    Example: https://cust-success.cloud.databricks.com/

  • Warehouse ID: You need the ID of a SQL warehouse that you have at least CAN USE privileges on. To find your warehouse ID:

    1. Go to SQL Warehouses in your workspace.
    2. Select the warehouse you want to use.
    3. Copy the warehouse ID from the URL or the warehouse details page.

    Alternatively, use the List warehouses endpoint GET /api/2.0/sql/warehouses to programmatically retrieve a list of all SQL warehouses that you have permissions to access. The response includes the warehouse ID.

Create or select a Genie Agent

A well-structured Genie Agent has the following characteristics:

  • Uses well-annotated data: Genie relies on table metadata and column comments. Verify that your Unity Catalog data sources have clear, descriptive comments.
  • Is user tested: Test your agent by asking questions you expect from end users. Use testing to create and refine example SQL queries.
  • Includes company-specific context: Add instructions, example SQL, and functions. See Add SQL examples and instructions. Aim for at least five tested example SQL queries.
  • Uses benchmarks to test accuracy: Add at least five benchmark questions based on anticipated user questions. See Benchmarks.

For more information on creating an agent, see Create and manage a Genie Agent and Curate an effective Genie Agent.

You can either create a new Genie Agent or use an existing one:

Create a new agent

Create a Genie Agent programmatically using the Create Genie Agent API. The following example demonstrates a well-structured agent that follows best practices. Replace the placeholders with your values:

POST /api/2.0/genie/spaces
Host: <DATABRICKS_INSTANCE>
Authorization: Bearer <your_authentication_token>
{
  "description": "Space for analyzing sales performance and trends",
  "parent_path": "/Workspace/Users/<username>",
  "serialized_space": "{\"version\":1,\"config\":{\"sample_questions\":[{\"id\":\"a1b2c3d4e5f6\",\"question\":[\"What were total sales last month?\"]},{\"id\":\"b2c3d4e5f6g7\",\"question\":[\"Show top 10 customers by revenue\"]},{\"id\":\"c3d4e5f6g7h8\",\"question\":[\"Compare sales by region for Q1 vs Q2\"]}]},\"data_sources\":{\"tables\":[{\"identifier\":\"sales.analytics.orders\",\"description\":[\"Transactional order data including order date, amount, and customer information\"],\"column_configs\":[{\"column_name\":\"order_date\",\"get_example_values\":true},{\"column_name\":\"status\",\"get_example_values\":true,\"build_value_dictionary\":true},{\"column_name\":\"region\",\"get_example_values\":true,\"build_value_dictionary\":true}]},{\"identifier\":\"sales.analytics.customers\"},{\"identifier\":\"sales.analytics.products\"}]},\"instructions\":{\"text_instructions\":[{\"id\":\"01f0b37c378e1c91\",\"content\":[\"When calculating revenue, sum the order_amount column. When asked about 'last month', use the previous calendar month (not the last 30 days). Round all monetary values to 2 decimal places.\"]}],\"example_question_sqls\":[{\"id\":\"01f0821116d912db\",\"question\":[\"Show top 10 customers by revenue\"],\"sql\":[\"SELECT customer_name, SUM(order_amount) as total_revenue\\n\",\"FROM sales.analytics.orders o\\n\",\"JOIN sales.analytics.customers c ON o.customer_id = c.customer_id\\n\",\"GROUP BY customer_name\\n\",\"ORDER BY total_revenue DESC\\n\",\"LIMIT 10\"]},{\"id\":\"01f099751a3a1df3\",\"question\":[\"What were total sales last month\"],\"sql\":[\"SELECT SUM(order_amount) as total_sales\\n\",\"FROM sales.analytics.orders\\n\",\"WHERE order_date >= DATE_TRUNC('month', CURRENT_DATE - INTERVAL 1 MONTH)\\n\",\"AND order_date < DATE_TRUNC('month', CURRENT_DATE)\"]}],\"join_specs\":[{\"id\":\"01f0c0b4e8151\",\"left\":{\"identifier\":\"sales.analytics.orders\",\"alias\":\"orders\"},\"right\":{\"identifier\":\"sales.analytics.customers\",\"alias\":\"customers\"},\"sql\":[\"orders.customer_id = customers.customer_id\"]}],\"sql_snippets\":{\"filters\":[{\"id\":\"01f09972e66d1\",\"sql\":[\"orders.order_amount > 1000\"],\"display_name\":\"high value orders\",\"synonyms\":[\"large orders\",\"big purchases\"]}],\"expressions\":[{\"id\":\"01f09974563a1\",\"alias\":\"order_year\",\"sql\":[\"YEAR(orders.order_date)\"],\"display_name\":\"year\"}],\"measures\":[{\"id\":\"01f09972611f1\",\"alias\":\"total_revenue\",\"sql\":[\"SUM(orders.order_amount)\"],\"display_name\":\"total revenue\",\"synonyms\":[\"revenue\",\"total sales\"]}]}}}",
  "title": "Sales Analytics Space",
  "warehouse_id": "<warehouse-id>"
}

Response:
{
  "space_id": "3c409c00b54a44c79f79da06b82460e2",
  "title": "Sales Analytics Space",
  "description": "Space for analyzing sales performance and trends",
  "warehouse_id": "<warehouse-id>",
  "serialized_space": "{\n  \"version\": 1,\n  \"config\": {\n    \"sample_questions\": [\n      {\n        \"id\": \"a1b2c3d4e5f600000000000000000000\",\n        \"question\": [\n          \"What were total sales last month?\"\n        ]\n      },\n      {\n        \"id\": \"b2c3d4e5f6g700000000000000000000\",\n        \"question\": [\n          \"Show top 10 customers by revenue\"\n        ]\n      },\n      {\n        \"id\": \"c3d4e5f6g7h800000000000000000000\",\n        \"question\": [\n          \"Compare sales by region for Q1 vs Q2\"\n        ]\n      }\n    ]\n  },\n  \"data_sources\": {\n    \"tables\": [\n      {\n        \"identifier\": \"sales.analytics.orders\",\n        \"description\": [\n          \"Transactional order data including order date, amount, and customer information\"\n        ],\n        \"column_configs\": [\n          {\n            \"column_name\": \"order_date\",\n            \"get_example_values\": true\n          },\n          {\n            \"column_name\": \"status\",\n            \"get_example_values\": true,\n            \"build_value_dictionary\": true\n          },\n          {\n            \"column_name\": \"region\",\n            \"get_example_values\": true,\n            \"build_value_dictionary\": true\n          }\n        ]\n      },\n      {\n        \"identifier\": \"sales.analytics.customers\"\n      },\n      {\n        \"identifier\": \"sales.analytics.products\"\n      }\n    ]\n  },\n  \"instructions\": {\n    \"text_instructions\": [\n      {\n        \"id\": \"01f0b37c378e1c91\",\n        \"content\": [\n          \"When calculating revenue, sum the order_amount column. When asked about 'last month', use the previous calendar month (not the last 30 days). Round all monetary values to 2 decimal places.\"\n        ]\n      }\n    ],\n    \"example_question_sqls\": [\n      {\n        \"id\": \"01f0821116d912db\",\n        \"question\": [\n          \"Show top 10 customers by revenue\"\n        ],\n        \"sql\": [\n          \"SELECT customer_name, SUM(order_amount) as total_revenue\\n\",\n          \"FROM sales.analytics.orders o\\n\",\n          \"JOIN sales.analytics.customers c ON o.customer_id = c.customer_id\\n\",\n          \"GROUP BY customer_name\\n\",\n          \"ORDER BY total_revenue DESC\\n\",\n          \"LIMIT 10\"\n        ]\n      },\n      {\n        \"id\": \"01f099751a3a1df3\",\n        \"question\": [\n          \"What were total sales last month\"\n        ],\n        \"sql\": [\n          \"SELECT SUM(order_amount) as total_sales\\n\",\n          \"FROM sales.analytics.orders\\n\",\n          \"WHERE order_date >= DATE_TRUNC('month', CURRENT_DATE - INTERVAL 1 MONTH)\\n\",\n          \"AND order_date < DATE_TRUNC('month', CURRENT_DATE)\"\n        ]\n      }\n    ],\n    \"join_specs\": [\n      {\n        \"id\": \"01f0c0b4e8151\",\n        \"left\": {\n          \"identifier\": \"sales.analytics.orders\",\n          \"alias\": \"orders\"\n        },\n        \"right\": {\n          \"identifier\": \"sales.analytics.customers\",\n          \"alias\": \"customers\"\n        },\n        \"sql\": [\n          \"orders.customer_id = customers.customer_id\"\n        ]\n      }\n    ],\n    \"sql_snippets\": {\n      \"filters\": [\n        {\n          \"id\": \"01f09972e66d1\",\n          \"sql\": [\"orders.order_amount > 1000\"],\n          \"display_name\": \"high value orders\",\n          \"synonyms\": [\"large orders\", \"big purchases\"]\n        }\n      ],\n      \"expressions\": [\n        {\n          \"id\": \"01f09974563a1\",\n          \"alias\": \"order_year\",\n          \"sql\": [\"YEAR(orders.order_date)\"],\n          \"display_name\": \"year\"\n        }\n      ],\n      \"measures\": [\n        {\n          \"id\": \"01f09972611f1\",\n          \"alias\": \"total_revenue\",\n          \"sql\": [\"SUM(orders.order_amount)\"],\n          \"display_name\": \"total revenue\",\n          \"synonyms\": [\"revenue\", \"total sales\"]\n        }\n      ]\n    }\n  }\n}\n"
}

Use an existing agent

If you already have a Genie Agent, you can find the space ID using the List Genie Agents API. You can also find and copy the space ID from the Genie Agent Settings tab.

GET /api/2.0/genie/spaces
Host: <DATABRICKS_INSTANCE>
Authorization: Bearer <your_authentication_token>

Response:
{
  "spaces": [
    {
      "description": "Space for analyzing sales performance and trends",
      "serialized_space": "{\"version\":1,\"config\":{\"sample_questions\":[{\"id\":\"a1b2c3d4e5f6\",\"question\":[\"What were total sales last month?\"]},{\"id\":\"b2c3d4e5f6g7\",\"question\":[\"Show top 10 customers by revenue\"]},{\"id\":\"c3d4e5f6g7h8\",\"question\":[\"Compare sales by region for Q1 vs Q2\"]}]},\"data_sources\":{\"tables\":[{\"identifier\":\"sales.analytics.orders\",\"description\":[\"Transactional order data including order date, amount, and customer information\"],\"column_configs\":[{\"column_name\":\"order_date\",\"get_example_values\":true},{\"column_name\":\"status\",\"get_example_values\":true,\"build_value_dictionary\":true},{\"column_name\":\"region\",\"get_example_values\":true,\"build_value_dictionary\":true}]},{\"identifier\":\"sales.analytics.customers\"},{\"identifier\":\"sales.analytics.products\"}]},\"instructions\":{\"text_instructions\":[{\"id\":\"01f0b37c378e1c91\",\"content\":[\"When calculating revenue, sum the order_amount column. When asked about 'last month', use the previous calendar month (not the last 30 days). Round all monetary values to 2 decimal places.\"]}],\"example_question_sqls\":[{\"id\":\"01f0821116d912db\",\"question\":[\"Show top 10 customers by revenue\"],\"sql\":[\"SELECT customer_name, SUM(order_amount) as total_revenue\\n\",\"FROM sales.analytics.orders o\\n\",\"JOIN sales.analytics.customers c ON o.customer_id = c.customer_id\\n\",\"GROUP BY customer_name\\n\",\"ORDER BY total_revenue DESC\\n\",\"LIMIT 10\"]},{\"id\":\"01f099751a3a1df3\",\"question\":[\"What were total sales last month\"],\"sql\":[\"SELECT SUM(order_amount) as total_sales\\n\",\"FROM sales.analytics.orders\\n\",\"WHERE order_date >= DATE_TRUNC('month', CURRENT_DATE - INTERVAL 1 MONTH)\\n\",\"AND order_date < DATE_TRUNC('month', CURRENT_DATE)\"]}],\"join_specs\":[{\"id\":\"01f0c0b4e8151\",\"left\":{\"identifier\":\"sales.analytics.orders\",\"alias\":\"orders\"},\"right\":{\"identifier\":\"sales.analytics.customers\",\"alias\":\"customers\"},\"sql\":[\"orders.customer_id = customers.customer_id\"]}],\"sql_snippets\":{\"filters\":[{\"id\":\"01f09972e66d1\",\"sql\":[\"orders.order_amount > 1000\"],\"display_name\":\"high value orders\",\"synonyms\":[\"large orders\",\"big purchases\"]}],\"expressions\":[{\"id\":\"01f09974563a1\",\"alias\":\"order_year\",\"sql\":[\"YEAR(orders.order_date)\"],\"display_name\":\"year\"}],\"measures\":[{\"id\":\"01f09972611f1\",\"alias\":\"total_revenue\",\"sql\":[\"SUM(orders.order_amount)\"],\"display_name\":\"total revenue\",\"synonyms\":[\"revenue\",\"total sales\"]}]}}}",
      "space_id": "3c409c00b54a44c79f79da06b82460e2",
      "title": "Sales Analytics Space",
      "warehouse_id": "<warehouse-id>",
    },
    {
      "description": "Space for marketing campaign analysis",
      "serialized_space": "{\"version\":1,\"config\":{\"sample_questions\":[{\"id\":\"a1b2c3d4e5f6\",\"question\":[\"Show total revenue by state\"]}]},\"data_sources\":{\"tables\":[{\"identifier\":\"sales.gold.orders\"}]}}",
      "space_id": "7f8e9d0c1b2a3456789abcdef0123456",
      "title": "Marketing Analytics Space",
      "warehouse_id": "<warehouse-id>",
    }
  ]
}

Use the space_id from the response in subsequent API calls.

Understanding the serialized_space field

The serialized_space field is a JSON string that defines the configuration and data sources for your Genie Agent. In the API request, this JSON must be escaped as a string. The field contains:

  • version: Schema version number for backwards compatibility. Use 2 as shown in the example below.
  • config: Agent configuration including:
    • sample_questions: Example questions to guide users. Each question requires an id (32-character hex string) and question (array of strings).
  • data_sources: Data sources available to the agent:
    • tables: Array of table objects with identifier (three-level namespace), optional description, and optional column_configs.
    • metric_views: Array of metric view objects (same structure as tables).
  • instructions: Structured instructions for the agent:
    • text_instructions: High-level guidance for the LLM.
    • example_question_sqls: Example questions with SQL answers, optionally with parameters and usage_guidance.
    • sql_functions: References to SQL functions available to the agent.
    • join_specs: Pre-defined join relationships between tables. The sql field requires exactly two elements: the join condition, using backtick-quoted alias references, and a relationship type annotation, for example "--rt=FROM_RELATIONSHIP_TYPE_MANY_TO_ONE--". See Join specs format.
    • sql_snippets: Reusable filters, expressions, and measures.
  • benchmarks: Questions for evaluating agent quality, each with a ground-truth SQL answer.

The unescaped version of the serialized_space field from the create agent example looks like:

{
  "version": 2,
  "config": {
    "sample_questions": [
      {
        "id": "a1b2c3d4e5f60000000000000000000a",
        "question": ["What were total sales last month?"]
      },
      {
        "id": "b2c3d4e5f6a70000000000000000000b",
        "question": ["Show top 10 customers by revenue"]
      }
    ]
  },
  "data_sources": {
    "tables": [
      {
        "identifier": "sales.analytics.customers",
        "description": ["Customer master data including contact information and account details"],
        "column_configs": [
          {
            "column_name": "customer_id",
            "description": ["Unique identifier for each customer"],
            "synonyms": ["cust_id", "account_id"]
          },
          {
            "column_name": "customer_name",
            "enable_entity_matching": true
          },
          {
            "column_name": "internal_notes",
            "exclude": true
          }
        ]
      },
      {
        "identifier": "sales.analytics.orders",
        "description": ["Transactional order data including order date, amount, and customer information"],
        "column_configs": [
          {
            "column_name": "order_date",
            "enable_format_assistance": true
          },
          {
            "column_name": "region",
            "enable_format_assistance": true,
            "enable_entity_matching": true
          },
          {
            "column_name": "status",
            "enable_format_assistance": true,
            "enable_entity_matching": true
          }
        ]
      },
      {
        "identifier": "sales.analytics.products"
      }
    ],
    "metric_views": [
      {
        "identifier": "sales.analytics.revenue_metrics",
        "description": ["Pre-aggregated revenue metrics by region and time period"],
        "column_configs": [
          {
            "column_name": "period",
            "description": ["Time period for the metric (monthly, quarterly, yearly)"],
            "enable_format_assistance": true
          }
        ]
      }
    ]
  },
  "instructions": {
    "text_instructions": [
      {
        "id": "01f0b37c378e1c9100000000000000a1",
        "content": [
          "When calculating revenue, sum the order_amount column. ",
          "When asked about 'last month', use the previous calendar month. ",
          "Round all monetary values to 2 decimal places."
        ]
      }
    ],
    "example_question_sqls": [
      {
        "id": "01f0821116d912db00000000000000b1",
        "question": ["Show top 10 customers by revenue"],
        "sql": [
          "SELECT customer_name, SUM(order_amount) as total_revenue\n",
          "FROM sales.analytics.orders o\n",
          "JOIN sales.analytics.customers c ON o.customer_id = c.customer_id\n",
          "GROUP BY customer_name\n",
          "ORDER BY total_revenue DESC\n",
          "LIMIT 10"
        ]
      },
      {
        "id": "01f099751a3a1df300000000000000b2",
        "question": ["What were total sales last month"],
        "sql": [
          "SELECT SUM(order_amount) as total_sales\n",
          "FROM sales.analytics.orders\n",
          "WHERE order_date >= DATE_TRUNC('month', CURRENT_DATE - INTERVAL 1 MONTH)\n",
          "AND order_date < DATE_TRUNC('month', CURRENT_DATE)"
        ]
      },
      {
        "id": "01f099751a3a1df300000000000000b3",
        "question": ["Show sales for a specific region"],
        "sql": [
          "SELECT SUM(order_amount) as total_sales\n",
          "FROM sales.analytics.orders\n",
          "WHERE region = :region_name"
        ],
        "parameters": [
          {
            "name": "region_name",
            "type_hint": "STRING",
            "description": ["The region to filter by (e.g., 'North America', 'Europe')"],
            "default_value": {
              "values": ["North America"]
            }
          }
        ],
        "usage_guidance": ["Use this example when the user asks about sales filtered by a specific geographic region"]
      }
    ],
    "sql_functions": [
      {
        "id": "01f0c0b4e815100000000000000000f1",
        "identifier": "sales.analytics.fiscal_quarter"
      }
    ],
    "join_specs": [
      {
        "id": "01f0c0b4e815100000000000000000c1",
        "left": {
          "identifier": "sales.analytics.orders",
          "alias": "orders"
        },
        "right": {
          "identifier": "sales.analytics.customers",
          "alias": "customers"
        },
        "sql": ["`orders`.`customer_id` = `customers`.`customer_id`", "--rt=FROM_RELATIONSHIP_TYPE_MANY_TO_ONE--"],
        "comment": ["Join orders to customers on customer_id"],
        "instruction": ["Use this join when you need customer details for order analysis"]
      }
    ],
    "sql_snippets": {
      "filters": [
        {
          "id": "01f09972e66d100000000000000000d1",
          "sql": ["orders.order_amount > 1000"],
          "display_name": "high value orders",
          "synonyms": ["large orders", "big purchases"],
          "comment": ["Filters to orders over $1000"],
          "instruction": ["Use when the user asks about high-value or large orders"]
        }
      ],
      "expressions": [
        {
          "id": "01f09974563a100000000000000000e1",
          "alias": "order_year",
          "sql": ["YEAR(orders.order_date)"],
          "display_name": "year",
          "synonyms": ["fiscal year", "calendar year"],
          "comment": ["Extracts the year from order date"],
          "instruction": ["Use for year-over-year analysis"]
        }
      ],
      "measures": [
        {
          "id": "01f09972611f100000000000000000f1",
          "alias": "total_revenue",
          "sql": ["SUM(orders.order_amount)"],
          "display_name": "total revenue",
          "synonyms": ["revenue", "total sales"],
          "comment": ["Sum of all order amounts"],
          "instruction": ["Use this measure for revenue calculations"]
        }
      ]
    }
  },
  "benchmarks": {
    "questions": [
      {
        "id": "01f0d0b4e815100000000000000000g1",
        "question": ["What is the average order value?"],
        "answer": [
          {
            "format": "SQL",
            "content": ["SELECT AVG(order_amount) as avg_order_value\n", "FROM sales.analytics.orders"]
          }
        ]
      }
    ]
  }
}

When constructing your agent, create this JSON structure and then escape it as a string for the API request. For complete schema details, see the Create Genie Agent API reference.

Validation rules for serialized_space

The serialized_space JSON must conform to the following validation rules. JSON that is not valid is rejected during agent creation or update.

Version

  • Version field: Required. Use 2 for new agents. The version number exists for backwards compatibility.

ID format

All ID fields must be 32-character lowercase hexadecimal strings (UUID format without hyphens).

  • Valid: a1b2c3d4e5f60000000000000000000a
  • Not valid: a1b2c3d4e5f6 (too short), A1B2C3D4E5F60000000000000000000A (uppercase), a1b2c3d4-e5f6-0000-0000-00000000000a (contains hyphens)

IDs are required for:

  • config.sample_questions[].id
  • instructions.text_instructions[].id
  • instructions.example_question_sqls[].id
  • instructions.join_specs[].id
  • instructions.sql_snippets.filters[].id
  • instructions.sql_snippets.expressions[].id
  • instructions.sql_snippets.measures[].id
  • benchmarks.questions[].id (if benchmarks are included)

You can use the following command to generate a valid ID:

python3 -c "import random,datetime;t=int((datetime.datetime.now()-datetime.datetime(1582,10,15)).total_seconds()*1e7);print(f'{(t&0xFFFFFFFFFFFF0000)|(1<<12)|((t&0xFFFF)>>4):016x}{random.getrandbits(62)|0x8000000000000000:016x}')"

This generates a time-ordered UUID. IDs generated in sequence sort alphabetically in the order they were created, which satisfies the sorting requirements automatically.

Sorting requirements

Collections containing IDs or identifiers must be pre-sorted. The system validates that arrays are already sorted and rejects unsorted input.

Collection Sort key
data_sources.tables identifier (alphabetically)
data_sources.metric_views identifier (alphabetically)
data_sources.tables[].column_configs column_name (alphabetically)
data_sources.metric_views[].column_configs column_name (alphabetically)
config.sample_questions id (alphabetically)
instructions.text_instructions id (alphabetically)
instructions.example_question_sqls id (alphabetically)
instructions.sql_functions (id, identifier) tuple (alphabetically)
instructions.join_specs id (alphabetically)
instructions.sql_snippets.filters id (alphabetically)
instructions.sql_snippets.expressions id (alphabetically)
instructions.sql_snippets.measures id (alphabetically)
benchmarks.questions id (alphabetically)

Uniqueness constraints

  • Question IDs: All IDs in config.sample_questions and benchmarks.questions must be unique across both collections.
  • Instruction IDs: All IDs across text_instructions, example_question_sqls, sql_functions, join_specs, and all sql_snippets types must be unique.
  • Column configs: The combination of (table_identifier, column_name) must be unique within the agent.

Size and length limits

  • String length: Individual string elements are limited to 25,000 characters.
  • Array size: Repeated fields are limited to 10,000 items.
  • Text instructions: At most 1 text instruction is allowed per agent.
  • Tables and metric views: Subject to workspace-specific limits.
  • SQL content: Query text in sql and join_specs.sql fields is subject to length limits.

Join specs format

The sql field in each join spec must contain exactly two elements:

  1. The join condition, using backtick-quoted alias references:

    "`orders`.`customer_id` = `customers`.`customer_id`"
    
  2. A relationship type annotation in the following format:

    "--rt=FROM_RELATIONSHIP_TYPE_<CARDINALITY>--"
    

    Valid cardinality values:

    • FROM_RELATIONSHIP_TYPE_MANY_TO_ONE
    • FROM_RELATIONSHIP_TYPE_ONE_TO_MANY
    • FROM_RELATIONSHIP_TYPE_ONE_TO_ONE
    • FROM_RELATIONSHIP_TYPE_MANY_TO_MANY

Omitting the relationship type annotation causes the API to reject the request with a parsing error. For multi-column joins, create a separate join spec for each relationship.

Other requirements

  • Table identifiers: Must use three-level namespace format (catalog.schema.table).
  • Benchmark answers: Each benchmark question must have exactly one answer with format set to SQL.
  • SQL snippets: Filter, expression, and measure SQL fields must not be empty.

Genie API reference

The preceding sections show how to prepare a Genie Agent and manage agents across workspaces. For starting conversations, sending messages, and retrieving results from Genie Agents, see the REST API reference:

  • Agent mode APIs: Send prompts in Agent mode, stream its reasoning and SQL results, and receive final reports with citations. See the Agent mode API reference.
  • Chat mode APIs: Start a Chat mode conversation, ask follow-up questions, and retrieve generated SQL, query results, and visualizations. See the Conversation API reference.

Best practices and limits

Best practices for using the Genie API

To maintain performance and reliability when using the Genie API:

  • Implement retry logic with exponential backoff: The API doesn't retry failed requests for you, so add your own queuing and exponential backoff. This helps your application handle transient failures and avoid unnecessary repeat requests as it grows.
  • Log API responses: Implement comprehensive logging of API requests and responses to help with debugging, monitoring usage patterns, and tracking costs.
  • Poll for status updates every 1 to 5 seconds: Continue polling until a conclusive message status, such as COMPLETED, FAILED, or CANCELLED, is received. Limit polling to 10 minutes for most queries. If there is no conclusive response after 10 minutes, stop polling and return a timeout error or prompt the user to manually check the query status later.
  • Use exponential backoff for polling: Increase the delay between polls up to a maximum of one minute. This reduces unnecessary requests for long-running queries while still allowing low latency for fast ones.
  • Start a new conversation for each session: Avoid reusing conversation threads across sessions, as this can reduce accuracy due to unintended context reuse.
  • Maintain conversation limits: To manage old conversations and stay under the 10,000 conversation limit:
    1. Use the GET /api/2.0/genie/spaces/{space_id}/conversations endpoint to see all existing conversation threads in an agent.
    2. Identify conversations that are no longer needed, such as older conversations or test conversations.
    3. Use the DELETE /api/2.0/genie/spaces/{space_id}/conversations/{conversation_id} endpoint to remove conversations programmatically.

Monitor the agent

After your application is set up, you can monitor questions and responses in the Databricks UI.

Encourage users to test the agent so that you learn about the types of questions they are likely to ask and the responses they receive. Provide users with guidance to help them start testing the agent. Use the Monitoring tab to view questions and responses. See Monitor the agent.

You can also use audit logs to monitor activity in a Genie Agent. See Genie Agent events.