OPS Gateway exposes OpenAI and Anthropic-compatible endpoints backed by Claude CLI.
When auth is enabled (via OG_ADMIN_KEY env var), all /v1/* endpoints require an API key. Pass it via either header:
Authorization: Bearer og-your-key-here # or x-api-key: og-your-key-here
Admin endpoints (/admin/*) require the master admin key set in OG_ADMIN_KEY.
Health check, dashboard, and docs are always accessible without auth.
Per-key rate limits are enforced on API endpoints. When exceeded, the server returns 429 with a Retry-After header.
Default limits (configurable per key):
Requests/minute: 30 (OG_DEFAULT_RPM) Tokens/minute: 100k (OG_DEFAULT_TPM) Tokens/day: 1M (OG_DEFAULT_TPD)
Returns the list of available Claude models.
curl http://localhost:3456/v1/models \ -H "Authorization: Bearer og-your-key"
{
"object": "list",
"data": [
{ "id": "claude-opus-4-20250514", "aliases": ["opus"], "context_window": 200000 },
{ "id": "claude-sonnet-4-20250514", "aliases": ["sonnet"], "context_window": 200000 },
{ "id": "claude-haiku-4-20250414", "aliases": ["haiku"], "context_window": 200000 }
]
}
| Name | Type | Required | Description |
|---|---|---|---|
| messages | array | Required | Array of message objects with role and content |
| model | string | Optional | Model ID or alias (default: sonnet) |
| stream | boolean | Optional | Enable SSE streaming |
| max_tokens | integer | Optional | Maximum output tokens |
| temperature | number | Optional | Sampling temperature (0-1) |
curl -X POST http://localhost:3456/v1/chat/completions \
-H "Authorization: Bearer og-your-key" \
-H "Content-Type: application/json" \
-d '{
"messages": [{"role": "user", "content": "Hello!"}],
"model": "sonnet",
"stream": false
}'
| Name | Type | Required | Description |
|---|---|---|---|
| messages | array | Required | Array of message objects |
| max_tokens | integer | Required | Maximum output tokens |
| model | string | Optional | Model ID or alias |
| system | string | Optional | System prompt |
| stream | boolean | Optional | Enable SSE streaming |
curl -X POST http://localhost:3456/v1/messages \
-H "Authorization: Bearer og-your-key" \
-H "Content-Type: application/json" \
-d '{
"messages": [{"role": "user", "content": "Hello!"}],
"max_tokens": 1024,
"model": "sonnet"
}'
curl http://localhost:3456/health
{ "status": "ok", "uptime_seconds": 3600, "claude_cli": "2.1.72" }
All admin endpoints require the master admin key.
curl -X POST http://localhost:3456/admin/keys \
-H "Authorization: Bearer YOUR_ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{
"clientName": "my-app",
"limits": {
"requestsPerMinute": 60,
"tokensPerMinute": 200000,
"tokensPerDay": 2000000
}
}'
{
"id": "key_abc123",
"key": "og-full-key-shown-once-only...",
"prefix": "og-abc12345...",
"clientName": "my-app",
"limits": { "requestsPerMinute": 60, "tokensPerMinute": 200000, "tokensPerDay": 2000000 },
"createdAt": "2025-01-01T00:00:00.000Z"
}
curl http://localhost:3456/admin/keys \ -H "Authorization: Bearer YOUR_ADMIN_KEY"
curl -X PATCH http://localhost:3456/admin/keys/key_abc123 \
-H "Authorization: Bearer YOUR_ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{ "clientName": "new-name", "limits": { "requestsPerMinute": 100 } }'
curl -X DELETE http://localhost:3456/admin/keys/key_abc123 \ -H "Authorization: Bearer YOUR_ADMIN_KEY"
{ "id": "key_abc123", "revoked": true, "revokedAt": "2025-01-01T12:00:00.000Z" }
curl http://localhost:3456/admin/usage \ -H "Authorization: Bearer YOUR_ADMIN_KEY"
| Variable | Default | Description |
|---|---|---|
| PORT | 3456 | Server port |
| OG_ADMIN_KEY | unset | Master admin key. Enables auth when set. |
| OG_AUTH_ENABLED | auto | Explicit auth toggle (auto-enabled with admin key) |
| OG_DEFAULT_RPM | 30 | Default requests/minute per key |
| OG_DEFAULT_TPM | 100000 | Default tokens/minute per key |
| OG_DEFAULT_TPD | 1000000 | Default tokens/day per key |
| OG_DATA_DIR | ./data | Directory for keys.json persistence |
All errors follow this format:
{
"error": {
"message": "Human-readable error message",
"type": "authentication_error | rate_limit_error | validation_error | invalid_request_error"
}
}
| Code | Type | Description |
|---|---|---|
| 401 | authentication_error | Missing or invalid API key |
| 403 | authorization_error | Invalid admin key |
| 429 | rate_limit_error | Rate limit exceeded (check Retry-After header) |
| 400 | validation_error | Missing required fields |
| 404 | not_found | Resource not found |