v1.0

Documentation

Everything you need to add runtime AI policy enforcement to your application in minutes.

01 5-Minute Quickstart

From signup to your first proxied request — follow these steps in order.

1
Sign up and log in
Create your account at sentinelgate.polsia.app/signup.html. You'll land on the dashboard automatically.
2
Add your OpenAI API key (BYOK)
SentinelGate uses your own API key — it never shares one. Go to the Dashboard → LLM Keys section and click Add Key.
Your key is encrypted at rest using AES-256-GCM and never logged. You can revoke it anytime.
3
Generate an sg_live_* API key
Go to Dashboard → API Keys and click Generate Key. Copy it — it's shown only once.
EXAMPLE
sg_live_a1b2c3d4e5f6...  # your key — keep it secret
4
Create your first policy
Go to Dashboard → Policies and click New Policy. Give it a name (e.g. "Default") and add a rule. Example rules:
  • block — block requests that match a jailbreak pattern
  • redact — strip PII (SSN, credit cards, emails) before they reach OpenAI
  • allow — pass through with full audit logging
Activate the policy with the toggle — only one policy can be active at a time.
5
Make your first proxied request
Replace api.openai.com/v1 with sentinelgate.polsia.app/v1 and swap your API key for your sg_live_* key.
CURL
curl https://sentinelgate.polsia.app/v1/chat/completions \
  -H "Authorization: Bearer sg_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-4o-mini",
    "messages": [
      { "role": "user", "content": "Hello!" }
    ]
  }'
The response is identical to OpenAI's. Check the response headers — you'll see X-SentinelGate-Action confirming the policy decision.
6
Check the audit log
Open Dashboard → Audit Log to see every request: model used, policy applied, action taken (allow/block/redact), latency, and full request summary.
CURL
curl https://sentinelgate.polsia.app/api/audit \
  -H "Authorization: Bearer sg_live_YOUR_KEY"
You're live. All traffic through sentinelgate.polsia.app/v1 is now inspected, policy-enforced, and audited per your account.

02 How It Works

SentinelGate sits between your app and the OpenAI API. Every request passes through the policy engine before reaching OpenAI.

FLOW
Your App
    POST /v1/chat/completions  (with sg_live_* key)
SentinelGate
    Resolve API key → user + policy
    Apply rules: block / redact / mask / allow
    Log audit event to PostgreSQL
    Relay request → OpenAI (with your BYOK key)
OpenAI
    Response streamed back
SentinelGate
    Attach X-SentinelGate-* response headers
Your App
    OpenAI-identical response

The proxy is fully transparent — no SDK changes required, no response format changes. Drop it in with a single base URL swap.


03 API Reference

Proxy Endpoint

POST /v1/chat/completions

OpenAI-compatible chat completions endpoint. Accepts the same request body as OpenAI's Chat Completions API — no changes required.

Authentication

Pass your sg_live_* key in the Authorization header. Do not use your OpenAI key here — SentinelGate uses your saved BYOK key internally.

HEADER
Authorization: Bearer sg_live_...

Request Body

Field Type Status Description
model string required OpenAI model ID (e.g. gpt-4o, gpt-4o-mini)
messages array required Array of message objects with role and content
temperature number optional Sampling temperature (0–2)
max_tokens integer optional Maximum tokens in response
stream boolean optional Stream the response (SSE)

Response Headers

HeaderExampleDescription
X-SentinelGate-RequestId sg_req_abc123 Unique audit event ID
X-SentinelGate-Action allow Policy decision: allow, redact, or block
X-SentinelGate-Policy My Policy Name of the active policy
X-SentinelGate-Latency 312 Total latency in milliseconds

Status Codes

200 OK 400 Invalid request body 401 Unauthorized (invalid API key) 403 Blocked by policy 500 Upstream error
A 403 means your active policy blocked the request. Check the audit log for the rule that triggered it. Set a BYOK key first — requests will 400 if no LLM key is stored.

Audit Logs

GET /api/audit

Paginated list of audit events scoped to your account. Newest events first.

Query Parameters

ParamTypeDefaultDescription
page integer 1 Page number
limit integer 25 Events per page (max 100)
action string Filter by action: allow, block, redact

Example Response

JSON
{
  "success": true,
  "events": [
    {
      "request_id": "sg_req_abc123",
      "timestamp": "2026-03-20T06:00:00Z",
      "model": "gpt-4o-mini",
      "action": "allow",
      "policy_name": "Default",
      "rules_applied": [],
      "latency_ms": 312,
      "upstream_status": 200
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 25,
    "total": 142,
    "pages": 6
  }
}
GET /api/audit/stats

Aggregated stats for the last N hours — total requests, blocked/allowed/redacted counts, avg latency, unique tenants.

Query Parameters

ParamTypeDefaultDescription
hours integer 24 Lookback window in hours (max 168 = 7 days)

Example Response

JSON
{
  "success": true,
  "period_hours": 24,
  "stats": {
    "total_requests": "142",
    "allowed": "130",
    "blocked": "5",
    "redacted": "7",
    "avg_latency_ms": "298"
  },
  "recent_blocks": [...]
}

Policies

GET /api/policies

List all policies for your account.

POST /api/policies

Create a new policy.

Request Body

FieldTypeStatusDescription
name string required Unique policy name for your account
description string optional Human-readable description
rules array optional Array of rule objects (see below)
is_active boolean optional Activate immediately (deactivates others)

Rule Object

JSON
{
  "type": "keyword",      // "keyword" | "pattern" | "jailbreak" | "pii"
  "action": "block",      // "block" | "redact" | "mask" | "allow"
  "pattern": "ignore all", // regex or keyword string
  "description": "Block prompt injection attempts"
}
PUT /api/policies/:id

Update an existing policy. Same body shape as POST. Activating a policy deactivates all others.

DELETE /api/policies/:id

Delete a policy. Cannot delete the active policy.

GET /api/policies/:id/audit

Audit events scoped to a specific policy ID. Supports ?page and ?limit.


04 Authentication

All API endpoints (both proxy and management) authenticate via Bearer token in the Authorization header.

HEADER
Authorization: Bearer sg_live_YOUR_API_KEY

API keys are in the format sg_live_ followed by 64 hex characters. They are hashed (SHA-256) before storage — SentinelGate cannot recover your key if lost. Generate a new one from the dashboard.

Your API key has full access to your account — audit logs, policies, and the proxy endpoint. Treat it like a password. Rotate it from the dashboard if compromised.

05 Error Responses

All errors return JSON with a success: false flag and a message field.

JSON
{
  "success": false,
  "message": "No LLM API key configured. Add one in the dashboard."
}
StatusMeaning
400Bad request — missing or invalid fields
401Unauthorized — API key missing, invalid, or revoked
403Blocked by policy — request matched a block rule
404Resource not found
409Conflict — e.g. duplicate policy name
500Internal error or upstream (OpenAI) error

06 Integration Examples

Python (openai SDK)

PYTHON
from openai import OpenAI

client = OpenAI(
    api_key="sg_live_YOUR_SENTINELGATE_KEY",
    base_url="https://sentinelgate.polsia.app/v1"
)

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

print(response.choices[0].message.content)

That's the only change. Replace your existing api_key with your sg_live_* key and add base_url. The entire OpenAI SDK works as-is.

Streaming

PYTHON
with client.chat.completions.stream(
    model="gpt-4o-mini",
    messages=[{"role": "user", "content": "Tell me a story"}]
) as stream:
    for chunk in stream.text_stream:
        print(chunk, end="", flush=True)

Node.js (openai SDK)

JAVASCRIPT
import OpenAI from 'openai';

const client = new OpenAI({
  apiKey: 'sg_live_YOUR_SENTINELGATE_KEY',
  baseURL: 'https://sentinelgate.polsia.app/v1'
});

const response = await client.chat.completions.create({
  model: 'gpt-4o-mini',
  messages: [
    { role: 'user', content: 'Hello!' }
  ]
});

console.log(response.choices[0].message.content);

CommonJS

JAVASCRIPT (CJS)
const OpenAI = require('openai');

const client = new OpenAI({
  apiKey: 'sg_live_YOUR_SENTINELGATE_KEY',
  baseURL: 'https://sentinelgate.polsia.app/v1'
});

Check response headers

JAVASCRIPT
const response = await fetch('https://sentinelgate.polsia.app/v1/chat/completions', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer sg_live_YOUR_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    model: 'gpt-4o-mini',
    messages: [{ role: 'user', content: 'Hello!' }]
  })
});

console.log(response.headers.get('X-SentinelGate-Action')); // "allow"
console.log(response.headers.get('X-SentinelGate-RequestId')); // "sg_req_..."

curl

SHELL
# Basic request
curl https://sentinelgate.polsia.app/v1/chat/completions \
  -H "Authorization: Bearer sg_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-4o-mini",
    "messages": [{ "role": "user", "content": "Hello!" }]
  }'

# Show response headers (see X-SentinelGate-*)
curl -i https://sentinelgate.polsia.app/v1/chat/completions \
  -H "Authorization: Bearer sg_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"gpt-4o-mini","messages":[{"role":"user","content":"Hello!"}]}'

# List audit events
curl https://sentinelgate.polsia.app/api/audit \
  -H "Authorization: Bearer sg_live_YOUR_KEY"

# Get stats for the last 48 hours
curl "https://sentinelgate.polsia.app/api/audit/stats?hours=48" \
  -H "Authorization: Bearer sg_live_YOUR_KEY"

# List policies
curl https://sentinelgate.polsia.app/api/policies \
  -H "Authorization: Bearer sg_live_YOUR_KEY"

# Create a policy
curl -X POST https://sentinelgate.polsia.app/api/policies \
  -H "Authorization: Bearer sg_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Production Policy",
    "rules": [
      { "type": "jailbreak", "action": "block", "description": "Block jailbreak attempts" },
      { "type": "pii", "action": "redact", "description": "Strip PII before OpenAI" }
    ],
    "is_active": true
  }'
SentinelGate Docs — v1.0
Home Pricing Get started