FAQs

Indiequery API Documentation

By Marc Hendricks

Contents


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

  1. Log in to Indiequery
  2. Go to your Account page
  3. 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 executing
  • SUCCESS - Query completed successfully
  • ERROR - Query failed
  • TIMEOUT - 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 by
  • sort_direction - asc or desc

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:

  1. Structured responses: All responses are JSON with consistent field names
  2. Predictable endpoints: RESTful patterns make URLs easy to construct
  3. Clear error messages: Error responses include descriptive messages
  4. Pagination: Large result sets are paginated with standard page and page_size parameters

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