curl --request PATCH \
--url https://odyssey.asteroid.ai/agents/v2/workflows/{workflowId}/head/files \
--header 'Content-Type: application/json' \
--header 'X-Api-Key: <api-key>' \
--data '
{
"baseRev": 123,
"deletes": [
"<string>"
],
"writes": [
{
"contentBase64": "<string>",
"path": "<string>"
}
]
}
'import requests
url = "https://odyssey.asteroid.ai/agents/v2/workflows/{workflowId}/head/files"
payload = {
"baseRev": 123,
"deletes": ["<string>"],
"writes": [
{
"contentBase64": "<string>",
"path": "<string>"
}
]
}
headers = {
"X-Api-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {'X-Api-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
baseRev: 123,
deletes: ['<string>'],
writes: [{contentBase64: '<string>', path: '<string>'}]
})
};
fetch('https://odyssey.asteroid.ai/agents/v2/workflows/{workflowId}/head/files', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://odyssey.asteroid.ai/agents/v2/workflows/{workflowId}/head/files",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'baseRev' => 123,
'deletes' => [
'<string>'
],
'writes' => [
[
'contentBase64' => '<string>',
'path' => '<string>'
]
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-Api-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://odyssey.asteroid.ai/agents/v2/workflows/{workflowId}/head/files"
payload := strings.NewReader("{\n \"baseRev\": 123,\n \"deletes\": [\n \"<string>\"\n ],\n \"writes\": [\n {\n \"contentBase64\": \"<string>\",\n \"path\": \"<string>\"\n }\n ]\n}")
req, _ := http.NewRequest("PATCH", url, payload)
req.Header.Add("X-Api-Key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.patch("https://odyssey.asteroid.ai/agents/v2/workflows/{workflowId}/head/files")
.header("X-Api-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"baseRev\": 123,\n \"deletes\": [\n \"<string>\"\n ],\n \"writes\": [\n {\n \"contentBase64\": \"<string>\",\n \"path\": \"<string>\"\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://odyssey.asteroid.ai/agents/v2/workflows/{workflowId}/head/files")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["X-Api-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"baseRev\": 123,\n \"deletes\": [\n \"<string>\"\n ],\n \"writes\": [\n {\n \"contentBase64\": \"<string>\",\n \"path\": \"<string>\"\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"createdAt": "2023-11-07T05:31:56Z",
"files": [
{
"createdAt": "2023-11-07T05:31:56Z",
"fileName": "<string>",
"filePath": "<string>",
"fileSize": 123,
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"updatedAt": "2023-11-07T05:31:56Z",
"checksum": "<string>",
"mimeType": "<string>"
}
],
"graph": {
"nodes": [
{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"properties": {
"type": "start"
},
"type": "start",
"description": "<string>",
"position": {
"x": 123,
"y": 123
}
}
],
"sticky_notes": [
{
"content": "<string>",
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"color": "<string>",
"position": {
"x": 123,
"y": 123
},
"size": {
"height": 123,
"width": 123
}
}
],
"transitions": [
{
"from": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"properties": {
"type": "iris"
},
"require_confirmation": true,
"to": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"type": "iris",
"description": "<string>",
"schema": {}
}
]
},
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"inputs": [
{
"name": "<string>",
"required": true,
"schema": {},
"defaultValue": "<unknown>",
"description": "<string>"
}
],
"isPublished": true,
"rev": 123,
"rules": "<string>",
"settings": {
"max_timeout_mins": 123,
"viewport_height": 123,
"viewport_width": 123,
"custom_environment_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a"
},
"version": 123,
"workflowId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"author": "<string>",
"environmentTemplate": {
"config": {
"provider": "anchor"
},
"type": "browser"
},
"parentId": "3c90c3cc-0d44-4b50-8888-8dd25736052a"
}{
"code": 400,
"message": "<string>",
"detail": "<string>",
"errors": [
{
"detail": "<string>",
"parameter": "<string>"
}
],
"instance": "<string>",
"status": 123,
"title": "<string>",
"type": "<string>"
}{
"code": 401,
"message": "<string>",
"detail": "<string>",
"instance": "<string>",
"status": 123,
"title": "<string>",
"type": "<string>"
}{
"code": 403,
"message": "<string>",
"detail": "<string>",
"instance": "<string>",
"status": 123,
"title": "<string>",
"type": "<string>"
}{
"code": 404,
"message": "<string>",
"detail": "<string>",
"instance": "<string>",
"status": 123,
"title": "<string>",
"type": "<string>"
}{
"code": 409,
"message": "<string>",
"detail": "<string>",
"instance": "<string>",
"status": 123,
"title": "<string>",
"type": "<string>"
}{
"code": 500,
"message": "<string>",
"detail": "<string>",
"instance": "<string>",
"status": 123,
"title": "<string>",
"type": "<string>"
}Patch workflow head files
Patch the editable head’s file representation in place: apply file writes and deletes, re-derive the structured workflow, and persist it. Structural-file writes require a matching baseRev. When the head is frozen (published or executed) the edit forks a fresh version behind the scenes.
curl --request PATCH \
--url https://odyssey.asteroid.ai/agents/v2/workflows/{workflowId}/head/files \
--header 'Content-Type: application/json' \
--header 'X-Api-Key: <api-key>' \
--data '
{
"baseRev": 123,
"deletes": [
"<string>"
],
"writes": [
{
"contentBase64": "<string>",
"path": "<string>"
}
]
}
'import requests
url = "https://odyssey.asteroid.ai/agents/v2/workflows/{workflowId}/head/files"
payload = {
"baseRev": 123,
"deletes": ["<string>"],
"writes": [
{
"contentBase64": "<string>",
"path": "<string>"
}
]
}
headers = {
"X-Api-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {'X-Api-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
baseRev: 123,
deletes: ['<string>'],
writes: [{contentBase64: '<string>', path: '<string>'}]
})
};
fetch('https://odyssey.asteroid.ai/agents/v2/workflows/{workflowId}/head/files', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://odyssey.asteroid.ai/agents/v2/workflows/{workflowId}/head/files",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'baseRev' => 123,
'deletes' => [
'<string>'
],
'writes' => [
[
'contentBase64' => '<string>',
'path' => '<string>'
]
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-Api-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://odyssey.asteroid.ai/agents/v2/workflows/{workflowId}/head/files"
payload := strings.NewReader("{\n \"baseRev\": 123,\n \"deletes\": [\n \"<string>\"\n ],\n \"writes\": [\n {\n \"contentBase64\": \"<string>\",\n \"path\": \"<string>\"\n }\n ]\n}")
req, _ := http.NewRequest("PATCH", url, payload)
req.Header.Add("X-Api-Key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.patch("https://odyssey.asteroid.ai/agents/v2/workflows/{workflowId}/head/files")
.header("X-Api-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"baseRev\": 123,\n \"deletes\": [\n \"<string>\"\n ],\n \"writes\": [\n {\n \"contentBase64\": \"<string>\",\n \"path\": \"<string>\"\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://odyssey.asteroid.ai/agents/v2/workflows/{workflowId}/head/files")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["X-Api-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"baseRev\": 123,\n \"deletes\": [\n \"<string>\"\n ],\n \"writes\": [\n {\n \"contentBase64\": \"<string>\",\n \"path\": \"<string>\"\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"createdAt": "2023-11-07T05:31:56Z",
"files": [
{
"createdAt": "2023-11-07T05:31:56Z",
"fileName": "<string>",
"filePath": "<string>",
"fileSize": 123,
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"updatedAt": "2023-11-07T05:31:56Z",
"checksum": "<string>",
"mimeType": "<string>"
}
],
"graph": {
"nodes": [
{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"properties": {
"type": "start"
},
"type": "start",
"description": "<string>",
"position": {
"x": 123,
"y": 123
}
}
],
"sticky_notes": [
{
"content": "<string>",
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"color": "<string>",
"position": {
"x": 123,
"y": 123
},
"size": {
"height": 123,
"width": 123
}
}
],
"transitions": [
{
"from": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"properties": {
"type": "iris"
},
"require_confirmation": true,
"to": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"type": "iris",
"description": "<string>",
"schema": {}
}
]
},
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"inputs": [
{
"name": "<string>",
"required": true,
"schema": {},
"defaultValue": "<unknown>",
"description": "<string>"
}
],
"isPublished": true,
"rev": 123,
"rules": "<string>",
"settings": {
"max_timeout_mins": 123,
"viewport_height": 123,
"viewport_width": 123,
"custom_environment_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a"
},
"version": 123,
"workflowId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"author": "<string>",
"environmentTemplate": {
"config": {
"provider": "anchor"
},
"type": "browser"
},
"parentId": "3c90c3cc-0d44-4b50-8888-8dd25736052a"
}{
"code": 400,
"message": "<string>",
"detail": "<string>",
"errors": [
{
"detail": "<string>",
"parameter": "<string>"
}
],
"instance": "<string>",
"status": 123,
"title": "<string>",
"type": "<string>"
}{
"code": 401,
"message": "<string>",
"detail": "<string>",
"instance": "<string>",
"status": 123,
"title": "<string>",
"type": "<string>"
}{
"code": 403,
"message": "<string>",
"detail": "<string>",
"instance": "<string>",
"status": 123,
"title": "<string>",
"type": "<string>"
}{
"code": 404,
"message": "<string>",
"detail": "<string>",
"instance": "<string>",
"status": 123,
"title": "<string>",
"type": "<string>"
}{
"code": 409,
"message": "<string>",
"detail": "<string>",
"instance": "<string>",
"status": 123,
"title": "<string>",
"type": "<string>"
}{
"code": 500,
"message": "<string>",
"detail": "<string>",
"instance": "<string>",
"status": 123,
"title": "<string>",
"type": "<string>"
}Authorizations
Path Parameters
The ID of the workflow
Body
The file writes and deletes to apply
Request to patch the editable head's file representation
The revision this edit is based on. Agent-file-only patches overlay the current head even when this is stale. A structural-file patch is rejected with 409 when it does not match the stored head revision.
Paths of files to delete.
Files to upsert.
Show child attributes
Show child attributes
Response
The request has succeeded.
An immutable snapshot of a workflow's configuration
When this workflow was created. For the editable head this is restamped on each in-place edit, so it doubles as the last-edited time.
The files stored on this workflow version. Empty when the workflow has no files.
Show child attributes
Show child attributes
The workflow graph
Show child attributes
Show child attributes
The unique ID of this workflow
Typed input definitions for workflow execution. Includes names referenced in prompts, which default to optional strings.
Show child attributes
Show child attributes
Whether this is the workflow's published version (the API default). At most one version per workflow is published.
Monotonic optimistic-concurrency revision. Only meaningful for the editable head: supply it as baseRev on the next head patch. Agent-file-only patches overlay the current head if it has moved; structural-file patches are rejected with 409 when stale. Frozen snapshots never receive in-place patches.
The rules/instructions for this workflow
The settings for this version
Show child attributes
Show child attributes
The monotonic per-workflow version number.
The ID of the workflow this version belongs to
The email of the user who created this workflow.
Optional environment template. Defaults to browser/anchor if not provided.
Show child attributes
Show child attributes
The ID of the parent workflow this was derived from (for lineage tracking)

