Skip to main content

AI Query and Data Explorer

Two tools for safe, read-only access to your managed databases: AI Query translates natural language into SQL, and the Data Explorer lets you run arbitrary read-only queries and inspect schemas through the FoundryDB controller. Neither can mutate your data.

Both work with PostgreSQL and MySQL services in Running status.

AI Query (NL2SQL)

AI Query converts a plain-language question into a read-only SQL query. The translation is powered by Claude (Anthropic). You can translate, review, and optionally execute the result in two separate calls, or execute directly in a single step.

Requires the AI Query feature to be configured (an Anthropic API key in your deployment). Returns 501 if this is not set up.

Endpoints

POST /managed-services/{serviceId}/ai-query/translate
POST /managed-services/{serviceId}/ai-query/execute

Translate a Question to SQL

curl -u $USER:$PASS \
-X POST https://api.foundrydb.com/managed-services/$SERVICE_ID/ai-query/translate \
-H "Content-Type: application/json" \
-d '{
"question": "Show the top 10 largest tables by size",
"database_name": "defaultdb"
}'

Response:

{
"sql": "SELECT tablename, pg_total_relation_size(quote_ident(tablename)) AS size FROM pg_tables WHERE schemaname = 'public' ORDER BY size DESC LIMIT 10",
"explanation": "Lists the 10 largest tables in the public schema by total size including indexes.",
"database_type": "postgresql"
}
FieldDescription
questionRequired. Natural language question, max 1000 characters.
database_nameOptional. Target database. Defaults to the service default.

The sql field is empty when the question cannot be answered with a read-only query. A warning field is set when the model generated a blocked statement.

Execute a Query

curl -u $USER:$PASS \
-X POST https://api.foundrydb.com/managed-services/$SERVICE_ID/ai-query/execute \
-H "Content-Type: application/json" \
-d '{
"sql": "SELECT tablename, pg_total_relation_size(quote_ident(tablename)) AS size FROM pg_tables WHERE schemaname = '\''public'\'' ORDER BY size DESC LIMIT 10",
"database_name": "defaultdb"
}'

Response:

{
"columns": ["tablename", "size"],
"rows": [
["orders", 1234567890],
["products", 98765432]
],
"row_count": 2,
"execution_ms": 18,
"truncated": false
}

The execute endpoint accepts any read-only SQL, not only queries produced by translate. Only SELECT, SHOW, DESCRIBE, EXPLAIN, and WITH statements are permitted. The connection runs inside a READ ONLY transaction with a 30-second statement timeout. Results are capped at 1000 rows; truncated is true when the cap is hit.

Typical Workflow

  1. Call /ai-query/translate with a natural language question.
  2. Review the generated SQL and explanation.
  3. Call /ai-query/execute with the SQL once you are satisfied it is correct.

This two-step approach lets you inspect the query before it runs, which is useful in dashboards, chatbots, and support tools where you want a human review step.

Data Explorer

The Data Explorer provides brokered read-only query execution and schema introspection through the controller. It is designed for internal tools, dashboards, and scripts that need database access without direct database credentials.

Tasks are asynchronous. You POST to submit a task and GET to poll for the result.

Endpoints

POST /managed-services/{id}/data-explorer/query
GET /managed-services/{id}/data-explorer/query?task_id={task_id}
POST /managed-services/{id}/data-explorer/schema
GET /managed-services/{id}/data-explorer/schema?task_id={task_id}

Run a Query

Submit:

curl -u $USER:$PASS \
-X POST https://api.foundrydb.com/managed-services/$SERVICE_ID/data-explorer/query \
-H "Content-Type: application/json" \
-d '{
"statement": "SELECT id, name, created_at FROM products ORDER BY created_at DESC",
"database": "defaultdb",
"limit": 100,
"offset": 0,
"timeout_ms": 5000
}'

Response (202 Accepted):

{ "task_id": "a1b2c3d4-..." }

Poll:

curl -u $USER:$PASS \
"https://api.foundrydb.com/managed-services/$SERVICE_ID/data-explorer/query?task_id=a1b2c3d4-..."

While the task is running, the poll response has status: "pending" or status: "in_progress" with HTTP 202. Once complete, it returns HTTP 200:

{
"task_id": "a1b2c3d4-...",
"status": "completed",
"result": {
"columns": [
{ "name": "id", "type": "int8" },
{ "name": "name", "type": "text" },
{ "name": "created_at", "type": "timestamptz" }
],
"rows": [
[1001, "Widget Pro", "2026-06-20T08:32:00Z"]
],
"row_count": 1,
"truncated": false
}
}

Request Body Fields

FieldDefaultDescription
statementRequiredSQL to execute. Must be read-only (SELECT, SHOW, DESCRIBE, EXPLAIN, WITH).
databaseEngine defaultDatabase to connect to.
limitMax allowedRow cap. Clamped to the platform maximum.
offset0Starting row offset.
timeout_msDefaultStatement timeout in milliseconds. Clamped to the platform maximum.

Introspect a Schema

Submit:

curl -u $USER:$PASS \
-X POST https://api.foundrydb.com/managed-services/$SERVICE_ID/data-explorer/schema \
-H "Content-Type: application/json" \
-d '{ "database": "defaultdb" }'

The request body is optional. If omitted, the service's default database is introspected.

Poll:

curl -u $USER:$PASS \
"https://api.foundrydb.com/managed-services/$SERVICE_ID/data-explorer/schema?task_id=a1b2c3d4-..."

Response when complete:

{
"task_id": "a1b2c3d4-...",
"status": "completed",
"result": {
"tables": [
{
"name": "products",
"schema": "public",
"columns": [
{ "name": "id", "type": "int8", "nullable": false },
{ "name": "name", "type": "text", "nullable": false },
{ "name": "created_at", "type": "timestamptz", "nullable": true }
]
}
]
}
}

Polling Pattern

The response status field and HTTP status code together tell you whether to keep polling:

statusHTTPAction
pending202Poll again.
in_progress202Poll again.
completed200Read result.
failed200Read error_message.

Poll every 500ms to 1 second for typical queries. Tasks complete quickly for simple queries.

Security Model

Both AI Query and the Data Explorer enforce read-only access at multiple layers:

  • The controller checks the statement against an allowlist of read-only statement types before dispatching the task.
  • The agent runs the query inside a READ ONLY transaction, so any statement that slips through the allowlist check is rejected by the database engine.
  • A statement timeout prevents long-running queries from holding connections.
  • All queries are recorded in the platform audit log with the submitting user, service ID, database, and statement text.

What's Next