Customers · API reference
Workflow format
The workflow definition you send to create a workflow: steps, handles, port types, what may connect to what, and every node type.
- Before you start
- An API key with the workflows:write scope, and the id of a project or agent.
- You'll end with
- A workflow definition that passes validation the first time.
A workflow is a list of steps and the connections between them. You can create one from code by sending that list to Create a workflow; Sushibelt lays it out as a graph on the canvas, where your team can open and edit it. This page is the full format: the request, how steps connect, the port types, and every node type.
Tip: the easiest way to get a workflow right
Build and test it on the canvas, then run it by its id. Create workflows from code when you need many similar ones, or when an agent designs them.
The request#
A workflow belongs to an agent, inside a project. Pass agentId to add the workflow to an agent you already have, or projectId to create a new agent for it. In the app, both ids are in the address bar when you open an agent: /your-team/workspace/PROJECT_ID/AGENT_ID/canvas.
| Name | Description |
|---|---|
namestring · Required | The workflow's name. |
agentIdstring (uuid) · Optional | Add the workflow to this agent. |
projectIdstring (uuid) · Optional | Create a new agent in this project and add the workflow to it. |
agentNamestring · Optional | The new agent's name, when you pass projectId. Defaults to name. |
stepsarray of WorkflowStep · Required | No description. |
When you create a new agent, or add to an agent that has no active workflow, the new workflow becomes the one Run an agent runs. Adding a workflow to an agent that already has an active one leaves it unchanged.
Steps#
Each step is one node on the canvas.
| Name | Description |
|---|---|
keystring · Required | A name for this step, unique within the request. Other steps refer to it in inputs. |
typestring · Required | The node type. One of 55 values; see the list below. |
labelstring · Optional | The name shown on the canvas. Defaults to the node type's name. |
configobject · Optional | The node's settings; the fields depend on the node type. Set apiInputKey on a TextEntry or PromptBuilder step to let a run replace its value. |
inputsarray of one of: string, WorkflowStepInput · Optional | The steps this step reads from. A step key alone connects first output to first input. |
Connecting steps#
A step's inputs list the steps it reads from. A node has named ports, called handles: inputs on one side, outputs on the other. There are two ways to connect:
- By key alone, such as
"inputs": ["prompt"]: connects the other step's first output to this step's first input. Right for most nodes, which have one of each. - With handles, such as
{ "from": "style", "targetHandle": "input-b" }: names the ports, for a node with more than one input or output.
| Name | Description |
|---|---|
fromstring · Required | The key of the step to connect from. |
sourceHandlestring · Optional | The output handle on that step. |
targetHandlestring · Optional | The input handle on this step. |
The handle ids of every node are in the node types table below.
Port types#
Every handle carries a type, which decides what may connect to it.
| Type | Description |
|---|---|
string | Text: a prompt, an answer, a caption. |
image | An image file. |
file | Any file. |
json | Structured data. |
code | Source code, such as a GLSL shader. |
config | Settings for a model step, overriding its own. |
map | One map image, such as depth. |
maps | A set of texture maps for one material: albedo, normal, roughness, metal. |
mesh | A 3D mesh (GLB and similar). |
rig | A skeleton for a mesh. |
audio | An audio file. |
boolean | True or false. |
any | Anything. Used by pass-through inputs. |
same | Whatever arrived at the node's pass-through input. |
num | A number. |
array | A list. |
What may connect to what#
- An output connects to an input of the same type.
- An
anyinput takes every output, and ananyoutput connects to every input. - A
sameoutput carries the type of whatever reached the node's pass-through input, and is checked as that type. - An input that lists several kinds, such as a delivery step's
asset, takes any of them. numberandnumare the same type, and so aremodel3dandmesh.
For each input type, the outputs it takes besides any and same:
| Input type | Description |
|---|---|
string | string, json, code, boolean, num |
image | image |
file | file |
json | json |
code | code |
config | config |
map | map |
maps | maps |
mesh | mesh |
rig | rig |
audio | audio |
boolean | boolean |
num | num |
array | array |
Validation#
A workflow is checked when you create it and again every time it runs, by the same rules the canvas uses. Creating one that fails answers 422; so does starting a run of one. The rules:
- Every step has a
key, unique in the request, and a knowntype. - Every connection names a
keyin the same request. - No node with ports is left unconnected.
- Every required input is connected.
- Every required setting is filled, such as a Text node's
textor a Prompt builder'stemplate, unless a connection supplies it. - Every connection joins types that fit, by the rules above.
- There are no loops: a step cannot depend on itself through other steps.
- No step uses a node type that cannot run (see Older type ids).
The answer lists each problem in errors, each with a message naming the node and, usually, its nodeId. A problem with the step list itself — an unknown type, a repeated key, a connection to no step — answers with a single error instead.
Settings#
A step's config holds its settings: the same values the inspector on the canvas shows. The ones you are most likely to set from code:
| Node type and setting | Description |
|---|---|
TextEntry · text | The text the node passes on, exactly as written. |
TextEntry · apiInputKey | A name that lets a run replace text. See Pass inputs to a run. |
PromptBuilder · template | A template with {{input-a}} and {{input-b}} slots, filled from what is connected to those inputs. |
PromptBuilder · apiInputKey | A name that lets a run replace template. |
DiffusionWorker · providerKey, model | The provider and model that make the image. Leave them out to let Sushibelt choose. Each image model's page shows the values under Run it from code. |
Delivery nodes · repo, branch, path, commitMessage, manifest | Where and how files are committed. See Deliver to GitHub, GitLab or Unity. |
A complete example#
Two pieces of text joined into a prompt, made into an image, and shown in a gallery. The subject is exposed as an input named subject, so each run can change it.
curl -X POST "https://app.sushibelt.ai/api/v1/workflows" \
-H "Authorization: Bearer $SUSHIBELT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Fox in oils",
"projectId": "YOUR_PROJECT_ID",
"steps": [
{
"key": "subject",
"type": "TextEntry",
"config": {
"text": "a red fox",
"apiInputKey": "subject"
}
},
{
"key": "style",
"type": "TextEntry",
"config": {
"text": "as an oil painting"
}
},
{
"key": "prompt",
"type": "PromptBuilder",
"config": {
"template": "{{input-a}}, {{input-b}}"
},
"inputs": [
{
"from": "subject",
"targetHandle": "input-a"
},
{
"from": "style",
"targetHandle": "input-b"
}
]
},
{
"key": "image",
"type": "DiffusionWorker",
"inputs": [
"prompt"
]
},
{
"key": "preview",
"type": "ImageGallery",
"inputs": [
"image"
]
}
]
}'{
"workflowId": "3f1c9a52-8d4e-4b7a-9c61-2e5f0d7a1b90",
"agentId": "5e0b7c3d-2a61-4f8e-b9d4-07c1a6e2f853",
"projectId": "00000000-0000-0000-0000-000000000000",
"stepsCount": 5
}Then run it with { "inputs": { "subject": "a white wolf" } }. See Pass inputs to a run.
Node types#
Every node the canvas offers, grouped as the canvas groups them. The type is what you send; the name under it is what the canvas calls it. Each row lists the node's input and output handles with their port types.
Start#
Bring something in to work with.
| Type | Description |
|---|---|
TextEntryText | Type a prompt or any text. No inputs. Output: output (string). |
ImageLoaderImage | Start from a picture you have. No inputs. Output: output (image). |
FileUploaderFile | Upload a file from your machine. No inputs. Output: output (file). |
JsonLoaderData | Supply a fixed block of data. No inputs. Output: output (json). |
WebhookListenerWebhook trigger | Start the run from an HTTP request. No inputs. Output: output (json). |
S3BucketWatcherWatch an S3 folder | Run when a new file lands. No inputs. Output: output (file). |
ShaderSnippetShader code | Supply GLSL to run later. No inputs. Output: output (code). |
2D#
Generate, guide, enlarge and cut out pictures.
| Type | Description |
|---|---|
DiffusionWorkerImage generator | Make a picture from a description. Inputs: prompt (string, required), image (image), config (config). Output: output (image). |
ControlNetFilterComposition guide | Force a pose, edge or depth layout. Inputs: image (image, required), control (string, required). Output: output (image). |
UpscalerUpscaler | Enlarge an image 2× or 4×. Inputs: input (image, required). Output: output (image). |
BackgroundRemoverBackground remover | Cut the subject out of a picture. Inputs: input (image, required). Output: output (image). |
ImageCropperCrop | Cut an image to a region. Inputs: input (image, required). Output: output (image). |
Maps#
Depth and material maps from a picture.
| Type | Description |
|---|---|
DepthEstimatorDepth map | Estimate depth from a picture. Inputs: input (image, required). Output: output (map). |
PbrSynthesizerMaterial maker | Turn a texture into PBR maps. Inputs: input (image, required). Output: output (image). |
TextureManifestTexture set | Bundle maps into one material. No inputs. Output: output (maps). |
3D#
Meshes from pictures, made game-ready.
| Type | Description |
|---|---|
TwoDToThreeDImage to 3D | Build a mesh from a picture. Inputs: image (image, required), maps (maps), prompt (string). Output: output (mesh). |
MeshDecimatorDecimate | Cut a mesh to a triangle budget. Inputs: input (mesh, required). Output: output (mesh). |
ThreeDStudioViewer3D preview | Look at a mesh in the canvas. Inputs: mesh (mesh, required), maps (maps). No output: it ends a chain. |
Motion#
Skeletons and animation for a mesh.
| Type | Description |
|---|---|
AutoRiggerRigger | Add a skeleton to a mesh. Inputs: mesh (mesh, required), rig (rig). Output: output (mesh). |
RigImporterRig importer | Bring in an existing rig. No inputs. Output: output (rig). |
Audio#
Speech and sound.
| Type | Description |
|---|---|
AudioGenAudio generator | Turn text into speech. Inputs: prompt (string, required), config (config). Output: output (audio). |
Text#
Write, describe, template and embed text.
| Type | Description |
|---|---|
LlmWorkerWriter | Ask a language model for text. Inputs: prompt (string, required), config (config). Output: output (string). |
VisionInterrogatorImage describer | Say what is in a picture. Inputs: input (image, required). Output: output (string). |
PromptBuilderPrompt builder | Fill a template with upstream values. Inputs: input-a (string, required), input-b (string). Output: output (string). |
EmbedderEmbedder | Turn text into a vector for search. Inputs: input (string). Output: output (json). |
Logic#
Route, repeat and reshape data.
| Type | Description |
|---|---|
CustomApiCallCustom API | Call any HTTPS API with your own key. Inputs: prompt (string), image (image). Output: text (string), images (image). |
ConditionalSwitchBranch | Send data one way or the other. Inputs: condition (boolean, required), input (any, required). Output: output (same). |
MathOperatorMaths | Do arithmetic on a number. Inputs: a (num, required), b (num, required). Output: output (num). |
VariableMapperRename fields | Match one node’s output to another’s input. Inputs: input (any, required). Output: output (same). |
JsonExtractorPick a value | Pull one field out of data. Inputs: json (json, required), key (string, required). Output: output (json). |
Show & send#
Look at results, or deliver them.
| Type | Description |
|---|---|
ImageGalleryImage gallery | Show the pictures a run made. Inputs: input (image, required). No output: it ends a chain. |
AudioPlayerAudio player | Hear what a run made. Inputs: input (audio, required). No output: it ends a chain. |
TextConsoleText output | Show text as it arrives. Inputs: input (string, required). No output: it ends a chain. |
JsonInspectorInspect data | Read raw output. Inputs: input (json, required). No output: it ends a chain. |
ShaderPlaybackShader playback | Run a shader with live controls. Inputs: input (code, required). No output: it ends a chain. |
GithubDeliveryGitHub | Commit results to a repo. Inputs: asset (image, audio, mesh, maps, map, rig, file, required). No output: it ends a chain. |
GitlabDeliveryGitLab | Commit results to a repo. Inputs: asset (image, audio, mesh, maps, map, rig, file, required). No output: it ends a chain. |
PlasticDeliveryPlastic SCM | Check results in to a repo. Inputs: asset (image, audio, mesh, maps, map, rig, file, required). No output: it ends a chain. |
UnityDeliveryUnity | Send assets to a Unity project. Inputs: asset (image, audio, mesh, maps, map, rig, file, required). No output: it ends a chain. |
S3UploaderUpload to S3 | Put results in a bucket. Inputs: input (image, audio, mesh, maps, map, rig, file, required). No output: it ends a chain. |
DiscordSlackDiscord or Slack | Post results to a channel. Inputs: text (string), image (image). No output: it ends a chain. |
ApiPostActionSend to a URL | POST the result somewhere. Inputs: input (json, string, num, boolean, array, image, audio, mesh, maps, map, rig, file, required). No output: it ends a chain. |
Older type ids#
The API also accepts these type ids, so that older workflows keep working. Do not use them in new workflows: they are not on the canvas, and some are refused when a run starts.
InputStage, ProcessingStage, ExportStage, Prompt, Knowledgebase, Service, Github, CloudStorage, ImageGen, 3DTransform, BatchSplitter, IterationGate, PythonSandbox