Structured Output | Parasail
Overview
Parasail's OpenAI-compatible endpoint can return structured, machine-parseable output so you don't have to scrape JSON out of free-form text. There are two distinct ways to do this:
Prompt-only JSON—you ask the model for JSON in the prompt. Simple, but the model can still drift (extra prose, missing keys, invalid JSON).
Server-enforced schemas—you pass a schema with the request and the server constrains decoding so the output is guaranteed to match. On Parasail this is done with
guided_jsonorresponse_format(JSON Schema).
Use server-enforced schemas whenever you need to parse the result programmatically.
Prompt-only JSON vs. server-enforced schemas
| Approach | How | Guarantee |
|---|---|---|
| Prompt-only JSON | Describe the desired JSON in the prompt | None—best-effort |
guided_json |
Pass a JSON Schema in extra_body |
Output is constrained to the schema |
response_format (JSON Schema) |
Pass response_format={"type": "json_schema", ...} |
Output is constrained to the schema |
Both server-enforced approaches use the same Parasail base URL:
https://api.parasail.io/v1
Supported models
The following models support guided/structured decoding as of June 2026. Capabilities change over time—use the models endpoint to check model availability, then validate structured-output support with a small test request.
Treat this table as a starting point for testing. Before relying on a constraint in production, send a small request with the same model and constraint type you plan to use.
| Model | Guided JSON / JSON Schema | Regex | Choice |
|---|---|---|---|
| parasail-llama-33-70b-fp8 | Y | Y | Y |
| parasail-llama-4-scout-instruct | Y | Y | Y |
| parasail-llama-4-maverick-instruct-fp8 | Y | Y | Y |
| parasail-qwen3-30b-a3b | Y | Y | Y |
| parasail-qwen3-235b-a22b | Y | Y | Y |
| parasail-qwen3-32b | Y | Y | Y |
| parasail-gemma3-27b-it | Y | Y | Y |
| parasail-mistral-devstral-small | Y | Y | Y |
Server-enforced JSON with guided_json
Pass a JSON Schema via the OpenAI SDK's extra_body parameter. The server uses guided decoding to ensure the response matches your schema.
import json
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.parasail.io/v1",
api_key="<PARASAIL_API_KEY>",
)
schema = {
"type": "object",
"properties": {
"location": {"type": "string"},
"date": {"type": "string", "format": "date"},
},
"required": ["location", "date"],
"additionalProperties": False,
}
completion = client.chat.completions.create(
model="parasail-qwen3-32b",
messages=[
{"role": "user", "content": "What's the weather like in Manhattan Beach on 2025-06-03?"}
],
extra_body={"guided_json": schema},
)
# The content is already constrained to match the schema
data = json.loads(completion.choices[0].message.content)
print(json.dumps(data, indent=2))
Expected output:
{
"location": "Manhattan Beach",
"date": "2025-06-03"
}
Server-enforced JSON with response_format
Parasail also accepts the OpenAI response_format field with type: "json_schema"—the same shape OpenAI uses. Combine strict: true with additionalProperties: false for the tightest output.
import json
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.parasail.io/v1",
api_key="<PARASAIL_API_KEY>",
)
schema = {
"type": "object",
"properties": {
"capital": {"type": "string"},
"country": {"type": "string"},
},
"required": ["capital", "country"],
"additionalProperties": False,
}
resp = client.chat.completions.create(
model="parasail-qwen3-32b",
messages=[{"role": "user", "content": "What is the capital of France?"}],
response_format={
"type": "json_schema",
"json_schema": {"name": "capital_lookup", "strict": True, "schema": schema},
},
)
data = json.loads(resp.choices[0].message.content)
print(json.dumps(data, indent=2))
Expected output:
{
"capital": "Paris",
"country": "France"
}
Prompt-only JSON
If you don't need a hard guarantee, you can simply ask the model for JSON. This works with any model but is best-effort—always validate and json.loads() the result before relying on it.
import json
from openai import OpenAI
client = OpenAI(
base_url="https://api.parasail.io/v1",
api_key="<PARASAIL_API_KEY>",
)
resp = client.chat.completions.create(
model="parasail-qwen3-32b",
messages=[
{
"role": "user",
"content": (
"Return ONLY a JSON object with keys 'location' and 'date' "
"for the weather in Manhattan Beach on 2025-06-03. No prose."
),
}
],
)
print(resp.choices[0].message.content)
Other guided decoding constraints (regex and choice)
For models listed with regex or choice support in the table above, guided decoding can also constrain output to a regular expression or a fixed set of choices via extra_body:
# Constrain to an ISO date
extra_body = {"guided_regex": r"\d{4}-\d{2}-\d{2}"}
# Constrain to one of a fixed set of values
extra_body = {"guided_choice": ["red", "green", "blue"]}
cURL example
curl https://api.parasail.io/v1/chat/completions \
-H "Authorization: Bearer $PARASAIL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "parasail-qwen3-32b",
"messages": [{"role": "user", "content": "What is the capital of France?"}],
"guided_json": {
"type": "object",
"properties": {
"capital": {"type": "string"},
"country": {"type": "string"}
},
"required": ["capital", "country"],
"additionalProperties": false
}
}'
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| Model ignores the constraint | Using prompt-only JSON | Switch to guided_json or response_format for server-enforced schemas. |
| Valid JSON but unexpected extra keys | additionalProperties not set |
Add "additionalProperties": false to your schema. |
| Need to stream large JSON | Output too large for one chunk | Set stream=True; constraints still apply. Concatenate delta.content and parse at the end. |