---
title: "Get a workflow"
method: GET
path: "/hub/workflows/{collection_topic}/{flow_topic}"
tags: ["Workflows"]
---

# Get a workflow

`GET /hub/workflows/{collection_topic}/{flow_topic}`

## Request

- Base URL: `https://api.quiva.ai`
- URL: `https://api.quiva.ai/hub/workflows/{collection_topic}/{flow_topic}`
- Auth: one of:
  - HTTP bearer
  - API key in header `x-api-key`
- TypeScript: <https://skmtc.dev/quivaworks/apis/quiva-ai-gateway-3/docs/hub/workflows/:collection_topic/:flow_topic/get.ts> (a function with typed inputs; its response is checked against the schema)

Fetch a workflow’s full config (nodes, edges, static, result). Path segments are the last two parts of the workflow subject.

## Query parameters

- `draft` boolean

## Response `200`

Workflow retrieved successfully

- GetWorkflowResponse
  - `subject` string: Subject identifier for the workflow
  - `name` string: Name of the workflow
  - `description` string: Description of the workflow
  - `config` WorkflowConfig: The execution graph. Must be acyclic (not server-checked). Nodes run in topological order; condition nodes can alter the path.
    - `nodes` NodeWorkflow[]
      - `id` string, required: Must equal data.id
      - `data` union, required: Node definition. id: unique, ^[a-zA-Z_][a-zA-Z0-9_:]*$, not a reserved word (trigger, static, RESOLVE_ERROR, RESOLVE_SUCCESS). payload is REQUIRED on every node type. Reference a node's output downstream via $.{id}.
        - TriggerNodeData: Entry-point metadata for the visual editor. SKIPPED at runtime — optional; run input arrives via the run request 'trigger' field ($.trigger), not through this node.
          - `id` string, required
          - `name` string
          - `description` string
          - `node_type` 'trigger', required
          - `trigger_type` 'manual' | 'schedule' | 'webhook' | 'gateway' | 'embed' | 'email' | 'object-store' | 'record' | 'task' | 'email-delivery' | 'mail': How the flow starts. `email-delivery` fires on delivery events of emails sent from templates. `mail` fires from a Microsoft 365 mail automation with the filed email, its attachment files riding as knowledge. `task` starts from a task event.
          - `payload` object, required: Config varies by `trigger_type`; `{}` for manual. For `email-delivery`: `event_type` (array of `bounce`, `blocked`, `dropped`, `undeliverable`, `deferred`, and other delivery events; default is bounce, blocked, dropped and undeliverable, `deferred` is left out because it is usually temporary), `class` (only emails of this class) and `template_key` (only emails sent from this template). For `task`: `space_id`, `event_type`, `folder`, `status`, `status_from`, `status_to`, `allow_self_trigger`. The trigger data reaches the flow at `$.trigger`.
        - AgentNodeData: Invoke an LLM agent. The inline definition MUST be nested under payload.agent — flat payloads (api_key/llm_provider/model at payload top level) are silently dropped at runtime and the node fails with 'a subject, node_subject or agent property is required'. IMPORTANT: the node output at $.{id}.result is a JSON-ENCODED STRING even when output_schema is set — add an eval node to JSON.parse it before branching on its fields.
          - `id` string, required
          - `name` string
          - `description` string
          - `node_type` 'agent', required
          - `payload` object, required: One of 'agent' (inline definition), 'subject' (saved agent subject) or 'node_subject' (agent node template) is required. prompt/await live at this level, NOT inside agent.
            - `agent` object
              - …
            - `subject` string: Saved agent subject (alternative to inline 'agent')
            - `node_subject` string: Agent node template subject (alternative to inline 'agent')
            - `prompt` union: string or object; supports JSONPath, e.g. 'Summarise |$.trigger.text'. Empty = the raw trigger is used as the prompt.
              - …
            - `await` boolean
            - `knowledge` string[]
        - FunctionNodeData: Invoke a compute function. subject is REQUIRED and must exist — discover via GET /compute/functions.
          - `id` string, required
          - `name` string
          - `description` string
          - `node_type` 'function', required
          - `subject` string, required
          - `payload` unknown, required
          - `response_map` unknown
          - `options` NodeOptions: Execution options for function/flow/integration/http nodes
            - `flat_map` boolean: Flatten array results
            - `backoff_ms` integer: Delay between retries (ms)
            - `timeout` integer: ms
            - `attempts` integer: Retry attempts on failure
            - `ignore_response_codes` integer[]: HTTP status codes treated as success
        - IntegrationNodeData: HTTP request to a third-party API, optionally via an OAuth connection. Result shape: { status, statusText, headers, data }. 4xx/5xx responses become node errors (tolerate/retry via options).
          - `id` string, required
          - `name` string
          - `description` string
          - `node_type` 'integration', required
          - `integration_id` string: e.g. 'slack'
          - `request_type_id` string: e.g. 'post_chat_postMessage'
          - `oauth` string: OAuth connection identifier
          - `payload` HttpPayload, required: JSONPath supported in all fields. IMPORTANT: the base URL key is snake_case 'base_url' — a 'baseURL' key is silently ignored.
            - `base_url` string: Joined with url; snake_case, NOT baseURL
            - `url` string, required: Path or full URL
            - `method` string, required: GET/POST/PUT/DELETE/PATCH... (case-insensitive)
            - `data` object: Request body
            - `params` object
            - `query` object
            - `headers` object
            - `timeout` integer: ms (default 30000)
          - `options` NodeOptions: Execution options for function/flow/integration/http nodes
            - `flat_map` boolean: Flatten array results
            - `backoff_ms` integer: Delay between retries (ms)
            - `timeout` integer: ms
            - `attempts` integer: Retry attempts on failure
            - `ignore_response_codes` integer[]: HTTP status codes treated as success
        - HttpNodeData: Plain HTTP request (no OAuth metadata). Same payload and behaviour as integration.
          - `id` string, required
          - `name` string
          - `description` string
          - `node_type` 'http', required
          - `payload` HttpPayload, required: JSONPath supported in all fields. IMPORTANT: the base URL key is snake_case 'base_url' — a 'baseURL' key is silently ignored.
            - `base_url` string: Joined with url; snake_case, NOT baseURL
            - `url` string, required: Path or full URL
            - `method` string, required: GET/POST/PUT/DELETE/PATCH... (case-insensitive)
            - `data` object: Request body
            - `params` object
            - `query` object
            - `headers` object
            - `timeout` integer: ms (default 30000)
          - `options` NodeOptions: Execution options for function/flow/integration/http nodes
            - `flat_map` boolean: Flatten array results
            - `backoff_ms` integer: Delay between retries (ms)
            - `timeout` integer: ms
            - `attempts` integer: Retry attempts on failure
            - `ignore_response_codes` integer[]: HTTP status codes treated as success
        - FlowNodeData: Invoke another published workflow as a sub-flow. subject is REQUIRED and must exist.
          - `id` string, required
          - `name` string
          - `description` string
          - `node_type` 'flow', required
          - `subject` string, required: Sub-workflow subject: ms.hub.config.workflow.{collection}.{flow} (published form, no 'published' segment); must exist
          - `payload` unknown, required
          - `await` boolean: Wait for sub-flow completion
          - `response_map` unknown
          - `options` NodeOptions: Execution options for function/flow/integration/http nodes
            - `flat_map` boolean: Flatten array results
            - `backoff_ms` integer: Delay between retries (ms)
            - `timeout` integer: ms
            - `attempts` integer: Retry attempts on failure
            - `ignore_response_codes` integer[]: HTTP status codes treated as success
        - EvalNodeData: Run a JavaScript expression over named params.
          - `id` string, required
          - `name` string
          - `description` string
          - `node_type` 'eval', required
          - `payload` object, required
            - `code` string, required: Plain JavaScript expression — JSONPath is NOT resolved inside code
            - `params` object, required: Named params usable in code; each VALUE is JSONPath-resolved, e.g. { "c": "$.AGENT.result" }
          - `options` NodeOptions: Execution options for function/flow/integration/http nodes
            - `flat_map` boolean: Flatten array results
            - `backoff_ms` integer: Delay between retries (ms)
            - `timeout` integer: ms
            - `attempts` integer: Retry attempts on failure
            - `ignore_response_codes` integer[]: HTTP status codes treated as success
        - ConditionNodeData: Branching. Evaluates rules and activates the listed node ids; non-selected branches are skipped. Reserved targets: RESOLVE_SUCCESS (end flow ok), RESOLVE_ERROR (fail flow). Any other target must be an existing node id, and you should also add edges from this node to each then/else target.
          - `id` string, required
          - `name` string
          - `description` string
          - `node_type` 'condition', required
          - `payload` object, required
            - `rules` object[]
              - …
        - RulesNodeData: Evaluate a rules object against facts/context; output is { <ruleKey>: outcome }.
          - `id` string, required
          - `name` string
          - `description` string
          - `node_type` 'rules', required
          - `payload` object, required
            - `rules` object, required: Rules map (same engine as condition nodes)
            - `facts` object
            - `context` object
        - MapNodeData: Reshape data: the payload template is JSONPath-resolved and becomes the node output.
          - `id` string, required
          - `name` string
          - `description` string
          - `node_type` 'map', required
          - `payload` union, required: Object or array template; string values may be JSONPath references
            - object
            - unknown[]
              - …
          - `options` object
            - `flat_map` boolean: Flatten array results
        - StaticNodeData: Merge literal values into $.static. LITERALS ONLY — JSONPath is not resolved in this payload.
          - `id` string, required
          - `name` string
          - `description` string
          - `node_type` 'static', required
          - `payload` object, required
        - DelayNodeData: Pause the branch for time_ms milliseconds. The node type is 'delay' — 'wait' is NOT a valid type (the engine silently ignores it).
          - `id` string, required
          - `name` string
          - `description` string
          - `node_type` 'delay', required
          - `payload` object, required
            - `time_ms` integer, required: Milliseconds; supports JSONPath
        - ScheduleNodeData: Schedule another workflow run for later.
          - `id` string, required
          - `name` string
          - `description` string
          - `node_type` 'schedule', required
          - `payload` object, required
            - `flow_subject` string, required: Workflow subject to schedule; supports JSONPath
            - `trigger` unknown, required
            - `trigger_in` string: Relative delay, e.g. '5m', '1h', '2d'
            - `trigger_on` string: Cron expression or ISO date
        - InputNodeData: Pause the flow for human input: creates an escalation task (emailing assignees) and pauses. Resume via runWorkflow with the run_id and the human response as trigger — that response becomes this node's output.
          - `id` string, required
          - `name` string
          - `description` string
          - `node_type` 'input', required
          - `payload` EscalationPayload, required
            - `message` string, required: Prompt for the human; supports JSONPath
            - `title` string: Escalation task title
            - `description` string
            - `priority` string
            - `assignees` string: Comma-separated user ids; each is notified by email
            - `fields` union: A JSON Schema (type `object` with `properties`) or a `$.` reference to one. With it the hub writes one `flow_input` action on the task and the task's assignees answer it as a form. Submitting resumes the run with the values at `$.resume`, marks the action done and posts the answer as a task comment. Without `fields` the run pauses as before and is resumed from Monitor.
              - …
            - `task_id` string: Ask on this existing task instead of raising a new one.
            - `keep_status` boolean: Leaves the form action out of the task's status automation.
        - HumanInTheLoopNodeData: Alias of 'input': pause for human approval/input via an escalation task.
          - `id` string, required
          - `name` string
          - `description` string
          - `node_type` 'human-in-the-loop', required
          - `payload` EscalationPayload, required
            - `message` string, required: Prompt for the human; supports JSONPath
            - `title` string: Escalation task title
            - `description` string
            - `priority` string
            - `assignees` string: Comma-separated user ids; each is notified by email
            - `fields` union: A JSON Schema (type `object` with `properties`) or a `$.` reference to one. With it the hub writes one `flow_input` action on the task and the task's assignees answer it as a form. Submitting resumes the run with the values at `$.resume`, marks the action done and posts the answer as a task comment. Without `fields` the run pauses as before and is resumed from Monitor.
              - …
            - `task_id` string: Ask on this existing task instead of raising a new one.
            - `keep_status` boolean: Leaves the form action out of the task's status automation.
        - QuivaEndpointNodeData: Invoke a Quiva endpoint. subject is REQUIRED — discover via GET /hub/quiva-endpoints.
          - `id` string, required
          - `name` string
          - `description` string
          - `node_type` 'quiva-endpoint', required
          - `subject` string, required
          - `payload` unknown, required
        - ErrorNodeData: Terminate the flow with an error status code and message.
          - `id` string, required
          - `name` string
          - `description` string
          - `node_type` 'error', required
          - `payload` object, required
            - `status_code` integer, required
            - `message` string
      - `position` object: Optional visual editor position { x, y }
    - `edges` Edge[]
      - `id` string, required
      - `source` string, required: Source node id
      - `target` string, required: Target node id
    - `static` object: Static variables accessible via $.static
    - `result` string: JSONPath selecting the run's return value, e.g. '$.FINAL_NODE.result'. Without it the run returns the full step log array.
    - `options` object
      - `run_type` 'normal' | 'debounced' | 'ordered'
      - `order_on` string: JSONPath key for run_type=ordered
      - `debounce_on` string: JSONPath key for run_type=debounced
      - `debounce_time` integer: ms
      - `debounce_max` integer: ms
  - `modified` integer: Timestamp of last modification

## Other responses

- `400`: Bad request

## Changes

- **2026-11-12** `8730377687f9`: 2 breaking, 13 warning, 4 info
  - added `#/components/schemas/TriggerNodeData, #/components/schemas/AgentNodeData, #/components/schemas/FunctionNodeData, #/components/schemas/IntegrationNodeData, #/components/schemas/HttpNodeData, #/components/schemas/FlowNodeData, #/components/schemas/EvalNodeData, #/components/schemas/ConditionNodeData, #/components/schemas/RulesNodeData, #/components/schemas/MapNodeData, #/components/schemas/StaticNodeData, #/components/schemas/DelayNodeData, #/components/schemas/ScheduleNodeData, #/components/schemas/InputNodeData, #/components/schemas/HumanInTheLoopNodeData, #/components/schemas/QuivaEndpointNodeData, #/components/schemas/ErrorNodeData` to the `config/nodes/items/data` response property `oneOf` list for the response status `200`
  - the `config/nodes/items/data` response's property type changed from `object` to no type for status `200`
  - removed the optional property `config/edges/items/sourceHandle` from the response with the `200` status
  - removed the optional property `config/edges/items/targetHandle` from the response with the `200` status
  - …15 more
- …earlier changes not shown

[Operation history](https://skmtc.dev/quivaworks/apis/quiva-ai-gateway-3/changes/hub/workflows/:collection_topic/:flow_topic/get.md)

---

[API](https://skmtc.dev/quivaworks/apis/quiva-ai-gateway-3.md) - [All operations](https://skmtc.dev/quivaworks/apis/quiva-ai-gateway-3/llms.txt) - [OpenAPI document](https://skmtc.dev/quivaworks/apis/quiva-ai-gateway-3/revisions/f80cd5f3ac1c?raw)
