nodes are its steps and its edges connect them. Every node has an id, a type, a config, and an optional label that’s shown in the graph. This page lists each node type’s config fields. The authoritative definition is the JSON Schema at https://api.prod.major.build/public/workflow.schema.json.
agent_call
Runs an agent with a prompt.app_call
Calls an endpoint on one of your deployed apps.
The node’s output is the response body. A body that isn’t a JSON object is wrapped as
{ "body": ... }.
Retries back off exponentially, starting at 2 seconds and capped at 30 seconds between attempts. A call where the app never answers isn’t retried. In the editor, set Max retries and Retry on in the node inspector.
In the workflow editor, pick the Endpoint from the endpoints Major extracted from the app’s deployed API, or click Enter manually to type the method and path. If the endpoint’s path has a parameter such as {id}, fill it in under Path. Edit input in the node’s Request body field, or its Query params field for GET and DELETE.
router
Branches the run on state.
Branches are checked top to bottom and the first one whose
when is true wins. A condition that evaluates to null doesn’t match. Every target in the winning to list runs in parallel. The router must have exactly one outgoing edge per target named in its branches and default.
for_each
Runs a loop body once per item in a list.
A
for_each has two outgoing edges: one with "loop": "body" into the loop body, and one with "loop": "exit" that runs after the last iteration. Every path from the body must lead back to the for_each. Loop bodies are the only cycles a workflow may have.
Inside the body, <for_each_id>.item and <for_each_id>.index are the current item and its position. After the exit edge, <for_each_id>.results holds each iteration’s final output, in item order.
join
Waits for parallel branches to meet.
Every edge into a join must come from the same fan-out (a
router branch with several targets, for example), with no other join in between. Keep each parallel leg a simple line into the join.
wait
Pauses the run.jev_noul, jev_choice, and jev_score
Ask Jev (TypeSafe’s judgment model) a question about some text, then branch on the answer with arouter. Use them to filter, classify, or rate content. In the editor they’re called Jev yes/no, Jev choice, and Jev score.
All three take a text field: the text to judge. It supports {{ }} interpolation, so it’s usually built from run state, for example "{{trigger.input.email_body}}".
jev_noul
Asks one or more yes/no questions.
The output is each question’s yes-probability, from 0 to 1, under its id. For a node
judge with a question is_urgent, branch with judge.is_urgent > 0.5.
jev_choice
Picks one label from a list of options.
The output is
{ "choice": "<label>", "confidence": ..., "probabilities": { "<label>": ... } }. Branch with, for example, classify.choice == "billing".
jev_score
Rates the text on an ordered scale.
The output is
{ "score": ..., "confidence": ..., "probabilities": ... }. score is the expected score from 0 to the last level’s position, so it can fall between levels. Branch with, for example, rate.score >= 1.5.
human_approval
Asks a person to choose in Slack. Requires the Major Slack integration.
The output is
{ "choice": "<value>", "responded_by": "<user id>" }, or { "choice": "<on_timeout value>", "timed_out": true } on timeout. A human_approval has one outgoing edge, which should lead to a router that branches on <node_id>.choice. Only Major members with access to the workflow can answer.
end
Finishes the run.
An
end node has no outgoing edges.
Edges
Each edge is{ "id": "...", "from": "node_id", "to": "node_id" }, with an optional label shown in the graph. Only for_each out-edges carry "loop": "body" or "loop": "exit".
Graph rules
Saving checks the definition against these rules, and errors name the path that failed:- At most 50 nodes, and the file is at most 256 KB.
- Node ids and edge ids are unique.
triggeris reserved and can’t be a node id. entryand every edge’sfromandtoname an existing node.- Only
routerandfor_eachfan out. Every other node has exactly one outgoing edge, andendnodes have none. - A node can have several inbound edges only if at most one of them can be active at a time. Parallel paths must meet at a
joinfirst. - Every node is reachable from
entry, and every path reaches anendnode or loops back to afor_each.
Next steps
State and input
Reference node outputs and workflow input.
Triggers
Start the workflow automatically.