Skip to content

Request normalization

The same OpenAI-style parameter can behave differently across open-model serving stacks: honored, ignored, or rejected with a stack-specific error. Keln normalizes the request surface per model, so one request shape works everywhere.

Parameters

Standard parameters are honored or translated per model. Support for some parameters varies by route (seed, n, logprobs, logit_bias, the frequency/presence penalties, stop); a request that uses one goes to capacity that supports it, and tools, JSON modes, and image input route the same way. When no capacity serving the model can honor a hard requirement, the request returns a 400 naming the parameter.

Open-model extensions (top_k, min_p, repetition_penalty) are passed through where the serving stack supports them. Fields Keln accepts but does not act on are named in the x-keln-inert-params response header.

Message shapes

  • developer role is treated as system.
  • Content can be a string or a text-part array.
  • A replayed reasoning field folds into reasoning_content, and replayed reasoning_content is preserved, so multi-turn tool calling keeps the trace (reasoning).
  • cache_control blocks are ignored (caching is automatic).
  • Unknown fields are ignored.

Repairs in flight

Responses are normalized to the spec shape:

  • Streamed tool-call fragments arrive with dense, 0-based indices.
  • A <think> block glued into content is lifted back out into reasoning_content.
  • A route that ignores max_tokens is cut at your cap server-side.
  • Stop-sequence dialect differences are absorbed.

Rejected before billing

Oversized requests return 400 context_length_exceeded, counted with the model's tokenizer against its context window (context_length in /v1/models), before any tokens are billed.

Stripped before dispatch

End-user identifiers (user, safety_identifier), storage and metadata flags, and provider-steering fields are removed before a request leaves Keln, part of zero data retention. Injected provider system prompts are detected and removed, so the model sees your messages only.

Full per-parameter behavior: API reference →