Developers

API reference

One OpenAI-compatible endpoint for every model. If your code talks to OpenAI or OpenRouter today, it talks to Aggregate after two lines.

Quickstart

Create a key in your account, make sure your API balance is above zero, then send a request.

curl https://aggregat.xyz/api/v1/chat/completions \  -H "Authorization: Bearer sk-aggr-…" \  -H "Content-Type: application/json" \  -d '{    "model": "anthropic/claude-sonnet-4.5",    "messages": [{"role": "user", "content": "Hello"}]  }'

Base URL

Every endpoint below is relative to this URL. It is a drop-in replacement for the OpenAI and OpenRouter base URLs.

base url
https://aggregat.xyz/api/v1

Authentication

Send your key as a bearer token. Keys start with sk-aggr- and are shown once at creation; we store only a hash.

header
Authorization: Bearer sk-aggr-…

Endpoints

OpenAI-compatible request and response bodies. The Anthropic Messages route accepts the Anthropic shape unchanged.

MethodPathWhat it does
POST/chat/completionsChat completions, OpenAI shape. Tools, JSON mode, vision, streaming.
POST/completionsLegacy text completions.
POST/embeddingsVector embeddings.
POST/images/generationsImage generation on supported models.
GET/modelsEvery model id with list pricing and context length.
POST/messagesAnthropic Messages shape, passed through as-is.

Streaming

Set stream: true. Server-sent events pass through untouched, chunk for chunk. Usage and cost arrive on the final chunk, and your balance is charged once the stream ends.

typescript
const stream = await client.chat.completions.create({  model: "anthropic/claude-sonnet-4.5",  messages: [{ role: "user", content: "Write a haiku about latency." }],  stream: true,}); for await (const chunk of stream) {  process.stdout.write(chunk.choices[0]?.delta?.content ?? "");}

Response headers

Every response carries its own receipt.

x-aggr-costUSD charged for this request: the model's list rate minus your staking discount.
x-aggr-discountDiscount applied, in basis points (0 for non-stakers). Tier by staked AGGR, plus any provider-token bonus.
x-aggr-balanceAPI balance remaining after the charge.
x-aggr-gateway-msTime added by the gateway itself, excluding the provider.

Errors

Errors use standard HTTP status codes and an error object with a code and a human-readable message. Failed upstream calls are never charged.

StatusCodeMeaning
400bad_requestThe body is malformed or the model id is unknown.
401invalid_keyMissing, malformed or revoked key.
402insufficient_balanceAPI balance is empty. Buy or activate SPARK.
403key_limit_reachedThis key hit its own spending limit.
429rate_limitedThe upstream provider is throttling. Retry with backoff.
502upstream_errorThe provider failed. You are not charged.

Model naming

Model ids follow the provider/model convention used by OpenRouter, so existing ids work as they are. Call GET /models for the live list with pricing.

anthropic/claude-sonnet-4.5openai/gpt-5google/gemini-2.5-prometa-llama/llama-4-maverickdeepseek/deepseek-chatmistralai/mistral-large

Per-key limits

Give each key a USD spending cap when you create it. Once a key has spent its limit, it returns 403 key_limit_reached while your other keys keep working. All keys draw on one account balance, so a key can never spend more than the balance either.

Zero data retention

Prompts and completions stream through memory and are never written to disk, logs or analytics. We keep what billing needs: key, model, token counts, cost and latency. Requests go upstream with the provider's own data-retention controls applied.

Questions or a missing endpoint? Write to hello@aggregate.xyz.