Structured outputs
response_format is accepted and dropped (openai-ignorable-keys). When you need output in a fixed shape, use native tool calling as the shape: put a JSON Schema in a function's parameters and force that function with tool_choice — the arguments come back as JSON in that schema.
{"model": "qwen3.8-flash-next-whitehacker", "max_tokens": 2048,
"tools": [{"type": "function", "function": {"name": "report_finding",
"parameters": {"type": "object", "required": ["severity", "title", "evidence"],
"properties": {"severity": {"enum": ["low", "medium", "high", "critical"]},
"title": {"type": "string"}, "evidence": {"type": "string"}}}}}],
"tool_choice": {"type": "function", "function": {"name": "report_finding"}},
"messages": [{"role": "user", "content": "Review this handler: ..."}]}
→ choices[0].message.tool_calls[0].function.arguments
"{\"severity\":\"high\",\"title\":\"Auth bypass via ...\",\"evidence\":\"...\"}"
Asking in the prompt
messages: [{"role":"user","content":"Return ONLY a JSON object {\"finding\": string, \"severity\": \"low|medium|high\"}. No prose."}]
# then parse; validate on your side; retry on a parse failure
arguments arrive as a string (JSON text). Parse and validate on your side; a model can miss the schema, so resend on a validation failure.