generate_sql

Converts a natural language question into a SQL query

Recent Requests
Log in to see full request history
TimeStatusUser Agent
Retrieving recent requests…
LoadingLoading…

The /v2/generate_sql endpoint converts natural language questions into SQL queries. It allows you to interact with your database using natural language.

Basic Usage

To generate a SQL query, send a request with your question:

// Request
{
  "projectId": 1,
  "question": "Show me all customers"
}

// Response
{
  "id": "1fbc0d64-1c58-45b2-a990-9183bbbcf913",
  "sql": "SELECT * FROM \"olist_customers_dataset\"",
  "threadId": "9c537507-9cec-46ed-b877-07bfa6322bed"
}

Getting Both Wren SQL and Dialect SQL

Use the returnBothSqlDialect parameter to receive both the original Wren SQL and the database-specific dialect SQL:

// Request
{
  "projectId": 1,
  "question": "Show me top 10 customers with their details",
  "returnBothSqlDialect": true
}

// Response
{
  "id": "1fbc0d64-1c58-45b2-a990-9183bbbcf913",
  "sql": "SELECT \"customer_id\" AS \"Customer_ID\", \"customer_unique_id\" AS \"Customer_Unique_ID\", \"customer_city\" AS \"Customer_City\", \"customer_state\" AS \"Customer_State\" FROM \"olist_customers_dataset\" LIMIT 10",
  "dialectSql": "SELECT olist_customers_dataset.customer_id AS `Customer_ID`, olist_customers_dataset.customer_unique_id AS `Customer_Unique_ID`, olist_customers_dataset.customer_city AS `Customer_City`, olist_customers_dataset.customer_state AS `Customer_State` FROM (SELECT __source.customer_city AS customer_city, __source.customer_id AS customer_id, __source.customer_state AS customer_state, __source.customer_unique_id AS customer_unique_id FROM `wrenai-saas-staging`.sample_dataset_ecommerce.olist_customers_dataset AS __source) AS olist_customers_dataset LIMIT 10",
  "threadId": "9c537507-9cec-46ed-b877-07bfa6322bed"
}

Understanding the Response Fields

  • sql: Clean, readable Wren SQL that's optimized for understanding
  • dialectSql: Database-specific SQL that will actually be executed, including schema prefixes, table references, and database-specific syntax

When to Use returnBothSqlDialect

  • Debugging: Compare the generated Wren SQL with the actual executed SQL
  • Transparency: See exactly what SQL will run against your database
  • Integration: Use the dialectSql directly in your database tools if needed

SQL Dialect Compatibility

The returnSqlDialect parameter returns only the dialect SQL:

// Request
{
  "projectId": 1,
  "question": "Show me all customers",
  "returnSqlDialect": true
}

// Response  
{
  "id": "1fbc0d64-1c58-45b2-a990-9183bbbcf913",
  "sql": "SELECT olist_customers_dataset.customer_id, olist_customers_dataset.customer_unique_id FROM `project.dataset.olist_customers_dataset`",
  "threadId": "9c537507-9cec-46ed-b877-07bfa6322bed"
}

Conversation Context

You can use the threadId returned in the response to ask follow-up questions while maintaining context:

// Follow-up question
{
  "projectId": 1,
  "question": "list top 10 only",
  "threadId": "9c537507-9cec-46ed-b877-07bfa6322bed"
}

// Response
{
  "id": "2589615b-abbd-48b0-926f-128faa96a87e",
  "sql": "SELECT * FROM \"olist_customers_dataset\" ORDER BY \"customer_id\" ASC LIMIT 10",
  "threadId": "9c537507-9cec-46ed-b877-07bfa6322bed"
}

Executing Queries

Once you have the SQL, you can:

  • Pass the SQL to the /v2/run_sql endpoint to execute the query and get results
  • Use the returnSqlDialect: true parameter to get SQL in your database's native dialect and run it directly in your database

Non-SQL Query Handling

If your question can't be converted to SQL, you'll receive an error response with the following fields:

  • id: A unique identifier for the error response
  • code: An error code indicating the type of issue encountered:
    • NON_SQL_QUERY (HTTP 400): The question cannot be translated to SQL because it's unrelated to data querying
    • NO_DEPLOYMENT_FOUND (HTTP 400): No active deployment was found for the project
    • POLLING_TIMEOUT (HTTP 500): The operation timed out while waiting for a response from the AI service
  • error: A human-readable description explaining why the query couldn't be translated to SQL
  • explanationQueryId: An identifier you can use to get a more detailed explanation
// Example 1: Asking question "hello"
{
  "id": "e593369b-e222-4435-b874-dc10edb12a96",
  "code": "NON_SQL_QUERY",
  "error": "Vague greeting unrelated to schema, SQL, or user guide; no specific intent identified.",
  "explanationQueryId": "475afc1f-7950-4bc7-a248-a7da394d137a"
}

// Example 2: Asking question "what could you do"
{
  "id": "75c13d09-6f86-4e79-a00e-a4f85f73f2d7",
  "code": "NON_SQL_QUERY",
  "error": "User asks about Wren AI's features and capabilities, unrelated to database schema.",
  "explanationQueryId": "71b016c5-42bb-4897-82d6-46f9b0bf7d94"
}

Use the explanationQueryId with the /v2/stream_explanation endpoint to receive a detailed explanation response streamed as events.

User Guide Controls

Before answering, Wren classifies what a question is asking for. Most questions are about the data and become SQL. Some are not: "Do I need to know SQL?", "How do I get started?" Wren recognises those as product help and answers them from a built-in user guide describing Wren itself.

If you have embedded Wren in your own product that is usually the wrong answer — your users have never heard of Wren. This endpoint never shows you that answer, though: a product-help question fails with NON_SQL_QUERY whichever way these fields are set. What they change here is which non-SQL path ran, and whether a genuine data question phrased as a how-to gets misread as product help in the first place. Two per-request fields control it:

  • allowUserGuide (boolean, default true) — set false and product help is removed from classification altogether, so a how-to phrased data question is no longer misread as one.
  • userGuidePrompt (string) — supply your own guide and Wren uses it in place of ours, both when classifying the question and when answering it through explanationQueryId. Ignored when allowUserGuide is false.

Both default to today's behavior, so omitting them leaves the request unchanged. Both are per-request: re-send them on every turn of a thread. See User Guide Controls for the shared behaviour, including what happens to a question your guide does not cover.

Switch the built-in guide off:

{
  "projectId": 1,
  "question": "How do I get started?",
  "allowUserGuide": false
}

Or answer from your own guide instead — same question, your content:

{
  "projectId": 1,
  "question": "How do I get started?",
  "userGuidePrompt": "# Northwind Insights - Help\n\n## Getting started\nOpen **Explore** in the left sidebar and pick a dataset. Type your question in\nthe box at the top; results appear as a table you can switch to a chart.\n\n## Saving a report\nClick **Save** in the top-right of any answer to add it to *My Reports*.\nSaved reports refresh every morning at 06:00 UTC.\n\n## Sharing a report\nOpen a saved report and choose **Share > Copy link**. Links work only for\nteammates in your workspace; external sharing must be enabled by an admin."
}

Either way the request fails with NON_SQL_QUERY — what changes is the error prose and the path behind explanationQueryId.

{
  "id": "dde3ba13-cffa-4577-a042-16e926f8735a",
  "invalidSessionProperties": [],
  "code": "NON_SQL_QUERY",
  "error": "This is a product usage/setup question, not a data analysis request.",
  "explanationQueryId": "f70a16d9-898c-4116-80f2-dd658b39da4c"
}
{
  "id": "7809befc-7144-49ed-92fa-b3be30800f79",
  "invalidSessionProperties": [],
  "code": "NON_SQL_QUERY",
  "error": "This is a how-to question about using the system, not about database analysis.",
  "explanationQueryId": "5baaf959-8b8f-4ce8-aed3-141f63770ad6"
}

Stream the explanationQueryId from /v2/stream_explanation to read the answer itself; a supplied userGuidePrompt is used there too.

Their practical value on this endpoint is rescuing a genuine data question that was misread as a how-to:

{
  "projectId": 1,
  "question": "How do I find orders that were cancelled?"
}
{
  "id": "330e6140-716a-4e1e-9a1b-0f43d3779f92",
  "invalidSessionProperties": [],
  "code": "NON_SQL_QUERY",
  "error": "User is asking how to query cancelled orders; this is a system usage question.",
  "explanationQueryId": "d04001d7-00e1-4818-bdaf-6c95f547e927"
}

The same question with product help switched off generates SQL (usage omitted from the body below):

{
  "projectId": 1,
  "question": "How do I find orders that were cancelled?",
  "allowUserGuide": false
}
{
  "id": "d5ecab42-efe8-40e9-a01e-bc84e19b5afd",
  "invalidSessionProperties": [],
  "threadId": "6a96edab-7dcd-4242-82e3-d6f7b14ac5bd",
  "sql": "SELECT\n  order_id,\n  customer_id,\n  order_status,\n  order_purchase_timestamp,\n  order_approved_at,\n  order_delivered_carrier_date,\n  order_delivered_customer_date,\n  order_estimated_delivery_date\nFROM `olist_orders_dataset`\nWHERE order_status = 'canceled'\nORDER BY order_purchase_timestamp DESC"
}

If your integration only ever asks data questions, sending allowUserGuide: false on every request removes this failure mode for the questions we tested.

Body Params
integer
required

The project to query.

string
required

The natural language question to convert to SQL.

string

Optional thread ID to maintain conversation context. A new one is generated if omitted.

string

Optional language override for AI responses. Defaults to the project language. Recommended to follow RFC 5646 (see https://gist.github.com/msikma/8912e62ed866778ff8cd).

boolean
Defaults to false

If true, sql is returned in the data source's native SQL dialect (falls back to Wren SQL if conversion fails).

boolean
Defaults to false

If true, the response includes both sql (Wren SQL) and dialectSql (native dialect).

boolean
Defaults to true

Set false to stop answering product questions from the user guide.

string

Replaces the built-in user guide. Ignored when allowUserGuide is false.

Headers
string

Comma-separated key=value pairs applied as row/column-level security session properties (e.g. region=US,tier=pro). Unknown keys are echoed back in the invalidSessionProperties response field.

Responses

Language
Credentials
Bearer
LoadingLoading…
Response
Click Try It! to start a request and see the response here! Or choose an example:
application/json