---
title: "Save an agent"
method: PUT
path: "/api/workflows"
tags: ["Agents"]
---

# Save an agent

`PUT /api/workflows`

## Request

- Base URL: `https://platform.ultralytics.com`
- URL: `https://platform.ultralytics.com/api/workflows`
- Auth: HTTP bearer

Creates an agent when id is omitted, or replaces the graph of the agent at version. Returns the block errors the Agents canvas shows; the agent is saved either way. Open it at /agents?workflow=<id>, where runs start.

## Query parameters

- `owner` string

## Request body

- object
  - `id` string
  - `name` string, required
  - `graph` object, required: nodes[] are {id, type: "agent", position: {x, y}, data: {label, type, config}} with string or number config values; place each block 220 right of its input and branches 180 apart. edges[] are {id, source, target}; templateId is "". Dataset {dataset: slug or "official:coco8", split: train|val|test, maxInputs: up to 20 on free shared trials, 0 = all with a deployment} reads images; given an input, {dataset: slug} collects them. Image {dataset, image: image ID, name} is one dataset image; uploads happen on the canvas. YOLO {model: "ul://ultralytics/yolo26/yolo26n" (-seg, -pose, -obb, -cls suffixes) or ul://owner/project/model, task, conf?}; official models detect the 80 COCO classes. LLM {model: e.g. gemini-nano-banana-2.1, prompt} reads the image and upstream text. Gate {kind: "condition", path: "<YOLO or Deployment block id>.counts.<class>" or ".confidence.<class or *>", op: eq|ne|gt|gte|lt|lte|between, value, upper?} or {kind: "every", unit: frames|seconds, value}. Deployment {deployment: slug, conf?}. Export {model, format} stands alone. Output {}. Slack {message}. Webhook {url: HTTPS, body: JSON object as a string}. Messages and bodies insert the upstream result at "{output}". Each block has at most one input. Dataset and Image blocks start chains; Export, Output, Slack, and Webhook end them.
    - `nodes` object[], required
      - `id` string, required
      - `type` 'agent', required
      - `position` object, required
        - `x` number, required
        - `y` number, required
      - `data` object, required
        - `label` string, required
        - `type` 'Dataset' | 'Image' | 'YOLO' | 'LLM' | 'Gate' | 'Export' | 'Deployment' | 'Output' | 'Slack' | 'Webhook', required
        - `config` object, required
    - `edges` object[], required
      - `id` string, required
      - `source` string, required
      - `target` string, required
    - `templateId` string, required
  - `version` integer, required: Version being replaced; 0 creates the agent

## Response `200`

Agent saved

- SaveAgentResponse
  - `id` string, required
  - `version` integer, required
  - `errors` object[], required
    - `id` string, required
    - `label` string, required
    - `message` string, required

## Other responses

- `400`: Invalid graph
- `401`: Missing or invalid authentication
- `403`: Workspace editor access required
- `409`: Agent changed since it was read; retrieve it and retry
- `429`: Rate limit exceeded

## Changes

- **2026-10-01** `9da7270119bb`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/ultralytics/apis/ultralytics-platform-api/changes/api/workflows/put.md)

---

[API](https://skmtc.dev/ultralytics/apis/ultralytics-platform-api.md) - [All operations](https://skmtc.dev/ultralytics/apis/ultralytics-platform-api/llms.txt) - [OpenAPI document](https://skmtc.dev/ultralytics/apis/ultralytics-platform-api/revisions/9c562e23b0e4?raw)
