---
title: "Invoke Workflow (Sync)"
method: POST
path: "/v1/workflows/{workflow_id}/invoke"
tags: ["API v1", "Workflows", "Workflows Invocation"]
---

# Invoke Workflow (Sync)

`POST /v1/workflows/{workflow_id}/invoke`

## Request

- Base URL: `https://api.xpander.ai` (the document declares no server; this is the origin it was published from)
- URL: `https://api.xpander.ai/v1/workflows/{workflow_id}/invoke`
- Auth: API key in header `x-api-key`

Invoke a workflow and wait for completion. Returns the final result.

## Path parameters

- `workflow_id` string, required

## Query parameters

- `version` string, nullable: The workflow version to invoke. default = latest

## Request body

- AgentExecutionRequest
  - `input` AgentExecutionInputInput, required
    - `text` string, nullable
    - `files` string[], nullable
    - `attachments` AttachmentRef[], nullable
      - `url` string, required
      - `name` string, nullable
      - `mime` string, nullable
      - `size` integer, nullable
      - `kind` 'image' | 'pdf' | 'document' | 'text' | 'audio' | 'video' | 'archive' | 'unknown': Coarse attachment class, resolved from mime/magic/extension. Mirrored in xpander-sdk (models/task.py + models/generic-adjacent); keep the members identical.
      - `sha256` string, nullable
      - `expires_at` string, nullable
      - `source` string, nullable
      - `transcript` string, nullable
    - `user` UserInput: Represents the details of a user. Attributes: id (Optional[str]): The unique identifier of the user. Defaults to None. first_name (Optional[str]): The first name of the user. Defaults to None. last_name (Optional[str]): The last name of the user. Defaults to None. email (str): The email address of the user. This field is required. additional_attributes (Optional[dict]): Possible additional parameters for the assistant's service. role (Optional[str]): The user's role in the organization. Defaults to "member". is_super_admin (Optional[bool]): Whether the user is a super admin. Defaults to False. timezone (Optional[str]): The user's timezone in IANA format (e.g. "America/New_York"). Defaults to None.
      - `id` string, nullable
      - `first_name` string, nullable
      - `last_name` string, nullable
      - `email` string, required
      - `additional_attributes` object, nullable
      - `role` string, nullable
      - `is_super_admin` boolean, nullable
      - `timezone` string, nullable
    - `principal` Principal: Typed caller identity: who invoked the run and through which door.
      - `kind` 'user' | 'slack' | 'api_key' | 'system' | 'anonymous', required
      - `id` string, required
      - `email` string, nullable
      - `display_name` string, nullable
    - `from_agent_id` string, nullable
    - `from_agent_name` string, nullable
  - `id` string, nullable
  - `minted_conversation_id` boolean, nullable
  - `normalized_id_fields` string[], nullable
  - `payload_extension` object, nullable
  - `parent_execution_id` string, nullable
  - `worker_id` string, nullable
  - `source` string, nullable
  - `output_format` 'text' | 'markdown' | 'json' | 'voice'
  - `output_schema` object, nullable
  - `run_locally` boolean, nullable
  - `additional_context` string, nullable
  - `instructions_override` string, nullable
  - `test_run_node_id` string, nullable
  - `expected_output` string, nullable
  - `engagement_instructions` string, nullable: Channel engagement-rule action prompts for this turn, rendered into the gateway system context in addition to the agent's instructions.
  - `output_format_instructions` string, nullable: Channel-binding output-format text for this turn, rendered into the gateway system context in addition to the agent's instructions.
  - `events_streaming` boolean, nullable
  - `mcp_servers` object[], nullable
  - `triggering_agent_id` string, nullable
  - `title` string, nullable
  - `think_mode` 'default' | 'harder'
  - `disable_attachment_injection` boolean, nullable
  - `user_tokens` object, nullable
  - `user_oidc_token` string, nullable
  - `return_metrics` boolean, nullable
  - `llm_model_provider` string, nullable: Per-execution override for the LLM provider (e.g. 'openai', 'anthropic'). Falls back to the agent's configured provider when unset.
  - `llm_model_name` string, nullable: Per-execution override for the LLM model name. Falls back to the agent's configured model when unset.
  - `llm_reasoning_effort` 'low' | 'medium' | 'high' | 'xhigh'
  - `harness_cli` 'claude-code' | 'codex' | 'opencode' | 'xpander': A CLI the harness container can run; chosen per conversation, never per agent.
  - `permission_mode` 'full' | 'gated'
  - `builtin_tools` HarnessBuiltinTools: The CLI's own built-in tools (`harness`) and the platform's tools (`xpander`); a missing half stays on.
    - `harness` HarnessBuiltinToggle: One built-in tool set switched on or off; None leaves the decision to the next layer down.
      - `enabled` boolean, nullable
    - `xpander` HarnessBuiltinToggle: One built-in tool set switched on or off; None leaves the decision to the next layer down.
      - `enabled` boolean, nullable
  - `tool_call_limit` integer, nullable: Max tool calls for this execution. The budget belongs to the work, not the agent: a scheduled run knows how much it is worth. Falls back to the agent's setting when unset.
  - `source_node_type` 'workbench' | 'sdk' | 'task' | 'assistant' | 'webhook' | 'mcp' | 'a2a' | 'telegram' | 'slack' | 'whatsapp' | 'ms-teams' | 'email' | 'api'
  - `is_app` boolean, nullable
  - `verified_user_transport` string, nullable: Transport that VERIFIED input.user this turn ('chat' = Bearer session, 'mcp' = OAuth). Set only by the services that resolved the user themselves and stripped from caller-supplied bodies; downstream consent gates key off it.
  - `is_steering` boolean, nullable
  - `sub_tasks_mode` 'sync' | 'async' | 'auto'
  - `channel_session` ChannelSessionRef: Names the (channel, external key) whose standing conversation this turn belongs to.
    - `channel` string, required
    - `channel_key` string
    - `adopt_conversation_id` string, nullable
  - `channel_context` string, nullable: Pre-rendered cross-channel recency block for channel turns; the gateway appends it to the turn's context verbatim.
  - `thread_context` string, nullable: Pre-rendered history of the channel thread this turn arrived in; the gateway appends it to the turn's context, and it never becomes part of the user's message.
  - `attachment_context` string, nullable: Pre-rendered text a channel extracted from this message's attachments and links (OCR, transcripts, fetched pages, readable files); the gateway appends it to the turn's context, and it never becomes part of the user's message.

## Response `200`

Successful Response

- CreatedTask: Task creation response model. Extends AgentExecution with additional agent_id field.
  - `background_auth_eligible` boolean
  - `id` string, required
  - `agent_id` string, required
  - `organization_id` string, required
  - `input` AgentExecutionInputOutput, required
    - `text` string, nullable
    - `files` string[], nullable
    - `attachments` AttachmentRef[], nullable
      - `url` string, required
      - `name` string, nullable
      - `mime` string, nullable
      - `size` integer, nullable
      - `kind` 'image' | 'pdf' | 'document' | 'text' | 'audio' | 'video' | 'archive' | 'unknown': Coarse attachment class, resolved from mime/magic/extension. Mirrored in xpander-sdk (models/task.py + models/generic-adjacent); keep the members identical.
      - `sha256` string, nullable
      - `expires_at` string, nullable
      - `source` string, nullable
      - `transcript` string, nullable
    - `user` UserOutput: Represents the details of a user. Attributes: id (Optional[str]): The unique identifier of the user. Defaults to None. first_name (Optional[str]): The first name of the user. Defaults to None. last_name (Optional[str]): The last name of the user. Defaults to None. email (str): The email address of the user. This field is required. additional_attributes (Optional[dict]): Possible additional parameters for the assistant's service. role (Optional[str]): The user's role in the organization. Defaults to "member". is_super_admin (Optional[bool]): Whether the user is a super admin. Defaults to False. timezone (Optional[str]): The user's timezone in IANA format (e.g. "America/New_York"). Defaults to None.
      - `id` string, nullable
      - `first_name` string, nullable
      - `last_name` string, nullable
      - `email` string, required
      - `additional_attributes` object, nullable
      - `role` string, nullable
      - `is_super_admin` boolean, nullable
      - `timezone` string, nullable
      - `display_name` string, required
    - `principal` Principal: Typed caller identity: who invoked the run and through which door.
      - `kind` 'user' | 'slack' | 'api_key' | 'system' | 'anonymous', required
      - `id` string, required
      - `email` string, nullable
      - `display_name` string, nullable
    - `from_agent_id` string, nullable
    - `from_agent_name` string, nullable
  - `status` 'pending' | 'executing' | 'paused' | 'error' | 'failed' | 'completed' | 'stopped'
  - `internal_status` string, nullable
  - `last_executed_node_id` string, nullable
  - `agent_version` string, nullable
  - `created_at` string, date-time, required
  - `started_at` string, date-time, nullable
  - `paused_at` string, date-time, nullable
  - `finished_at` string, date-time, nullable
  - `result` string, nullable
  - `parent_execution` string, nullable
  - `conversation_id` string, nullable
  - `sub_executions` string[], nullable
  - `finished_sub_executions` string[], nullable
  - `should_update_parent` boolean, nullable
  - `is_manually_stopped` boolean, nullable
  - `is_background` boolean, nullable
  - `payload_extension` object, nullable
  - `hitl_request` HumanInTheLoopRequest: Model representing human-in-the-loop approval records for tasks. Attributes: wait_node_id (str): The id of the node that triggered this HITL.
    - `wait_node_id` string, required
  - `pending_eca_request` PendingECARequest
    - `connector_name` string, required
    - `auth_url` string, required
  - `pending_tool_approvals` PendingToolApproval[], nullable: Tool calls held for a person's approval on this execution; each names the request id a decision route takes.
    - `request_id` string, required
    - `tool_name` string, required
    - `tool_label` string
    - `summary` string, nullable
    - `gate_reason` 'per_tool' | 'connector_mutating' | 'connector_read_only' | 'credential_policy' | 'gated_command' | 'elicitation'
    - `created_at` string, date-time, nullable
    - `expires_at` string, date-time, nullable
    - `kind` 'approval' | 'elicitation'
    - `message` string, nullable
    - `requested_schema` object, nullable
  - `source` string, nullable
  - `worker_id` string, nullable
  - `additional_context` string, nullable
  - `instructions_override` string, nullable
  - `expected_output` string, nullable
  - `engagement_instructions` string, nullable
  - `output_format_instructions` string, nullable
  - `test_run_node_id` string, nullable
  - `is_orchestration` boolean, nullable
  - `is_gateway` boolean, nullable
  - `conversation_kind` 'direct' | 'gateway': direct: the head row never runs a model turn, every message is one task on the agent; gateway: a router-era head.
  - `is_app` boolean, nullable
  - `is_desktop` boolean, nullable
  - `device_id` string, nullable
  - `desktop_user_id` string, nullable
  - `verified_user_transport` string, nullable
  - `sub_tasks_mode` 'sync' | 'async' | 'auto'
  - `output_format` 'text' | 'markdown' | 'json' | 'voice'
  - `voice_id` string, nullable
  - `output_schema` object, nullable
  - `events_streaming` boolean, nullable
  - `used_mutating_tools` boolean, nullable
  - `is_continuous` boolean, nullable
  - `mcp_servers` object[], nullable
  - `triggering_agent_id` string, nullable
  - `title` string, nullable
  - `think_mode` 'default' | 'harder'
  - `disable_attachment_injection` boolean, nullable
  - `deep_planning` DeepPlanning
    - `enabled` boolean, nullable
    - `enforce` boolean, nullable
    - `started` boolean, nullable
    - `question_raised` boolean, nullable
    - `tasks` DeepPlanningItem[], nullable
      - `id` string, required
      - `title` string, required
      - `description` string, nullable
      - `input` unknown
      - `output` unknown
      - `tool_name` string, nullable
      - `completed` boolean, nullable
  - `must_deep_plan` boolean, nullable
  - `short_summary` string, nullable
  - `execution_attempts` integer, nullable
  - `user_tokens` object, nullable
  - `user_oidc_token` string, nullable
  - `return_metrics` boolean, nullable
  - `tokens` LLMTokens
    - `completion_tokens` integer, nullable
    - `prompt_tokens` integer, nullable
    - `total_tokens` integer, nullable
    - `cache_read_tokens` integer, nullable
    - `cache_write_tokens` integer, nullable
  - `llm_model_provider` string, nullable: Snapshot of the LLM provider used for this execution (request override or agent default at run time).
  - `llm_model_name` string, nullable: Snapshot of the LLM model name used for this execution (request override or agent default at run time).
  - `llm_reasoning_effort` 'low' | 'medium' | 'high' | 'xhigh'
  - `execution_kind` 'turn' | 'resident': A turn ends when the CLI answers; a resident process stays Executing until the agent finishes it.
  - `harness_cli` 'claude-code' | 'codex' | 'opencode' | 'xpander': A CLI the harness container can run; chosen per conversation, never per agent.
  - `harness_cli_switches` HarnessCliSwitch[], nullable: Harness agents only: the conversation's CLI timeline, oldest first; the first entry is the CLI it started on, every later one a switch.
    - `cli` 'claude-code' | 'codex' | 'opencode' | 'xpander', required: A CLI the harness container can run; chosen per conversation, never per agent.
    - `at` string, date-time, required
  - `permission_mode` 'full' | 'gated'
  - `builtin_tools` object, nullable: Harness agents only: the resolved built-in tool sets this execution runs with, {"harness": {"enabled": bool}, "xpander": {"enabled": bool}}; inherited per half by later tasks of the conversation unless one names its own.
  - `tool_call_limit` integer, nullable: Max tool calls for this execution; unset leaves the agent's own ceiling in place.
  - `archived_at` string, date-time, nullable: When the conversation was archived; unset while it is live.
  - `archived_by` string, nullable: Who archived the conversation (user id), when it was.
  - `archived_by_agent_id` string, nullable: The agent that archived the conversation on its own, when one did; unset when a person archived it.
  - `deleted_at` string, date-time, nullable: When the user deleted the conversation; a deleted conversation never mirrors to history again and reads as not found.
  - `waiting_reason` string, nullable, required: Why a live resident process is waiting rather than working (`plan_limit`); None otherwise.
  - `resumes_at` string, date-time, nullable, required: When a waiting process resumes on its own (ISO), read from its booked wake; None otherwise.

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/xpander/apis/xpander-ai-api-service.md) - [All operations](https://skmtc.dev/xpander/apis/xpander-ai-api-service/llms.txt) - [OpenAPI document](https://skmtc.dev/xpander/apis/xpander-ai-api-service/revisions/4389ec0875d0?raw)
