Skip to Content
API ReferenceGateway API Reference

Gateway API Reference

The Curate-Me AI Gateway is an OpenAI-compatible reverse proxy that adds governance, cost tracking, and observability to LLM requests. It runs on port 8002 and is available at https://api.curate-me.ai.

Authentication

All requests require a Curate-Me API key. There are three ways to provide it:

MethodHeader / ParameterPriority
Explicit headerX-CM-API-Key: cm_sk_your_key1 (highest)
Bearer tokenAuthorization: Bearer cm_sk_your_key2
Query parameter?api_key=cm_sk_your_key3 (SSE/EventSource only)

Key prefixes: API keys start with cm_sk_, cm_gw_, or cm_. Runner tokens use the cm_rt_ prefix.

Provider key: The upstream provider’s API key can be sent via:

  • X-Provider-Key: sk-your-openai-key (preferred, explicit)
  • Authorization: Bearer sk-your-openai-key (when the gateway key is in X-CM-API-Key)
  • Stored in the gateway (no provider key needed per-request)

Dashboard JWT fallback: The gateway also accepts dashboard JWTs via Authorization: Bearer <jwt> for admin endpoints called from the dashboard UI.

Authentication errors

{ "error": { "message": "Missing or invalid credentials.", "type": "authentication_error", "code": "invalid_api_key", "gateway_error_code": "GW_AUTH_001" } }
Error CodeStatusMeaning
GW_AUTH_001401Missing or unrecognized credentials
GW_AUTH_002401Invalid, expired, or revoked API key
GW_AUTH_003401API key has been rotated; use the replacement
GW_AUTH_004403Client IP not in the key’s IP allowlist

Proxy endpoints

These endpoints accept the same request format as the upstream provider and forward the request through the governance chain.

POST /v1/chat/completions

OpenAI-compatible chat completions. Works with OpenAI, DeepSeek, Groq, Mistral, xAI, Together, Fireworks, and any provider that uses the OpenAI format.

curl https://api.curate-me.ai/v1/chat/completions \ -H "Content-Type: application/json" \ -H "X-CM-API-Key: cm_sk_your_key" \ -H "Authorization: Bearer sk-your-openai-key" \ -d '{ "model": "gpt-4o", "messages": [ {"role": "system", "content": "You are a helpful assistant."}, {"role": "user", "content": "What is the capital of France?"} ], "stream": false }'

Streaming:

curl https://api.curate-me.ai/v1/chat/completions \ -H "Content-Type: application/json" \ -H "X-CM-API-Key: cm_sk_your_key" \ -H "Authorization: Bearer sk-your-openai-key" \ -d '{ "model": "gpt-4o", "messages": [{"role": "user", "content": "Tell me a joke"}], "stream": true }'

The gateway passes SSE chunks through transparently. Token usage is extracted from the final [DONE] chunk for cost recording.

POST /v1/messages

Anthropic-compatible messages endpoint.

curl https://api.curate-me.ai/v1/messages \ -H "Content-Type: application/json" \ -H "X-CM-API-Key: cm_sk_your_key" \ -H "X-Provider-Key: sk-ant-your-key" \ -H "anthropic-version: 2023-06-01" \ -d '{ "model": "claude-sonnet-4-20250514", "max_tokens": 1024, "messages": [ {"role": "user", "content": "Hello, Claude!"} ] }'

POST /v1/embeddings

OpenAI-compatible embeddings endpoint.

curl https://api.curate-me.ai/v1/embeddings \ -H "Content-Type: application/json" \ -H "X-CM-API-Key: cm_sk_your_key" \ -H "Authorization: Bearer sk-your-openai-key" \ -d '{ "model": "text-embedding-3-small", "input": "The quick brown fox" }'

GET /v1/models

List available models from all configured providers. Returns an OpenAI-compatible model list.

curl https://api.curate-me.ai/v1/models \ -H "X-CM-API-Key: cm_sk_your_key"

GET /v1/health

Gateway health check. Returns status and active provider count.

curl https://api.curate-me.ai/v1/health \ -H "X-CM-API-Key: cm_sk_your_key"

Response headers

Every proxied response includes governance metadata headers:

HeaderTypeDescription
X-CM-Request-IDstringUnique request identifier for tracing
X-CM-CostfloatEstimated cost for this request (USD)
X-CM-Daily-CostfloatCumulative daily spend for the org (USD)
X-CM-Daily-BudgetfloatDaily budget limit for the org (USD)
X-CM-Governance-Time-MsfloatTime spent in governance checks (ms)
X-RateLimit-LimitintMax requests per minute
X-RateLimit-RemainingintRequests remaining in current window
X-RateLimit-ResetintUnix timestamp when the window resets
X-CM-Approval-IDstringApproval ID (only when HITL triggers, status 202)

Admin endpoints

Admin endpoints are prefixed with /gateway/admin/ and require an API key with admin scopes.

Policies

GET /gateway/admin/policies

List governance policies. Returns the policy for the authenticated org.

curl https://api.curate-me.ai/gateway/admin/policies \ -H "X-CM-API-Key: cm_sk_your_key"

GET /gateway/admin/policies/{org_id}

Get the governance policy for a specific org.

curl https://api.curate-me.ai/gateway/admin/policies/org_abc123 \ -H "X-CM-API-Key: cm_sk_your_key"

PUT /gateway/admin/policies/{org_id}

Create or replace a governance policy. Full document replacement (PUT semantics).

curl -X PUT https://api.curate-me.ai/gateway/admin/policies/org_abc123 \ -H "X-CM-API-Key: cm_sk_your_key" \ -H "Content-Type: application/json" \ -d '{ "rpm_limit": 100, "daily_budget": 50.00, "monthly_budget": 1000.00, "max_cost_per_request": 2.00, "pii_scan_enabled": true, "pii_action": "block", "allowed_models": [], "hitl_cost_threshold": 10.00 }'

DELETE /gateway/admin/policies/{org_id}

Delete a governance policy, reverting to tier defaults.

curl -X DELETE https://api.curate-me.ai/gateway/admin/policies/org_abc123 \ -H "X-CM-API-Key: cm_sk_your_key"

POST /gateway/admin/policies/simulate

Simulate a draft policy against recent traffic. Returns how many requests would have been blocked and by which governance step.

curl -X POST https://api.curate-me.ai/gateway/admin/policies/simulate \ -H "X-CM-API-Key: cm_sk_your_key" \ -H "Content-Type: application/json" \ -d '{ "draft_policy": {"rpm_limit": 30, "daily_budget": 10.00}, "replay_hours": 24 }'

API Keys

GET /gateway/admin/keys

List gateway API keys for the org. Returns metadata only — key secrets are never included.

curl https://api.curate-me.ai/gateway/admin/keys \ -H "X-CM-API-Key: cm_sk_your_key"

POST /gateway/admin/keys

Create a new gateway API key. The plaintext key is returned only once in the response.

curl -X POST https://api.curate-me.ai/gateway/admin/keys \ -H "X-CM-API-Key: cm_sk_your_key" \ -H "Content-Type: application/json" \ -d '{ "name": "production-api", "scopes": ["proxy", "admin"] }'

Secrets (stored provider keys)

POST /gateway/admin/secrets

Store a provider API key encrypted in the gateway. After storing, requests to that provider no longer need an X-Provider-Key header.

curl -X POST https://api.curate-me.ai/gateway/admin/secrets \ -H "X-CM-API-Key: cm_sk_your_key" \ -H "Content-Type: application/json" \ -d '{ "provider": "openai", "plaintext_key": "sk-your-openai-key", "label": "Production OpenAI key" }'

GET /gateway/admin/secrets

List stored provider secrets (metadata only, never plaintext).

curl https://api.curate-me.ai/gateway/admin/secrets \ -H "X-CM-API-Key: cm_sk_your_key"

POST /gateway/admin/secrets/rotate

Rotate a stored provider secret. The old key is revoked and the new one is encrypted.

curl -X POST https://api.curate-me.ai/gateway/admin/secrets/rotate \ -H "X-CM-API-Key: cm_sk_your_key" \ -H "Content-Type: application/json" \ -d '{ "provider": "openai", "plaintext_key": "sk-new-openai-key" }'

DELETE /gateway/admin/secrets/{provider}

Revoke a stored provider secret. After revocation, requests will need explicit X-Provider-Key headers again.

curl -X DELETE https://api.curate-me.ai/gateway/admin/secrets/openai \ -H "X-CM-API-Key: cm_sk_your_key"

Usage and Costs

GET /gateway/admin/usage

Get gateway usage records.

ParameterTypeDefaultDescription
daysint7Look-back period (1-90)
limitint100Max records to return (1-1000)
curl "https://api.curate-me.ai/gateway/admin/usage?days=7&limit=50" \ -H "X-CM-API-Key: cm_sk_your_key"

GET /gateway/admin/usage/daily

Get daily cost breakdown.

ParameterTypeDefaultDescription
daysint30Number of days to retrieve (1-90)
curl "https://api.curate-me.ai/gateway/admin/usage/daily?days=30" \ -H "X-CM-API-Key: cm_sk_your_key"

GET /gateway/admin/usage/{request_id}

Get a single usage record by request ID.

curl "https://api.curate-me.ai/gateway/admin/usage/gw_a1b2c3d4" \ -H "X-CM-API-Key: cm_sk_your_key"

Latency

GET /gateway/admin/latency

Get request latency statistics (p50, p95, p99) broken down by provider and model.

curl https://api.curate-me.ai/gateway/admin/latency \ -H "X-CM-API-Key: cm_sk_your_key"

Approvals (HITL)

GET /gateway/admin/approvals/{approval_id}

Check the status of a HITL approval request.

curl https://api.curate-me.ai/gateway/admin/approvals/apr_abc123 \ -H "X-CM-API-Key: cm_sk_your_key"

Response:

{ "approval_id": "apr_abc123", "status": "pending", "estimated_cost": 12.50, "model": "gpt-5.1", "retry_after_seconds": 30, "created_at": "2026-03-17T14:32:01Z" }

Possible status values: pending, approved, rejected, expired.

Provider Targets

GET /gateway/admin/provider-targets

List all configured provider targets for the org.

curl https://api.curate-me.ai/gateway/admin/provider-targets \ -H "X-CM-API-Key: cm_sk_your_key"

POST /gateway/admin/provider-targets/{provider_id}/discover-models

Trigger model discovery on a provider. Returns discovered model IDs.

curl -X POST https://api.curate-me.ai/gateway/admin/provider-targets/openai/discover-models \ -H "X-CM-API-Key: cm_sk_your_key"

Discovery

GET /gateway/admin/discovery/catalog

List discovered models across all providers.

ParameterTypeDefaultDescription
provider_idstring-Filter by provider
limitint200Max results (1-1000)
cursorstring-Pagination cursor
curl "https://api.curate-me.ai/gateway/admin/discovery/catalog?limit=50" \ -H "X-CM-API-Key: cm_sk_your_key"

GET /gateway/admin/discovery/history

List discovery run audit history.

curl "https://api.curate-me.ai/gateway/admin/discovery/history?limit=10" \ -H "X-CM-API-Key: cm_sk_your_key"

Error response format

All gateway errors use the OpenAI-compatible error format:

{ "error": { "message": "Human-readable description", "type": "error_type", "param": null, "code": "error_code", "gateway_error_code": "GW_XXX_NNN", "remediation": "How to fix the issue" } }

Error code reference

CodeStatusMeaning
GW_AUTH_001401Missing credentials
GW_AUTH_002401Invalid or expired API key
GW_AUTH_003401Key has been rotated
GW_AUTH_004403IP not in allowlist
GW_RATE_001429Rate limit exceeded
GW_PLAN_001403Inactive subscription
GW_PLAN_002429Plan quota exceeded
GW_PLAN_003403Model not available on plan
GW_COST_001403Per-request cost exceeds limit
GW_COST_002403Daily budget exhausted
GW_COST_003403Monthly budget exhausted
GW_PII_001403PII detected in request
GW_SAFETY_001403Content safety violation
GW_MODEL_001403Model not in allowlist
GW_SESSION_BUDGET_001403Runner session budget exceeded
GW_BUDGET_HIERARCHY_001403Hierarchical budget exceeded

Rate limit headers

Rate limit headers are included on every response (both allowed and denied):

X-RateLimit-Limit: 60 X-RateLimit-Remaining: 42 X-RateLimit-Reset: 1708642860

When rate-limited, the response also includes:

Retry-After: 18

The Retry-After value is in seconds.


Supported providers

The gateway supports 50+ LLM providers. The provider is determined by the model name or by explicit routing via provider targets. Major providers include:

ProviderModelsFormat
OpenAIGPT-4o, GPT-5.1, o1, o3OpenAI
AnthropicClaude Sonnet 4, Opus 4, Haiku 3.5Anthropic Messages
GoogleGemini 2.5 Pro, FlashOpenAI-compatible
DeepSeekDeepSeek Chat, ReasonerOpenAI-compatible
GroqLlama, MixtralOpenAI-compatible
MistralMistral Large, MediumOpenAI-compatible
xAIGrokOpenAI-compatible
TogetherOpen-source modelsOpenAI-compatible
FireworksOpen-source modelsOpenAI-compatible
CohereCommand R+OpenAI-compatible
OpenRouterMulti-provider routingOpenAI-compatible

See the full provider list at Gateway > Providers.

Next steps