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

# API Calls

> Generate execution-ready API call plans from natural language requests.

Turning natural language into API calls is one of the most direct applications of structured output. The user says "refund \$25 for order ORD-9842," and the model produces a valid `POST /refunds` request with the right body fields. The schema defines every endpoint as a `oneOf` branch with `const` values for method and path, so the model can't invent endpoints that don't exist or mix parameters from different calls.

This pattern is especially valuable for internal tools where users interact with backend APIs through a natural language interface. The schema acts as a whitelist of allowed operations.

## Goal

Map natural language intent into exactly one valid API call definition, with validated parameters, ready for your backend to execute.

## Schema contract

<CodeGroup>
  ```json JSON Schema theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
  {
    "oneOf": [
      {
        "type": "object",
        "properties": {
          "endpoint": { "const": "get_order" },
          "method": { "const": "GET" },
          "path": { "const": "/orders/{order_id}" },
          "path_params": {
            "type": "object",
            "properties": {
              "order_id": { "type": "string", "pattern": "^ORD-[0-9]{4,10}$" }
            },
            "required": ["order_id"],
            "additionalProperties": false
          }
        },
        "required": ["endpoint", "method", "path", "path_params"],
        "additionalProperties": false
      },
      {
        "type": "object",
        "properties": {
          "endpoint": { "const": "create_refund" },
          "method": { "const": "POST" },
          "path": { "const": "/refunds" },
          "body": {
            "type": "object",
            "properties": {
              "order_id": { "type": "string", "pattern": "^ORD-[0-9]{4,10}$" },
              "amount": { "type": "number", "minimum": 0.01 },
              "reason": {
                "type": "string",
                "enum": ["duplicate", "fraud", "requested_by_customer", "other"]
              }
            },
            "required": ["order_id", "amount", "reason"],
            "additionalProperties": false
          }
        },
        "required": ["endpoint", "method", "path", "body"],
        "additionalProperties": false
      }
    ]
  }
  ```

  ```python Pydantic theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
  from typing import Annotated, Literal
  from pydantic import BaseModel, ConfigDict, Field

  class GetOrderPathParams(BaseModel):
      model_config = ConfigDict(extra="forbid")
      order_id: str = Field(..., pattern=r"^ORD-[0-9]{4,10}$")

  class GetOrderCall(BaseModel):
      model_config = ConfigDict(extra="forbid")
      endpoint: Literal["get_order"]
      method: Literal["GET"]
      path: Literal["/orders/{order_id}"]
      path_params: GetOrderPathParams

  class RefundBody(BaseModel):
      model_config = ConfigDict(extra="forbid")
      order_id: str = Field(..., pattern=r"^ORD-[0-9]{4,10}$")
      amount: float = Field(..., ge=0.01)
      reason: Literal["duplicate", "fraud", "requested_by_customer", "other"]

  class CreateRefundCall(BaseModel):
      model_config = ConfigDict(extra="forbid")
      endpoint: Literal["create_refund"]
      method: Literal["POST"]
      path: Literal["/refunds"]
      body: RefundBody

  ApiCall = Annotated[GetOrderCall | CreateRefundCall, Field(discriminator="endpoint")]
  ```

  ```typescript Zod theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
  import { z } from "zod";

  const apiCallSchema = z.discriminatedUnion("endpoint", [
    z.object({
      endpoint: z.literal("get_order"),
      method: z.literal("GET"),
      path: z.literal("/orders/{order_id}"),
      path_params: z.object({
        order_id: z.string().regex(/^ORD-[0-9]{4,10}$/),
      }).strict(),
    }).strict(),
    z.object({
      endpoint: z.literal("create_refund"),
      method: z.literal("POST"),
      path: z.literal("/refunds"),
      body: z.object({
        order_id: z.string().regex(/^ORD-[0-9]{4,10}$/),
        amount: z.number().min(0.01),
        reason: z.enum(["duplicate", "fraud", "requested_by_customer", "other"]),
      }).strict(),
    }).strict(),
  ]);
  ```

  ```bash curl theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
  curl https://api.dottxt.ai/v1/chat/completions \
    -H "Authorization: Bearer $DOTTXT_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "openai/gpt-oss-20b",
      "messages": [{ "role": "user", "content": "Issue a $25 refund for order ORD-9842 because the customer was charged twice." }],
      "response_format": {
        "type": "json_schema",
        "json_schema": {
          "name": "api_call",
          "schema": {
            "oneOf": [
              {
                "type": "object",
                "properties": {
                  "endpoint": { "const": "get_order" },
                  "method": { "const": "GET" },
                  "path": { "const": "/orders/{order_id}" },
                  "path_params": {
                    "type": "object",
                    "properties": {
                      "order_id": { "type": "string", "pattern": "^ORD-[0-9]{4,10}$" }
                    },
                    "required": ["order_id"],
                    "additionalProperties": false
                  }
                },
                "required": ["endpoint", "method", "path", "path_params"],
                "additionalProperties": false
              },
              {
                "type": "object",
                "properties": {
                  "endpoint": { "const": "create_refund" },
                  "method": { "const": "POST" },
                  "path": { "const": "/refunds" },
                  "body": {
                    "type": "object",
                    "properties": {
                      "order_id": { "type": "string", "pattern": "^ORD-[0-9]{4,10}$" },
                      "amount": { "type": "number", "minimum": 0.01 },
                      "reason": { "type": "string", "enum": ["duplicate", "fraud", "requested_by_customer", "other"] }
                    },
                    "required": ["order_id", "amount", "reason"],
                    "additionalProperties": false
                  }
                },
                "required": ["endpoint", "method", "path", "body"],
                "additionalProperties": false
              }
            ]
          }
        }
      }
    }'
  ```
</CodeGroup>

## Example input

```text theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
Issue a $25 refund for order ORD-9842 because the customer was charged twice.
```

## Example output

```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
{
  "endpoint": "create_refund",
  "method": "POST",
  "path": "/refunds",
  "body": {
    "order_id": "ORD-9842",
    "amount": 25,
    "reason": "duplicate"
  }
}
```

## Implementation tips

* **`const` on method and path locks each branch.** The model can't produce `"method": "DELETE"` for the refund endpoint or change the path. This makes the schema a whitelist of allowed operations.
* **`oneOf` ensures a single action.** The model commits to one endpoint per request. If you need multi-step operations, run the model in a loop; don't try to batch multiple API calls into one schema.
* **Parameter-level constraints catch bad input early.** The `order_id` pattern (`^ORD-[0-9]{4,10}$`) and `amount` minimum (`0.01`) reject invalid values at generation time, before your API sees them.
* **Validate before executing.** Even with a strict schema, run the output through your API's own validation layer. The schema catches structural issues; your API validates business rules (e.g., "this order is not eligible for refund").

## Related docs

* [Unions of objects](/json-schema/union-of-objects): discriminated unions for routing to different endpoint shapes
* [Agent output](/json-schema/agent-output): structure agent responses with tool calls and final answers
* [Conditional Requirements](/json-schema/conditional-requirements): require different parameters depending on the endpoint
* [Composition reference](/json-schema/reference/composition) | [Object reference](/json-schema/reference/object)
