Develop / Guides
Files
How to send files to models, which file parts Noirdoc Shield inspects and what happens when you upload through /v1/files.
Files reach a model in two ways:
- Inline in the body: as a Base64
data:URL in a message to/v1/chat/completions,/v1/responsesor/v1/messages. Noirdoc Shield can decode and inspect inline UTF-8 text files. - Upload through
/v1/files: the gateway passes the file to the provider unchanged. Messages then refer to it byfile_id.
Allow file and image attachments
Under Models → Shield in Advanced Settings, the Allow file and image attachments in requests (allow_file_content) switch is on by default. If it is off, the gateway rejects these requests with 403 file_content_not_allowed:
- Messages with file, image or audio parts, including with a
file_idreference - All requests to
/v1/filesand/v1/skills - Transcriptions through
/v1/audio/transcriptions
Send files inline
When Noirdoc Shield is active for a request to /v1/chat/completions, /v1/responses or /v1/messages, the gateway distinguishes between inline UTF-8 text files and binary or referenced content (details on the inspected fields under Inspected fields):
- Inline UTF-8 text files: Shield decodes inline UTF-8 files (
text/*, JSON, XML, CSV, Markdown and YAML under 4 MiB decoded) before forwarding, redacting matches or blocking the request with 403shield_violationaccording to the active protection filters. If the total text to inspect exceeds 4 MiB, the gateway answers with 413shield_input_too_large. - Binary documents, media and references: Shield cannot inspect binary documents (PDF, DOCX, XLSX, PPTX), images, audio, video or file references via
file_idor external URL as text:- Under the
enforcedorganisation policy, the gateway rejects such requests before forwarding with 422shield_uninspectable_content. Extract the text client-side beforehand and send it as message text or an inline UTF-8 text file. - Under
default_on, a key or tag set toon, orX-Noirdoc-Shield: on(non-enforced), Shield inspects all text fields and inline UTF-8 text files of the request, forwards binary parts and file references untouched, and marks the partial inspection in the response withX-Noirdoc-Shield: partial; redacted=<n>andX-Noirdoc-Masked: false.
- Under the
Generated files downloaded via GET /v1/files/{id}/content are passed through directly – Shield is stateless and stores no placeholder mappings.
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": [
{
"type": "text",
"text": "Summarise the notes."
},
{"type": "file", "file": {
"filename": "notes.txt",
"file_data": "data:text/plain;base64,Sm9uYXMg..."
}}
]
}]
}'Upload files
/v1/files passes uploading, retrieving and deleting files through to the provider unchanged. Noirdoc Shield inspects nothing here. The gateway therefore rejects uploads (POST /v1/files) under the enforced policy or with X-Noirdoc-Mask: on with 403 masking_not_supported_for_endpoint (otherwise it forwards the upload uninspected). Listing, retrieving, downloading and deleting remain allowed.
The header that carries your key determines the provider:
Authorization: Bearerorapi-key: Files API in the OpenAI formatx-api-key(Anthropic SDK): Anthropic’s Files API. The gateway adds the requiredanthropic-betavalue.
With X-Provider: anthropic, you choose Anthropic even with Authorization: Bearer.
curl https://api.noirdoc.de/v1/files \
-H "Authorization: Bearer $NOIRDOC_API_KEY" \
-F purpose="user_data" \
-F file="@contract.pdf"import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.noirdoc.de/v1",
api_key=os.environ["NOIRDOC_API_KEY"],
)
uploaded = client.files.create(
file=open("contract.pdf", "rb"), purpose="user_data"
)
print(uploaded.id)import fs from "node:fs";
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://api.noirdoc.de/v1",
apiKey: process.env.NOIRDOC_API_KEY,
});
const uploaded = await client.files.create({
file: fs.createReadStream("contract.pdf"),
purpose: "user_data",
});
console.log(uploaded.id);Managed providers
With providers managed by Noirdoc, several organisations share one account at the provider. The gateway therefore assigns every uploaded file to your organisation:
GET /v1/fileslists your organisation’s files.- The gateway treats a
file_idof another organisation like an unknown one: 404object_not_found. This also applies to references in messages.
With your own provider (BYOK), this assignment does not apply; there you see your provider’s account.
Skills
/v1/skills passes requests through to Anthropic’s Skills API, also without Shield inspection. The same rule as for /v1/files applies under enforced and X-Noirdoc-Mask: on: the gateway then rejects creating skills and versions with 403 masking_not_supported_for_endpoint. The endpoints are described in detail under Files & Skills.
Legacy file analysis (sunset on 30.11.2026)
For pre-existing organisations still running legacy masking during the transition period until 30.11.2026, the gateway continues to apply file_analysis_mode to inline files when masking is active (including PDF, DOCX, XLSX and text up to the configured maximum size of 25 MB by default, optionally with OCR for scans and images):
passthrough(Pass through): forwards the file without inspection.detect_only(Detect only): detects personal data and forwards the file unchanged (rejected with 403file_pii_blockedunderenforced).pseudonymize(Pseudonymize): replaces personal data with placeholders such as<<PERSON_1>>(DOCX, XLSX and text keep their format; PDFs are replaced by their masked text). Text-based downloads viaGET /v1/files/{id}/contentare re-identified using stored mappings.block(Block): rejects files containing personal data with 403file_pii_blocked.
If legacy file analysis cannot process a file in the block or pseudonymize modes (size limit exceeded, unreadable or unknown format), the gateway answers with 422 file_unprocessable. Once an organisation switches to Noirdoc Shield under Models → Shield, these modes are replaced by the inline UTF-8 text inspection described above.
Errors
| Status | Code | Meaning |
|---|---|---|
| 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 | masking_not_supported_for_endpoint | The endpoint supports neither Noirdoc Shield nor legacy masking, yet the policy is enforced or the request sends X-Noirdoc-Mask: on (and on /v1/images/generations also X-Noirdoc-Shield: on). During the legacy masking transition until 30.11.2026, this also affects /v1/embeddings and /v1/rerank on pre-existing organisations that have not switched to Shield yet. |
| 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. |
| 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 | 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 | file_analysis_error | Reserved for file analysis errors. The gateway does not currently send this code. |