DGX LLM Chat Gateway

Billing — Per-Tenant Usage API

dgx billing-data ist token-scoped und kommt aus dem append-only audit-log. Endpoint liefert stündlich oder täglich aggregierte cost-buckets für deinen tenant.

Vollständige interne Architektur: docs/BILLING.md (Cost-Pipeline ADR 0010, Tenant-Markup, OpenRouter-Reconciliation).

GET /v1/billing/usage

Query-Params

ParamTypeDefaultBeispiel
fromISO 8601 UTC (required)2026-05-16T00:00:00Z
toISO 8601 UTC (required)2026-05-16T23:59:59Z
granularityhour | dayhourhour

Range maximal 31 Tage. to >= from. Granularity-Buckets sind UTC.

Response

{
  "tenant_id": "godelmann-gocreate-test",
  "from": "2026-05-16T00:00:00+00:00",
  "to": "2026-05-16T23:59:59+00:00",
  "granularity": "hour",
  "bucket_count": 13,
  "buckets": [
    {
      "bucket_start": "2026-05-16T15:00:00+00:00",
      "bucket_end": "2026-05-16T16:00:00+00:00",
      "total_requests": 42,
      "total_cost_eur": 1.37,
      "total_cost_usd": 1.62,
      "total_upstream_cost_usd": 0.981052,
      "by_model": {
        "godelmann-gocreate-private-llama-text": {
          "requests": 30, "cost_eur": 0.00, "cost_usd": 0.00, "upstream_usd": 0.0
        },
        "godelmann-gocreate-premium-gemini-image-standard": {
          "requests": 12, "cost_eur": 1.20, "cost_usd": 1.40, "upstream_usd": 0.815
        }
      },
      "by_cost_source": { "upstream": 12, "zero": 30 }
    }
  ],
  "total": {
    "requests": 317,
    "cost_eur": 1.37,
    "cost_usd": 1.62,
    "upstream_cost_usd": 0.981052
  }
}

Felder

FeldBedeutung
bucket_start / bucket_endUTC-Boundaries des Buckets (start=inclusive, end=exclusive)
total_cost_eurEUR-Total inkl. tenant_markup + FX_MARKUP (5% ECB-Aufschlag), ceil-zu-cent pro request
total_cost_usdUSD-Total back-converted aus EUR via ECB-rate (pure, ohne markups) — was du in EUR zahlst, in USD ausgedrückt
total_upstream_cost_usdRAW upstream-USD VOR markups (für diff-checks vs OpenRouter / Anthropic)
by_modelPer-model-Aggregation. "(unknown)" für Events ohne joined http-audit-record
by_cost_sourceCounter pro cost_source: upstream (cost vom Provider), zero (local-backend), free (free-tier), unknown

Beispiele

Heutiger Tag stundengenau

TODAY=$(date -u +%Y-%m-%d)
curl -H "Authorization: Bearer $BEARER" -H "SPASS-User-Id: $USR" \
  "https://dgx.spass.fun/v1/billing/usage?from=${TODAY}T00:00:00Z&to=${TODAY}T23:59:59Z&granularity=hour" \
  | jq '.total'

Letzte 7 Tage Tagesübersicht

TO=$(date -u +%Y-%m-%d)
FROM=$(date -u -d "7 days ago" +%Y-%m-%d)
curl -H "Authorization: Bearer $BEARER" -H "SPASS-User-Id: $USR" \
  "https://dgx.spass.fun/v1/billing/usage?from=${FROM}T00:00:00Z&to=${TO}T23:59:59Z&granularity=day" \
  | jq '.buckets[] | {date: .bucket_start[0:10], requests: .total_requests, cost_eur: .total_cost_eur}'

Filter auf einzelnes Model

curl ... | jq '.buckets[] | {bucket: .bucket_start, image_cost: .by_model["godelmann-gocreate-premium-gemini-image-standard"].cost_eur}'

Cost-Pipeline (zusammengefasst)

eur = original_upstream_usd × rate_eur_per_usd × 1.05 × tenant_markup → ceil zu cent
usd = eur / rate_eur_per_usd

Auth + Scope

Was im Audit-Log enthalten ist

Was (noch) NICHT enthalten ist

Errors

HTTPCodeWann
400invalid_field (from/to)malformed ISO 8601
400invalid_field (granularity)nicht hour/day
400invalid_field (to)range > 31 Tage
401unauthorizedbearer fehlt/invalid
500storage_erroraudit-log nicht lesbar (operational-bug, sollte nicht passieren)

Siehe /docs/errors für volle Error-Tabelle.