Skip to main content
A
Docs

API Reference

OpenAI-compatible API endpoints, management APIs, and SDK integration examples.

Base URL

http://localhost:8080/v1

The Gateway exposes an OpenAI-compatible API. Any client or SDK that works with OpenAI works with Anar Gateway by pointing the base URL to the Gateway.

OpenAI-Compatible Endpoints

Health Check

GET
/health

Returns the Gateway health status

curl http://localhost:8080/health

Returns 200 OK when the Gateway is ready to accept requests.

Chat Completions

POST
/v1/chat/completions

Create a chat completion with optional streaming

Supports all OpenAI chat completion parameters including streaming via Server-Sent Events.

Request:

{
  "model": "llama-3.3-70b-versatile",
  "messages": [
    {"role": "system", "content": "You are a helpful government AI assistant."},
    {"role": "user", "content": "What is the UAE's national AI strategy?"}
  ],
  "temperature": 0.7,
  "max_tokens": 1024,
  "stream": false
}

Response:

{
  "id": "chatcmpl-abc123",
  "object": "chat.completion",
  "model": "llama-3.3-70b-versatile",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "The UAE National Strategy for Artificial Intelligence 2031..."
      },
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 28,
    "completion_tokens": 150,
    "total_tokens": 178
  }
}

Streaming:

Set "stream": true to receive Server-Sent Events:

curl http://localhost:8080/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "llama-3.3-70b-versatile",
    "messages": [{"role": "user", "content": "Hello"}],
    "stream": true
  }'

Each SSE chunk follows the OpenAI streaming format:

data: {"id":"chatcmpl-abc","choices":[{"delta":{"content":"Hello"},"index":0}]}

data: {"id":"chatcmpl-abc","choices":[{"delta":{},"finish_reason":"stop","index":0}]}

data: [DONE]

Embeddings

POST
/v1/embeddings

Generate text embeddings

Request:

{
  "model": "text-embedding-3-large-uaenorth",
  "input": "Sovereign AI infrastructure for government"
}

Response:

{
  "object": "list",
  "data": [
    {
      "object": "embedding",
      "index": 0,
      "embedding": [0.0023, -0.0092, 0.0151, ...]
    }
  ],
  "model": "text-embedding-3-large-uaenorth",
  "usage": {
    "prompt_tokens": 5,
    "total_tokens": 5
  }
}

The text-embedding-3-large-uaenorth model produces 3072-dimensional vectors deployed in the UAE North sovereign region.

List Models

GET
/v1/models

List all available models across configured providers

curl http://localhost:8080/v1/models

Returns models from all configured providers with metadata about capabilities and availability.

Management Endpoints

Cost Tracking

GET
/costs

Query usage records with filtering and pagination

Query Parameters:

ParameterTypeDescription
modelstringFilter by model name
providerstringFilter by provider
tenant_idstringFilter by tenant/virtual key
start_timestringStart of time range (RFC3339)
end_timestringEnd of time range (RFC3339)
pageintPage number (default: 1)
limitintPage size (default: 50)
sort_bystringSort field
sort_dirstringasc or desc

Response:

{
  "data": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "request_id": "req-abc123",
      "model": "llama-3.3-70b-versatile",
      "provider": "groq",
      "prompt_tokens": 150,
      "completion_tokens": 500,
      "total_tokens": 650,
      "cost_usd": 0.000484,
      "tenant_id": "ministry-dev-key",
      "timestamp": "2026-02-16T10:30:00Z"
    }
  ],
  "total": 1542,
  "page": 1,
  "limit": 50
}
GET
/costs/summary

Aggregated cost summary by model, provider, tenant, and day

Response:

{
  "total_requests": 15420,
  "total_cost_usd": 12.847,
  "total_tokens": 4521000,
  "by_model": [
    {
      "model": "llama-3.3-70b-versatile",
      "requests": 12000,
      "prompt_tokens": 1800000,
      "completion_tokens": 2400000,
      "total_tokens": 4200000,
      "cost_usd": 9.96
    }
  ],
  "by_provider": [
    {"provider": "groq", "requests": 14000, "cost_usd": 10.50},
    {"provider": "azure", "requests": 1420, "cost_usd": 2.35}
  ],
  "by_tenant": [
    {"tenant_id": "ministry-dev", "requests": 8000, "cost_usd": 5.20}
  ],
  "daily_costs": [
    {"date": "2026-02-16", "cost_usd": 1.23}
  ]
}
GET
/costs/export

Export usage records as CSV download

Returns a CSV file with headers: id, request_id, model, provider, prompt_tokens, completion_tokens, total_tokens, cost_usd, tenant_id, timestamp.

Audit Logs

GET
/logs/events

Search audit events with filtering

Query parameters match the same pattern as cost tracking: actor, action, outcome, resource, provider, model, request_id, start_time, end_time, search, page, limit.

GET
/logs/stats

Audit event statistics and aggregations

Returns counts by action, outcome, provider, hourly event rates, unique actor counts, and recent failure counts.

Error Responses

All errors follow the OpenAI error format:

{
  "error": {
    "message": "Descriptive error message",
    "type": "error_type"
  }
}

Error Types

TypeStatusDescription
rbac_denied401/403Authentication required or insufficient permissions
oidc_auth_error401Invalid or expired OIDC token
guardrails_blocked403Content blocked by safety policy
guardrails_error502Guard service unavailable (when fail_open: false)
rate_limit_exceeded429Budget or rate limit exceeded
provider_error502Upstream provider returned an error

SDK Examples

Python (OpenAI SDK)

from openai import OpenAI

client = OpenAI(
    base_url="http://localhost:8080/v1",
    api_key="sk-anar-dev-key",
)

response = client.chat.completions.create(
    model="llama-3.3-70b-versatile",
    messages=[
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "Summarize Abu Dhabi's AI investments"},
    ],
    temperature=0.7,
)
print(response.choices[0].message.content)

Streaming:

stream = client.chat.completions.create(
    model="llama-3.3-70b-versatile",
    messages=[{"role": "user", "content": "Hello"}],
    stream=True,
)
for chunk in stream:
    if chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="")

Embeddings:

response = client.embeddings.create(
    model="text-embedding-3-large-uaenorth",
    input="Sovereign AI for government",
)
vector = response.data[0].embedding  # 3072-dimensional

JavaScript (OpenAI SDK)

import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "http://localhost:8080/v1",
  apiKey: "sk-anar-dev-key",
});

const response = await client.chat.completions.create({
  model: "llama-3.3-70b-versatile",
  messages: [
    { role: "system", content: "You are a helpful assistant." },
    { role: "user", content: "Summarize Abu Dhabi's AI investments" },
  ],
});
console.log(response.choices[0].message.content);

Streaming:

const stream = await client.chat.completions.create({
  model: "llama-3.3-70b-versatile",
  messages: [{ role: "user", content: "Hello" }],
  stream: true,
});

for await (const chunk of stream) {
  const content = chunk.choices[0]?.delta?.content;
  if (content) process.stdout.write(content);
}

cURL

# Chat completion
curl http://localhost:8080/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer sk-anar-dev-key" \
  -d '{
    "model": "llama-3.3-70b-versatile",
    "messages": [{"role": "user", "content": "Hello from Anar Gateway"}]
  }'

# Embeddings
curl http://localhost:8080/v1/embeddings \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer sk-anar-dev-key" \
  -d '{
    "model": "text-embedding-3-large-uaenorth",
    "input": "Sovereign AI for government"
  }'

# Cost summary
curl "http://localhost:8080/costs/summary?start_time=2026-02-01T00:00:00Z"

# Audit events
curl "http://localhost:8080/logs/events?action=model_request&limit=10"

Authentication

When RBAC or OIDC is enabled, include the Authorization header with all requests:

Authorization: Bearer sk-anar-your-api-key

Or with a JWT token:

Authorization: Bearer eyJhbGciOiJSUzI1NiIs...

Requests to bypass paths (/health, /metrics) do not require authentication.

Rate Limits

Rate limits are enforced per virtual key, team, or customer scope. When a limit is exceeded, the Gateway returns:

HTTP/1.1 429 Too Many Requests
Retry-After: 30

{
  "error": {
    "message": "Rate limit exceeded: 100 requests per minute",
    "type": "rate_limit_exceeded"
  }
}

Rate limits are configurable via the governance API with two dimensions: requests per minute and tokens per minute.