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

# Introduction

> One endpoint for every model call. Label the call with its task, and Protégé serves it from the cheapest model that clears that task's eval.

Protégé is one OpenAI-compatible endpoint. There is no second API to learn: every
workload goes through chat completions, and one extra field on the request body
says which workload it is. You point your SDK at it and keep your existing code.

```bash theme={null}
https://api.protege.sh/v1/chat/completions
```

That one field is `task`: a stable label for the piece of work the call belongs
to, like `invoice_extraction` or `ticket_triage`.

Protégé is a managed API. Every model runs on our capacity, so there are no
provider accounts to connect and no upstream keys to pass through: one key, one
bill.

## Why the label matters

Most inference bills are not one workload, they are dozens of them sharing an
API key. A single agent turn might classify an intent, pull three fields out of a
document, draft a reply and check it. Billed together, those look like one
expensive line item. Billed by task, most of them turn out to be small, bounded
and repetitive, and priced for reasoning they no longer need.

`task` is what separates them. Once calls arrive labelled:

<CardGroup cols={2}>
  <Card title="Routing" icon="route" href="/concepts/routing">
    Each task gets sent to the cheapest model that clears its eval, not to
    whatever model the codebase happens to name.
  </Card>

  <Card title="Measurement" icon="chart-column" href="/concepts/projects-and-workloads">
    Cost, latency and quality are reported per task, so you can see which
    workloads are worth optimizing before anyone touches a model.
  </Card>

  <Card title="Failures" icon="gavel" href="/concepts/failures">
    The calls that went wrong are tracked per task and scored by a judge, so you
    learn what to fix rather than just that the average moved.
  </Card>

  <Card title="Task-specific models" icon="graduation-cap" href="/concepts/failures">
    Traces and failures accumulate per task, so a task that stays expensive
    becomes a candidate for a specialist model trained on its own work.
  </Card>
</CardGroup>

## Drop-in by design

The request and response bodies are the OpenAI chat completions shapes. If your
code already speaks to OpenAI, Anthropic through a compatible layer, or any
gateway, the change is a base URL, a key, and `task`.

<CodeGroup>
  ```python Python theme={null}
  from openai import OpenAI

  client = OpenAI(
      base_url="https://api.protege.sh/v1",
      api_key=os.environ["PROTEGE_API_KEY"],
  )

  resp = client.chat.completions.create(
      model="deepseek-v4-flash",
      messages=[{"role": "user", "content": "Extract the invoice total."}],
      extra_body={"task": "invoice_extraction"},
  )
  ```

  ```typescript TypeScript theme={null}
  import OpenAI from "openai";

  const client = new OpenAI({
    baseURL: "https://api.protege.sh/v1",
    apiKey: process.env.PROTEGE_API_KEY,
  });

  const resp = await client.chat.completions.create({
    model: "deepseek-v4-flash",
    messages: [{ role: "user", content: "Extract the invoice total." }],
    // @ts-expect-error - `task` is a Protégé extension
    task: "invoice_extraction",
  });
  ```

  ```bash cURL theme={null}
  curl https://api.protege.sh/v1/chat/completions \
    -H "Authorization: Bearer $PROTEGE_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "task": "invoice_extraction",
      "model": "deepseek-v4-flash",
      "messages": [{"role": "user", "content": "Extract the invoice total."}]
    }'
  ```
</CodeGroup>

<Note>
  The OpenAI SDKs strip fields they do not recognise. Use `extra_body` in Python
  and cast the object in TypeScript, as shown above. See
  [Migrating](/migrate) for the details per SDK.
</Note>

## Next

<CardGroup cols={2}>
  <Card title="Quickstart" icon="play" href="/quickstart">
    First labelled call in about five minutes.
  </Card>

  <Card title="Chat completions" icon="code" href="/api-reference/chat-completions">
    Full parameter reference, including `task`.
  </Card>
</CardGroup>
