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

> ## Agent Instructions
> Agents: start with https://docs.pre.dev/agents.md, which has complete recipes, plan access, polling rules, errors and limits.
> Authenticate with the workspace API key (pdk_…) from Integrations → Built-in, sent as Authorization: Bearer <key>.
> REST API: https://api.pre.dev (OpenAPI: https://docs.pre.dev/api-reference/openapi.json). AI Gateway: https://api.pre.dev/v1, OpenAI-compatible (OpenAPI: https://docs.pre.dev/api-reference/ai-gateway.openapi.json).
> pre.dev MCP server: npx -y @predotdev/mcp setup adds it to every local coding agent with every pre.dev tool plus the user's own Chrome; the hosted server is https://api.pre.dev/mcp. Search these docs over MCP at https://docs.pre.dev/mcp.

# Tools and structured output

> Tool calling and JSON-schema output with the standard OpenAI-compatible fields.

`tools`, `tool_choice`, `parallel_tool_calls`, `response_format`, and `structured_outputs` use the standard OpenAI-compatible fields. Support for each varies by model; check `supported_parameters` in the model's row from [`GET /v1/models`](https://predev.mintlify.site/ai-gateway/api/models) before relying on it.

## Tool calling

```typescript Node.js theme={null}
import OpenAI from 'openai';

const client = new OpenAI({ baseURL: 'https://api.pre.dev/v1', apiKey: process.env.PREDEV_API_KEY! });

const tools: OpenAI.Chat.Completions.ChatCompletionTool[] = [{
  type: 'function',
  function: {
    name: 'get_weather',
    description: 'Current weather for a city',
    parameters: {
      type: 'object',
      properties: { city: { type: 'string' } },
      required: ['city'],
    },
  },
}];

const first = await client.chat.completions.create({
  model: 'anthropic/claude-sonnet-5',
  messages: [{ role: 'user', content: 'What is the weather in Lisbon?' }],
  tools,
  tool_choice: 'auto',
});
const call = first.choices[0].message.tool_calls?.[0];
if (call?.type === 'function') {
  const args = JSON.parse(call.function.arguments);
  const weather = { city: args.city, tempC: 24 }; // your implementation
  const second = await client.chat.completions.create({
    model: 'anthropic/claude-sonnet-5',
    messages: [
      { role: 'user', content: 'What is the weather in Lisbon?' },
      first.choices[0].message,
      { role: 'tool', tool_call_id: call.id, content: JSON.stringify(weather) },
    ],
    tools,
  });
  console.log(second.choices[0].message.content);
}
```

```python Python theme={null}
import json
import os
from openai import OpenAI

client = OpenAI(base_url="https://api.pre.dev/v1", api_key=os.environ["PREDEV_API_KEY"])

tools = [{
    "type": "function",
    "function": {
        "name": "get_weather",
        "description": "Current weather for a city",
        "parameters": {
            "type": "object",
            "properties": {"city": {"type": "string"}},
            "required": ["city"],
        },
    },
}]

messages = [{"role": "user", "content": "What is the weather in Lisbon?"}]
first = client.chat.completions.create(
    model="anthropic/claude-sonnet-5", messages=messages, tools=tools, tool_choice="auto"
)
call = (first.choices[0].message.tool_calls or [None])[0]
if call:
    args = json.loads(call.function.arguments)
    weather = {"city": args["city"], "tempC": 24}  # your implementation
    messages.append(first.choices[0].message)
    messages.append({"role": "tool", "tool_call_id": call.id, "content": json.dumps(weather)})
    second = client.chat.completions.create(
        model="anthropic/claude-sonnet-5", messages=messages, tools=tools
    )
    print(second.choices[0].message.content)
```

Set `parallel_tool_calls: false` to force one call per turn on models that would otherwise emit several.

## Structured output

Use `response_format` with a JSON schema. The schema is enforced on models that support structured outputs.

```bash curl theme={null}
curl --fail-with-body https://api.pre.dev/v1/chat/completions \
  -H "Authorization: Bearer $PREDEV_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-6-luna",
    "messages": [{ "role": "user", "content": "Extract: Ada Lovelace, born 1815, London." }],
    "response_format": {
      "type": "json_schema",
      "json_schema": {
        "name": "person",
        "strict": true,
        "schema": {
          "type": "object",
          "properties": {
            "name": { "type": "string" },
            "born": { "type": "integer" },
            "city": { "type": "string" }
          },
          "required": ["name", "born", "city"],
          "additionalProperties": false
        }
      }
    }
  }'
```

```typescript Node.js theme={null}
const completion = await client.chat.completions.create({
  model: 'openai/gpt-6-luna',
  messages: [{ role: 'user', content: 'Extract: Ada Lovelace, born 1815, London.' }],
  response_format: {
    type: 'json_schema',
    json_schema: {
      name: 'person',
      strict: true,
      schema: {
        type: 'object',
        properties: { name: { type: 'string' }, born: { type: 'integer' }, city: { type: 'string' } },
        required: ['name', 'born', 'city'],
        additionalProperties: false,
      },
    },
  },
});
const person = JSON.parse(completion.choices[0].message.content!);
```

```python Python theme={null}
completion = client.chat.completions.create(
    model="openai/gpt-6-luna",
    messages=[{"role": "user", "content": "Extract: Ada Lovelace, born 1815, London."}],
    response_format={
        "type": "json_schema",
        "json_schema": {
            "name": "person",
            "strict": True,
            "schema": {
                "type": "object",
                "properties": {"name": {"type": "string"}, "born": {"type": "integer"}, "city": {"type": "string"}},
                "required": ["name", "born", "city"],
                "additionalProperties": False,
            },
        },
    },
)
person = json.loads(completion.choices[0].message.content)
```

Add the `response-healing` plugin to repair near-valid JSON from models without native schema support:

```json theme={null}
{
  "model": "deepseek/deepseek-v4.1-flash",
  "plugins": [{ "id": "response-healing" }],
  "response_format": { "type": "json_object" },
  "messages": [{ "role": "user", "content": "Return {\"ok\": true} as JSON." }]
}
```

Any plugin cost is part of the call's charge.


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