Indiequery API Documentation
Contents
- Overview
- Authentication
- Rate Limits
- Queries
- Dashboards
- Visualizations
- Error Responses
- Tips for AI/LLM Integration
Overview
Indiequery provides a REST API for programmatic access to your queries. Use the API to integrate Indiequery into your workflows, scripts, or applications.
Base URL: https://app.indiequery.com/api
Authentication
All API requests require authentication using an API key.
Getting Your API Key
- Log in to Indiequery
- Go to your Account page
- Your API key is displayed in the API Key card
Using Your API Key
Include your API key in the Authorization header:
Authorization: Bearer iq_your_api_key_here
Example with curl:
curl -H "Authorization: Bearer iq_abc123..." https://app.indiequery.com/api/queries
Rate Limits
To ensure fair usage, the API enforces the following rate limits:
| Limit Type | Rate |
|---|---|
| General requests | 60 per minute |
| Burst requests | 10 per second |
| Query executions | 30 per minute |
When you exceed a rate limit, the API returns a 429 Too Many Requests response.
Endpoints
List Queries
GET /api/queries
Returns all queries for your account.
Response:
[
{
"id": 1,
"name": "Active Users",
"connection": 1,
"connection_name": "Production DB",
"created_at": "2024-01-01T00:00:00Z",
"updated_at": "2024-01-02T00:00:00Z"
}
]
Get Query
GET /api/queries/{id}
Returns a single query with full details.
Response:
{
"id": 1,
"name": "Active Users",
"sql_query": "SELECT * FROM users WHERE active = true",
"connection": 1,
"connection_name": "Production DB",
"latest_run": {
"id": 10,
"status": "SUCCESS",
"executed_at": "2024-01-02T00:00:00Z",
"execution_time": 0.5,
"row_count": 100
},
"created_at": "2024-01-01T00:00:00Z",
"updated_at": "2024-01-02T00:00:00Z"
}
Create Query
POST /api/queries
Creates a new query.
Request Body:
{
"name": "Active Users",
"sql_query": "SELECT * FROM users WHERE active = true",
"connection": 1,
"execute": true
}
| Field | Required | Description |
|---|---|---|
| name | Yes | Query name (max 255 characters) |
| sql_query | Yes | SQL query to execute |
| connection | Yes | Connection ID |
| execute | No | Run the query immediately (default: false) |
Response: Returns the created query object.
Update Query
PUT /api/queries/{id}
Updates all fields of a query.
Request Body: Same as Create Query.
Partial Update (Rename)
PATCH /api/queries/{id}
Updates specific fields of a query.
Request Body:
{
"name": "New Query Name"
}
You can update any combination of: name, sql_query, connection, execute.
Delete Query
DELETE /api/queries/{id}
Deletes a query.
Response: 204 No Content
Run Query
To execute a query, use the execute parameter when creating or updating:
PATCH /api/queries/{id}
Content-Type: application/json
{
"execute": true
}
Response: The response includes a latest_run object with the run ID:
{
"id": 1,
"name": "My Query",
"latest_run": {
"id": 42,
"status": "PENDING",
"executed_at": "2024-01-02T00:00:00Z"
}
}
Use latest_run.id to poll the run status endpoint for results.
List Query Runs
GET /api/queries/{query_id}/runs
Returns execution history for a query.
Query Parameters:
page(default: 1)page_size(default: 50, max: 100)status(optional): Filter by PENDING, SUCCESS, ERROR, TIMEOUT
Response:
{
"count": 10,
"next": null,
"previous": null,
"results": [
{
"id": 1,
"executed_at": "2024-01-02T00:00:00Z",
"execution_time": 0.5,
"row_count": 100,
"status": "SUCCESS",
"error_message": null
}
]
}
Get Query Run Results
GET /api/queries/{query_id}/runs/{run_id}
Returns execution status and results.
Query Parameters:
page(default: 1)page_size(default: 25, max: 1000)include_sql(default: false): Include the SQL query text
Response:
{
"id": 1,
"status": "SUCCESS",
"execution_time": 0.5,
"row_count": 100,
"executed_at": "2024-01-02T00:00:00Z",
"error_message": null,
"results": {
"columns": ["id", "name", "email"],
"column_types": ["integer", "text", "text"],
"data": [
[1, "Alice", "[email protected]"],
[2, "Bob", "[email protected]"]
],
"page": 1,
"page_size": 25,
"total_rows": 100
}
}
Status Values:
PENDING- Query is executingSUCCESS- Query completed successfullyERROR- Query failedTIMEOUT- Query timed out
Dashboards
Dashboards group multiple queries together for organized viewing and bulk refresh.
List Dashboards
GET /api/dashboards
Returns all dashboards for your account.
Response:
[
{
"id": 1,
"name": "Sales Dashboard",
"query_count": 5,
"created_at": "2024-01-01T00:00:00Z",
"updated_at": "2024-01-02T00:00:00Z"
}
]
Get Dashboard
GET /api/dashboards/{id}
Returns a dashboard with its assigned queries.
Response:
{
"id": 1,
"name": "Sales Dashboard",
"query_count": 2,
"queries": [
{
"id": 1,
"query_id": 10,
"query_name": "Daily Revenue",
"order": 0,
"added_at": "2024-01-01T00:00:00Z"
},
{
"id": 2,
"query_id": 11,
"query_name": "Active Users",
"order": 1,
"added_at": "2024-01-01T00:00:00Z"
}
],
"created_at": "2024-01-01T00:00:00Z",
"updated_at": "2024-01-02T00:00:00Z"
}
Create Dashboard
POST /api/dashboards
Creates a new dashboard.
Request Body:
{
"name": "Sales Dashboard",
"project": 1
}
| Field | Required | Description |
|---|---|---|
| name | Yes | Dashboard name (max 255 characters) |
| project | Yes | ID of the parent container |
Response: Returns the created dashboard object.
Update Dashboard
PATCH /api/dashboards/{id}
Renames a dashboard.
Request Body:
{
"name": "New Dashboard Name"
}
Delete Dashboard
DELETE /api/dashboards/{id}
Deletes a dashboard and removes all query assignments.
Response: 204 No Content
Add Query to Dashboard
POST /api/dashboards/{id}/queries
Adds a query to a dashboard.
Request Body:
{
"query_id": 10,
"order": 0
}
| Field | Required | Description |
|---|---|---|
| query_id | Yes | ID of the query to add |
| order | No | Display order (default: 0) |
Remove Query from Dashboard
DELETE /api/dashboards/{id}/queries/{query_id}
Removes a query from a dashboard.
Response: 204 No Content
Refresh Dashboard
POST /api/dashboards/{id}/refresh
Executes all queries on the dashboard.
Response:
{
"status": "started",
"query_count": 5,
"tasks": [
{"query_id": 1, "query_name": "Revenue", "task_id": "abc-123", "status": "started"}
],
"skipped": [],
"errors": []
}
Reorder Dashboard Queries
PATCH /api/dashboards/{id}/queries/reorder
Reorders all queries on a dashboard. You must include ALL queries currently on the dashboard.
Request Body:
{
"queries": [
{"query_id": 10, "order": 0},
{"query_id": 11, "order": 1},
{"query_id": 12, "order": 2}
]
}
Get Query Dashboard Relationships
GET /api/queries/{query_id}/dashboards
Returns which dashboards a query is assigned to and which it can be added to.
Response:
{
"assigned_dashboards": [
{"id": 1, "name": "Sales Dashboard", "query_count": 5}
],
"available_dashboards": [
{"id": 2, "name": "Marketing Dashboard", "query_count": 3}
]
}
Visualizations
Visualizations render query results as charts or tables.
List Visualizations
GET /api/queries/{query_id}/visualizations
Returns all visualizations for a query.
Response:
[
{
"id": 1,
"visualization_type": "line_chart",
"created_at": "2024-01-01T00:00:00Z",
"updated_at": "2024-01-02T00:00:00Z"
}
]
Get Visualization
GET /api/queries/{query_id}/visualizations/{id}
Returns a visualization with its configuration and data.
Query Parameters (for tables):
page(default: 1)sort_column- Column name to sort bysort_direction-ascordesc
Response:
{
"visualization": {
"id": 1,
"visualization_type": "line_chart",
"query_name": "Daily Revenue"
},
"config": {
"x_axis_column": "date",
"show_legend": true,
"display_mode": "overlay",
"series": [
{
"name": "Revenue",
"values_column": "revenue",
"series_type": "line",
"color": "#3B82F6"
}
]
},
"data": {
"columns": ["date", "revenue"],
"rows": [["2024-01-01", 1000], ["2024-01-02", 1200]]
},
"status": "ready"
}
Create Visualization
POST /api/queries/{query_id}/visualizations
Creates a new visualization for a query.
Request Body (Chart):
{
"visualization_type": "line_chart",
"config": {
"x_axis_column": "date",
"show_legend": true,
"display_mode": "overlay"
},
"series": [
{
"name": "Revenue",
"values_column": "revenue",
"series_type": "line",
"color": "#3B82F6"
}
]
}
Request Body (Table):
{
"visualization_type": "table",
"config": {
"rows_per_page": 50,
"show_row_numbers": true,
"enable_sorting": true
}
}
Visualization Types:
| Type | Description |
|---|---|
| line_chart | Time series with lines |
| area_chart | Filled area chart |
| bar_chart | Vertical bars |
| table | Paginated data table |
Update Visualization
PUT /api/queries/{query_id}/visualizations/{id}
Updates a visualization's configuration.
Request Body: Same format as Create.
Delete Visualization
DELETE /api/queries/{query_id}/visualizations/{id}
Deletes a visualization.
Response: 204 No Content
Error Responses
The API uses standard HTTP status codes:
| Code | Description |
|---|---|
| 400 | Bad Request - Invalid input |
| 401 | Unauthorized - Invalid or missing API key |
| 403 | Forbidden - Endpoint not allowed via API |
| 404 | Not Found - Resource doesn't exist |
| 429 | Too Many Requests - Rate limit exceeded |
| 500 | Server Error - Something went wrong |
Error response format:
{
"error": "Description of what went wrong"
}
Tips for AI/LLM Integration
This API is designed to be easily consumed by AI assistants and LLMs:
- Structured responses: All responses are JSON with consistent field names
- Predictable endpoints: RESTful patterns make URLs easy to construct
- Clear error messages: Error responses include descriptive messages
- Pagination: Large result sets are paginated with standard
pageandpage_sizeparameters
When using this API with an AI assistant:
- Store your API key securely (environment variable or secrets manager)
- Handle rate limits with exponential backoff
- Poll query runs until status is SUCCESS or ERROR before fetching results