Crescendo Lab Docs Deploy
English
Sign up

Gateway usage and export

Usage shows spend, requests and each request's model, key, departments and end user. Monthly CSV export via console or gateway.usage.export; no prompt text.

Last updated

The Usage tab#

AI Gateway › Usage is for workspace owners and admins. Choose a period and, if you like, one key. It shows spend, requests and success rate, a daily trend, spend by key and by model, how auto chose, and then each request: when it ran, the key, the model that answered and why, its tokens and its result. A refused request says which limit refused it.

End users#

An application that serves many people through one key can say who each request is for. The Gateway records it as the request's end user:

EndpointField
/v1/chat/completionsuser
/v1/responsesuser
/v1/messagesmetadata.user_id

Only this identifier is recorded; nothing else in the request is stored for it, and the field is still passed to the provider unchanged. Use an id your own system understands, such as an employee number or a hashed address, rather than a name. A request without one is shown as having no end user.

Tags#

Tags label a request with what it was for, such as the team, the feature or the customer, so the Usage tab can split and filter spend by them. Send them as one JSON object in the X-AgentLab-Metadata header on any inference endpoint:

bash
curl https://api.agentlab.cresclab.com/v1/chat/completions \
  -H "Authorization: Bearer $AGENTLAB_API_KEY" \
  -H "Content-Type: application/json" \
  -H 'X-AgentLab-Metadata: {"team": "support", "feature": "summary"}' \
  -d '{"model": "auto", "messages": [{"role": "user", "content": "Hello"}]}'

With an SDK, pass the same header, for example in Python:

python
reply = client.chat.completions.create(
    model="auto",
    messages=[{"role": "user", "content": "Hello"}],
    extra_headers={"X-AgentLab-Metadata": '{"team": "support", "feature": "summary"}'},
)

On /v1/chat/completions and /v1/responses, OpenAI's own metadata body field is read as tags too, and is still passed to the provider unchanged. When a request sends both, they are joined; a key in both must have the same value. The header is never sent to the provider.

RuleLimit
TagsAt most 16 per request.
Keys1 to 64 letters, digits, _, . or -.
ValuesStrings of 1 to 512 characters, without control characters.

A request whose tags break a rule is refused with 400 invalid_metadata and a message naming the rule; tags are never dropped silently. On AI Gateway › Usage, choose Tag in the breakdown and pick a key to see spend by its values; select a value to narrow the whole page to it. The request details and the CSV export show each request's tags. Like the end user, tags are your own labels: do not put personal data or prompt text in them.

Export a month#

On the Usage tab, select Export CSV, choose a month and download it. The file has one row per request attempt, opens in Excel with its characters intact, and contains no prompt or response text.

ColumnContents
request_idThe request's id, as sent in its X-Request-Id header.
attempt_idThis attempt. A request that auto judged first, or that was retried, has more than one.
started_atWhen the attempt started, UTC (ISO 8601).
statecompleted, failed, uncertain (usage never reported), dispatched or prepared.
modelThe model the attempt was sent to.
decisionWhy that model: explicit_pin for a named model, otherwise how auto decided.
input_tokens, output_tokensMeasured tokens. Empty when the usage is not known.
cached_read_tokens, cache_write_tokensPrompt-cache tokens. Empty when the provider reported none.
cost_usdCost at the catalog price of the model on that day. Empty when the usage or the price is unknown.
key_id, key_nameThe key that sent it.
departmentsThe departments the key was charged to when the attempt started, separated by ; .
end_userThe end user the request named, or empty.
failure_codeWhy the attempt did not answer, when the Gateway recorded one, such as inference_allowance_exceeded.
tagsThe request's tags as one JSON object, such as {"team":"support"}, or empty.

An empty cell is unknown, never zero. Months are UTC calendar months. A cell that begins with =, +, -, @, a tab or a carriage return is prefixed with ' so a spreadsheet shows it rather than running it.

Export from code#

The same file comes from the gateway.usage.export procedure of the console API, page by page. Each call returns up to 5,000 rows as CSV text in content and a nextCursor; call again with that cursor until it is null, and join the content of every page in order. Only the first page carries the byte-order mark and the header row. The caller must be a workspace owner or admin.