Skip to main content

AI agent enrollment

A non-human workload can't complete a browser sign-in. Give it a service key instead.

An agentic workflow, CI job, or SDK script doesn't enroll the way a developer does — there's no one to sign in. Mint it a service key (ark_svc_…) instead: a durable, revocable credential carrying its own identity, team, and optional monthly budget.

Service keys are excluded from your billed seat count automatically. An enrolled agent never adds a per-seat charge, and you don't list it in ANYRAY_SEAT_EXCLUDE.

Mint a key

1
Open the Agents card

On the console's Users page, find the Agents card and choose Add agent.

2
Name it and pick a team

Both are slugs: 1–64 characters of letters, digits, dot, colon, hyphen, or underscore. The team is required — it's how the agent's spend rolls up in the console.

3
Copy the key

Copy the ark_svc_… value into the workload's secret store now. It's shown once; Anyray stores its hash, identity metadata, and budget, never the raw token.

Mint from the admin API instead

For a provisioning script, mint it directly. Requires an admin token with the clientkeys:manage capability.

Mint a service key
curl https://<your-anyray-gateway>/admin/service-keys \
-H "Authorization: Bearer $ANYRAY_ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "synthetic-deploy-agent",
"team": "platform",
"monthlyBudgetUsd": 50
}'
namestringrequired

The agent's identity, 1–64 characters matching [A-Za-z0-9_.:-]. Becomes its attribution user id in the console.

teamstringrequired

Same slug rules. Rolls the agent's spend up to a team.

monthlyBudgetUsdnumber

Caps the key's successful request cost per UTC calendar month. Omit it, or pass 0, for an uncapped key. Negative values clamp to 0.

Returns 201 with { key, record }key is the raw ark_svc_… token, returned only here. A malformed body returns 400.

Point the agent at the gateway

Most agent frameworks and SDKs read the base URL and key from the environment. Which two variables depends on the client's dialect:

OpenAI dialect
export OPENAI_BASE_URL=https://<your-anyray-gateway>/v1
export OPENAI_API_KEY=ark_svc_… # the key you just minted

The agent then calls models exactly as before — the gateway authenticates the key, routes, meters, and optimizes every request.

The agent is enrolled

Its next request appears in the console's live traffic view, attributed to the name and team you gave it. The Agents card lists the key with type: service.

Send the key on a raw HTTP request

A client that doesn't read the environment sends the key in a header. The gateway checks x-anyray-api-key first, then Authorization: Bearer, then x-api-key:

…or send it on a single request
curl https://<your-anyray-gateway>/v1/chat/completions \
-H "Authorization: Bearer ark_svc_…" \
-H "Content-Type: application/json" \
-d '{"model": "gpt-5", "messages": [{"role": "user", "content": "ping"}]}'

x-api-key works only because the token carries the ark_ prefix — that's what tells the gateway it's ours. A non-ark_ x-api-key is treated as your own provider key (BYO-key mode) and passed upstream untouched.

Wire the key into client code instead

To put the key straight into the OpenAI or Anthropic SDKs, LangChain, the Vercel AI SDK, or LlamaIndex, see SDKs & frameworks — a service key goes wherever those examples take a gateway key. The console's Enroll agent dialog prints the same snippets with your gateway URL and the new key already filled in.

Manage keys

ActionHow
List every agentThe Agents card, or get /admin/service-keys (metadata only — never the raw token)
Revoke oneThe Agents card, or delete /admin/service-keys/:id

Revoking marks the key rather than deleting it, so the agent's historical spend stays out of your seat count after it's retired.

The budget is a soft cap

monthlyBudgetUsd is fail-open. Completed successful requests update the shared counter after their responses, so concurrent requests can overshoot it. If the counter is unavailable, traffic continues rather than stalling.