Responses and Embeddings
The two OpenAI-shaped endpoints beyond Chat Completions. Responses is inspected on both transports; Embeddings are relayed and recorded.
Two OpenAI-shaped endpoints sit alongside /v1/chat/completions. They
are not the same kind of surface, and the difference is worth knowing
before you point production traffic at either.
- Responses is inspected. Tool calls the model returns are evaluated against your workspace's policy, and a call your policy stops is rewritten before your client sees it.
- Embeddings is a relay. There is no tool call in an embedding to evaluate, so the body goes upstream unchanged and the call is recorded.
Responses
From 0.8, Responses uses workspace provider selection and the selected provider's stored credential. OpenAI and the measured Bedrock mantle gpt-oss lane are supported; provider selection does not make an unsupported model/API pair compatible. See Bedrock's capability table.
Client-executed function calls in the response are evaluated against your workspace policy before they are released. Both plain and streamed requests are inspected. A denied call is withheld and explained before it reaches your client; the original tool is never invoked.
Responses calls also enter request history. Model, provider, latency and available usage are recorded under your workspace's capture setting. Missing provider token counts remain unavailable; they are not inferred as zero.
What a blocked call looks like
The request still succeeds with 200. By default the blocked item is
withheld: an assistant message takes its slot, keeping its id:
{"id":"fc_…","type":"message","role":"assistant","status":"completed","content":[{"type":"output_text","text":"[Sentisec blocked tool_use: …]","annotations":[]}]}Other items in the same response are released, with one exception: a call that changes something is not sent when another call in the response is held or refused (calls proposed together). On a stream, the frames of an in-progress tool call are held until it can be decided, and on a block the explanation arrives in their place. The frames of a call that changes something, and every frame after them, arrive once every call in the response has been decided. The arguments of a stopped call never reach your client. Sequence numbers, item ids and output indexes continue unbroken, and frames of other items pass through unchanged.
With the rename opt-in, the item instead keeps its call_id and id
and comes back as sentisec_tool_call_blocked, with
{"error":"tool_call_blocked","reason":"…"} as its arguments
(how and where it works).
In shadow mode every item passes untouched; the verdict records what enforcing would have done. See Protection modes.
Reading the verdict
A non-streaming call carries the X-Sentisec-Verdict response header. A
streamed call does not carry it at all — a response's headers go out
before its body, so no value written at the start of a stream could be
true of the end of it. On a stream the verdict rides the
trailing frame instead.
Neither surface is a block-detection channel. Detect a block from the response body, as shown above, and read the recorded verdict from the session (Sessions) or the dashboard. What each header case means is on Headers and streaming frames.
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 own infrastructure
before the response reaches Sentisec. Sentisec cannot gate their execution inside the provider. Any returned
summary is an observation after that execution, not an opportunity to stop it.
Where one appears in a response, 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.
Embeddings
Embeddings are not actions. There is no tool call to evaluate, no argument to rewrite, and nothing a model can be talked into doing with a vector. So this endpoint is deliberately a passthrough: your body goes to the upstream unchanged and the response comes back unchanged.
It exists so that a retrieval pipeline pointed at your Sentisec base URL does not silently fall outside your view. Captured embeddings calls write a request record — model, token counts, provider, latency — which is what makes ingestion visible on the dashboard alongside the rest of the workspace's traffic.
Supported upstreams: OpenAI and the Gemini API
(gemini-embedding-001). Any other provider returns
404 embeddings_not_supported_for_provider — that vendor has no
OpenAI-shape embeddings endpoint, so switching provider is the fix, not
reconfiguration. Vertex AI is included in that: its embeddings live on a
different, non-OpenAI-shaped surface.
curl https://api.sentisec.ch/ws/$SENTISEC_WORKSPACE_ID/v1/embeddings \
-H "Authorization: Bearer $SENTISEC_API_KEY" -H "content-type: application/json" \
-d '{"model":"text-embedding-3-small","input":"The quick brown fox."}'What each one records
Both endpoints run inside the workspace boundary. Requests are authenticated against your workspace key, served with your workspace's stored provider credential, and counted against your plan's request rate. They differ in what lands in your request history:
- Embeddings writes one usage record per call — model, token counts, provider, latency — under your content-retention setting.
- Responses, from 0.8, also records per-request model, provider, latency and available token counts, alongside its session and verdicts. Request and response content follow the workspace capture setting.
Related
- Chat endpoints — Messages and Chat Completions
- Headers and streaming frames
- Errors and limits
- Providers
Chat endpoints
Send Anthropic Messages or OpenAI Chat Completions traffic through Sentisec — request shape, streaming, blocked tool calls, and model discovery.
Headers and streaming frames
The headers Sentisec reads and adds, how requests are stitched into sessions, and the trailing verdict frame on streamed responses.