Scalattice requirements: the API checks the finished answer and fails closed
Developers

Requirements: completions that can fail

Most APIs return HTTP 200 with whatever the model said. Scalattice can return 422 when the answer is the wrong shape.

This is a JSON field on POST /v1/chat/completions, not an HTTP header. Routing still uses X-Scalattice-Region and friends. Requirements sit next to messages and say what a right answer looks like.

The finished text is assessed by the hypervisor. If it fails, Scalattice retries. If it still fails, you get 422, not a maybe. Your OpenAI SDK, LiteLLM proxy, or curl script can branch on that the same way they branch on credits or rate limits.

What you can require

Pick the checks that match the job. We do not guess that a request is "coding" versus "JSON."

  • json: the output must parse as JSON
  • schema: a small JSON Schema (no $ref)
  • contains / not_contains: substrings
  • regex / not_regex: Go RE2 patterns
  • instruct: append the scheme to the prompt (default true)
  • max_attempts and max_spend: stop retrying

Omit requirements, or send {}, to skip checks. Image routes ignore the object. Checks are data, not programs: no callback URL, no shell, no running of the model output.

Python

The official OpenAI SDK drops unknown fields unless you pass extra_body:

from openai import OpenAI

client = OpenAI(base_url="https://api.scalattice.cloud/v1", api_key="slt_...")

response = client.chat.completions.create(
    model="qwen-3-8b",
    messages=[{"role": "user", "content": "Return JSON with score 0-1 and summary."}],
    extra_body={
        "requirements": {
            "json": True,
            "schema": {
                "type": "object",
                "required": ["score", "summary"],
                "properties": {
                    "score": {"type": "number", "minimum": 0, "maximum": 1},
                    "summary": {"type": "string", "minLength": 3},
                },
            },
            "max_attempts": 3,
            "max_spend": 0.05,
        }
    },
)
print(response.choices[0].message.content)

When it fails

HTTP 422 includes which checks failed, how many attempts ran, and USD spent:

{
  "error": {
    "code": "requirements_unmet",
    "requirements": {
      "met": false,
      "attempts": 3,
      "spentUsd": 0.012,
      "failed": [{"check": "json", "detail": "output is not valid JSON"}]
    }
  }
}

Each attempt is a billed completion. usage on a successful response is the sum. Streaming cannot retry a finished answer, so stream: true plus requirements is 400.

Not tool calling

OpenAI-style tools is a separate field. The model may ask your client to run a function. Scalattice never runs it. Put tools on the request, not inside requirements.

Full field table and limits: Cloud docs, Requirements. Setup if you are new: OpenAI SDK drop-in.