Skip to content

Reference

Analytics API

Read your workspace's usage, cost and credit balance programmatically, with a management-scope API key — no browser session required. Every ₹ figure returned is the same ledger-truth number the dashboard shows: ₹ only, never USD or an FX-converted figure.

A management key is not a read-only credential in general — the same key also drives this workspace’s key-management control plane (creating and revoking other keys) through identity’s own /mgmt/* endpoints. This page covers only its READ surface: analytics, credits balance, and usage export.

Getting a management key

In the dashboard, under API keys, use Management key (not Create API key, which mints an inference-only key). The raw ub-mgmt-… token is shown once, at creation — store it like any other secret.

dashboard
# Dashboard → API keys → "Management key" — this mints a
# ub-mgmt-{user_id}-{secret} key, workspace-scoped, shown once.

A management key is a distinct credential class from your inference key (ub-gw-…). It is never valid for inference — the gateway does not recognize its prefix at all — and an inference key is never accepted on the endpoints below.

Authentication & scope

Send it as a bearer token, exactly like an inference key, against the control-plane host:

HeaderAuthorization: Bearer ub-mgmt-…
Hosthttps://unoblox.ai/api/webapi
ScopeFor these read endpoints only: its OWN workspace, bounded by the workspace role of the user who created it.

A management key is not a superuser: on these endpoints it can see exactly what a SESSION with the same workspace role could see, no more. A Billing or Developer role, for example, cannot read credits/balance (that needs the BillingView permission), and analytics/query additionally needs MembersView to group or filter by member, and ApiKeysView to group or filter by api_key — the same rule a signed-in session follows.

Every endpoint below takes the workspace id from the URL path, never from the request body. If that path workspace is not the key’s own workspace, the request fails closed with 403 UB-API-382 — it never discloses whether the other workspace exists:

wrong workspace → 403
{ "error": { "message": "This API key does not belong to this workspace.", "type": "permission_denied", "code": 403, "error_code": "UB-API-382" } }

A malformed, unknown, disabled, revoked, retired or expired key, a key missing the required usage operation grant, or a request from an IP outside the key’s own CIDR allowlist, all get a single, deliberately undifferentiated 401 UB-API-381 — the same anti-enumeration posture your inference key’s own auth errors use.

Analytics query

POST/workspaces/:workspace_id/analytics/query

The same query engine and metric/dimension registry the dashboard’s usage boards run on — a management key reads the workspace, not just its own traffic (unlike an inference key), but only as far as its own workspace role permits (see Authentication & scope above):

curl
curl -X POST https://unoblox.ai/api/webapi/workspaces/$WORKSPACE_ID/analytics/query \
  -H "Authorization: Bearer $UNOBLOX_MANAGEMENT_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "metrics": ["requests", "spend"],
    "group_by": ["model"],
    "time": { "from_unix_ms": 1735689600000, "to_unix_ms": 1738368000000, "grain": "day", "tz": "Asia/Kolkata" }
  }'
200 response
{
  "columns": [
    { "id": "time", "kind": "time" },
    { "id": "model", "kind": "dimension" },
    { "id": "requests", "kind": "metric", "unit": "count" },
    { "id": "spend", "kind": "metric", "unit": "inr_paise" }
  ],
  "rows": [
    ["2026-09-20", "<model-id>", 1042, 128650]
  ],
  "watermark_unix_ms": 1738367940000,
  "partial_last_bucket": false
}

watermark_unix_ms is how current the data is; partial_last_bucket marks a bucket still filling in. See API reference for the full metric/dimension catalog.

Analytics meta

GET/workspaces/:workspace_id/analytics/meta

Lists the metrics and dimensions available at workspace scope (units, additivity, cardinality) — a free, in-memory registry read, not rate-limited:

curl
curl https://unoblox.ai/api/webapi/workspaces/$WORKSPACE_ID/analytics/meta \
  -H "Authorization: Bearer $UNOBLOX_MANAGEMENT_KEY"

Credits balance

GET/workspaces/:workspace_id/credits/balance

The workspace’s current wallet balance — the same ledger figure the dashboard shows, in paise:

curl
curl https://unoblox.ai/api/webapi/workspaces/$WORKSPACE_ID/credits/balance \
  -H "Authorization: Bearer $UNOBLOX_MANAGEMENT_KEY"
200 response
{
  "workspace_id": "ws_...",
  "account": "user:wallet:ws_...",
  "currency": "INR",
  "balance_minor": 542310
}

This already reflects any IN-FLIGHT requests: a request holds its estimated cost out of the balance the moment it starts, before the actual ₹ figure is known — so the balance can drop before a request settles. spend_paise/spend_inr in the export below are different: they only ever show a request’s SETTLED charge (including GST), bucketed by the UTC day the settle posted — an in-flight hold never appears there, and never inflates a day’s total.

Usage/activity export (CSV)

GET/workspaces/:workspace_id/usage/activity/export

A daily CSV of requests, tokens and ₹ spend for a window (from_unix_ms/to_unix_ms query params; defaults to the trailing 30 days, capped at 366 days). Days are UTC calendar days. spend_paise is the exact integer ledger figure; spend_inr is the same amount as a fixed-point ₹ string — never a floating-point value, and never USD.

curl
curl "https://unoblox.ai/api/webapi/workspaces/$WORKSPACE_ID/usage/activity/export?from_unix_ms=1735689600000&to_unix_ms=1738368000000" \
  -H "Authorization: Bearer $UNOBLOX_MANAGEMENT_KEY" \
  -o usage-activity.csv
usage-activity.csv
date_utc,requests,tokens_total,spend_paise,spend_inr
2026-09-20,1353,842011,222850,2228.50
2026-09-21,1408,861204,231900,2319.00

Rate limits & errors

EndpointCap
analytics/query60 requests/minute per key
analytics/metaNone — a free, in-memory registry read
credits/balance60 requests/minute per key
usage/activity/export10 requests/minute per key

On top of the caps above, the key’s own configured rpm (requests/minute) is ALSO enforced here — and that budget is SHARED with the same key’s key-management calls (creating/revoking other keys), not a separate one per surface.

A cap is enforced per key, independent of any session or inference-key limit on the same workspace. See Rate limits for the general shape of a 429, and Errors for the full code list, including UB-API-381–UB-API-383 and UB-API-414.

Scoped to one workspace, not a superuser

A management key can only ever read the workspace it was created in — it cannot enumerate or read any other workspace, and it can never be used against the inference gateway. It is NOT read-only overall, though: the same key also drives this workspace’s key-management control plane via identity’s /mgmt/* endpoints (creating and revoking other keys) — treat it with the same care as a session with the same workspace role.