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

# Key Orchestrator Graph

> Read or replace a key's executable orchestrator graph — Entry → Classifier/Router → Model → Guardrail.

The orchestrator graph is a runnable per-key flow: `Entry → Classifier / Router → Model → Guardrail`. When `enabled`, every request to the key runs the path you drew — routing, model selection, per-node skills, and guardrails all applied. It takes precedence over the [model plan](/api-reference/keys/model-plan) and applies on **both** the native and OpenAI-compatible endpoints.

This is the REST surface behind the dashboard's Orchestrator canvas and the [MCP configuration tools](/mcp/tools).

## Authentication

Requires an API key with `billing` scope; the caller must own the key.

## Path Parameters

<ParamField path="id" type="string" required>The API key UUID.</ParamField>

## Get the graph

`GET /api/v1/keys/{id}/orchestrator-graph`

<ResponseField name="key_id" type="string">The API key UUID.</ResponseField>
<ResponseField name="graph" type="object | null">The saved graph (`{ version, enabled, nodes, edges }`) or `null` when none is set.</ResponseField>

## Replace the graph

`PUT /api/v1/keys/{id}/orchestrator-graph`

<ParamField body="enabled" type="boolean" required>
  When `true`, the orchestrator runs this graph. An enabled graph **must** have an `entry` node and at least one `model` node with an engine, or the request is rejected.
</ParamField>

<ParamField body="nodes" type="object[]" required>
  Up to 100 nodes. Each: `{ id, type, position?, config? }`. `type` is one of `entry`, `classifier`, `router`, `model`, `guardrail`, `description`, `output`. A model node's `config.upstreamId` is its engine; a guardrail node's `config.guardrailPolicyId` is its policy (before the model = screens input, after = screens output).
</ParamField>

<ParamField body="edges" type="object[]" required>
  Each: `{ id, source, target, modes?, when?, default? }`. Classifier branches use `modes` (the mode that takes the edge); Router branches use `when` (keywords); `default` is the fallback edge.
</ParamField>

## Example

<CodeGroup>
  ```bash curl theme={null}
  curl -X PUT https://www.hitheo.ai/api/v1/keys/KEY_ID/orchestrator-graph \
    -H "Authorization: Bearer $THEO_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "enabled": true,
      "nodes": [
        { "id": "entry", "type": "entry", "config": { "label": "User Prompt" } },
        { "id": "classifier", "type": "classifier", "config": { "label": "Classifier" } },
        { "id": "m_fast", "type": "model", "config": { "upstreamId": "arca-velox-5.1", "label": "fast" } },
        { "id": "m_think", "type": "model", "config": { "upstreamId": "arca-magnus-5.1", "label": "think" } }
      ],
      "edges": [
        { "id": "e_in", "source": "entry", "target": "classifier" },
        { "id": "e_fast", "source": "classifier", "target": "m_fast", "modes": ["fast"] },
        { "id": "e_think", "source": "classifier", "target": "m_think", "modes": ["think"] }
      ]
    }'
  ```

  ```ts SDK theme={null}
  await theo.keys.setOrchestratorGraph("KEY_ID", { enabled: true, nodes, edges });
  ```
</CodeGroup>
