POST https://scanner.milgram.dev/v1/chat/completionsAuthorization: Bearer mgs_…For clients and gateways that only speak OpenAI chat completions. The body is an ordinary chat completion
request; the answer is a chat.completion whose assistant message is, as a JSON string, the verdict
POST /v1/scan returns for the same messages and tools.
Request
Section titled “Request”| Field | |
|---|---|
model |
Required: nam-shub-v2-20261008 or nam-shub@latest. |
messages |
The conversation, read exactly as /v1/scan reads it (see conversations). |
tools, functions |
Optional tool definitions, scanned with the conversation. |
stream |
Optional. true for streamed chunks. |
stream_options.include_usage |
Optional. Adds OpenAI’s usage chunk to a stream. |
response_format |
Optional: text or json_object. The content is JSON either way. Any other type is refused with 400 invalid_request. |
n |
Must be 1 if present. |
Generation parameters (temperature, max_tokens, stop, and so on) are accepted and ignored: a verdict
is not sampled. A message’s role, when present, must be system, developer, user, assistant, tool
or function; a message without one counts as user, and any other role is refused with
400 invalid_role. The body must be JSON.
Response
Section titled “Response”{ "id": "chatcmpl-0199c8a25b3e7c419a6f2d8e4b1c7f30", "object": "chat.completion", "created": 1790000000, "model": "nam-shub-v2-20261008", "system_fingerprint": "fp_0000000000000000", "choices": [{ "index": 0, "finish_reason": "stop", "logprobs": null, "message": { "role": "assistant", "refusal": null, "content": "{\"flagged\":true,\"severity\":\"critical\",\"categories\":{…},\"messages\":[…]}" } }], "usage": { "prompt_tokens": 12, "completion_tokens": 307, "total_tokens": 319 }}- The
contentis the verdict: the scan object without its envelope andusage. Parse it as JSON. modelis always the release served, even when the request namednam-shub@latest.prompt_tokenscounts the scanned text as/v1/scan’sinput_tokensdoes, andcompletion_tokenscounts the verdict’s JSON as itsoutput_tokensdoes: the same conversation gets the same usage from both endpoints.
Streaming
Section titled “Streaming”With "stream": true the answer comes as chat.completion.chunk events: the role, the verdict in one piece,
then the stop with usage, then data: [DONE]. With stream_options.include_usage, OpenAI’s usage chunk
(empty choices) is sent too. A large input streams at once, with progress comments while it is scanned; a
failure then ends the stream with a chunk whose finish_reason is error, carrying the
error object, then [DONE].