> ## Documentation Index
> Fetch the complete documentation index at: https://studio-docs.prem.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Structured JSON Output with Prem SDK

> This guide shows you how to prompt LLMs to return structured JSON outputs using both Prem Python and TypeScript SDKs.

## Why Use Structured Output?

Structured output lets you define the exact format you expect in the model's response, making it easier to parse, validate, and integrate downstream.

## Prerequisites

* An API key from Prem Studio
* Python ≥ 3.8 or Node.js ≥ 18
* premai or openai SDK installed

## Supported Models

The list of supported models is constantly evolving. For the most up-to-date list of models that support structured JSON output, please visit the [models list page](https://studio.premai.io/models).

Models that support JSON output are clearly marked with a <span style={{display: 'inline-block', backgroundColor: '#0ea5e9', color: 'white', padding: '2px 6px', borderRadius: '4px', fontSize: '0.75rem', fontWeight: '500'}}>json</span> tag on the models page.

## Generate Structured Output with Prem

This quick guide is gonna show you how to extract structured data from a raw CV using the Prem SDK. You'll define a clear schema (e.g. name, email, education, work experience) and let the model return a clean JSON object that matches it.

Why it's useful:
It turns messy, unstructured CV text into structured data automatically — no regex, no manual parsing.

When to use it:
Perfect for dev teams building HR tools, job platforms, or internal automation scripts that need to process and understand user-submitted resumes.

<Steps>
  <Step title="Setup Environment">
    <CodeGroup>
      ```bash javascript/typescript theme={null}
      npm install premai
      npm install --save-dev @types/node
      export PREMAI_API_KEY=your_api_key
      ```

      ```bash python theme={null}
      pip install premai pydantic json-repair
      export PREMAI_API_KEY=your_api_key
      ```
    </CodeGroup>
  </Step>

  <Step title="Define Output Structure and Example Text to Parse">
    <CodeGroup>
      ```javascript javascript/typescript theme={null}
      type PersonCV = {
          name: string;
          email?: string;
          phone?: string;
          address?: string;
          education?: string[];
          work_experience?: string[];
          skills?: string[];
          awards_and_honors?: string[];
      };

      const schema = {
          name: "PersonCV",
          schema: {
              type: "object",
              properties: {
              name: { type: "string" },
              email: { type: "string" },
              phone: { type: "string" },
              address: { type: "string" },
              education: { type: "array", items: { type: "string" } },
              work_experience: { type: "array", items: { type: "string" } },
              skills: { type: "array", items: { type: "string" } },
              awards_and_honors: { type: "array", items: { type: "string" } }
              },
              required: ["name"]
          }
      };

      const cvText = `
          John Doe
          123 Main Street, Anytown, USA | john.doe@email.com | 555-123-4567

          Education
          Bachelor of Science in Computer Science, University of Example, 2020-2024
          Relevant Coursework: Data Structures, Algorithms, Database Management

          Work Experience
          Software Engineer Intern, Example Corp, Summer 2023
          - Assisted in developing and testing software applications.
          - Wrote and maintained technical documentation.

          Skills
          Programming Languages: Python, Java, C++
          Databases: SQL, NoSQL
          Operating Systems: Windows, Linux

          Awards and Honors
          Dean's List, University of Example, 2021-2024
          `;
      ```

      ```python python theme={null}
      from pydantic import BaseModel
      import json_repair


      class PersonCV(BaseModel):
          name: str
          email: str | None = None
          phone: str | None = None
          address: str | None = None
          education: list[str] | None = None
          work_experience: list[str] | None = None
          skills: list[str] | None = None
          awards_and_honors: list[str] | None = None

      cv_text = """
          John Doe
          123 Main Street, Anytown, USA | john.doe@email.com | 555-123-4567

          Education
          Bachelor of Science in Computer Science, University of Example, 2020-2024
          Relevant Coursework: Data Structures, Algorithms, Database Management

          Work Experience
          Software Engineer Intern, Example Corp, Summer 2023
          -	Assisted in developing and testing software applications.
          -	Wrote and maintained technical documentation.

          Skills
          Programming Languages: Python, Java, C++
          Databases: SQL, NoSQL
          Operating Systems: Windows, Linux

          Awards and Honors
          Dean's List, University of Example, 2021-2024
      """
      ```
    </CodeGroup>
  </Step>

  <Step title="Initialize Client">
    <CodeGroup>
      ```javascript javascript/typescript theme={null}
      import PremAI from "premai";

      const client = new PremAI({
          apiKey: process.env.PREMAI_API_KEY || "",
      });
      ```

      ```python python theme={null}
      import os
      from premai import PremAI
      import json_repair

      client = PremAI(api_key=os.getenv("PREMAI_API_KEY"))
      ```
    </CodeGroup>
  </Step>

  <Step title="Format Messages and Send Request with Expected Output Schema">
    <CodeGroup>
      ```javascript javascript/typescript theme={null}
      const messages: ChatCompletionsParams.Message[] = [
          { role: "system", content: "You are a helpful assistant that can parse a person's info and return a structured object." },
          { role: "user", content: cvText }
      ] as any;

      const response = await client.chat.completions({
          model: "phi-4",
          messages,
          response_format: {
              type: "json_schema",
              json_schema: schema
          },
      });
      ```

      ```python python theme={null}
      messages = [
          {"role": "system", "content": "You are a helpful assistant that can parse a person's info and return a structured object."},
          {"role": "user", "content": cv_text}
      ]

      response = client.chat.completions(
          model="phi-4",
          messages=messages,
          response_format={
              "type": "json_schema",
              "json_schema": {
                  "name": PersonCV.name,
                  "schema": PersonCV.model_json_schema(),
              },
          },
      )
      ```
    </CodeGroup>
  </Step>

  <Step title="Parse the Output">
    <CodeGroup>
      ```javascript javascript/typescript theme={null}
      const raw = response.choices[0].message.content || "";

      const start = raw.indexOf("{");
      const end = raw.lastIndexOf("}") + 1;
      const content = raw.slice(start, end);

      const parsed: PersonCV = JSON.parse(content);

      console.log(JSON.stringify(parsed, null, 2));
      ```

      ```python python theme={null}
      content = response.choices[0].message.content

      output = json_repair.loads(content)
      parsed = PersonCV.model_validate(output)

      print(parsed.model_dump_json(indent=2))
      ```
    </CodeGroup>

    <Note>
      The `json_repair.loads()` function automatically handles malformed JSON and extracts valid JSON from text that may contain extra content before or after the JSON block. This is much more robust than using `json.loads()` and manual string extraction, which can fail with malformed JSON responses.
    </Note>
  </Step>
</Steps>

## Full Copy-Paste Example

<CodeGroup>
  ```javascript javascript/typescript theme={null}
  import { ChatCompletionsParams } from "premai/resources/chat";
  import PremAI from "premai";

  type PersonCV = {
      name: string;
      email?: string;
      phone?: string;
      address?: string;
      education?: string[];
      work_experience?: string[];
      skills?: string[];
      awards_and_honors?: string[];
  };

  const schema = {
      name: "PersonCV",
      schema: {
          type: "object",
          properties: {
          name: { type: "string" },
          email: { type: "string" },
          phone: { type: "string" },
          address: { type: "string" },
          education: { type: "array", items: { type: "string" } },
          work_experience: { type: "array", items: { type: "string" } },
          skills: { type: "array", items: { type: "string" } },
          awards_and_honors: { type: "array", items: { type: "string" } }
          },
          required: ["name"]
      }
  };

  const cvText = `
      John Doe
      123 Main Street, Anytown, USA | john.doe@email.com | 555-123-4567

      Education
      Bachelor of Science in Computer Science, University of Example, 2020-2024
      Relevant Coursework: Data Structures, Algorithms, Database Management

      Work Experience
      Software Engineer Intern, Example Corp, Summer 2023
      - Assisted in developing and testing software applications.
      - Wrote and maintained technical documentation.

      Skills
      Programming Languages: Python, Java, C++
      Databases: SQL, NoSQL
      Operating Systems: Windows, Linux

      Awards and Honors
      Dean's List, University of Example, 2021-2024
  `;

  const client = new PremAI({
      apiKey: process.env.PREMAI_API_KEY || "",
  });

  const messages: ChatCompletionsParams.Message[] = [
      { role: "system", content: "You are a helpful assistant that can parse a person's info and return a structured object." },
      { role: "user", content: cvText }
  ] as any;

  const response = await client.chat.completions({
      model: "phi-4",
      messages,
      response_format: {
          type: "json_schema",
          json_schema: schema
      },
  });

  const raw = response.choices[0].message.content || "";

  const start = raw.indexOf("{");
  const end = raw.lastIndexOf("}") + 1;
  const content = raw.slice(start, end);

  const parsed: PersonCV = JSON.parse(content);

  console.log(JSON.stringify(parsed, null, 2));

  ```

  ```python python theme={null}
  import os
  from pydantic import BaseModel
  from premai import PremAI
  import json_repair


  class PersonCV(BaseModel):
      name: str
      email: str | None = None
      phone: str | None = None
      address: str | None = None
      education: list[str] | None = None
      work_experience: list[str] | None = None
      skills: list[str] | None = None
      awards_and_honors: list[str] | None = None

  cv_text = """
      John Doe
      123 Main Street, Anytown, USA | john.doe@email.com | 555-123-4567

      Education
      Bachelor of Science in Computer Science, University of Example, 2020-2024
      Relevant Coursework: Data Structures, Algorithms, Database Management

      Work Experience
      Software Engineer Intern, Example Corp, Summer 2023
      -	Assisted in developing and testing software applications.
      -	Wrote and maintained technical documentation.

      Skills
      Programming Languages: Python, Java, C++
      Databases: SQL, NoSQL
      Operating Systems: Windows, Linux

      Awards and Honors
      Dean's List, University of Example, 2021-2024
  """

  client = PremAI(api_key=os.getenv("PREMAI_API_KEY"))

  messages = [
      {"role": "system", "content": "You are a helpful assistant that can parse a person's info and return a structured object."},
      {"role": "user", "content": cv_text}
  ]

  response = client.chat.completions(
      model="phi-4",
      messages=messages,
      response_format={
          "type": "json_schema",
          "json_schema": {
              "name": PersonCV.__name__,
              "schema": PersonCV.model_json_schema(),
          },
      },
  )

  content = response.choices[0].message.content

  output = json_repair.loads(content)
  parsed = PersonCV.model_validate(output)

  print(parsed.model_dump_json(indent=2))
  ```
</CodeGroup>

## Pro Tips

* We use the [json-repair](https://github.com/mangiucugna/json_repair) package to automatically handle malformed JSON and extract valid JSON from model responses, making the parsing much more robust than using `json.loads()`.
* For even more advanced structured output handling, consider using the [instructor](https://python.useinstructor.com/) package which provides additional validation and retry mechanisms.
* If the model doesn't follow your schema correctly, simplify the schema by reducing nesting or optional fields.
* Be explicit in your instructions (e.g., "Return only valid JSON without any explanation or extra text.")
* Include examples in your prompt (few-shot prompting) to help the model understand the expected format more accurately.

## Other Common Use-Cases

* Extracting metadata from documents
* Structured answers for UI rendering
* Converting text into application-specific formats
