Gateway documentation
LLMGuard exposes an OpenAI-compatible API. Any OpenAI SDK works by changing the base URL and the API key.
Quickstart
- Connect a provider in Settings → Providers (your own key, encrypted at rest).
- Create an application and an LLMGuard API key (shown once).
- Send requests to
POST /v1/chat/completions.
curl $GATEWAY_URL/v1/chat/completions \
-H "Authorization: Bearer llmg_live_…" \
-H "Content-Type: application/json" \
-d '{"model":"openai/gpt-4o-mini","messages":[{"role":"user","content":"Hello"}]}'Models
Models are namespaced as provider/model: openai/gpt-4.1, anthropic/claude-sonnet-5-5, google/gemini-2.5-flash, mistral/mistral-large-latest, deepseek/deepseek-chat. GET /v1/models lists the models available to your key.
Streaming
Set "stream": true to receive Server-Sent Events in the OpenAI chunk format, ending with data: [DONE]. Add stream_options.include_usage to receive a final usage chunk. Usage is recorded even if the client disconnects mid-stream.
Response headers
x-request-id— correlation id, searchable in Monitoring → Requestsx-uaig-dlp-action— ALLOW, LOG or MASKx-uaig-provider— provider that served the requestx-uaig-cost— estimated cost (non-streaming)x-uaig-quota-usage-percent— highest consumption among applicable limits
Errors
Errors use an OpenAI-compatible envelope and never contain provider credentials or stack traces.
{ "error": { "code": "DLP_BLOCKED", "type": "permission_error",
"message": "Request blocked by data loss prevention: …",
"details": { "categories": ["FINANCIAL"], "rules": ["Credit card number"] },
"request_id": "req_…" } }| 400 | INVALID_REQUEST | Malformed body, unknown model namespace, provider-side validation error |
| 401 | INVALID_API_KEY | Missing, malformed, unknown, revoked or expired LLMGuard API key |
| 403 | POLICY_BLOCKED | A policy forbids this provider/model/size (details.violation) |
| 403 | DLP_BLOCKED | Sensitive data detected (details.categories, details.rules — never the values) |
| 429 | RATE_LIMITED | Upstream provider rate limit, or too many invalid key attempts |
| 429 | QUOTA_EXCEEDED | A quota or budget with BLOCK enforcement is exhausted (Retry-After header) |
| 502 | PROVIDER_ERROR | Provider rejected the organization credentials or returned an unexpected error |
| 503 | PROVIDER_UNAVAILABLE | Provider unreachable or timed out |
| 503 | PROVIDER_NOT_CONFIGURED | The provider is not connected for your organization |
DLP behaviour
All text fields (message content, content parts, tool-call arguments) are normalized (Unicode NFKC, zero-width characters removed) and scanned before forwarding. BLOCK rejects the request; MASK replaces matches with tokens such as [REDACTED_EMAIL]; LOG records a detection and forwards unchanged. Detection logs never contain matched values.
Quotas & budgets
Quotas (requests/minute, requests/day, tokens/day, tokens/month, cost/day, cost/month) and monthly budgets apply to the organization, a team, an application or a key. Request counts are enforced atomically; token and cost limits are checked before each request and charged with the provider-reported usage afterwards. Periods are computed in UTC.
Webhooks
Alerts (budget/quota thresholds, high-severity DLP, provider incidents) are delivered as JSON POSTs signed with x-uaig-signature: t=<unix>,v1=<hex HMAC-SHA256(secret, "t.body")>.