The API exposed by apps/api (Rust proxy) is compatible with the OpenAI API format. Any client library or tool that supports a custom base URL can use OpenProxy without code changes.

Base URL

EnvironmentURL
Local developmenthttp://localhost:5060
Production (Docker)https://api.example.com (after reverse proxy)

Authentication

All endpoints except /health require a Bearer token issued by the apps/server backend:

Authorization: Bearer op_xxxxxxxxxxxxxxxxxxxxxxxxxxxx

Each API key can be scoped to specific models, have rate limits, a usage quota, and expiry settings configured in the admin panel.

Endpoints

MethodPathAuth requiredDescription
GET/healthNoLiveness probe
GET/v1/modelsYesList models the key can access
POST/v1/chat/completionsYesOpenAI-compatible chat (streaming supported)
POST/v1/messagesYesAnthropic-compatible messages
POST/v1/embeddingsYesEmbeddings

GET /health

Returns 200 OK with a plain-text body when the proxy is running.

curl http://localhost:5060/health
# → 200 OK

GET /v1/models

Returns all models the authenticated API key is permitted to access.

curl http://localhost:5060/v1/models \
  -H "Authorization: Bearer <your-api-key>"

Response

{
  "object": "list",
  "data": [
    { "id": "gpt-4o", "object": "model", "created": 0, "owned_by": "openai" },
    { "id": "claude-3-5-sonnet", "object": "model", "created": 0, "owned_by": "anthropic" }
  ]
}

POST /v1/chat/completions

OpenAI-compatible chat completions. The proxy selects a provider + upstream key, forwards the request, and returns the response transparently.

Request

curl http://localhost:5060/v1/chat/completions \
  -H "Authorization: Bearer <your-api-key>" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-4o",
    "messages": [
      { "role": "system", "content": "You are a helpful assistant." },
      { "role": "user", "content": "Hello!" }
    ],
    "stream": false
  }'

Set "stream": true to receive a Server-Sent Events (SSE) stream.

Response (non-streaming)

{
  "id": "chatcmpl-xxx",
  "object": "chat.completion",
  "created": 1700000000,
  "model": "gpt-4o",
  "choices": [
    {
      "index": 0,
      "message": { "role": "assistant", "content": "Hello! How can I help?" },
      "finish_reason": "stop"
    }
  ],
  "usage": { "prompt_tokens": 19, "completion_tokens": 10, "total_tokens": 29 }
}

POST /v1/messages

Anthropic-compatible messages endpoint for models such as claude-3-5-sonnet.

curl http://localhost:5060/v1/messages \
  -H "Authorization: Bearer <your-api-key>" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-3-5-sonnet",
    "max_tokens": 1024,
    "messages": [
      { "role": "user", "content": "Summarize quantum entanglement in one paragraph." }
    ]
  }'

POST /v1/embeddings

curl http://localhost:5060/v1/embeddings \
  -H "Authorization: Bearer <your-api-key>" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "text-embedding-3-small",
    "input": "The food was delicious."
  }'

Using with client libraries

Python (openai)

from openai import OpenAI

client = OpenAI(
    api_key="op_xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    base_url="http://localhost:5060/v1",
)

response = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "Hello!"}],
)
print(response.choices[0].message.content)

TypeScript (openai)

import OpenAI from "openai";

const client = new OpenAI({
  apiKey: "op_xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  baseURL: "http://localhost:5060/v1",
});

const completion = await client.chat.completions.create({
  model: "gpt-4o",
  messages: [{ role: "user", content: "Hello!" }],
});
console.log(completion.choices[0].message.content);

Error responses

HTTP StatusMeaning
401 UnauthorizedMissing or invalid API key
403 ForbiddenKey does not have access to the requested model
400 Bad RequestMalformed request body
429 Too Many RequestsRate limit or quota exceeded
502 Bad GatewayAll upstream providers failed for this request
5xxInternal error or upstream unreachable

Error body format

{
  "error": {
    "message": "You do not have access to model gpt-4o",
    "type": "permission_error",
    "code": 403
  }
}

Troubleshooting

SymptomLikely causeFix
401Key missing or wrong formatInclude Authorization: Bearer op_... header
403Model not in key’s allowlistAdd model access in admin panel
429Quota exhaustedIncrease quota or use a different key
502All providers down or keys exhaustedCheck provider API status; add working provider keys
Slow initial responseCold start or key decryption first timeThe proxy caches decrypted keys — subsequent calls are faster