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

# Output Schema

> Define the structure of your endpoint's response

The output schema defines what your endpoint returns. While optional, defining an output schema ensures consistent responses and enables validation of LLM outputs.

## Why Define Output Schema?

<CardGroup cols={2}>
  <Card title="Consistent Responses" icon="equals">
    Ensure every response follows the same structure
  </Card>

  <Card title="Documentation" icon="book">
    OpenAPI docs show exactly what callers receive
  </Card>

  <Card title="Validation" icon="shield-check">
    Catch malformed LLM responses before they reach your app
  </Card>

  <Card title="Type Safety" icon="brackets-curly">
    Frontend/backend code can rely on specific fields
  </Card>
</CardGroup>

## Adding Output Fields

Navigate to your endpoint's **Output Schema** tab and click **Add Field**.

### Field Configuration

| Property        | Required | Description                                        |
| --------------- | -------- | -------------------------------------------------- |
| **Name**        | Yes      | Field name in the response JSON                    |
| **Type**        | Yes      | Data type (string, number, boolean, array, object) |
| **Description** | No       | What this field contains                           |

<Note>
  Output fields are never "required" in the traditional sense—they define what the LLM *should* return. If the LLM doesn't include a field, it will be omitted from the response.
</Note>

## Field Types

Output schemas support the same types as input schemas:

<Tabs>
  <Tab title="String">
    ```json theme={null}
    {
      "name": "summary",
      "type": "string",
      "description": "The summarized content"
    }
    ```
  </Tab>

  <Tab title="Number">
    ```json theme={null}
    {
      "name": "confidence",
      "type": "number",
      "description": "Confidence score between 0 and 1"
    }
    ```
  </Tab>

  <Tab title="Boolean">
    ```json theme={null}
    {
      "name": "is_spam",
      "type": "boolean",
      "description": "Whether the content is spam"
    }
    ```
  </Tab>

  <Tab title="Array">
    ```json theme={null}
    {
      "name": "keywords",
      "type": "array",
      "items": { "type": "string" },
      "description": "Extracted keywords"
    }
    ```
  </Tab>

  <Tab title="Object">
    ```json theme={null}
    {
      "name": "metadata",
      "type": "object",
      "properties": {
        "word_count": { "type": "integer" },
        "language": { "type": "string" }
      }
    }
    ```
  </Tab>

  <Tab title="Image">
    Adding an image output field signals that this endpoint **generates images**. When present, the rendered prompt is sent to the model's image generation API — no JSON output instructions are appended.

    ```json theme={null}
    {
      "name": "generated_image",
      "type": "image",
      "description": "The generated product image"
    }
    ```

    **Configuring generation defaults:**

    Use the **Example Value** field on the image output to store default generation config as JSON:

    ```json theme={null}
    {
      "size": "1024x1024",
      "quality": "high"
    }
    ```

    These defaults can be overridden per-prompt using the **Custom Parameters** panel. See [Image Generation & Vision](/guides/image-generation) for the full configuration guide.

    <Note>
      Generation parameters (size, quality, background, etc.) are **model/provider-specific**. Check your provider's API docs for supported values.
    </Note>
  </Tab>
</Tabs>

## Prompting for Structured Output

Your prompt must instruct the LLM to return JSON matching your schema. Here's the pattern:

```liquid theme={null}
Analyze the following text for sentiment:

{{ inputs.text }}

Respond with a JSON object containing:
- sentiment: "positive", "negative", or "neutral"
- confidence: a number between 0 and 1
- keywords: an array of key terms that influenced the analysis

Return only valid JSON, no additional text.
```

<Warning>
  If your prompt doesn't ask for JSON output, the LLM may return plain text that won't parse correctly.
</Warning>

## Example Schemas

### Sentiment Analysis

**Output Schema:**

```json theme={null}
{
  "type": "object",
  "properties": {
    "sentiment": {
      "type": "string",
      "description": "Overall sentiment"
    },
    "confidence": {
      "type": "number",
      "description": "Confidence score 0-1"
    },
    "aspects": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "aspect": { "type": "string" },
          "sentiment": { "type": "string" }
        }
      },
      "description": "Sentiment by aspect"
    }
  }
}
```

**Example Response:**

```json theme={null}
{
  "sentiment": "positive",
  "confidence": 0.92,
  "aspects": [
    { "aspect": "price", "sentiment": "neutral" },
    { "aspect": "quality", "sentiment": "positive" },
    { "aspect": "delivery", "sentiment": "positive" }
  ]
}
```

### Content Classification

**Output Schema:**

```json theme={null}
{
  "type": "object",
  "properties": {
    "category": {
      "type": "string",
      "description": "Primary category"
    },
    "subcategories": {
      "type": "array",
      "items": { "type": "string" },
      "description": "Secondary categories"
    },
    "confidence_scores": {
      "type": "object",
      "description": "Confidence per category"
    }
  }
}
```

### Text Extraction

**Output Schema:**

```json theme={null}
{
  "type": "object",
  "properties": {
    "entities": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "text": { "type": "string" },
          "type": { "type": "string" },
          "start": { "type": "integer" },
          "end": { "type": "integer" }
        }
      }
    },
    "summary": {
      "type": "string"
    }
  }
}
```

## Response Validation

When an output schema is defined, Endprompt:

1. Parses the LLM response as JSON
2. Validates against your schema
3. Returns the validated response

If validation fails, you'll see details in the execution logs.

<Tip>
  Start without an output schema while experimenting, then add one once you've stabilized the prompt's output format.
</Tip>

## JSON Schema Preview

The Output Schema tab shows the complete JSON Schema:

```json theme={null}
{
  "type": "object",
  "properties": {
    "summary": {
      "type": "string",
      "description": "Concise summary of the content"
    },
    "bullet_points": {
      "type": "array",
      "items": { "type": "string" },
      "description": "Key points as bullet list"
    },
    "word_count": {
      "type": "integer",
      "description": "Number of words in summary"
    }
  }
}
```

## Best Practices

<AccordionGroup>
  <Accordion title="Keep schemas simple" icon="minimize">
    Flat structures are easier for LLMs to produce consistently than deeply nested ones.
  </Accordion>

  <Accordion title="Be explicit in prompts" icon="comment">
    Tell the LLM exactly what JSON structure you expect, including field names.
  </Accordion>

  <Accordion title="Use descriptive field names" icon="tag">
    Field names like `is_spam` are clearer than `spam` or `s`.
  </Accordion>

  <Accordion title="Document everything" icon="book">
    Add descriptions to every field—they appear in your OpenAPI docs.
  </Accordion>

  <Accordion title="Test edge cases" icon="flask">
    Test with unusual inputs to see if the LLM still produces valid JSON.
  </Accordion>
</AccordionGroup>

## Without Output Schema

If you don't define an output schema:

* The raw LLM response is returned
* No JSON parsing or validation occurs
* The response may be plain text or unstructured

This is fine for simple use cases where you just need text back.

## Next Steps

<CardGroup cols={2}>
  <Card title="Create a Prompt" icon="wand-magic-sparkles" href="/prompts/create-prompt">
    Write prompts that produce structured output
  </Card>

  <Card title="Test Your Endpoint" icon="flask" href="/prompts/testing">
    Verify your schema works with real requests
  </Card>
</CardGroup>
