Axuz Developers

GET /v1/teams/{teamId}/billing/usage

Consumo do workspace (assentos, storage, ...)

  • Access: Team member
  • Service: https://api-billing.axuz.net

Accepted authentication

  • sessionCookie — Sessão plena Axuz (cookie de sessão da casa). Sessão restrita é 403 enrollment_required.
  • bearerSession — JWT de acesso da sessão em `Authorization: Bearer`.

Consumo que o painel "Uso" mostra contra os limites do plano.

Leitura AO VIVO das fontes donas do dado, com cache in-process de TTL curto (60s; 5s quando alguma fonte falhou). Nada é escrito pra servir esta rota — nem no Neon nem no Postgres local (piso 8 do CLAUDE.md: contador/métrica não vive no Neon). Só o consolidado mensal (overage/fatura) é persistido, e isso é outro fluxo.

Procedência por métrica: * users — axuz_api (memberships ativos), mesma definição de assento que o job AggregateUsageMetrics usa em users_seats. * storage_bytes — axuz_files_api (cota do team). * projects, channels, timelines, ai_tokens_month, webhook_deliveries_month — SEM produtor na frota hoje; saem 0 com available:false e note:"no_producer" no _meta. Ver _meta antes de renderizar.

As consultas cross-service reencaminham a credencial do caller (o billing não tem service-account de tenant alheio), e o {teamId} já passou pelo gate de membership do router.

_meta é ADITIVO: quem só lê as chaves numéricas (contrato Record<string, number> dos clients) segue funcionando.

Parameters

NameInTypeRequiredDescription
teamIdpathstringyes

Responses

200

Consumo do workspace. 200 mesmo com fonte fora do ar — a métrica afetada vem marcada available:false no _meta (degradação graciosa, piso 10). Zero SEM marcação significa zero medido de verdade.

NameTypeRequiredDescription
usersintegeryes

Assentos ativos (memberships status=active). Fonte -- axuz_api.

projectsintegeryes

Sem produtor hoje -- ver _meta

channelsintegeryes

Sem produtor hoje -- ver _meta

timelinesintegeryes

Sem produtor hoje -- ver _meta

storage_bytesintegeryes

Bytes ocupados pelo team. Fonte -- axuz_files_api.

ai_tokens_monthintegeryes

Sem produtor hoje -- ver _meta

webhook_deliveries_monthintegeryes

Sem produtor hoje -- ver _meta

_metaBillingUsageMetayes

Procedência do payload. Existe pra que a UI saiba distinguir "0 medido" de "0 porque a fonte não respondeu" -- sem isso o painel mente pro cliente com cara de medição.

_meta.collected_atstring<date-time>yes

Quando o snapshot foi coletado (UTC, RFC3339).

_meta.metricsobjectyes

Uma entrada por chave numérica do payload.

400

input inválido

NameTypeRequiredDescription
errorstringyes

401

Sem credencial valida

NameTypeRequiredDescription
errorstringyes

403

Sem permissao (nao e owner/admin; token sem escopo; token de integracao em rota nao permitida)

NameTypeRequiredDescription
errorstringyes

429

Limite de requisições excedido.

NameTypeRequiredDescription
errorstringyes

500

Erro interno. Tente de novo com backoff; reporte o X-Request-Id.

NameTypeRequiredDescription
errorstringyes

Examples

"Try it" is turned off in this reference. Use the examples with your test credential.

curl

curl -sS -X GET 'https://api-billing.axuz.net/v1/teams/TEAM_ID/billing/usage' \
  -H "Authorization: Bearer $AXUZ_TOKEN"

Node.js

const res = await fetch("https://api-billing.axuz.net/v1/teams/TEAM_ID/billing/usage", {
  method: 'GET',
  headers: {
    Authorization: `Bearer ${process.env.AXUZ_TOKEN}`,
  },
});
if (!res.ok) throw new Error(`HTTP ${res.status}: ${await res.text()}`);
console.log(await res.json());

Python

import os
import requests

res = requests.request(
    "GET",
    "https://api-billing.axuz.net/v1/teams/TEAM_ID/billing/usage",
    headers={
        "Authorization": f"Bearer {os.environ['AXUZ_TOKEN']}",
    },
    timeout=30,
)
res.raise_for_status()
print(res.json())