How to use the SQL generators via the public API
Integrate with our public API in minutes and let your application generate accurate SQL and NoSQL queries.
Table of contents
Introduction
The public API exposes the same text-to-SQL engine that powers SQLAI.ai through one endpoint:
POST https://api.sqlai.ai/v2To get started you need:
Authentication
Create an API key on your public API page and send it as a bearer token:
Authorization: Bearer YOUR_API_KEYThe full key is shown once when you create it. Store it like a password: anyone who has it can spend the credits on your plan. If a key is exposed, revoke it on the same page and create a replacement. Each key has its own rate limit, so you can use separate keys for production, staging and scripts.
Text-to-SQL
A minimal fetch request looks like this:
const response = await fetch('https://api.sqlai.ai/v2', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${process.env.SQLAI_API_KEY}`,
},
body: JSON.stringify({
prompt: 'Get the user with id 13',
engine: 'postgres',
engineVersion: '17',
dataSource: [
{ table: 'users', column: 'id', type: 'bigint' },
{ table: 'users', column: 'name', type: 'text' },
{ table: 'users', column: 'email', type: 'text' },
],
}),
});
const { query, error } = await response.json();
if (error) throw new Error(error);
console.log(query); // SELECT * FROM users WHERE id = 13;Parameters
| Field | Required | Description |
|---|---|---|
prompt | Yes | The natural-language instruction, or the SQL to explain in explainSQL mode. Minimum 5 characters, maximum 400,000. |
engine | Yes | The database engine. See the supported databases for the exact API name. |
engineVersion | No | The target version, e.g. 17. When omitted, portable SQL is generated. |
reasoning | No | fast for the lowest latency, smart (default) for deeper analysis. |
dataSource | No | The schema, either as an array or as a string. |
dataSourceId | No | The id of a database already saved in SQLAI.ai. The saved schema and its rules are used automatically. |
mode | No | textToSQL (default) generates a query; explainSQL explains the SQL in prompt. |
If no dataSource and no dataSourceId is provided, the API still answers, but with no schema to ground it. Always send the schema for production use.
Data sources
Attached database
Pass the id of a database from your databases. Its schema and any rules you defined are used, and it works with schemas far too large to send with every request:
{
"prompt": "Get the user with id 13",
"engine": "postgres",
"engineVersion": "17",
"dataSourceId": "cmf1example0008abcd1234efgh"
}Schema array
The recommended inline format is an array of columns. references and meta are optional:
[
{
"table": "users",
"column": "id",
"type": "bigint",
"meta": "PK"
},
{
"table": "users",
"column": "name",
"type": "text"
},
{
"table": "orders",
"column": "user_id",
"type": "bigint",
"references": "users.id"
}
]You can retrieve your database schema as an array with a ready-made SQL query for the common engines.
Schema string
Very small schemas can be sent as semicolon-separated lines (table;column;type;references;meta):
users;id;bigint;;
users;name;text;;
orders;user_id;bigint;users.id;Response
A successful request returns the generated query:
{
"query": "SELECT * FROM users WHERE id = 13;"
}An error always comes back in the same envelope with an HTTP error status:
{
"error": "No active subscription found. See /pricing to upgrade."
}| Status | Meaning |
|---|---|
200 | Query generated. |
400 | The request body or engine is invalid / not supported. |
401 | Missing or invalid API key. |
402 | No active paid plan, or the plan's credits are used up. |
413 | The schema is larger than the API accepts (about 150k tokens). |
429 | Too many requests. Retry after a short pause. |
500 | Generation failed. Retry; if it keeps failing, contact support. |
Each successful request uses one generation from your plan. Prefer dataSourceId for large schemas, and cache results where the same question appears often.
Explain SQL
Set mode to explainSQL and send the query as the prompt. The response keeps the same envelope; query contains the Markdown explanation:
const response = await fetch('https://api.sqlai.ai/v2', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${process.env.SQLAI_API_KEY}`,
},
body: JSON.stringify({
mode: 'explainSQL',
prompt: 'SELECT u.name, COUNT(o.id) FROM users u LEFT JOIN orders o ON o.user_id = u.id GROUP BY u.name;',
engine: 'postgres',
}),
});
const { query: explanation } = await response.json();
console.log(explanation);MongoDB and NoSQL
For mongodb, the API returns a db.runCommand() document instead of SQL. Everything else works the same:
const response = await fetch('https://api.sqlai.ai/v2', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${process.env.SQLAI_API_KEY}`,
},
body: JSON.stringify({
prompt: 'Find all products that are sold out',
engine: 'mongodb',
reasoning: 'fast',
}),
});
const { query } = await response.json();
// { find: "products", filter: { quantity: 0 } }Need help?
If an engine is missing, the rate limit is too low for your volume, or you want a dedicated contract, contact us.