Skip to main content

Overview

The Usage API lets you pull ACU (Activity Consumption Unit) consumption data for your organization programmatically — by time period, user, or usage category. Use it to build internal dashboards, feed billing systems, or monitor spend across teams. Base URL: https://api.console.textql.com/billing/v1
You can query usage data directly in Ana without any API setup. The TextQL Usage connector is already available in your platform inside the connector selection.
TextQL Usage connector in chat

Authentication

All requests require a Bearer token. Your token is a Base64-encoded string in the format {member_id}:{api_token}, created in Settings → Developers → API Keys. Pass it in one of two ways:
# Authorization header
-H 'Authorization: Bearer YOUR_TOKEN'

# Or as a custom header
-H 'tql_api_key: YOUR_TOKEN'

Your First Request

Fetch the last 90 days of usage for your organization with a single call:
curl 'https://api.console.textql.com/billing/v1/usage' \
  -H 'Authorization: Bearer YOUR_TOKEN'
Response:
{
  "data": [
    {
      "start_datetime": "2026-01-31T00:00:00Z",
      "end_datetime": "2026-02-01T00:00:00Z",
      "organization": "acme-engineering",
      "email": "m.chen@acme.com",
      "category": "llm_tokens",
      "acu": 8241.05
    }
  ],
  "pagination": {
    "page": 1,
    "page_size": 100,
    "total_count": 3
  }
}
Each record represents one user’s usage within one time bucket, for one category.

Parameters

All parameters are optional query parameters on GET /usage.

Date Range

ParameterFormatDefaultDescription
start_dateRFC 333990 days before end_dateInclusive lower bound
end_dateRFC 3339Current UTC timeExclusive upper bound
# Usage for January 2026
curl 'https://api.console.textql.com/billing/v1/usage?start_date=2026-01-01T00:00:00Z&end_date=2026-01-31T23:00:00Z' \
  -H 'Authorization: Bearer YOUR_TOKEN'

Granularity

Controls the size of each time bucket. Defaults to day.
ValueBucket size
hour1 hour
day1 calendar day
month1 calendar month
# Monthly rollup
curl 'https://api.console.textql.com/billing/v1/usage?granularity=month' \
  -H 'Authorization: Bearer YOUR_TOKEN'

Filtering

By organization — useful for tenants with multiple orgs:
curl 'https://api.console.textql.com/billing/v1/usage?organization=acme-engineering,acme-research' \
  -H 'Authorization: Bearer YOUR_TOKEN'
By user email — case-insensitive:
curl 'https://api.console.textql.com/billing/v1/usage?email=j.ramirez@acme.com,s.patel@acme.com' \
  -H 'Authorization: Bearer YOUR_TOKEN'
By usage category:
CategoryWhat it measures
llm_tokensLLM inference consumption
compute_hoursPython and execution environment usage
cell_executionsIndividual cell runs
curl 'https://api.console.textql.com/billing/v1/usage?category=llm_tokens,compute_hours' \
  -H 'Authorization: Bearer YOUR_TOKEN'
Filters can be combined freely:
# LLM usage for one user, by hour, for a specific week
curl 'https://api.console.textql.com/billing/v1/usage?email=m.chen@acme.com&category=llm_tokens&granularity=hour&start_date=2026-01-27T00:00:00Z&end_date=2026-02-03T00:00:00Z' \
  -H 'Authorization: Bearer YOUR_TOKEN'

Sorting

Use the sort parameter to control result order. Prefix with - for descending.
ValueDescription
start_datetimeOldest first
-start_datetimeNewest first (default)
acuLowest usage first
-acuHighest usage first
emailAlphabetical by user
-emailReverse alphabetical by user
curl 'https://api.console.textql.com/billing/v1/usage?sort=-acu' \
  -H 'Authorization: Bearer YOUR_TOKEN'

Pagination

ParameterDefaultMax
page_size1001000
page1
# Page 2, 50 records per page
curl 'https://api.console.textql.com/billing/v1/usage?page=2&page_size=50' \
  -H 'Authorization: Bearer YOUR_TOKEN'
Use pagination.total_count in the response to calculate how many pages exist.

Code Examples

Python — fetch all records across pages:
import requests

TOKEN = "your-token"
BASE = "https://api.console.textql.com/billing/v1"
headers = {"Authorization": f"Bearer {TOKEN}"}

def get_all_usage(**params):
    records = []
    page = 1
    while True:
        resp = requests.get(f"{BASE}/usage", headers=headers, params={**params, "page": page, "page_size": 1000})
        data = resp.json()
        records.extend(data["data"])
        if len(records) >= data["pagination"]["total_count"]:
            break
        page += 1
    return records

# Example: all LLM usage for January, grouped by month
usage = get_all_usage(
    start_date="2026-01-01T00:00:00Z",
    end_date="2026-02-01T00:00:00Z",
    granularity="month",
    category="llm_tokens",
)
JavaScript:
const TOKEN = "your-token";
const BASE = "https://api.console.textql.com/billing/v1";

async function getUsage(params = {}) {
  const query = new URLSearchParams(params).toString();
  const res = await fetch(`${BASE}/usage?${query}`, {
    headers: { Authorization: `Bearer ${TOKEN}` },
  });
  return res.json();
}

// Example: top spenders this month
const data = await getUsage({
  granularity: "month",
  sort: "-acu",
  page_size: 10,
});

Response Fields

FieldTypeDescription
start_datetimestring (UTC)Start of the time bucket, inclusive
end_datetimestring (UTC)End of the time bucket, exclusive
organizationstringOrganization name
emailstringUser email (lowercase). Empty if usage cannot be attributed to a specific user
categorystringUsage category
acunumberUsage in ACUs. Records with zero or negative values are omitted

Error Reference

StatusCodeCause
400invalid_parameterBad date range, unknown category, unknown org, or invalid granularity
401unauthorizedToken is missing, invalid, or expired
403forbiddenToken does not have access to the requested organization’s data

Troubleshooting & Support

ProblemWhat to check
401 on every requestConfirm your token is Base64-encoded in {member_id}:{api_token} format and hasn’t expired
403 on a specific orgYour API key may not have access to that organization — check your role in Settings → Members
Empty data arrayThe filters you applied may return no records — try widening the date range or removing category/email filters
acu values seem lowRecords with zero or negative ACU are omitted; usage may also be split across multiple category buckets
Unknown org errorThe organization value must match the org name exactly as it appears in TextQL
If you’re still running into issues, contact support at support@textql.com and include the full request URL and response body.