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

> ## Agent Instructions
> Phaseo Gateway base URL: https://api.phaseo.app/v1. Send `Authorization: Bearer $PHASEO_API_KEY` with every request.
> Model IDs look like `provider/model`, for example `openai/gpt-6-astra`. Do not guess IDs: list them with `GET /v1/models` or check https://phaseo.app/models. `phaseo/free` routes to an available free model and needs no wallet balance.
> For new text integrations prefer `POST /v1/responses`. `POST /v1/chat/completions` (OpenAI format) and `POST /v1/messages` (Anthropic format) suit existing code.
> The full API contract is https://phaseo.app/docs/openapi/v1/openapi.yaml. Official SDKs: `@phaseo/sdk` (TypeScript) and `phaseo` (Python), plus Go, C#, PHP, Ruby and Rust.
> Search these docs over MCP at https://phaseo.app/docs/mcp, and install Phaseo skills with `npx skills add https://phaseo.app/docs`. If a page is wrong or out of date, report it with the MCP `submit_feedback` tool.
> Manage Phaseo accounts with the `phaseo` CLI (`npm install -g @phaseo/cli`, then `phaseo login` or `phaseo login --device-code`), the `/v1` Management API or the MCP server at `https://mcp.phaseo.app/mcp?access=manage`. Do not send users to the dashboard for account tasks. A person is still needed for sign-up, approving a sign-in, paying the first top-up on the checkout link that `phaseo credits add` returns when no card is saved, confirming each saved-card top-up from the emailed link, and account security (password, MFA, passkeys). Create API keys with `phaseo keys create --name <name> --json`; never guess one. Credit top-ups need `phaseo login --scopes billing:write` first. Task map: https://phaseo.app/docs/v1/developers/manage-from-an-agent.md.

# Structured Outputs

> Return predictable JSON with json_object or json_schema output formats.

Structured outputs let you enforce machine-readable output instead of free-form text.

## Endpoint support

Use structured outputs on:

* `/v1/chat/completions` with `response_format`
* `/v1/responses` with `text.format`
* `/v1/messages` can still return JSON text, but does not use the same `response_format` contract

## Request

```bash theme={null}
curl https://api.phaseo.app/v1/chat/completions \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-5-nano",
    "messages": [
      { "role": "user", "content": "Return a JSON object with city and weather for London." }
    ],
    "response_format": {
      "type": "json_schema",
      "json_schema": {
        "name": "weather_schema",
        "strict": true,
        "schema": {
          "type": "object",
          "properties": {
            "city": { "type": "string" },
            "weather": { "type": "string" }
          },
          "required": ["city", "weather"],
          "additionalProperties": false
        }
      }
    }
  }'
```

## Response

```json theme={null}
{
  "id": "chatcmpl_...",
  "choices": [
    {
      "index": 0,
      "finish_reason": "stop",
      "message": {
        "role": "assistant",
        "content": "{\"city\":\"London\",\"weather\":\"Cloudy\"}"
      }
    }
  ]
}
```

## Contract notes

* `response_format.type` should be `text`, `json_object`, or `json_schema`.
* For `json_schema`, include a schema object (`response_format.json_schema.schema` on chat-style payloads, or `text.format.schema` on responses-style payloads).
* Validate JSON on your server before downstream use.

## Design your schema

Start with a small object, mark required fields explicitly, and use enums for known categories. Set `additionalProperties: false` when extra keys must be rejected. Keep the requested schema and your server validator in sync; version them together.

## Validate the result

Parse and validate the complete result before using it downstream. This TypeScript example uses Zod and matches the weather schema above:

```typescript theme={null}
import { z } from "zod";

const Weather = z.object({
  city: z.string(),
  weather: z.string(),
}).strict();

function parseWeather(content: string) {
  return Weather.parse(JSON.parse(content));
}
```

Handle refusals, missing content, and truncated responses before parsing. If validation fails, allow at most a bounded corrective retry, then return a safe failure. Retried generations can incur additional charges. Valid JSON does not establish that the values are factually correct or authorise an action.

Track validation failures by model and schema version. Recheck your evaluation cases when either changes. For malformed JSON recovery, see [response healing](https://phaseo.app/docs/v1/cookbook/response-healing-for-structured-json.md).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.