Skip to main content

Usage

Monitor request volume, token consumption and performance in detail. The page's eyebrow reads Analytics and its heading is Usage.

No money on this page

Usage reports volume, not charges. There is no cost card, no cost column and no cost chart anywhere on screen. Amounts live on Billing, with one exception: the Export files carry cost figures. See Export.

Choosing whose usage to view

A My Usage / Team Usage toggle sits at the top of the page. It defaults to My Usage, and Team Usage is available only to organization admins and owners. Team Usage widens every figure on the page to the whole organization and reveals the Organization Users Usage table.

One API key at a time

This page scopes usage to a person or to the whole organization. To read the same board for a single credential, open API Keys and use the Analytics action on the key's row. The metrics, the ranges and the tables are the same ones described here, narrowed to that one key. See Key Analytics.

Choosing a date range

Five range pills sit above the metrics:

Today · 7D · 30D · 90D · Custom

The default is 30D. The 7, 30 and 90 day pills are exact calendar ranges aligned to your active timezone, not approximate rolling windows, so opening the same pill twice returns the same period.

Presets are only these five

There is no Yesterday pill and no Last 24 hours pill. Both windows are available, but as fixed ranges inside the Custom popover.

Custom range

Selecting Custom opens a split-panel popover so you can pick a window whichever way is fastest:

  • Quick ranges (left): a "Last [N] ⟨unit⟩" builder (minutes, hours, days, weeks, months, years) plus one-click fixed ranges such as This week and This month. Choosing one fills the custom range on the right.
  • Custom range (right): a timezone badge, collapsed FROM and TO date-time fields, a live summary of the window, and Apply.

Each FROM/TO field opens a compact calendar for the date and an HH:mm field for the time (24-hour), so you can narrow usage to an incident window ("between 14:30 and 16:00 today") rather than only whole days.

  • Time errors appear on blur only, so you are not warned mid-keystroke; an invalid time such as 25:70 is rejected.
  • Nested popovers close innermost-first: Escape or an outside click closes the open calendar or time popover before the whole picker.
  • Ranges are capped to the last 365 days. A longer quick range such as "Last 2 years" is clamped, with a "Limited to the last 365 days" note.

The outer preset pills remain date-only; the whole end-of-day is included automatically.

Times use your local timezone

Dates, times and preset day boundaries resolve against your browser's local timezone, and the picker displays the timezone it is using. An explicit, non-UTC timezone on your profile takes precedence over the browser. A profile timezone of literally UTC is treated as unset and falls back to the browser.

Chart granularity

Granularity is derived from the range you pick rather than fixed:

Range lengthPoints
Up to 7 daysHourly
Up to 90 daysDaily
LongerWeekly

Daily, weekly and monthly points are cut on your local day boundaries, daylight-saving transitions included, so traffic just before local midnight is charted on the day it happened rather than on the neighbouring one. Hourly points stay on UTC hours — an hour is an hour wherever you are.

Headline metrics

Eight tiles sit at the top. Each carries a delta pill comparing the selected range against the immediately preceding period of equal length, plus a sparkline.

TileMeaning
Total RequestsChat and completion calls in range
Total TokensInput plus output
Input TokensPrompt tokens
Output TokensGenerated tokens
Request Success RateShare of requests that completed
Avg DurationMean end-to-end request time
Avg Tokens/SecMean generation throughput
Top ModelMost-used model in range

The caption beneath the grid states the scope of all eight:

Every figure above counts chat and completion requests, metered in tokens. Audio is metered separately, in seconds and characters, and is not counted here.

Usage over time

The chart offers a layout control: Focus, Board, or Overlay, defaulting to Focus. Focus foregrounds one measure at a time, Board lays the measures out side by side, and Overlay draws them together on shared axes.

Four measures are available: Requests, Tokens, Input tokens and Output tokens.

Insight cards

Token distribution

A donut splitting input against output tokens, with an I/O ratio footer.

Performance & cache

RowMeaning
Avg LatencyMean request duration
Tokens / requestMean tokens produced and consumed per call
Avg Tokens/SecMean generation throughput
Cache ReadInput tokens served from the prefix cache
Cache hit requestsRequests that hit the cache at all
Cache hit rateShare of requests that hit the cache
Cache Read counts tokens, not requests

Cache Read is a token count: how many prompt tokens were served from the prefix cache. Cache hit requests and Cache hit rate count requests, and are a different measure. The same Cache Read label is used on the Dashboard token split row and in the cache popover of the Usage by Model table. Plan and pricing copy keeps its own wording — a plan's Cached $/1M rate and its cached-token quota rows refer to the same tokens under the names used on Plans and Billing.

Models with automatic prefix caching reuse the computed prefix of a prompt across requests, and cached input is charged at a reduced rate. Keep the shared or system portion of your prompts stable at the start of each request to make the cache work for you.

Audio usage

Subtitled "Speech-to-text and text-to-speech requests, metered in seconds of audio and characters of text", this card reports three measures. Each is drawn only when it is non-zero:

MeasureUnit
Audio RequestsCalls
TranscribedSeconds of input audio
SynthesizedCharacters of input text

The card carries this note:

Audio holds no plan quota or commitment allowance. It is measured on its own, separately from token usage.

In My Usage the card also carries an Organization-wide pill: audio totals always cover the whole organization, even in your personal view. That is a deliberate choice, not a missing number. A per-member audio figure would be partial in a way you could not detect, because audio requests only began recording which member made them partway through the platform's history and there is no way to work out the earlier ones. An organization total has no such hole, and it is the same number for every role.

When there is nothing to show, the card reads "No audio usage in the selected date range."

Speech-to-text is metered per second of input audio, rounded up, with an optional per-model minimum billed duration; a rate displayed per minute is a readability convenience, not the billing granularity. Text-to-speech is priced on the input text, per 1,000,000 characters, and a single request accepts at most 4096 characters. See Speech to Text and Text to Speech.

Tables

Usage by Model

ColumnDescription
ModelModel identifier
Total RequestsCalls to that model
InputInput tokens
OutputOutput tokens
Total TokensInput plus output
Avg LatencyMean request duration
Share of tokensThat model's percentage of all tokens in range

Organization Users Usage

Visible in Team Usage only, and only to admins and owners. It lists each member with their request count, tokens, share of the organization and status.

A blank cell is not a zero

When a member's figures cannot be read, the cell renders Not available rather than 0. An unreadable number is never displayed as an absence of usage.

Recent Activity

The most recent text requests, capped at 10 rows, with a Refresh button. There is no "view all" link; use the Export for a full history.

Export

Open the Export menu on the Usage page. Choose a format, then an option.

Formats

  • Excel (.xlsx): one styled workbook with one sheet per section.
  • CSV (.csv): a CSV file cannot hold multiple sheets, so the export always downloads a ZIP archive containing one CSV per sheet. Each member is numbered in sheet order and named after its sheet: a Quick Export of your personal usage produces 01_overview.csv, 02_models.csv and 03_daily_trends.csv. Each file keeps its own headers and a UTF-8 byte-order mark, so it opens cleanly in Excel or any spreadsheet tool.

Options

  • Quick Export: "Includes Overview, Models, and Daily Trends."
  • Export With History: "Adds a Usage History sheet with the most recent 5,000 rows." The detail sheet is fetched in pages and stitched together; the 5,000-row cap keeps the file performant.

In Team Usage the export also carries a Users sheet.

The export is the only place cost figures survive

Nothing on the Usage screen is priced, but the exported sheets are. The Overview sheet carries Total Cost, Avg Cost / Request and Audio Cost; the Models sheet carries a per-model Cost column; the Daily Trends sheet carries a per-day Cost column. If you need priced usage as a file, this is where to get it.

The selected date range, including hour and minute when set through Custom, is preserved in the file's metadata.

Spending alerts

When you have a personal daily limit configured, the platform emails you at 80% and 90% of it. See Cost Limits.

API Reference

Get current usage

curl "https://api.bulutistan.ai/api/v1/usage/current" \
-H "Authorization: Bearer sk-proj-your-api-key"
This endpoint is period-to-date

/usage/current reports the billing period that is open now, from the instant that period opened to now. It accepts no start_date or end_date. For an arbitrary range, use /usage/tenant-breakdown or the portal's Export.

period_start is that instant, seconds included — a period opened mid-day by a plan change, a billing-mode change or a commitment renewal reports the moment it opened, not midnight. This is the same window /api/v1/plan/current and the Billing page report, so the three agree. It was previously a fixed calendar month, which matched the billing period only for organizations anchored on the 1st. See Plans.

Query parameters

ParameterValuesDefaultNotes
scopeuser, tenantusertenant is honoured only for admins and owners. A member asking for tenant is narrowed to their own rows rather than refused.
formatdisplay, detail, invoice, rawdisplayControls cost precision: user-friendly, full precision, two decimals, and eight decimals respectively.
# Organization-wide usage (admin or owner)
curl "https://api.bulutistan.ai/api/v1/usage/current?scope=tenant" \
-H "Authorization: Bearer sk-proj-your-api-key"

Response fields

tenant_id, period_start, period_end, total_requests, successful_requests, failed_requests, success_rate, total_input_tokens, total_output_tokens, total_tokens, total_cached_tokens, cache_hit_requests, average_tokens_per_request, total_cost, total_cache_savings, average_cost_per_request, average_cost_per_token, total_cost_formatted, average_cost_per_request_formatted, average_cost_per_token_formatted, currency, average_duration_ms, models_used, top_model, models_breakdown, audio.

{
"tenant_id": "c63f88b3-cb39-4f07-8353-4982557f7533",
"period_start": "2026-08-01T00:00:00",
"period_end": "2026-08-14T09:30:00",
"total_requests": 1250,
"successful_requests": 1200,
"failed_requests": 50,
"success_rate": 0.96,
"total_input_tokens": 125000,
"total_output_tokens": 85000,
"total_tokens": 210000,
"total_cached_tokens": 18000,
"cache_hit_requests": 210,
"average_tokens_per_request": 168.0,
"total_cost": "45.50000000",
"total_cost_formatted": "$45.50",
"currency": "USD",
"average_duration_ms": 850.0,
"models_used": ["your-chat-model"],
"top_model": "your-chat-model",
"models_breakdown": [
{
"model_name": "your-chat-model",
"requests": 1250,
"input_tokens": 125000,
"output_tokens": 85000,
"total_tokens": 210000,
"total_cost": 45.5,
"avg_duration_ms": 850.0
}
]
}
audio may be absent

The audio block is omitted from the payload entirely (not returned as null) when there is no audio usage, and it is populated only on a tenant-scoped read. Its absence from a personal-scope response does not mean your organization sent no audio traffic. Read audio totals with scope=tenant.

Get usage history

Individual usage events, most recent first.

curl "https://api.bulutistan.ai/api/v1/usage/history?api_key_id=<key-id>&limit=50" \
-H "Authorization: Bearer sk-proj-your-api-key"

Alongside the date, model, endpoint, limit and offset filters, api_key_id narrows the feed to the events produced by one API key. Every returned event carries its own api_key_id, so you can attribute a request to the credential that made it without filtering first.

Get per-user breakdown

Admin or owner only.

curl "https://api.bulutistan.ai/api/v1/usage/tenant-breakdown" \
-H "Authorization: Bearer sk-proj-your-api-key"

Accepts start_date, end_date and timezone. The requested range may span at most 90 days.

{
"tenant_id": "c63f88b3-cb39-4f07-8353-4982557f7533",
"period": {
"start_date": "2026-07-01T00:00:00",
"end_date": "2026-07-31T23:59:59"
},
"users": [
{
"user_id": "uuid-1",
"total_requests": 500,
"input_tokens": 80000,
"output_tokens": 20000,
"total_tokens": 100000,
"total_cost": 20.0,
"successful_requests": 490,
"failed_requests": 10
}
],
"tenant_total": {
"total_requests": 800,
"total_tokens": 160000,
"total_cost": 32.0
}
}

Users are returned sorted by cost, highest first.

Python example

import requests

api_key = "sk-proj-your-api-key"
base_url = "https://api.bulutistan.ai"
headers = {"Authorization": f"Bearer {api_key}"}

usage = requests.get(
f"{base_url}/api/v1/usage/current",
headers=headers,
params={"scope": "tenant", "format": "display"},
).json()

print(f"Requests: {usage['total_requests']}")
print(f"Tokens: {usage['total_tokens']}")
print(f"Top model: {usage['top_model']}")

# `audio` is omitted when there is none, so ask for it defensively.
audio = usage.get("audio")
if audio:
print(f"Audio: {audio}")