Skip to main content

Query API

The Query API lets you take the logic and structure you define in Qluent and use it outside the product. Ask questions in plain English and receive structured data responses—perfect for building AI experiences.

Getting started

Prerequisites

  • A Qluent project with connected data sources
  • Project owner permissions (required to manage API keys)

Creating an API key

  1. Navigate to Project SettingsAPI Settings
  2. Click Create API Key
  3. Enter a descriptive name (e.g., "Slack Integration", "Query agent")
  4. Copy the key immediately—it will only be shown once

We store only a one-way hash of your key. If you lose it, you'll need to create a new one.

Authentication

All requests require your key in the X-API-Key header:

curl -X POST "https://api.qluent.io/api/v1/query/" \
-H "X-API-Key: qk_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{"question": "What were total sales last month?", "user_email": "analyst@company.com"}'

Making requests

Endpoint

POST https://api.qluent.io/api/v1/query/

Request body

FieldTypeRequiredDescription
questionstringYesNatural language question to answer
user_emailstringYesEmail of the user making the request (for audit)
thread_idstringThread ID for follow-up questions

Example request

curl -X POST "https://api.qluent.io/api/v1/query/" \
-H "X-API-Key: qk_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"question": "What were total sales last month?",
"user_email": "analyst@company.com"
}'

Example response

{
"success": true,
"thread_id": "thr_abc123",
"message_id": "msg_def456",
"question": "What were total sales last month?",
"sql": "SELECT SUM(amount) FROM sales WHERE date >= '2024-01-01'",
"explanation": "Total sales last month were $125,000 across 847 transactions.",
"data": [{"total_sales": 125000, "transaction_count": 847}],
"columns": ["total_sales", "transaction_count"],
"row_count": 1
}

Large result handling

For queries returning more than 1,000 rows, the response includes URLs for accessing the full dataset:

FieldTypeDescription
download_urlstringURL to download results as CSV. Requires browser authentication.
google_sheets_urlstringURL to open results in Google Sheets. Requires OAuth consent on first use.

When these URLs are present, the data array contains only the first 1,000 rows. Use the URLs to access the complete dataset.

Follow-up questions

Continue a conversation by including the thread_id from the previous response:

curl -X POST "https://api.qluent.io/api/v1/query/" \
-H "X-API-Key: qk_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"question": "Break that down by region",
"thread_id": "thr_abc123",
"user_email": "analyst@company.com"
}'

Streaming responses (SSE)

For real-time progress updates during query execution, use the streaming endpoint:

POST https://api.qluent.io/api/v1/query/stream

The request body is the same as the standard endpoint. The response is a Server-Sent Events stream with these event types:

EventDescription
statusProcessing status updates
sqlThe generated SQL query
resultFinal query result with data
clarificationQuestion requires clarification
errorError occurred during processing

Feedback endpoint

Submit feedback on query responses to help improve result quality.

Endpoint

POST https://api.qluent.io/api/v1/feedback/

Request body

FieldTypeRequiredDescription
message_idstringYesThe message_id from a query response
positivebooleanYestrue for positive feedback, false for negative
commentstringNoOptional feedback text (max 10,000 chars)
user_emailstringYesEmail of user submitting feedback (must have project access)

Example request

curl -X POST "https://api.qluent.io/api/v1/feedback/" \
-H "X-API-Key: qk_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"message_id": "msg_def456",
"positive": true,
"comment": "Exactly what I needed",
"user_email": "analyst@company.com"
}'

Example response

{
"success": true,
"feedback_id": 123,
"message": "Feedback submitted successfully"
}

Error codes

Error CodeHTTP StatusDescription
INVALID_REQUEST400Malformed request body
INVALID_API_KEY401Invalid or missing API key
USER_NOT_AUTHORIZED403User does not have access to this project
MESSAGE_NOT_FOUND404Invalid message_id or not in project

Error handling

Error CodeHTTP StatusDescription
INVALID_REQUEST400Malformed request body
INVALID_API_KEY401Invalid or missing API key
USER_NOT_AUTHORIZED403User does not have access to this project
PROJECT_NOT_FOUND404Project not found
THREAD_NOT_FOUND404Thread not found or expired
CLARIFICATION_NEEDED422Question requires clarification
CANNOT_ANSWER422Question cannot be answered with available data
RATE_LIMIT_EXCEEDED429Too many requests
EXECUTION_ERROR500Failed to execute query
DATA_SOURCE_ERROR502Unable to connect to data source
SERVICE_UNAVAILABLE503Service temporarily unavailable
QUERY_TIMEOUT504Query execution timed out

Rate limits

LimitValue
Requests per minute100 per project
Concurrent requests10 per project
Max query execution time5 minutes

When rate limited, implement exponential backoff using the retry_after field in the response.

Security FAQ

How are API keys generated and stored?

Your API key is generated using cryptographically secure randomness. The full key (qk_...) is shown only once at creation—we never store or display it again. We store only a one-way hash, so even if our database were compromised, your actual key cannot be recovered.

How does authentication work?

Every API request requires your key in the X-API-Key header. We hash the incoming key and compare it against stored hashes—your raw key never touches our database. Keys are project-scoped, meaning a key can only access data within its assigned project.

How is streaming secured?

The SSE streaming endpoint uses the same API key authentication as the standard query endpoint. All data is transmitted over HTTPS with TLS encryption. Each event in the stream is authenticated as part of the same request that provided the API key.

Can I encrypt API responses?

Yes. You can configure PGP encryption per API key:

  1. Upload your PGP public key in API Settings
  2. All responses are encrypted with your public key before transmission
  3. Only you can decrypt with your private key

Even Qluent cannot read the encrypted payload. Encryption can be enabled, updated, or removed at any time from Project Settings → API Settings.

Who can manage API keys?

Only project owners can create, configure, or revoke API keys. Keys can be instantly revoked if compromised. We track last_used_at so you can audit key activity.

What about rate limiting?

Per-project rate limits prevent abuse. Rate limit headers in every response let you monitor your usage.

Managing keys

  • View keys: Project Settings → API Settings
  • Revoke keys: Click Revoke next to any key (takes effect immediately)
  • Configure encryption: Click Configure to upload your PGP public key

Revoked keys stop working instantly. Applications using the key will receive 401 errors.