On this page

Automation

create-process-flow

Can be held for approval

Create a process flow: an empty shell, or a full manifest that provisions the process flow, its agents and wiring in one call. Needs the fabric:orchestrate.write grant.

curl -sS -X POST https://fabric.wexa.ai/mcp/$FABRIC_PROJECT_ID \
  -H "authorization: Bearer $FABRIC_API_KEY" \
  -H "Mcp-Session-Id: $MCP_SESSION_ID" \
  -H "content-type: application/json" -H "accept: application/json" \
  -d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"create-process-flow","arguments":{"name":"docs-fixture-scratch-flow-1790023297678","description":"Created to capture delete-process-flow, then deleted."}}}'
{
  "content": [
    {
      "type": "text",
      "text": "{\"lifecycle_id\":\"qlc_000209\",\"result\":{\"process_flow_id\":\"6ab196817566f41b5c28e33a\",\"flow\":{\"_id\":\"6ab196817566f41b5c28e33a\",\"name\":\"docs-fixture-scratch-flow-1790023297678\",\"description\":\"Created to capture delete-process-flow, then deleted.\"}}}"
    }
  ],
  "isError": false
}

Parameters

ParameterTypeRequiredNotes
descriptionstringOptionalDescription of the flow.
flow_namestringOptionalOnly with manifest. Overrides manifest.flow.name.
kb_tagsarrayOptionalOnly used with manifest. Sets manifest.knowledge_base.tags and REPLACES (never merges with) the context of every agent with has_knowledge_base true. Entries are tag tokens, never sentences; see More details.
manifestobjectOptionalThe process flow, its agents and the wiring in one payload; see the manifest. Supply this, or name for a bare process flow. Validated strictly: an unrecognized field is rejected.
modestringOptionalOnly used with manifest. create (default) refuses a taken name with a 409. create_if_absent returns the existing process flow untouched. upsert replaces its agents.
namestringOptionalNames the process flow when you pass no manifest; required then.
rolestringOptionalRole of the flow.
Errors
  • ValidationError (400 or 422): an invalid manifest, skill ids not in this project, a skilled agent with no skills, or no name in shell mode. See the manifest.
  • ValidationError (400): the organization agent limit is full (Customer has exceeded number of coworkers). See the limit.
  • ConflictError (409): mode is create and the name is taken, or create_if_absent or upsert finds several process flows with the name.
Show full response

A real response, captured from a live call to create-process-flow:

{
  "lifecycle_id": "qlc_000209",
  "result": {
    "flow": {
      "_id": "6ab196817566f41b5c28e33a",
      "agents": [],
      "anomaly_detection": {
        "instructions": "",
        "is_enabled": false
      },
      "created_at": 1790023297.679563,
      "cron_details": {
        "agentflow_id": "",
        "collection_name": null,
        "count": null,
        "executed_by": null,
        "filters": null,
        "frequency": "",
        "goal": {
          "display_template": "",
          "template": ""
        },
        "limit": null,
        "projectID": "",
        "query": {},
        "query_limit": null
      },
      "default_goal": "",
      "description": "Created to capture delete-process-flow, then deleted.",
      "failover_agentflow_ids": null,
      "image": "https://files.example.com/connectors/knowledge_base.jpeg",
      "isActive": true,
      "is_cron_scheduled": false,
      "is_deleted": false,
      "kind": "flow",
      "last_used": 1790023297.679572,
      "name": "docs-fixture-scratch-flow-1790023297678",
      "organization_id": "6a79a770b6c128ccc24bfca8",
      "projectID": "6aa9beb7ec8121a43b6c791b",
      "role": " ",
      "type": "master",
      "unique_id": "1cuikfo",
      "updated_at": 1790023297.679571
    },
    "process_flow_id": "6ab196817566f41b5c28e33a"
  }
}
More details

Two modes. Shell-only: pass just name, description and role to create an empty process flow, and add agents later, one at a time, with update-process-flow. Full manifest: pass a manifest (Process flow Manifest v1.0: process flow, agents[] of skilled_agent and decider_agent nodes, wiring) to provision the process flow, all its agents and the wiring in one call. Prefer the manifest form whenever you already know the complete structure, for example after reasoning about what the request needs, or after running a compiler-style process flow and reading its raw JSON through get-execution's last_agent_output (never its conclusion, which is always prose). The docs tool with {topic: 'orchestrate'} returns the full manifest contract and a worked example.

Refusals in full: an invalid manifest (a missing flow.name, a duplicate ref, an initial_agent that names no agent, a next pointing at nothing, an unknown type; several near-misses carry a hint naming the field you meant, and every problem is reported at once); agents[].skills ids that do not exist in this project (an id that does not resolve silently does nothing at run time, so it is rejected up front); a skilled agent with no skills, which the executor cannot run (the conversational form, role: "conversational" with has_knowledge_base: true and a non-empty context array of tag tokens, is the alternative; a prose context is refused); and, in shell mode, a missing name. The organization agent limit is raised upstream.

kb_tags is required when the manifest leaves knowledge_base.tags empty and an ingest entry has no tags of its own, and each entry must be a tag token (e.g. "b2b_saas_icp"): retrieval matches tags by exact string, so a prose context is refused. create_if_absent is safe to repeat. upsert fails with 409 when several process flows share the name.

If any agent needs a skill (a connector action), call list-skills first to find its real id: this tool never creates skills, only references existing ones. Skills arrive with a provisioned connector; no tool creates one. Provision the connector under Connectors in the console, or with provision-connector for a connector that needs no credential: one that needs an API key or an OAuth sign-in still needs a person in the console. If the skill you want is not in list-skills, its connector is not provisioned in this project yet. The console's Skills screen lists them with name, status, version and which agents use them. Granting a skill means editing an agent, which needs fabric:orchestrate.write. You grant skills, not actions: the action is what runs when the agent uses the skill.

kb_tags also sets the tags of the manifest's ingest entries. A process flow is a multi-agent orchestration, not a larger agent. It has no instructions, tools or model of its own: the reasoning happens in the agents it names. Reach for one when the work needs more than one worker; one worker's job, however long, is one agent. The console calls the screen Multi-Agent Process flows: open Orchestrate, then Multi-Agent Process flows, and choose Create Multi-Agent Process flow. The process flow and the agents it names have their own histories, promoted and rolled back independently; see Executions and versioning.

The manifest

The manifest is the definition. Editing it does not edit the agents' instructions, and editing an agent does not rewire the manifest.

PartWhat it holds
manifest_version"1.0", the only value accepted today. Omitting it means the same thing.
flowThe process flow itself: a name (required), and optionally a description and a role.
agentsThe agents taking part. At least one is required, each with a ref (a short label unique within the manifest) and a title.
wiringOne field, initial_agent, naming the agent that runs first.

The rest of the manifest points at an agent by its ref, including wiring.initial_agent, so you need no real ids beforehand. A decider_agent needs at least two branches. Validation reports every problem at once. Optional fields are off unless you set them: whether the agent reads the knowledge base, whether it pauses for a person before it proceeds, and whether its prompt receives a summary of earlier agents, named by ref and resolved to real ids for you.

curl -sS https://fabric.wexa.ai/v1/create-process-flow \
  -H "authorization: Bearer $FABRIC_API_KEY" \
  -H "content-type: application/json" \
  -d '{"manifest":{"manifest_version":"1.0","flow":{"name":"orders-triage"},"agents":[{"ref":"check","title":"Check order","prompt":{"template":"Check the order."},"skills":["<skill id from list-skills>"],"next":"notify"},{"ref":"notify","title":"Notify customer","prompt":{"template":"Tell the customer."},"skills":["<skill id from list-skills>"]}],"wiring":{"initial_agent":"check"}}}'

The three node types

Every entry in manifest.agents[] is one node in the process flow. type picks which kind, and it defaults to skilled_agent when you leave it out. There are three, and no others: an unknown type is refused with a message naming all three.

typeWhat the node doesYou must setRefused on this type
skilled_agentRuns the task itself, inside Wexa, using the skills you give it. The default.skills — or make it conversational: role: "conversational" with has_knowledge_base: true and a non-empty contextregistration_id
decider_agentBranches. It picks one route and the process flow carries on down it.conditions, at least 2, one per branch; next_agents maps each decision to another agent's refregistration_id, is_terminal_agent, is_user_specific_task
interop_agentThe external agent node. Hands its step to an agent on another platform and waits for it.registration_id — a peer agent connection from list-peer-agentsskills, is_preview_mode_enabled, conditions, is_terminal_agent, is_user_specific_task

A skilled agent with no skills is refused, because the executor cannot run it. The refusal says so and offers the conversational form as the alternative — context is an ARRAY of tag tokens like ["b2b_saas_icp"], never a sentence.

Settings every node type takes

These are the same agent fields create-agent takes, under the manifest's names; the two are mapped in one table at agent fields.

FieldTypeLeave it out and…
titlestringRequired. It is how the node is named everywhere a person looks.
role, role_descriptionstringEmpty.
promptobject{"template": "..."} is the task. display_template is derived from template when you omit it.
llmobjectmodel is an id from list-models settable; omitted, the agent is stored with your organization's default registry model, or the first registry model when none is marked default. max_tokens 4000; temperature 0.
has_knowledge_base + contextboolean + arrayOff. context holds tag tokens, matched against document tags by exact string.
context_accessobjectFull access. Send {"mode": "off"} to withhold the context graph, or "brief_only" for the project brief alone. mode is required whenever you send the object at all.
agent_base_promptstringThe platform default reasoning prompt.
context_required + context_target_agent_idsboolean + arrayOff. When on, name the earlier agents by their ref.

Settings only a skilled agent takes

FieldTypeLeave it out and…
is_preview_mode_enabledbooleanAutomatic approval. true pauses the node for a person to approve.
is_terminal_agentbooleanOff. Marks the node as the end of the flow. It is recorded and read back, but nothing in the run engine acts on it yet.
is_user_specific_taskbooleanOff. true runs the task once per active user rather than once for the whole flow.

An external agent node, end to end

Register the external agent first, then point a node at the connection it returns:

conn = fabric.register_peer_agent(
    name="invoice-reconciler",
    endpoint="https://agents.example.com/a2a/invoice-reconciler",
    protocol="a2a",                 # or "mcp"
    secret="<the external agent's token>",
)

fabric.create_process_flow(manifest={
    "manifest_version": "1.0",
    "flow": {"name": "Invoice reconciliation", "role": "conversational"},
    "agents": [{
        "ref": "reconcile",
        "type": "interop_agent",
        "title": "Reconcile with the finance platform",
        "prompt": {"template": "Reconcile the outstanding supplier invoices."},
        "registration_id": conn["connection_id"],
        "next": None,
    }],
    "wiring": {"initial_agent": "reconcile"},
})

The node carries no skills and no approval step: the external agent brings its own abilities and runs its step on its own platform. has_knowledge_base and context_access still work, and mean something narrower here — what Wexa knows is gathered once and bundled into what is handed over, never live access back into your project. Poll the run with get-execution: a node like this can stay open for a long time, and it can stop to ask a question.

What the external agent receives is the node prompt, plus the context sources that are on for the node: its role_description, the output of the agents before it, the project brief and the knowledge base. Set context_access to {"mode": "off"} for an external agent you do not trust, so that project information does not go to a third party.

An MCP external agent must expose exactly one tool, or the handshake fails and so does the node when it runs. Check the endpoint with handshake-peer-agent before you build the process flow.

A question from the external agent waits for a person to answer it in the console. While it waits, the execution has status interop_pending and carries the question — see a run waiting on an external agent. An MCP question is cancelled after 3 minutes with no answer. An A2A question has no time limit, and no tool cancels a parked run, so plan for a person to be there.

The external agent also gets the run goal. A {{goal}} placeholder in the node prompt is filled with the goal you give run-process-flow, so Handle case {{goal}} with a goal of CASE-123 is sent as Handle case CASE-123. The goal is also sent on its own Goal: line, and as goal in the structured context, unless the node prompt already is the goal. A value the node itself takes as an input named goal wins over the run goal.

An external agent returns no token usage. An external step shows only what Wexa spends on its own side: the knowledge base lookup when it is on, otherwise 0 tokens and $0.00.

Run the process flow with run-process-flow and read it back with get-process-flow. Every agent in a process flow makes its own governed calls: a policy decision that refuses one agent's call refuses that call, not the process flow's right to exist. To hand a step to an agent on another platform, see peer agents.

Marked consequential: it is audited in full, and a policy rule may hold it for a person to approve. See Policy and approvals.

Every tool call works the same way: How every tool call works.