Develop / Reference

Chat Completions

Generates a model response in the OpenAI chat format and inspects the messages with Noirdoc Shield when Shield is active for the request.

POST /v1/chat/completions
Family
chat
Shield
yes
Streaming
yes, SSE
Format
JSON
Billing
tokens

Request

The gateway accepts the body in the format of the OpenAI Chat Completions API. The base URL is https://api.noirdoc.de/v1.

model is required. Use a model ID from GET /v1/models. The model must belong to the chat family and run at a provider in the OpenAI format.

You send the key as Authorization: Bearer px-.... The other header forms are listed under Authentication & headers.

The example turns Noirdoc Shield on for this one request with X-Noirdoc-Shield: on. Set up Noirdoc Shield explains how the policy, keys, request tags and headers interact.

Shell
curl https://api.noirdoc.de/v1/chat/completions \
  -H "Authorization: Bearer $NOIRDOC_API_KEY" \
  -H "Content-Type: application/json" \
  -H "X-Noirdoc-Shield: on" \
  -d '{
    "model": "qwen3.8-27b",
    "messages": [
      {
        "role": "user",
        "content": "What does Mr Müller write to the firm?"
      }
    ]
  }'
Python
import os
from openai import OpenAI

client = OpenAI(
    base_url="https://api.noirdoc.de/v1",
    api_key=os.environ["NOIRDOC_API_KEY"],
)

response = client.chat.completions.create(
    model="qwen3.8-27b",
    messages=[
        {
            "role": "user",
            "content": "What does Mr Müller write to the firm?",
        }
    ],
    # Turn on Shield for this request
    extra_headers={"X-Noirdoc-Shield": "on"},
)
print(response.choices[0].message.content)
TypeScript
import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://api.noirdoc.de/v1",
  apiKey: process.env.NOIRDOC_API_KEY,
});

const response = await client.chat.completions.create(
  {
    model: "qwen3.8-27b",
    messages: [
      {
        role: "user",
        content: "What does Mr Müller write to the firm?",
      },
    ],
  },
  // Turn on Shield for this request
  { headers: { "X-Noirdoc-Shield": "on" } },
);
console.log(response.choices[0].message.content);

What Noirdoc changes

AreaBehaviour
ModelThe gateway resolves the model ID through the catalogue and sends the provider its own model name. If the response’s model field contains this name, the gateway replaces it with the ID you sent.
ProviderThe gateway selects the provider. The X-Noirdoc-Provider header in the response names it, including on a provider error. For streams, the header is missing if the provider answers only after 15 seconds; a comment line : provider=<slug> then names the provider, see Streaming. Providers & routing describes the order.
FailoverIf a provider answers with 429 or 5xx or cannot be reached before the response begins, the gateway tries the next provider for the same model, at most three providers per request. It does not mix your own providers (BYOK) and providers managed by Noirdoc.
Noirdoc ShieldWhen Shield is active, the gateway replaces sensitive values in messages in-place with fixed placeholders ([PERSON], [IBAN], …) or rejects the request with 403 shield_violation on a block match (such as secrets or prompt injection) — without prepending a system message, modifying the model response or holding back stream chunks. Inspected fields lists the inspected fields. Reversible placeholder masking (<<PERSON_1>>) applies only to pre-existing legacy organisations until 30.11.2026 (Legacy masking).
StreamingWith "stream": true, the gateway sets stream_options.include_usage to bill the tokens. If you did not request this yourself, it removes the extra event with the usage data from the stream.
Files and imagesParts of type image_url, file and input_audio in messages are allowed only if admins of your organisation have turned on Allow file and image attachments in requests under Models → Shield (Advanced Settings). Shield inspects inline UTF-8 text files under 4 MiB directly; binary PDFs, images or audio return X-Noirdoc-Shield: partial; redacted=<n> or 422 shield_uninspectable_content under enforced. Details: Files and images and Files.
File referencesWith providers managed by Noirdoc, a file_id in a file part must have been uploaded through your organisation. Otherwise, the gateway answers with 404 object_not_found.
HeadersThe gateway removes your key, X-Noirdoc-Shield and X-Noirdoc-Mask before forwarding the request.
Provider errorsThe gateway reports provider errors in the uniform error object, for example as 429 resource_exhausted or 503 provider_overloaded with Retry-After. You find the code under Error codes.

Sub-routes

MethodPathPurpose
POST/v1/chat/completionsgenerate a response
GET/v1/chat/completionslist stored chat completions
GET/v1/chat/completions/{id}retrieve a stored chat completion
DELETE/v1/chat/completions/{id}delete a stored chat completion
GET/v1/chat/completions/{id}/messagesretrieve the messages of a stored chat completion

With the providers managed by Noirdoc, the gateway rejects "store": true with 403 stored_responses_disabled unless admins of your organisation have turned on Allow Responses API storage at provider under Models → Shield (see Responses). The sub-routes for stored chat completions work only with your own provider key (BYOK). The gateway forwards them to the oldest active provider in the OpenAI format that your organisation has connected itself. Without your own provider, it answers with 403 endpoint_not_available_on_platform, because all organisations share Noirdoc’s provider accounts. If no provider in the OpenAI format is available at all, it answers with 502 provider_not_configured.

Stored chat completions retain one-way Shield placeholders such as [PERSON] (and under legacy masking until 30.11.2026, placeholders are not translated back on retrieval either).

The gateway answers other paths under /v1/chat/completions/ with 404 unsupported_endpoint.

Errors on this endpoint

Status Code Meaning
400 model_required The request names no model (model in the body, or in the form field for /v1/audio/transcriptions).
400 wrong_endpoint_for_model The model belongs to a different endpoint family or API format than the endpoint called.
400 invalid_request_body The body is not a JSON object or not encoded in UTF-8.
402 insufficient_credit The organisation's credit is used up or lower than the estimated maximum cost of the request (including Noirdoc Shield, also on BYOK routes when Shield is active).
402 key_budget_exhausted This key's budget is used up for the current period or does not cover the estimated cost of the request.
403 endpoint_not_available_on_platform The call would read data from the shared account of a provider managed by Noirdoc and is blocked there.
403 model_not_allowed_for_key The model is not one of this key's allowed models.
403 provider_not_allowed_for_tenant The organisation counts as bound by professional secrecy (§ 203 StGB); this excludes every provider that offers this model.
403 provider_not_allowed_for_key The key's restrictions (providers, data residency, CLOUD Act, § 203) exclude every provider of this model.
403 starter_model_not_allowed The organisation is still using only its starter credit, and the model or its managed provider is not included in starter credit.
403 shield_violation Noirdoc Shield blocked the request before forwarding to the provider because an active protection filter configured with block matched; message names the triggered rule (secrets, pii, ner, injection or custom).
403 file_content_not_allowed The request contains files, images or audio, and the organisation does not allow file content.
403 file_pii_blocked A file contains personal data, and the organisation's legacy file analysis (transition until 30.11.2026) is set to block or to detect_only under enforced.
404 object_not_found The object (file, skill or stored response) does not exist or does not belong to your organisation.
404 model_not_available The model ID is not available to the organisation.
413 shield_input_too_large The text to inspect in this request exceeds the Shield service limit of 4 MiB of encoded text in a single call.
422 shield_uninspectable_content The Shield policy is enforced, and the request carries content that Shield cannot inspect as text (binary_document such as PDF or Office, media_not_inspectable such as images, audio or video, file_reference by ID or URL, file_too_large at 4 MiB or above, file_not_decodable or unrecognised_content). The gateway did not forward the request.
422 shield_config_invalid The organisation's stored Shield configuration is invalid (for example enforced without any active protection filter, or a pattern that fails compilation); the gateway did not forward the request.
422 file_unprocessable A file could not be processed in legacy file analysis (transition until 30.11.2026): it is too large, unreadable or in a format without analysis. The gateway did not forward the request.
500 detection_error Detecting personal data in legacy masking (transition until 30.11.2026) failed; the gateway did not forward the request.
502 provider_not_configured The organisation has no suitable provider set up for this request.
502 provider_unreachable The gateway could not connect to the provider, or the connection dropped.
503 ownership_check_unavailable The gateway could not check just now whether the object belongs to your organisation and rejected the request. The response contains Retry-After with 5 seconds.
503 shield_unavailable The Noirdoc Shield inspection service is temporarily unreachable; the gateway never forwards a request that requires inspection uninspected (fail-closed). The response contains Retry-After with 5 seconds.
503 gateway_restarting The gateway was restarted (deployment) while the stream was still waiting for the provider's response. The error is in the running stream, because status code 200 has already been sent by then. The error object contains retry_after with 5 seconds.
504 provider_timeout The provider did not answer within the gateway's timeout. The response contains Retry-After with 10 seconds.

OpenAI reference

OpenAI’s API reference describes all other request and response fields: Chat Completions (checked on 30 September 2026).