## 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_json` or `response_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](https://docs.parasail.io/parasail-docs/api-reference/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. |

## Next steps

- [Chat completions guide](https://docs.parasail.io/parasail-docs/guides/chat-completions)

- [Tool/function calling guide](https://docs.parasail.io/parasail-docs/guides/tool-function-calling)

- [Chat Completions API reference](https://docs.parasail.io/parasail-docs/api-reference/chat-completions)

- [Models endpoint](https://docs.parasail.io/parasail-docs/api-reference/models-endpoint)
