Apply graph ops to a revision's flow
Apply graph ops to a revision’s flow.
POST
/
v1
/
assistants
/
{agent_id}
/
revisions
/
{revision_id}
/
graph
/
ops
Apply graph ops to a revision's flow
curl --request POST \
--url https://api-sandbox.featherhq.com/v1/assistants/{agent_id}/revisions/{revision_id}/graph/ops \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"ops": [
{
"op": "upsert_node",
"node": {}
}
],
"base_version": 123
}
'import requests
url = "https://api-sandbox.featherhq.com/v1/assistants/{agent_id}/revisions/{revision_id}/graph/ops"
payload = {
"ops": [
{
"op": "upsert_node",
"node": {}
}
],
"base_version": 123
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({ops: [{op: 'upsert_node', node: {}}], base_version: 123})
};
fetch('https://api-sandbox.featherhq.com/v1/assistants/{agent_id}/revisions/{revision_id}/graph/ops', 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://api-sandbox.featherhq.com/v1/assistants/{agent_id}/revisions/{revision_id}/graph/ops",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'ops' => [
[
'op' => 'upsert_node',
'node' => [
]
]
],
'base_version' => 123
]),
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://api-sandbox.featherhq.com/v1/assistants/{agent_id}/revisions/{revision_id}/graph/ops"
payload := strings.NewReader("{\n \"ops\": [\n {\n \"op\": \"upsert_node\",\n \"node\": {}\n }\n ],\n \"base_version\": 123\n}")
req, _ := http.NewRequest("POST", 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.post("https://api-sandbox.featherhq.com/v1/assistants/{agent_id}/revisions/{revision_id}/graph/ops")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"ops\": [\n {\n \"op\": \"upsert_node\",\n \"node\": {}\n }\n ],\n \"base_version\": 123\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api-sandbox.featherhq.com/v1/assistants/{agent_id}/revisions/{revision_id}/graph/ops")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"ops\": [\n {\n \"op\": \"upsert_node\",\n \"node\": {}\n }\n ],\n \"base_version\": 123\n}"
response = http.request(request)
puts response.read_body{
"updated": true,
"validation": {
"valid": true,
"error_count": 123,
"warning_count": 123,
"suggestion_count": 123,
"findings": [
{
"severity": "error",
"rule_id": "<string>",
"category": "<string>",
"message": "<string>",
"node_id": "<string>",
"edge_id": "<string>",
"related_node_ids": [
"<string>"
],
"related_edge_ids": [
"<string>"
],
"source_span": {
"start_line": 123,
"start_col": 123,
"end_line": 123,
"end_col": 123,
"raw_text_excerpt": "<string>"
},
"suggested_fix": "<string>",
"related_spans": [
{
"start_line": 123,
"start_col": 123,
"end_line": 123,
"end_col": 123,
"raw_text_excerpt": "<string>"
}
]
}
],
"normalized_graph": {},
"blocking_error_count": 123
},
"workflow_enabled": true,
"revision": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"workflow_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"instructions": "<string>",
"compilation_strategy": "<string>",
"compilation_status": "<string>",
"trigger_type": "<string>",
"trigger_config": {},
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"description": "<string>",
"compiled_graph": {},
"executable_graph": {},
"quality_report": {},
"compilation_errors": [
"<string>"
],
"compilation_task_id": "<string>",
"compilation_input_hash": "<string>",
"router_config_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"analyzer_model_settings": {
"model": "<string>",
"config": {
"temperature": 1,
"max_tokens": 2,
"top_p": 0.5,
"stop_sequences": [
"<string>"
],
"reasoning_effort": "none",
"request_timeout_ms": 10500,
"thinking_budget": 2
}
},
"router_model_settings": {
"model": "<string>",
"config": {
"temperature": 1,
"max_tokens": 2,
"top_p": 0.5,
"stop_sequences": [
"<string>"
],
"reasoning_effort": "none",
"request_timeout_ms": 10500,
"thinking_budget": 2
}
},
"policy_ids": [
"<unknown>"
],
"tool_input_defaults": {},
"tools": [
{
"tool": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"organization_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"description": "<string>",
"tool_type": "api_call",
"active_revision_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"active_revision": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"tool_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"description": "<string>",
"status": "<string>",
"created_by": "<string>",
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"default_count": 123,
"pinned_count": 123,
"stale_input_fields": [
"<string>"
],
"merged_input_preview": {},
"configuration": {
"url": "<string>",
"method": "GET",
"headers": [
{
"key": "<string>",
"value": "<string>",
"secure": false
}
],
"query_params": [
{
"key": "<string>",
"value": "<string>",
"secure": false
}
],
"body": {},
"timeout": 30,
"variables": [
{
"name": "<string>",
"type": "str",
"description": "<string>",
"required": false
}
],
"retry": {
"max_retries": 0,
"base_delay_seconds": 1,
"max_delay_seconds": 30,
"jitter": true
}
},
"transfer_target": {
"destination": "<string>",
"destination_source": {
"tool_id": "<string>",
"response_path": "<string>",
"type": "api_tool",
"input_mapping": {}
},
"mode": "cold"
},
"response_schema": {
"field_mappings": [
{
"path": "<string>",
"alias": "<string>"
}
]
},
"has_secrets": false,
"input_defaults": {},
"compatibility": {
"tool_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"old_revision_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"new_revision_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"has_blocking": true,
"active_blocking_count": 123,
"active_blocking_finding_count": 123,
"active_finding_count": 123,
"affected_assistant_count": 123,
"findings": [
{
"severity": "blocking",
"assistant_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"assistant_revision_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"revision_state": "active",
"finding_type": "<string>",
"field_path": "<string>",
"detail": "<string>",
"configuration_scope": "assistant_tool_default",
"workflow_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"workflow_revision_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"component_node_id": "<string>",
"graph_node_id": "<string>",
"graph_node_name": "<string>",
"step_id": "<string>",
"tool_ref_index": 123
}
]
}
},
"metadata": {}
}
}
],
"knowledge_base_ids": [
"3c90c3cc-0d44-4b50-8888-8dd25736052a"
],
"created_by": "<string>",
"graph_version": 0,
"warnings": [
"<string>"
]
},
"graph_version": 123,
"blocking_error_count": 0
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>",
"input": "<unknown>",
"ctx": {}
}
]
}Authorizations
Body
application/json
Body for POST /revisions/{id}/graph/ops — an ordered PATCH batch.
ops
(UpsertNodeOp · object | RemoveNodeOp · object | UpdateNodeFieldsOp · object | AddEdgeOp · object | RemoveEdgeOp · object | SetEntryNodeOp · object | UpsertContextVariableOp · object | RemoveContextVariableOp · object | SetPersonaOp · object | SetComponentOutputsOp · object)[]
required
Maximum array length:
200- UpsertNodeOp
- RemoveNodeOp
- UpdateNodeFieldsOp
- AddEdgeOp
- RemoveEdgeOp
- SetEntryNodeOp
- UpsertContextVariableOp
- RemoveContextVariableOp
- SetPersonaOp
- SetComponentOutputsOp
Show child attributes
Show child attributes
Response
Successful Response
Graph result plus the owning assistant revision's authored execution flag.
Validation result for a submitted CompiledWorkflowGraph payload.
Show child attributes
Show child attributes
Full revision response — the compile-poll target (WF-08).
Clients poll GET /workflows/revisions/{id} and read compilation_status
compilation_errors+compiled_graphto determine whether an async compile job is done.compilation_task_idis the Celery task handle the conductor uses to cancel an in-flight compile.
Show child attributes
Show child attributes
Was this page helpful?
⌘I
Apply graph ops to a revision's flow
curl --request POST \
--url https://api-sandbox.featherhq.com/v1/assistants/{agent_id}/revisions/{revision_id}/graph/ops \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"ops": [
{
"op": "upsert_node",
"node": {}
}
],
"base_version": 123
}
'import requests
url = "https://api-sandbox.featherhq.com/v1/assistants/{agent_id}/revisions/{revision_id}/graph/ops"
payload = {
"ops": [
{
"op": "upsert_node",
"node": {}
}
],
"base_version": 123
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({ops: [{op: 'upsert_node', node: {}}], base_version: 123})
};
fetch('https://api-sandbox.featherhq.com/v1/assistants/{agent_id}/revisions/{revision_id}/graph/ops', 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://api-sandbox.featherhq.com/v1/assistants/{agent_id}/revisions/{revision_id}/graph/ops",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'ops' => [
[
'op' => 'upsert_node',
'node' => [
]
]
],
'base_version' => 123
]),
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://api-sandbox.featherhq.com/v1/assistants/{agent_id}/revisions/{revision_id}/graph/ops"
payload := strings.NewReader("{\n \"ops\": [\n {\n \"op\": \"upsert_node\",\n \"node\": {}\n }\n ],\n \"base_version\": 123\n}")
req, _ := http.NewRequest("POST", 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.post("https://api-sandbox.featherhq.com/v1/assistants/{agent_id}/revisions/{revision_id}/graph/ops")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"ops\": [\n {\n \"op\": \"upsert_node\",\n \"node\": {}\n }\n ],\n \"base_version\": 123\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api-sandbox.featherhq.com/v1/assistants/{agent_id}/revisions/{revision_id}/graph/ops")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"ops\": [\n {\n \"op\": \"upsert_node\",\n \"node\": {}\n }\n ],\n \"base_version\": 123\n}"
response = http.request(request)
puts response.read_body{
"updated": true,
"validation": {
"valid": true,
"error_count": 123,
"warning_count": 123,
"suggestion_count": 123,
"findings": [
{
"severity": "error",
"rule_id": "<string>",
"category": "<string>",
"message": "<string>",
"node_id": "<string>",
"edge_id": "<string>",
"related_node_ids": [
"<string>"
],
"related_edge_ids": [
"<string>"
],
"source_span": {
"start_line": 123,
"start_col": 123,
"end_line": 123,
"end_col": 123,
"raw_text_excerpt": "<string>"
},
"suggested_fix": "<string>",
"related_spans": [
{
"start_line": 123,
"start_col": 123,
"end_line": 123,
"end_col": 123,
"raw_text_excerpt": "<string>"
}
]
}
],
"normalized_graph": {},
"blocking_error_count": 123
},
"workflow_enabled": true,
"revision": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"workflow_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"instructions": "<string>",
"compilation_strategy": "<string>",
"compilation_status": "<string>",
"trigger_type": "<string>",
"trigger_config": {},
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"description": "<string>",
"compiled_graph": {},
"executable_graph": {},
"quality_report": {},
"compilation_errors": [
"<string>"
],
"compilation_task_id": "<string>",
"compilation_input_hash": "<string>",
"router_config_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"analyzer_model_settings": {
"model": "<string>",
"config": {
"temperature": 1,
"max_tokens": 2,
"top_p": 0.5,
"stop_sequences": [
"<string>"
],
"reasoning_effort": "none",
"request_timeout_ms": 10500,
"thinking_budget": 2
}
},
"router_model_settings": {
"model": "<string>",
"config": {
"temperature": 1,
"max_tokens": 2,
"top_p": 0.5,
"stop_sequences": [
"<string>"
],
"reasoning_effort": "none",
"request_timeout_ms": 10500,
"thinking_budget": 2
}
},
"policy_ids": [
"<unknown>"
],
"tool_input_defaults": {},
"tools": [
{
"tool": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"organization_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"description": "<string>",
"tool_type": "api_call",
"active_revision_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"active_revision": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"tool_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"description": "<string>",
"status": "<string>",
"created_by": "<string>",
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"default_count": 123,
"pinned_count": 123,
"stale_input_fields": [
"<string>"
],
"merged_input_preview": {},
"configuration": {
"url": "<string>",
"method": "GET",
"headers": [
{
"key": "<string>",
"value": "<string>",
"secure": false
}
],
"query_params": [
{
"key": "<string>",
"value": "<string>",
"secure": false
}
],
"body": {},
"timeout": 30,
"variables": [
{
"name": "<string>",
"type": "str",
"description": "<string>",
"required": false
}
],
"retry": {
"max_retries": 0,
"base_delay_seconds": 1,
"max_delay_seconds": 30,
"jitter": true
}
},
"transfer_target": {
"destination": "<string>",
"destination_source": {
"tool_id": "<string>",
"response_path": "<string>",
"type": "api_tool",
"input_mapping": {}
},
"mode": "cold"
},
"response_schema": {
"field_mappings": [
{
"path": "<string>",
"alias": "<string>"
}
]
},
"has_secrets": false,
"input_defaults": {},
"compatibility": {
"tool_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"old_revision_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"new_revision_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"has_blocking": true,
"active_blocking_count": 123,
"active_blocking_finding_count": 123,
"active_finding_count": 123,
"affected_assistant_count": 123,
"findings": [
{
"severity": "blocking",
"assistant_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"assistant_revision_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"revision_state": "active",
"finding_type": "<string>",
"field_path": "<string>",
"detail": "<string>",
"configuration_scope": "assistant_tool_default",
"workflow_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"workflow_revision_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"component_node_id": "<string>",
"graph_node_id": "<string>",
"graph_node_name": "<string>",
"step_id": "<string>",
"tool_ref_index": 123
}
]
}
},
"metadata": {}
}
}
],
"knowledge_base_ids": [
"3c90c3cc-0d44-4b50-8888-8dd25736052a"
],
"created_by": "<string>",
"graph_version": 0,
"warnings": [
"<string>"
]
},
"graph_version": 123,
"blocking_error_count": 0
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>",
"input": "<unknown>",
"ctx": {}
}
]
}