RAG and data · 2026-10-17
JSON output from the free Qwen3.8 27B: json_object guide
Ask qwen/qwen3.8-27b-free for a JSON object with response_format json_object and validate it with json.loads; free with a daily quota, OpenAI-compatible.
Short answer: ask for a JSON object with response_format
LLMTR is a gateway that gives access to language models from different providers through one OpenAI-compatible API. You call the free Qwen3.8 27B there with the model id qwen/qwen3.8-27b-free on the /v1/chat/completions endpoint at https://llmtr.com/v1. For JSON output, add the response_format field to the request with the value {"type": "json_object"} and describe the keys you expect in the prompt.
For this row the model card lists JSON mode, tool calling and image input; it does not list JSON Schema (structured outputs, that is response_format json_schema). The row is free with a daily usage quota: input and output cost $0 per 1M tokens. The context window is 131,042 tokens, and a single response can carry at most 16,384 output tokens. Qwen describes Qwen3.8-27B as a dense model with 27 billion parameters.
How do you get JSON output from a free model?
Three pieces are enough. The first is response_format: {"type": "json_object"}. The second is the prompt: in the system message, say that you want JSON and give the key names, their types and the format of fields such as dates. JSON mode asks for the answer to be a JSON object; which keys it holds is up to the prompt. The third is validation: parse the answer with json.loads and check in code that the keys you expect are there.
The Python example below extracts an order record from free text. temperature 0 reduces how much the output varies for the same input; max_tokens 1,024 is a sufficient budget for a short object. Raise the budget for longer objects, but do not go above 16,384 on this row. The json.dumps call on the last line runs with ensure_ascii=False, so Turkish characters are printed as they are instead of as escape sequences.
Giving a small example object with the keys filled in can help the model follow the key names and the nested structure. Keep the example in the system message and fill it with values that look nothing like real data; that way you notice easily if a value from the example leaks into the answer.
In the end, which keys come back depends on how clear the prompt is, and whether they are usable depends on your own validation.
An OpenAI Python SDK example that asks qwen/qwen3.8-27b-free for an order object with response_format json_object and checks for truncation and missing keys.
import json
import os
from openai import OpenAI
client = OpenAI(base_url="https://llmtr.com/v1", api_key=os.environ["LLMTR_API_KEY"])
REQUIRED_KEYS = {"order_id", "items", "city", "delivery_date", "notes"}
text = "Order 4471: three A5 notebooks and two blue pens, deliver to Izmir on 21 October 2026, leave at the front desk."
response = client.chat.completions.create(
model="qwen/qwen3.8-27b-free",
messages=[
{
"role": "system",
"content": (
"Extract the order as a JSON object with these keys: "
"order_id (string), items (array of objects with name and quantity), "
"city (string), delivery_date (YYYY-MM-DD), notes (string or null). "
"Reply with the JSON object only."
),
},
{"role": "user", "content": text},
],
response_format={"type": "json_object"},
temperature=0,
max_tokens=1024,
)
choice = response.choices[0]
if choice.finish_reason == "length":
raise RuntimeError("The JSON was cut at max_tokens; raise max_tokens or shorten the input.")
data = json.loads(choice.message.content)
missing = REQUIRED_KEYS - data.keys()
if missing:
raise ValueError(f"Missing keys: {sorted(missing)}")
print(json.dumps(data, ensure_ascii=False, indent=2))
JSON mode versus JSON Schema
OpenAI-compatible APIs have two kinds of JSON output. json_object asks for the answer to be a valid JSON object but does not enforce keys or types. json_schema sends a JSON Schema and asks for the answer to follow it; this is called structured outputs. The model card lists only JSON mode for qwen/qwen3.8-27b-free. On this row, therefore, use json_object and enforce the schema in your own code.
For work where the schema must be enforced strictly, for example flows that write the answer straight into a database, choose a model whose card lists structured outputs, or validate this row's output with a library such as pydantic or jsonschema and request a new answer when it does not match. The table shows this row's values in the catalog.
| Property | Value |
|---|---|
| Model id | qwen/qwen3.8-27b-free |
| Endpoint | /v1/chat/completions |
| Price (per 1M tokens) | $0 input / $0 output, with a daily usage quota |
| Context window | 131,042 tokens |
| Max output per response | 16,384 tokens |
| JSON mode (json_object) | listed on the model card |
| JSON Schema (json_schema) | not listed on the model card |
| Tool calling and image input | listed on the model card |
| reasoning_effort | none; returns 400 if sent |
Validating the answer: finish_reason, json.loads and missing keys
A common way for JSON output to break is truncation. If finish_reason is length, the model reached the max_tokens limit and the JSON may be cut in half; json.loads then raises an error. The example catches this before parsing. The fix is to raise max_tokens or shrink the input; on this row a value above 16,384 returns 400 invalid_request.
The second step is the key check. The example lists any of the five expected keys that are missing. Look at the types as well: is quantity inside items a number, is delivery_date in YYYY-MM-DD form? You can ask once more for an answer that does not match, with a short follow-up message that names the problem; if the second attempt does not match either, send the record to human review.
With stream: true the JSON arrives in pieces. Parse the object only when the stream has ended and you have joined all the pieces.
Where does JSON output help in a RAG flow?
In a retrieval pipeline JSON output helps in three places: generating metadata tags such as category, date and language for each chunk before indexing; turning the user's question into a search filter such as a date range or a document type; and returning the answer from the retrieved chunks along with the numbers of the chunks it relies on. For metadata tags, list the allowed values in the prompt (for example invoice, contract or correspondence for the category) and check in code that the returned value is on that list; JSON mode does not restrict values to a list.
Give the retrieved chunks numbers in the prompt and ask for the numbers the answer relies on as an array; that is how you build citations in code. The chunks, plus the prompt and the room for the answer, must fit into the 131,042-token context. The model card also lists image input for this row: if you are extracting fields from a scanned document, add the image as an image_url part and apply the same validation.
Free usage: 429, the data note and the first request
HTTP 429 means one of the free usage limits has been reached; the limit can be daily or per minute, and the response carries a Retry-After header. Wait for the time the header gives; in batch extraction jobs, queue the requests. How to manage the daily quota is covered in this row's daily quota article.
According to the data note on the model card, prompts and completions may be logged by the provider and used to improve the model. In a RAG flow, the document chunks that go into the prompt are covered by this too; do not send chunks that contain personal data or confidential documents to this row.
To get started, create an account at llmtr.com, create a key under Dashboard > API Keys, keep it in the LLMTR_API_KEY environment variable and run the example with your own text.
Get JSON output from the free Qwen3.8 27B
Ask qwen/qwen3.8-27b-free for a JSON object with response_format json_object and validate the answer in code.
- Key and client. Create a key under Dashboard > API Keys and set the OpenAI client's base_url to https://llmtr.com/v1.
- JSON request. Describe the keys and their types in the system message, and send qwen/qwen3.8-27b-free as the model with {"type": "json_object"} as response_format.
- Validation. If finish_reason is not length, parse the answer with json.loads and check that the expected keys are present.
Frequently asked questions
Can I get JSON output from a free model?
Yes. On LLMTR the model card for qwen/qwen3.8-27b-free lists JSON mode: add response_format {"type": "json_object"} to a /v1/chat/completions request, describe the keys in the prompt and validate the answer with json.loads. The row is free with a daily usage quota.
Can I use json_schema on this row?
The model card does not list JSON Schema (structured outputs) for this row; it lists only JSON mode. Use json_object and enforce the schema in your own code; if the schema must be enforced strictly, choose a model whose card lists structured outputs.
Why does the JSON answer arrive cut off?
If finish_reason is length, the answer was cut at the max_tokens limit. Raise max_tokens (up to 16,384 on this row) or shrink the input.