anoman
Gateway

One API. Every provider.

OpenAI-compatible and Anthropic-compatible endpoints. Drop-in replacement — change base_url and api_key, nothing else.

API surface

Complete endpoint reference

OpenAI-compatible (/v1/)

  • POST
    /v1/chat/completionsMain completion. Returns 202 for batch-eligible requests.
  • POST
    /v1/completionsLegacy text completions.
  • GET
    /v1/modelsModel catalog with tier and batch support flag.
  • POST
    /v1/embeddingsEmbeddings passthrough.

Anthropic-compatible (/anthropic/)

  • POST
    /anthropic/v1/messagesFull Anthropic Messages API proxy with streaming. Set ANTHROPIC_BASE_URL=https://api.anoman.io/anthropic.

Public — no auth required (/public/v1/)

  • GET
    /public/v1/pricingModel pricing — 0% markup, pass-through at provider cost. No auth required.
  • GET
    /public/v1/statusSystem status + provider health. No auth required.
  • GET
    /public/v1/modelsPublic model catalog. No auth required.

Anoman-native (/anoman/v1/)

  • POST
    /anoman/v1/keysCreate virtual API key.
  • GET
    /anoman/v1/batch/{job_id}Poll batch job status or retrieve result.
  • GET
    /anoman/v1/usage/savingsCache and batch cost savings breakdown.
  • GET
    /anoman/v1/events/streamSSE stream — real-time gateway events.
  • POST
    /anoman/v1/burst/activateBuy temporary rate limit multiplier (2x/5x/10x).

Full API reference with request/response schemas: Docs / API Reference →

Batch routing

50% savings on non-interactive workloads

Document analysis, background agent tasks, overnight report generation — eligible requests are automatically routed to provider native batch APIs (Anthropic, OpenAI, Google) with 50% cost savings.

from openai import OpenAI
client = OpenAI(base_url="https://api.anoman.io/v1", api_key="anm-sk-...")

# Returns 202 for batch-eligible requests
response = client.chat.completions.create(
    model="claude-sonnet-4-6",
    messages=[{"role": "user", "content": "Summarise this doc..."}],
    extra_headers={"prefer_batch": "true"}
)

if response.status_code == 202:
    job_id = response.json()["id"]
    # Poll until complete
    result = client.get(f"/anoman/v1/batch/{job_id}")

Response transparency

Every response carries full context

{
  "choices": [{ "message": { "content": "..." } }],
  "usage": { "prompt_tokens": 512, "completion_tokens": 128 },
  "_anoman": {
    "guardrails": {
      "injection": { "status": "pass", "score": 0.12 },
      "pii": { "status": "pass" },
      "content": { "status": "pass" },
      "policy": { "status": "pass" }
    },
    "routing": {
      "mode": "realtime",
      "region": "id",
      "provider_type": "cloud_direct"
    },
    "cache": { "hit": false, "type": "none" },
    "weighted_tokens": 1240,
    "cost_usd": "0.0023",
    "burst": { "active": false }
  }
}

Route your first AI call through Anoman.