Providers

OpenAI

Point any OpenAI-shaped client at Sentisec. The OpenAI SDKs, Cursor, opencode, custom clients — all work with one base-URL change.

Sentisec speaks the OpenAI Chat Completions API natively. Any client built against OpenAI — the Python and TypeScript SDKs, Cursor, opencode, LangChain, your own client — points at Sentisec with a base-URL change and no code change.

Model ids beginning gpt-, o1, or o3 route to OpenAI automatically, so there is nothing else to configure.

Setup

Get an OpenAI key from platform.openai.com/api-keys.

Add it to your workspace. In the dashboard, open Settings → Providers. Under Provider keys, choose Add OpenAI key, paste the key, and click Save credential.

Mint a Sentisec API key. Settings → API keys → Issue key. Format: sk_sentisec_<8>_<32>. This is the key your client sends; your OpenAI key stays in the workspace.

Point your client at Sentisec. Two environment variables:

export OPENAI_BASE_URL=https://api.sentisec.ch/ws/<your-workspace-id>/v1
export OPENAI_API_KEY=$SENTISEC_API_KEY

Running Sentisec yourself? Substitute your own base URL — see enterprise access.

Warning
The workspace id in the URL is load-bearing

Use the workspace-scoped base URL. It is the form that guarantees your workspace's own policy travels with every request, on every transport. Your workspace id is on the dashboard next to your API key.

The /v1 suffix belongs on the OpenAI-shaped base URL — the SDKs expect to append paths like /chat/completions to it.

First call

curl -X POST https://api.sentisec.ch/ws/<your-workspace-id>/v1/chat/completions \
  -H "Authorization: Bearer $SENTISEC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-5.6-terra",
    "messages": [{"role": "user", "content": "hi"}]
  }'

You get back the standard OpenAI Chat Completions body. The session appears under Sessions in the dashboard.

OpenAI SDKs

import os
from openai import OpenAI

client = OpenAI(
    base_url="https://api.sentisec.ch/ws/<your-workspace-id>/v1",
    api_key=os.environ["SENTISEC_API_KEY"],
)

resp = client.chat.completions.create(
    model="gpt-5.6-terra",
    messages=[{"role": "user", "content": "hi"}],
)
import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://api.sentisec.ch/ws/<your-workspace-id>/v1",
  apiKey: process.env.SENTISEC_API_KEY!,
});

const resp = await client.chat.completions.create({
  model: "gpt-5.6-terra",
  messages: [{ role: "user", content: "hi" }],
});

Streaming ("stream": true) works on the same route, and tool calls are gated on both the streaming and non-streaming paths.

Model ids

Model idNotes
gpt-5.6-terraCurrent-generation balanced default. The id used in every sample on this site.
gpt-5.6-solCurrent-generation flagship — the top of the GPT-5.6 line.
gpt-5.6-lunaCurrent-generation cost tier.
gpt-4o, gpt-4o-miniMultimodal workhorses.
gpt-4-turboPrevious generation.
o1, o1-miniReasoning models.

These are the ids surfaced in model discovery (GET .../v1/models). Any id starting with gpt-, o1, or o3 is forwarded to OpenAI, which is the source of truth for what your key can call.

Embeddings

POST .../v1/embeddings works against OpenAI through your workspace endpoint:

curl -X POST https://api.sentisec.ch/ws/<your-workspace-id>/v1/embeddings \
  -H "Authorization: Bearer $SENTISEC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model": "text-embedding-3-small", "input": "hello"}'

Embeddings relay verbatim and are recorded for usage; there is no tool call in an embedding to gate.

Which endpoint is inspected

Sentisec exposes three OpenAI-shaped endpoints on your workspace URL. Both of the ones that carry tool calls are inspected.

EndpointWhat Sentisec does with it
POST .../v1/chat/completionsInspected. Every tool call the model returns is evaluated against your workspace policy before your client sees it — on both the streaming and the non-streaming path. A blocked call is withheld and explained in the message text, so it never reaches your tool.
POST .../v1/responsesInspected. Same evaluation, on both the streaming and the non-streaming path. A blocked call is withheld and explained, so your tool never runs it. This endpoint is OpenAI-only and writes no per-request usage record.
POST .../v1/embeddingsRelayed. An embedding contains no tool call to evaluate. The body goes upstream unchanged and every call is recorded for usage.

Chat Completions is what the OpenAI SDKs use by default and what every framework on this site drives, so for most readers it is already the path in use. gpt-5.6-terra is served on both Chat Completions and the Responses API, so the choice between them is about client shape and usage accounting, not about protection.

Full detail on both: Responses and Embeddings.

Tools OpenAI runs on its own side

The Responses API can execute web_search, file_search, computer_use, and remote MCP tools inside OpenAI's infrastructure before the response reaches Sentisec. Their arguments and results never cross your wire, so there is nothing for the integrity engine to inspect. Where one appears, Sentisec records it on the session timeline as observed-but-not-inspectable — it does not claim to have checked a call it never saw, and it cannot stop one.

What you get

On /v1/chat/completions, every call runs through the integrity engine before it reaches OpenAI, and every tool call the model asks for is evaluated before your tools run it. Verdicts and forensic evidence land in the dashboard. Function calling, structured outputs, vision, and streaming are all forwarded untouched.

If something goes wrong

ResponseWhat it means
401 no_upstream_credentialNo OpenAI key is stored on this workspace. Add it under Settings → Providers, in Provider keys — the request's row under Requests offers Add OpenAI key, which opens that page with OpenAI selected.
A 401 from OpenAIYour OpenAI key was revoked or is out of quota at the vendor.
400 upstream_provider_header_invalidYou sent an X-Sentisec-Upstream-Provider value that is not a known provider name.

More: Provider unavailable.

More

Protected docs