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

# Replace the draft

> Saves draft changes without deploying. Omitted description, graph and layout are preserved; an empty description clears it. Supply the complete graph to replace it. Structural errors reject the save; inspect meta.issues and data.draft.validation for remaining issues before deployment. Use simulate_dynamic_route without version_number to test the saved draft; deploy_dynamic_route performs full deployment validation. Requires the `dynamic_routes:write` scope.

Graph format: an object with an `elements` array. Each element has a unique `id`, a `type`, optional `properties`, and `outputs`, an object mapping output names to `{"elementId":"target-node-id"}`. Include `id: START, type: start` and `id: END, type: end`; `input` and `output` are not node types. A minimal deployable graph (replace the model with an available catalog ID permitted by your policy):
```json
{"elements":[{"id":"START","type":"start","outputs":{"next":{"elementId":"primary"}}},{"id":"primary","type":"model","properties":{"model":"cerebras/gpt-oss-120b"},"outputs":{"success":{"elementId":"END"},"fallback":{"elementId":"END"}}},{"id":"END","type":"end","outputs":{}}]}
```

Supported node types and properties:
- `start`: the START node; `outputs.next` selects the first node.
- `end`: the END node; `outputs` is `{}`.
- `model`: `properties.model` is a catalog model ID. `outputs.success` targets END or an observe node; `outputs.fallback` targets another model, pool, or END.
- `pool`: `properties.models` contains 2-10 `{model,metrics}` candidates; `properties.expression` is a numeric CEL expression such as `model.cost`, sorted ascending. Uses the same success/fallback outputs as model.
- `conditional`: `properties.cases` contains `{id,expression}` entries; each expression is a CEL predicate over `metadata`, `auth`, and `input`. Connect an output for each case ID and a `default` output. The first true case wins.
- `percentage`: `properties.buckets` contains at least two `{id,weight}` entries with positive integer weights totaling 100. Connect an output for each bucket ID.
- `classifier`: `properties.cases` contains 2-10 `{id,label,instructions}` entries with unique labels, plus optional `context` and `model` properties. Connect an output per case ID; no default output. Classification failures fail the route.
- `observe`: `properties.criteria` defines an asynchronous evaluation, with optional `score_type` (`score` or `binary`), `model`, `threshold`, and `sample_rate` (both greater than 0 and at most 1). Place after model/pool success or another observe node; `outputs.next` leads to another observe node or END.

Graphs must be acyclic. Every node except END accepts at most one incoming edge; use separate model nodes on separate branches. Deployment requires each path from START to reach a model or pool before END.



## OpenAPI

````yaml put /management/v1/dynamic-routes/{name}/draft
openapi: 3.1.0
info:
  description: Schema-driven generative API that orchestrates LLM-powered workflows.
  title: Task API
  version: 3.0.0
servers:
  - description: Production
    url: https://api.opper.ai
  - description: Local development
    url: http://localhost:8080
security:
  - BearerAuth: []
tags:
  - description: Schema-driven function management and execution
    name: Functions
  - description: OpenAI-compatible chat completions
    name: Chat
  - description: OpenAI Responses API compatible endpoint
    name: Responses
  - description: Google-compatible interactions endpoint
    name: Interactions
  - description: Model registry and capabilities
    name: Models
  - description: Synchronous image generation
    name: Images
  - description: Text-to-speech and speech-to-text
    name: Audio
  - description: Asynchronous video generation
    name: Videos
  - description: Reusable file storage for media inputs and generated outputs
    name: Files
  - description: Async generation status and downloads
    name: Artifacts
  - description: OpenAI-compatible embeddings
    name: Embeddings
  - description: Recorded HTTP request/response generations
    name: Generations
  - description: System health and status
    name: System
  - description: Roundtable endpoint — fan out a query to multiple LLMs and combine results
    name: Roundtable
  - description: Web search, fetch, and other utility tools
    name: Tools
  - description: Caller identity, credits, and usage
    name: Account
  - description: >-
      Programmatic project and API-key management. Authenticates with an
      `op-mak-…` management token; available on the control_plane and enterprise
      plans.
    name: Management
paths:
  /management/v1/dynamic-routes/{name}/draft:
    put:
      tags:
        - Management
      summary: Replace the draft
      description: >-
        Saves draft changes without deploying. Omitted description, graph and
        layout are preserved; an empty description clears it. Supply the
        complete graph to replace it. Structural errors reject the save; inspect
        meta.issues and data.draft.validation for remaining issues before
        deployment. Use simulate_dynamic_route without version_number to test
        the saved draft; deploy_dynamic_route performs full deployment
        validation. Requires the `dynamic_routes:write` scope.


        Graph format: an object with an `elements` array. Each element has a
        unique `id`, a `type`, optional `properties`, and `outputs`, an object
        mapping output names to `{"elementId":"target-node-id"}`. Include `id:
        START, type: start` and `id: END, type: end`; `input` and `output` are
        not node types. A minimal deployable graph (replace the model with an
        available catalog ID permitted by your policy):

        ```json

        {"elements":[{"id":"START","type":"start","outputs":{"next":{"elementId":"primary"}}},{"id":"primary","type":"model","properties":{"model":"cerebras/gpt-oss-120b"},"outputs":{"success":{"elementId":"END"},"fallback":{"elementId":"END"}}},{"id":"END","type":"end","outputs":{}}]}

        ```


        Supported node types and properties:

        - `start`: the START node; `outputs.next` selects the first node.

        - `end`: the END node; `outputs` is `{}`.

        - `model`: `properties.model` is a catalog model ID. `outputs.success`
        targets END or an observe node; `outputs.fallback` targets another
        model, pool, or END.

        - `pool`: `properties.models` contains 2-10 `{model,metrics}`
        candidates; `properties.expression` is a numeric CEL expression such as
        `model.cost`, sorted ascending. Uses the same success/fallback outputs
        as model.

        - `conditional`: `properties.cases` contains `{id,expression}` entries;
        each expression is a CEL predicate over `metadata`, `auth`, and `input`.
        Connect an output for each case ID and a `default` output. The first
        true case wins.

        - `percentage`: `properties.buckets` contains at least two `{id,weight}`
        entries with positive integer weights totaling 100. Connect an output
        for each bucket ID.

        - `classifier`: `properties.cases` contains 2-10
        `{id,label,instructions}` entries with unique labels, plus optional
        `context` and `model` properties. Connect an output per case ID; no
        default output. Classification failures fail the route.

        - `observe`: `properties.criteria` defines an asynchronous evaluation,
        with optional `score_type` (`score` or `binary`), `model`, `threshold`,
        and `sample_rate` (both greater than 0 and at most 1). Place after
        model/pool success or another observe node; `outputs.next` leads to
        another observe node or END.


        Graphs must be acyclic. Every node except END accepts at most one
        incoming edge; use separate model nodes on separate branches. Deployment
        requires each path from START to reach a model or pool before END.
      operationId: updateManagementDynamicRouteDraft
      parameters:
        - description: Route name
          in: path
          name: name
          required: true
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DynamicRouteDraftRequest'
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/DynamicRouteDetail'
                  meta:
                    properties:
                      issues:
                        items:
                          $ref: '#/components/schemas/DynamicRouteValidationIssue'
                        type: array
                    type: object
                type: object
          description: Successful response
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Bad request
        '401':
          description: Unauthorized - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                properties:
                  error:
                    type: string
                  required_scope:
                    description: Present on the scope refusal.
                    type: string
                type: object
          description: >-
            The token lacks the scope this endpoint requires (`required_scope`
            is returned). Presenting a runtime `op-…` key instead of a
            management `op-mak-…` token also lands here.
        '404':
          content:
            application/json:
              schema:
                properties:
                  error:
                    type: string
                type: object
          description: >-
            No such resource in the calling organization. A resource belonging
            to another organization is indistinguishable from one that does not
            exist.
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      security:
        - ManagementBearer: []
components:
  schemas:
    DynamicRouteDraftRequest:
      properties:
        description:
          description: New description. Omit to leave it unchanged.
          type: string
        graph:
          description: >-
            Routing graph object with elements. Each node has id, type, outputs
            mapping output names to {elementId: targetID}, and optional
            properties. Include START/start and END/end. Supported types: start,
            end, model, pool, conditional, percentage, classifier, observe. Omit
            graph on create to seed a default; copy its returned draft.graph to
            customize. See tool description for node properties and topology.
          examples:
            - elements:
                - id: START
                  outputs:
                    next:
                      elementId: model_default
                  type: start
                - id: model_default
                  outputs:
                    fallback:
                      elementId: END
                    success:
                      elementId: END
                  properties:
                    label: Default model
                    model: cerebras/gpt-oss-120b
                  type: model
                - id: END
                  outputs: {}
                  type: end
          properties:
            elements:
              items:
                properties:
                  id:
                    type: string
                  outputs:
                    additionalProperties:
                      properties:
                        elementId:
                          type: string
                      required:
                        - elementId
                      type: object
                    type: object
                  properties:
                    type: object
                  type:
                    type: string
                required:
                  - id
                  - type
                  - outputs
                type: object
              type: array
          required:
            - elements
          type: object
        layout:
          description: Editor canvas positions keyed by element id. Opaque to the gateway.
          type: object
      type: object
    DynamicRouteDetail:
      properties:
        active_version:
          properties:
            created_at:
              format: date-time
              type: string
            note:
              type: string
            uuid:
              format: uuid
              type: string
            version_number:
              type: integer
          required:
            - uuid
            - version_number
            - note
            - created_at
          type: object
        draft:
          properties:
            graph:
              description: The draft graph (DynamicRouteGraph).
              type: object
            layout:
              description: Editor canvas positions keyed by element id.
              type: object
            revision:
              type: integer
            validation:
              description: >-
                Validation issues on the draft (DynamicRouteValidationIssue);
                empty when it is deployable.
              type: array
          required:
            - graph
            - layout
            - validation
            - revision
          type: object
        latest_version_number:
          type: integer
        route:
          properties:
            created_at:
              format: date-time
              type: string
            deleted_at:
              format: date-time
              type: string
            description:
              type: string
            draft_graph:
              description: The draft graph (DynamicRouteGraph).
              type: object
            draft_layout:
              description: Editor canvas positions keyed by element id.
              type: object
            draft_revision:
              type: integer
            draft_validation:
              description: >-
                Validation issues on the draft (DynamicRouteValidationIssue);
                empty when it is deployable.
              type: array
            invocation_model:
              type: string
            name:
              type: string
            updated_at:
              format: date-time
              type: string
            uuid:
              format: uuid
              type: string
          required:
            - uuid
            - name
            - invocation_model
            - description
            - draft_revision
            - created_at
            - updated_at
          type: object
        version_count:
          type: integer
      required:
        - route
        - draft
        - version_count
      type: object
    DynamicRouteValidationIssue:
      properties:
        code:
          type: string
        field:
          type: string
        message:
          type: string
        node_id:
          type: string
        severity:
          type: string
      required:
        - code
        - message
        - severity
      type: object
    ErrorResponse:
      properties:
        error:
          properties:
            code:
              type: string
            details:
              description: Any value
            message:
              type: string
          required:
            - code
            - message
          type: object
        meta:
          type: object
      required:
        - error
      type: object
  securitySchemes:
    BearerAuth:
      bearerFormat: API Key
      description: API key authentication. Pass your API key as a Bearer token.
      scheme: bearer
      type: http
    ManagementBearer:
      bearerFormat: Management API Key
      description: >-
        Management API authentication. Pass an `op-mak-…` management token as a
        Bearer token. Runtime `op-…` API keys are rejected with 403 — they
        belong on the data-plane endpoints. Mint a management key from the
        platform UI under Settings → API keys.
      scheme: bearer
      type: http

````

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