Plugins

Configure processing around model calls and reuse parsed file content.

Plugins process requests or responses around a model call so models can use converted inputs. They do not change a model's native capabilities. file-parser is the first plugin: when needed, it converts documents or images to text before sending them to your chosen model.

The same plugins parameter works on create requests to /model/v1/chat/completions, /model/v1/messages, and /model/v1/responses, with or without streaming. The platform consumes it; it is not forwarded as an upstream model parameter.

Configuration and defaults

Add a plugins array to the request body. Each entry identifies a plugin by id:

{
  "plugins": [
    { "id": "file-parser", "enabled": true }
  ]
}

Omitting plugins or sending plugins: [] inherits the defaults; neither disables plugins. File parsing is enabled by default. PDFs and images pass through when the model supports them natively and they meet its limits. Otherwise, text PDFs and Office documents use local text extraction, scanned pages use OCR, and images use OCR plus a visual description. Extracted text consumes the main model's context window.

To disable conversion:

{
  "plugins": [
    { "id": "file-parser", "enabled": false }
  ]
}

Native inputs remain available when conversion is disabled; unsupported inputs are rejected. Plugin IDs, fields, and values are validated, so unknown configuration is not silently ignored.

PDF processing

pdf.engineBehavior
auto (default mode)Prefer native input. When conversion is needed, extract text locally and use OCR for scanned pages or pages with insufficient text.
nativeRequire native PDF input. Reject unsupported inputs or inputs beyond native limits, without falling back to text conversion.
ocrForce text conversion even when the model supports native PDFs. Pages with usable text still use local extraction; only pages needing recognition invoke OCR.

Omitting pdf.engine inherits the effective defaults. Without a tenant or platform override, this selects automatic mode. The request parameter currently accepts only explicit native or ocr; the string "auto" cannot override an existing default. You can set the tenant PDF default to automatic in the console.

{
  "plugins": [
    { "id": "file-parser", "pdf": { "engine": "ocr" } }
  ]
}

pdf.engine only affects PDFs. Set "image": { "describe": false } to disable conversion of non-native image inputs; this leaves native vision and document processing available.

Configuration precedence

From highest to lowest: platform policy > locked tenant settings > request > tenant defaults > plugin defaults.

Platform policy cannot be overridden. A request that changes a locked tenant value returns PLUGIN_SETTING_LOCKED. Unlocked settings can be overridden for one request without changing tenant defaults. Platform limits, including file size and page budgets, cannot be changed through request parameters.

Billing

  • Local extraction generates no additional model usage. The resulting text is still billed as input to the main model.
  • OCR is measured by pages actually processed. Image descriptions are measured by the description model's input, cached input, and output usage. Prices follow the models used.
  • OCR, image descriptions, and the main model have separate usage records. A main-model failure does not erase conversion usage already incurred.
  • A parsing cache hit makes no new conversion child call and adds no usage for that work. The next main-model call still incurs its actual input and output usage.

Annotations and replay

Responses after conversion carry file annotations. Preserve the complete object, including its hash and parsed content:

{
  "type": "file",
  "file": {
    "hash": "<preserve the returned hash>",
    "name": "notes.pdf",
    "content": [{ "type": "text", "text": "Extracted text" }]
  }
}
APINon-streaming locationStreaming location
Chat Completionschoices[].message.annotationschoices[].delta.annotations, once per choice
Anthropic MessagesTop-level message annotationsmessage_start.message.annotations
Responsesoutput_text.annotations inside a message's content[] in output[]Corresponding text snapshots in response.content_part.done, response.output_item.done, and terminal response events

Existing citation annotations and their indices are preserved. Responses adds file annotations to completed snapshots, leaving unfinished snapshots unchanged. The Messages top-level field and Responses type: "file" annotation are platform extensions; do not turn file annotations into Anthropic content blocks. Only actual conversion produces these annotations; native passthrough does not. If Responses returns only tool calls, refusal blocks, or empty output, the platform does not fabricate a text message to carry annotations.

On the next turn, keep the original user input and previous assistant content, including annotations:

// Chat Completions
messages.push(response.choices[0].message);

// Anthropic Messages: preserve the top-level extension
messages.push({
  role: "assistant",
  content: response.content,
  annotations: response.annotations,
});

// Responses: preserve output_text annotations
input.push(...response.output);

Then append the new user question. Streaming clients should preserve annotations in the accumulated response. If you assemble messages yourself, collect annotations from the events listed above. If an SDK's types omit extension fields, use its extra-field mechanism or read the raw JSON.

When the returned content matches the server's parsed artifact, original file, configuration, and model capabilities, parsing is skipped. Modified content, changed configuration, or unavailable cache entries can prevent reuse; client annotations alone do not prove that parsing occurred. If you no longer include the original file, annotation text still becomes ordinary conversation context. Sending only previous_response_id is not equivalent to explicitly returning file annotations.

Discovering input support

GET /model/v1/models exposes OpenRouter-shaped architecture.input_modalities containing only native modalities. Native PDF support appears as file; enabling a plugin never adds it to that array.

The extension x_praxis.input_modalities reports native, converted, or unsupported by input type:

{
  "architecture": { "input_modalities": ["text"] },
  "x_praxis": {
    "input_modalities": {
      "text": "native",
      "image": "converted",
      "pdf": "converted",
      "docx": "converted",
      "pptx": "converted",
      "xlsx": "converted",
      "audio": "unsupported",
      "video": "unsupported"
    }
  }
}

This example represents a chat model with native text input only. Support is derived from model capabilities and registered plugins. converted means a conversion path exists; effective tenant settings, request configuration, and limits still apply. Non-conversation calls such as embeddings and OCR do not gain conversation plugins. Audio and video currently have no conversion plugin and require native model support.

Limits

  • Inputs requiring conversion must provide inline content or an authorized file reference supported by the selected API. The plugin does not download arbitrary external URLs.
  • Conversion supports PDF, DOCX, PPTX, XLSX, and images. Office extraction reads document bodies, slide text, and cell values, not embedded objects or images within documents.
  • The limits are 10 MiB per file and 20 MiB per request; up to 100 parsed PDF pages and 20 paid OCR pages, with at most 10 pages per batch. Each request allows up to 4 paid child calls and 2 concurrent calls.
  • Conversion has a 90-second deadline. OCR child calls allow up to 45 seconds and image descriptions up to 30 seconds. During streaming conversion, : PRAXIS PROCESSING comments may arrive before model output; they are keepalives, not generated text.
  • Extraction is bounded to 1,000,000 characters and 1,000 spreadsheet rows per sheet. Model context and input limits still apply.
  • Responses converts newly submitted input only during create. Retrieve, cancel, and other object operations do not rerun conversion. A background: true request requiring conversion returns PLUGIN_BACKGROUND_UNSUPPORTED.
  • Concurrent cache misses can each incur conversion usage. If the main model fails, the current API does not guarantee that parsed file annotations will be returned.
Export

On this page