Agent Quickstart
Wire an autonomous agent up to AI Setu.
This page is for a runtime agent — code that calls AI Setu in production with no human in the loop. It can't poll for its balance, can't ask permission, and can't be handed a long-lived secret it might leak. That's a different problem than a human-driven app calling the API directly (see Quickstart for that case).
If you used a coding agent (Claude Code, Cursor) to set up your AI Setu
account via @ai-setu/mcp, that's a separate, admin-facing tool — see
MCP. It is not how your deployed runtime agent should
call inference; use @ai-setu/client with an API key or ephemeral token as
described below.
Two ways to authenticate a runtime agent
Workspace API key (tt_live_…) — the same key from
Quickstart. Simplest option if the agent runs
in your own trusted backend.
Ephemeral token (tt_ev_…) — a short-lived, narrowly-scoped, spend-capped
token your backend mints per agent session or per end-user, instead of
handing out the long-lived workspace key. Use this when the agent process is
less trusted (a sandboxed tool run, a per-customer session, a third-party
plugin) or when you want a hard, self-expiring ceiling on what a single
agent run can do.
Minting an ephemeral token
An ephemeral token is minted by your backend (an authenticated, admin-permissioned caller) against the control-plane API — never by the agent itself:
curl https://api.aisetu.ai/graphql \
-H "Authorization: Bearer $AI_SETU_PAT" \
-H "Content-Type: application/json" \
-d '{
"query": "mutation Mint($input: MintEphemeralTokenInput!) { mintEphemeralToken(input: $input) { token jti expiresAt scopes } }",
"variables": {
"input": {
"parentKeyId": "'"$PARENT_KEY_ID"'",
"scopes": ["chat", "model:openai/gpt-4o-mini"],
"ttlSeconds": 900,
"budgetMicros": 500000
}
}
}'scopes—chat,embeddings,messages, and/ormodel:<id>to narrow which models the token can call. Scopes can never exceed the parent key's own scopes.ttlSeconds— required, capped at 24 hours. The gateway verifies the token statelessly (no per-request lookup) and hard-enforces the cap regardless of what the token claims.budgetMicros— optional per-token spend cap in USD micros. Once hit, further calls on that token return402with codewesence.credential_cap_exceeded; nothing else on your workspace is affected.rateLimits— optional per-token request/token frequency limits.
Hand the returned token to the agent process; store jti if you want to
revoke it early. The agent uses it exactly like a workspace key:
import { AiSetu } from '@ai-setu/client';
const client = new AiSetu({ apiKey: ephemeralToken });
const res = await client.chat.completions.create({
model: 'openai/gpt-4o-mini',
messages: [{ role: 'user', content: 'Summarize this ticket.' }],
});Reacting to balance in-band
A runtime agent can't poll a dashboard or wait for a human to notice a low balance — so every successful response carries the signal in-band:
const client = new AiSetu({
onBalanceUpdate: (info) => {
if (info.isLow) {
myAlerting.notify(`AI Setu credit low: ${info.topUpUrl}`);
}
},
});
// Also synchronously available after any call:
console.log(client.lastBalance); // { micros, isLow, topUpUrl } or undefinedThis reads the X-AI-Setu-Balance-Micros, X-AI-Setu-Balance-Low, and
X-AI-Setu-Topup-URL response headers, present on every successful
/v1/chat/completions response.
Capping runaway spend
Layer these together for an agent loop you don't want to babysit:
budgetMicroson the ephemeral token itself (above) — the tightest, simplest ceiling: this specific agent run can spend at most this much, full stop.- Workspace-level budgets — if enabled on your deployment, a further cap on the key, BYOK Connection, or whole workspace, independent of any single token.
- Rate limits — cap request/token frequency, which matters for a loop that could otherwise retry in a tight cycle.
All three fail closed with a distinct error code — check error.code, not
just the HTTP status, to tell "out of credits" from "this budget period is
exhausted" from "you're calling too fast." See
Errors.
Reliability for long-running loops
Two behaviors matter most for an agent that can't just ask a human to retry:
- Failover happens before any response byte reaches you — a 5xx/429/timeout from the first candidate provider is retried on the next one automatically, with no partial output and no double billing.
- Caching means a repeated sub-call (the same tool
invocation, the same classification prompt) can resolve at $0 without a
round trip to the provider — useful for agent loops that re-ask the same
small questions across steps. Tool order is normalized before the cache
key is computed, so a loop that reorders its own
toolsarray between calls still hits.