---
title: "Get Super Node Interface"
method: GET
path: "/workflows/v1/super-nodes/{workflow_id}"
tags: ["Super Nodes"]
---

# Get Super Node Interface

`GET /workflows/v1/super-nodes/{workflow_id}`

Return the full super node definition for a workflow version.

If version_number is omitted, resolves to the workflow's active_version_number.
The response includes the stored hydrated snapshot captured at publish time —
no live DB re-fetch of the workflow is required.

## Path parameters

- `workflow_id` string, required

## Query parameters

- `version_number` integer, nullable

## Response `200`

Successful Response

- SuperNodeDetail — Full super node definition returned to callers who want to embed the super node. Contains the interface definition and a fresh hydrated snapshot of the sub-workflow config. Callers should store both in the SuperNodeConfig node they create in the parent workflow so the expander can run without a DB lookup at execution time.
  - `workflow_id` string, required
  - `workflow_version_number` integer, nullable
  - `name` string, nullable
  - `description` string, nullable
  - `super_node_interface` SuperNodeInterface — The interface definition of a super node. Describes what configuration fields callers must provide when instantiating this super node, and how those field values map into the encapsulated sub-workflow's nodes, edges, and dynamic variables.
    - `input_fields` SuperNodeInputField[] — List of input fields exposed by this super node to calling workflows
      - `name` string, required — Unique key for this field within the super node interface. Callers set field_values[name] = value.
      - `description` string, nullable — Human-readable description of what this field controls
      - `required` boolean — Whether this field must be provided by callers. If False and not provided, default_value is used.
      - `default_value` unknown
      - `json_schema` object, nullable — JSON Schema for this field, used by the UI to render and validate the config form
      - `mappings` SuperNodeFieldMapping[] — Where and how to inject the provided value into the sub-workflow (node/edge config fields or dynamic variables)
        - `target_type` 'node_config_field' | 'dynamic_variable' | 'edge_config_field' | 'workflow_config_field' | 'runtime_variable', required
        - `target_node_or_edge_logical_id` string, nullable — Logical ID of the node or edge in the sub-workflow whose config field should be set. Required when target_type is 'node_config_field' or 'edge_config_field'.
        - `target_field_path` string, nullable — Dot-separated path to the target field. For 'node_config_field': path within the target node's config, e.g. 'main_response_config.prompt'. For 'edge_config_field': path within the target edge's config, e.g. 'condition.condition_string'. For 'workflow_config_field': path within the sub-workflow's WorkflowConfig, e.g. 'default_prompt_prefix'. Required when target_type is 'node_config_field', 'edge_config_field', or 'workflow_config_field'.
        - `target_variable_name` string, nullable — Name of the variable to set. For 'dynamic_variable': sets a {{var}} dynamic variable, e.g. 'patient_name'. For 'runtime_variable': injects into the sub-workflow's runtime_variables dict. Required when target_type is 'dynamic_variable' or 'runtime_variable'.
      - `value_type` 'string' | 'integer' | 'number' | 'boolean' | 'object' | 'array' | 'enum' | 'any' — Declared shape of a super node input field's leaf value. Used at parent-workflow publish time to validate ``SuperNodeConfig.field_values`` against the interface declared by the sub-workflow.
      - `enum_values` unknown[], nullable — Required when value_type='enum'. Caller's value must be in this list.
        - unknown
      - `min_value` number, nullable — Inclusive lower bound for integer/number value types.
      - `max_value` number, nullable — Inclusive upper bound for integer/number value types.
      - `min_length` integer, nullable — Inclusive lower length for string/array value types.
      - `max_length` integer, nullable — Inclusive upper length for string/array value types.
  - `encapsulated_workflow_config` WorkflowConfigFullyHydratedOutput
    - `workflow_config` WorkflowConfigOutput
      - `logical_id` string, nullable — Unique identifier for the workflow
      - `name` string, nullable — Name of the workflow
      - `description` string, nullable — Description of the workflow
      - `category` string, nullable — Category of the workflow (e.g. 'User Created', 'System Examples', 'System Internal')
      - `attachable_llm_config_id` string, nullable — ID of the named LLM Configuration to use. If provided, overrides inline configuration.
      - `llms_config` union — Workflow level configuration for LLM based nodes used in the workflow. This will be used if no specific LLM configuration is provided for a node
        - AzureOpenAILLMConfigOutput
          - `logical_id` string, nullable — Unique identifier for the LLM configuration
          - `named_llm_config_id` string, nullable — If this configuration was resolved from a reusable named LLM configuration, this holds its ID.
          - `named_llm_config_name` string, nullable — If this configuration was resolved from a reusable named LLM configuration, this holds its name.
          - `provider` 'default_provider' | 'azure_openai' | 'openai' | 'google' | 'anthropic' | 'bedrock' | 'custom', nullable — The selected Large Language Model provider from the available options.
          - `streaming` boolean — Whether to enable streaming for the LLM response.
          - `max_retries` integer, nullable — Maximum number of retries for the LLM request in case of failure.
          - `max_parse_retries` integer, nullable — Maximum number of times to re-invoke the LLM when a successful response cannot be parsed into the expected structured (JSON) output. Distinct from `max_retries`, which controls transport-level retries (network errors, rate limits, 5xx) inside the LLM client.
          - `max_tokens` integer, nullable — Maximum number of tokens to generate in the response.
          - `temperature` number, nullable — Controls the randomness of the model's output. Lower values make the output more deterministic.
          - `request_timeout_ms` integer, nullable — Timeout for the request in milliseconds.
          - `seed` integer, nullable — Seed for random number generation to ensure reproducibility.
          - `model_kwargs` object — Additional keyword arguments to pass to the LLM provider's API.
          - `api_key` string, nullable — API key to access the LLM provider endpoint. Once saved, the key is stored securely and is never shown back in the UI. You can update it at any time by entering a new value; leaving it blank keeps the existing key in use for this LLM.
          - `do_not_split_sentences` boolean — Whether to avoid splitting sentences in the LLM response.
          - `truncated_max_recent_messages` integer, nullable — Maximum number of recent messages to keep when truncating the conversation history. If not set, no truncation is applied. If set, the recent conversation history will be truncated to contain only the specified number of messages when invoking the LLM for next response. If set to 0, only the system prompt is used.
          - `model` 'gpt-5-chat' | 'gpt-5-mini' | 'gpt-5-nano' | 'gpt-4.1-nano' | 'gpt-4.1-mini' | 'gpt-4.1'
          - `type` 'azure_openai_llm' — Differentiator field that helps in identifying this particular type of config when serializing and deserializing
          - `endpoint` string, nullable — Endpoint URL for Azure OpenAI API requests. Automatically inferred from env var `AZURE_OPENAI_ENDPOINT` if not provided.
          - `api_version` string, nullable — Azure OpenAI API version. Falls back to `OPENAI_API_VERSION` env var if not provided.
          - `reasoning_effort` string, nullable — Reasoning effort level for GPT-5-* models. Options are 'low', 'medium', 'high'.
        - OpenAILLMConfigOutput
          - `logical_id` string, nullable — Unique identifier for the LLM configuration
          - `named_llm_config_id` string, nullable — If this configuration was resolved from a reusable named LLM configuration, this holds its ID.
          - `named_llm_config_name` string, nullable — If this configuration was resolved from a reusable named LLM configuration, this holds its name.
          - `provider` 'default_provider' | 'azure_openai' | 'openai' | 'google' | 'anthropic' | 'bedrock' | 'custom', nullable — The selected Large Language Model provider from the available options.
          - `streaming` boolean — Whether to enable streaming for the LLM response.
          - `max_retries` integer, nullable — Maximum number of retries for the LLM request in case of failure.
          - `max_parse_retries` integer, nullable — Maximum number of times to re-invoke the LLM when a successful response cannot be parsed into the expected structured (JSON) output. Distinct from `max_retries`, which controls transport-level retries (network errors, rate limits, 5xx) inside the LLM client.
          - `max_tokens` integer, nullable — Maximum number of tokens to generate in the response.
          - `temperature` number, nullable — Controls the randomness of the model's output. Lower values make the output more deterministic.
          - `request_timeout_ms` integer, nullable — Timeout for the request in milliseconds.
          - `seed` integer, nullable — Seed for random number generation to ensure reproducibility.
          - `model_kwargs` object — Additional keyword arguments to pass to the LLM provider's API.
          - `api_key` string, nullable — API key to access the LLM provider endpoint. Once saved, the key is stored securely and is never shown back in the UI. You can update it at any time by entering a new value; leaving it blank keeps the existing key in use for this LLM.
          - `do_not_split_sentences` boolean — Whether to avoid splitting sentences in the LLM response.
          - `truncated_max_recent_messages` integer, nullable — Maximum number of recent messages to keep when truncating the conversation history. If not set, no truncation is applied. If set, the recent conversation history will be truncated to contain only the specified number of messages when invoking the LLM for next response. If set to 0, only the system prompt is used.
          - `model` 'gpt-5.4' | 'gpt-5.4-mini' | 'gpt-5.4-nano' | 'gpt-5.2' | 'gpt-5.1' | 'gpt-5-nano' | 'gpt-5-mini' | 'gpt-5' | 'gpt-5.4-pro' | 'gpt-5.2-pro' | 'gpt-5.2-chat-latest' | 'gpt-5.3-chat-latest' | 'gpt-4.1-nano' | 'gpt-4.1-mini' | 'gpt-4.1' | 'gpt-4' | 'gpt-4o-mini' | 'gpt-4o' | 'gpt-3.5-turbo'
          - `type` 'openai_llm' — Differentiator field that helps in identifying this particular type of config when serializing and deserializing
          - `base_url` string, nullable — Base URL path for OpenAI API requests, leave blank if not using a proxy or service emulator.
          - `organization` string, nullable — Organization ID for OpenAI API requests, Automatically inferred from env var `OPENAI_ORG_ID` if not provided.
          - `reasoning_effort` string, nullable — Reasoning effort level for GPT-5-* models. Options are 'minimal', 'low', 'medium', 'high'.
        - GoogleLLMConfigOutput
          - `logical_id` string, nullable — Unique identifier for the LLM configuration
          - `named_llm_config_id` string, nullable — If this configuration was resolved from a reusable named LLM configuration, this holds its ID.
          - `named_llm_config_name` string, nullable — If this configuration was resolved from a reusable named LLM configuration, this holds its name.
          - `provider` 'default_provider' | 'azure_openai' | 'openai' | 'google' | 'anthropic' | 'bedrock' | 'custom', nullable — The selected Large Language Model provider from the available options.
          - `streaming` boolean — Whether to enable streaming for the LLM response.
          - `max_retries` integer, nullable — Maximum number of retries for the LLM request in case of failure.
          - `max_parse_retries` integer, nullable — Maximum number of times to re-invoke the LLM when a successful response cannot be parsed into the expected structured (JSON) output. Distinct from `max_retries`, which controls transport-level retries (network errors, rate limits, 5xx) inside the LLM client.
          - `max_tokens` integer, nullable — Maximum number of tokens to generate in the response.
          - `temperature` number, nullable — Controls the randomness of the model's output. Lower values make the output more deterministic.
          - `request_timeout_ms` integer, nullable — Timeout for the request in milliseconds.
          - `seed` integer, nullable — Seed for random number generation to ensure reproducibility.
          - `model_kwargs` object — Additional keyword arguments to pass to the LLM provider's API.
          - `api_key` string, nullable — API key to access the LLM provider endpoint. Once saved, the key is stored securely and is never shown back in the UI. You can update it at any time by entering a new value; leaving it blank keeps the existing key in use for this LLM.
          - `do_not_split_sentences` boolean — Whether to avoid splitting sentences in the LLM response.
          - `truncated_max_recent_messages` integer, nullable — Maximum number of recent messages to keep when truncating the conversation history. If not set, no truncation is applied. If set, the recent conversation history will be truncated to contain only the specified number of messages when invoking the LLM for next response. If set to 0, only the system prompt is used.
          - `model` 'gemini-flash-latest' | 'gemini-flash-lite-latest' | 'gemini-3.6-flash' | 'gemini-3.1-pro-preview' | 'gemini-3.5-flash' | 'gemini-3.5-flash-lite' | 'gemini-3.1-flash-lite' | 'gemini-3-flash-preview' | 'gemini-2.5-pro' | 'gemini-2.5-flash' | 'gemini-2.5-flash-lite'
          - `type` 'google_llm' — Differentiator field that helps in identifying this particular type of config when serializing and deserializing
          - `thinking_budget` integer, nullable — Indicates the thinking budget in tokens. By default, it is set to 0.
        - AnthropicLLMConfigOutput
          - `logical_id` string, nullable — Unique identifier for the LLM configuration
          - `named_llm_config_id` string, nullable — If this configuration was resolved from a reusable named LLM configuration, this holds its ID.
          - `named_llm_config_name` string, nullable — If this configuration was resolved from a reusable named LLM configuration, this holds its name.
          - `provider` 'default_provider' | 'azure_openai' | 'openai' | 'google' | 'anthropic' | 'bedrock' | 'custom', nullable — The selected Large Language Model provider from the available options.
          - `streaming` boolean — Whether to enable streaming for the LLM response.
          - `max_retries` integer, nullable — Maximum number of retries for the LLM request in case of failure.
          - `max_parse_retries` integer, nullable — Maximum number of times to re-invoke the LLM when a successful response cannot be parsed into the expected structured (JSON) output. Distinct from `max_retries`, which controls transport-level retries (network errors, rate limits, 5xx) inside the LLM client.
          - `max_tokens` integer, nullable — Maximum number of tokens to generate in the response.
          - `temperature` number, nullable — Controls the randomness of the model's output. Lower values make the output more deterministic.
          - `request_timeout_ms` integer, nullable — Timeout for the request in milliseconds.
          - `seed` integer, nullable — Seed for random number generation to ensure reproducibility.
          - `model_kwargs` object — Additional keyword arguments to pass to the LLM provider's API.
          - `api_key` string, nullable — API key to access the LLM provider endpoint. Once saved, the key is stored securely and is never shown back in the UI. You can update it at any time by entering a new value; leaving it blank keeps the existing key in use for this LLM.
          - `do_not_split_sentences` boolean — Whether to avoid splitting sentences in the LLM response.
          - `truncated_max_recent_messages` integer, nullable — Maximum number of recent messages to keep when truncating the conversation history. If not set, no truncation is applied. If set, the recent conversation history will be truncated to contain only the specified number of messages when invoking the LLM for next response. If set to 0, only the system prompt is used.
          - `model` 'claude-opus-5' | 'claude-sonnet-5' | 'claude-fable-5' | 'claude-opus-4-8' | 'claude-opus-4-7' | 'claude-opus-4-6' | 'claude-opus-4-5-20251101' | 'claude-opus-4-1-20250805' | 'claude-sonnet-4-6' | 'claude-sonnet-4-5-20250929' | 'claude-haiku-4-5' | 'claude-haiku-4-5-20251001'
          - `type` 'anthropic_llm' — Differentiator field that helps in identifying this particular type of config when serializing and deserializing
          - `thinking_budget` integer, nullable — Token budget for Claude's extended thinking feature. Set to 0 to disable. When enabled, Claude will show its reasoning process before providing a final answer.
        - BedrockLLMConfigOutput
          - `logical_id` string, nullable — Unique identifier for the LLM configuration
          - `named_llm_config_id` string, nullable — If this configuration was resolved from a reusable named LLM configuration, this holds its ID.
          - `named_llm_config_name` string, nullable — If this configuration was resolved from a reusable named LLM configuration, this holds its name.
          - `provider` 'default_provider' | 'azure_openai' | 'openai' | 'google' | 'anthropic' | 'bedrock' | 'custom', nullable — The selected Large Language Model provider from the available options.
          - `streaming` boolean — Whether to enable streaming for the LLM response.
          - `max_retries` integer, nullable — Maximum number of retries for the LLM request in case of failure.
          - `max_parse_retries` integer, nullable — Maximum number of times to re-invoke the LLM when a successful response cannot be parsed into the expected structured (JSON) output. Distinct from `max_retries`, which controls transport-level retries (network errors, rate limits, 5xx) inside the LLM client.
          - `max_tokens` integer, nullable — Maximum number of tokens to generate in the response.
          - `temperature` number, nullable — Controls the randomness of the model's output. Lower values make the output more deterministic.
          - `request_timeout_ms` integer, nullable — Timeout for the request in milliseconds.
          - `seed` integer, nullable — Seed for random number generation to ensure reproducibility.
          - `model_kwargs` object — Additional keyword arguments to pass to the LLM provider's API.
          - `api_key` string, nullable — Amazon Bedrock long-term API key (bearer token). If set, it is used for authentication and the access-key fields below are ignored. Leave empty to authenticate with an access-key pair or the default AWS credential chain (IAM role).
          - `do_not_split_sentences` boolean — Whether to avoid splitting sentences in the LLM response.
          - `truncated_max_recent_messages` integer, nullable — Maximum number of recent messages to keep when truncating the conversation history. If not set, no truncation is applied. If set, the recent conversation history will be truncated to contain only the specified number of messages when invoking the LLM for next response. If set to 0, only the system prompt is used.
          - `model` 'zai.glm-5' | 'zai.glm-4.7' | 'zai.glm-4.7-flash' | 'moonshotai.kimi-k2.5' | 'moonshot.kimi-k2-thinking' | 'qwen.qwen3-vl-235b-a22b' | 'qwen.qwen3-32b-v1:0'
          - `type` 'bedrock_llm' — Differentiator field that helps in identifying this particular type of config when serializing and deserializing
          - `region` string, nullable — AWS region the Bedrock model is invoked in. Defaults to us-east-1 if not provided.
          - `aws_access_key_id` string, nullable — AWS access key ID for Bedrock. Leave empty to use the platform default (`BEDROCK_ACCESS_KEY` env var, then the AWS credential chain).
          - `aws_secret_access_key` string, nullable — AWS secret access key for Bedrock. Leave empty to use the platform default (`BEDROCK_SECRET_KEY` env var, then the AWS credential chain).
        - CustomLLMConfigOutput
          - `logical_id` string, nullable — Unique identifier for the LLM configuration
          - `named_llm_config_id` string, nullable — If this configuration was resolved from a reusable named LLM configuration, this holds its ID.
          - `named_llm_config_name` string, nullable — If this configuration was resolved from a reusable named LLM configuration, this holds its name.
          - `provider` 'default_provider' | 'azure_openai' | 'openai' | 'google' | 'anthropic' | 'bedrock' | 'custom', nullable — The selected Large Language Model provider from the available options.
          - `streaming` boolean — Whether to enable streaming for the LLM response.
          - `max_retries` integer, nullable — Maximum number of retries for the LLM request in case of failure.
          - `max_parse_retries` integer, nullable — Maximum number of times to re-invoke the LLM when a successful response cannot be parsed into the expected structured (JSON) output. Distinct from `max_retries`, which controls transport-level retries (network errors, rate limits, 5xx) inside the LLM client.
          - `max_tokens` integer, nullable — Maximum number of tokens to generate in the response.
          - `temperature` number, nullable — Controls the randomness of the model's output. Lower values make the output more deterministic.
          - `request_timeout_ms` integer, nullable — Timeout for the request in milliseconds.
          - `seed` integer, nullable — Seed for random number generation to ensure reproducibility.
          - `model_kwargs` object — Additional keyword arguments to pass to the LLM provider's API.
          - `api_key` string, nullable — API key to access the LLM provider endpoint. Once saved, the key is stored securely and is never shown back in the UI. You can update it at any time by entering a new value; leaving it blank keeps the existing key in use for this LLM.
          - `do_not_split_sentences` boolean — Whether to avoid splitting sentences in the LLM response.
          - `truncated_max_recent_messages` integer, nullable — Maximum number of recent messages to keep when truncating the conversation history. If not set, no truncation is applied. If set, the recent conversation history will be truncated to contain only the specified number of messages when invoking the LLM for next response. If set to 0, only the system prompt is used.
          - `model` string, nullable — Name of the model served behind the custom LLM gateway (free-form string, e.g. 'gpt-4.1-mini', 'llama-3-70b', 'mistral-large').
          - `reasoning_effort` string, nullable — Reasoning effort level for GPT-5-* models. Options are 'minimal', 'low', 'medium', 'high'.
          - `type` 'custom_llm' — Differentiator field that helps in identifying this particular type of config when serializing and deserializing
          - `base_url` string, nullable — Base URL of the custom OpenAI-compatible LLM gateway (e.g. 'http://api.interactly.ai/workflows/llm-proxy').
          - `default_headers` object, nullable — Optional HTTP headers to include in every request to the gateway (e.g. routing keys, tenant IDs).
          - `rewrite_base_url` boolean — When True, uses an httpx event hook to rewrite every request URL to the exact base_url. Use this for gateways that don't accept the /chat/completions suffix the SDK appends.
          - `verify_ssl` boolean — Whether to verify SSL certificates. Set to False for gateways with self-signed certificates.
          - `response_unwrap_key` string, nullable — When set, the gateway response JSON is expected to wrap the standard OpenAI response inside this key (e.g. 'result'). The runtime will extract the nested object before passing it to the OpenAI SDK. Leave empty for gateways that already return standard format.
          - `integration_auth` IntegrationAuthConfig — Configuration for integration-backed bearer-token authentication. Provider-agnostic: any integration that exposes an OAuth2 client-credentials token endpoint (Okta, Athena, ECW, ...) can be referenced here. The runtime only needs the integration ID – the integrations service resolves the provider and returns the bearer token.
            - `integration_id` string, nullable — ID of an integration to use for bearer-token authentication. When set, the runtime fetches a cached OAuth token from this integration and injects it as the Authorization header. Ignored when api_key or an Authorization default_header is already provided.
          - `use_responses_api` boolean — Whether to use the GPT 5.x+ style Responses API, instead of Chat Completions API for this Custom LLM. See https://developers.openai.com/api/reference/resources/responses
        - WorkflowDefaultLLMConfigOutput
          - `logical_id` string, nullable — Unique identifier for the LLM configuration
          - `named_llm_config_id` string, nullable — If this configuration was resolved from a reusable named LLM configuration, this holds its ID.
          - `named_llm_config_name` string, nullable — If this configuration was resolved from a reusable named LLM configuration, this holds its name.
          - `provider` 'default_provider' | 'azure_openai' | 'openai' | 'google' | 'anthropic' | 'bedrock' | 'custom', nullable — The selected Large Language Model provider from the available options.
          - `streaming` boolean — Whether to enable streaming for the LLM response.
          - `max_retries` integer, nullable — Maximum number of retries for the LLM request in case of failure.
          - `max_parse_retries` integer, nullable — Maximum number of times to re-invoke the LLM when a successful response cannot be parsed into the expected structured (JSON) output. Distinct from `max_retries`, which controls transport-level retries (network errors, rate limits, 5xx) inside the LLM client.
          - `max_tokens` integer, nullable — Maximum number of tokens to generate in the response.
          - `temperature` number, nullable — Controls the randomness of the model's output. Lower values make the output more deterministic.
          - `request_timeout_ms` integer, nullable — Timeout for the request in milliseconds.
          - `seed` integer, nullable — Seed for random number generation to ensure reproducibility.
          - `model_kwargs` object — Additional keyword arguments to pass to the LLM provider's API.
          - `api_key` string, nullable — API key to access the LLM provider endpoint. Once saved, the key is stored securely and is never shown back in the UI. You can update it at any time by entering a new value; leaving it blank keeps the existing key in use for this LLM.
          - `do_not_split_sentences` boolean — Whether to avoid splitting sentences in the LLM response.
          - `truncated_max_recent_messages` integer, nullable — Maximum number of recent messages to keep when truncating the conversation history. If not set, no truncation is applied. If set, the recent conversation history will be truncated to contain only the specified number of messages when invoking the LLM for next response. If set to 0, only the system prompt is used.
          - `type` 'global_default_llm' — Differentiator field that helps in identifying this particular type of config when serializing and deserializing
        - NoLLMConfigOutput
          - `logical_id` string, nullable — Unique identifier for the LLM configuration
          - `named_llm_config_id` string, nullable — If this configuration was resolved from a reusable named LLM configuration, this holds its ID.
          - `named_llm_config_name` string, nullable — If this configuration was resolved from a reusable named LLM configuration, this holds its name.
          - `provider` 'default_provider' | 'azure_openai' | 'openai' | 'google' | 'anthropic' | 'bedrock' | 'custom', nullable — The selected Large Language Model provider from the available options.
          - `streaming` boolean — Whether to enable streaming for the LLM response.
          - `max_retries` integer, nullable — Maximum number of retries for the LLM request in case of failure.
          - `max_parse_retries` integer, nullable — Maximum number of times to re-invoke the LLM when a successful response cannot be parsed into the expected structured (JSON) output. Distinct from `max_retries`, which controls transport-level retries (network errors, rate limits, 5xx) inside the LLM client.
          - `max_tokens` integer, nullable — Maximum number of tokens to generate in the response.
          - `temperature` number, nullable — Controls the randomness of the model's output. Lower values make the output more deterministic.
          - `request_timeout_ms` integer, nullable — Timeout for the request in milliseconds.
          - `seed` integer, nullable — Seed for random number generation to ensure reproducibility.
          - `model_kwargs` object — Additional keyword arguments to pass to the LLM provider's API.
          - `api_key` string, nullable — API key to access the LLM provider endpoint. Once saved, the key is stored securely and is never shown back in the UI. You can update it at any time by entering a new value; leaving it blank keeps the existing key in use for this LLM.
          - `do_not_split_sentences` boolean — Whether to avoid splitting sentences in the LLM response.
          - `truncated_max_recent_messages` integer, nullable — Maximum number of recent messages to keep when truncating the conversation history. If not set, no truncation is applied. If set, the recent conversation history will be truncated to contain only the specified number of messages when invoking the LLM for next response. If set to 0, only the system prompt is used.
          - `type` 'no_llm' — Differentiator field that helps in identifying this particular type of config when serializing and deserializing
        - LLMGroupConfigOutput
          - `type` 'llm_group' — Discriminator field which must always be 'llm_group'
          - `named_llm_config_id` string, nullable — If this configuration was resolved from a reusable named LLM configuration, this holds its ID.
          - `named_llm_config_name` string, nullable — If this configuration was resolved from a reusable named LLM configuration, this holds its name.
          - `logical_id` string, nullable — Unique identifier for the LLM Group
          - `llms` union[] — List of LLM configurations, in preferred order of use.
            - union
              - …
          - `operation_mode` 'parallel_select_one' | 'sequential_with_proactive'
          - `min_patience_time_ms` integer, nullable — Grace period in milliseconds until which we will unconditionally wait, unless all LLMs have responded.
          - `max_patience_time_ms` integer, nullable — Threshold milliseconds after which we will stop waiting. If no LLM has responded by this time, we will return None.
        - LLMGroupWithBackchannelConfigOutput
          - `type` 'llm_group_with_backchannel' — Discriminator field which must always be 'llm_group_with_backchannel'
          - `named_llm_config_id` string, nullable — If this configuration was resolved from a reusable named LLM configuration, this holds its ID.
          - `named_llm_config_name` string, nullable — If this configuration was resolved from a reusable named LLM configuration, this holds its name.
          - `id` string, nullable — Unique identifier for the LLM Group
          - `main_llm_config` LLMGroupConfigOutput
            - `type` 'llm_group' — Discriminator field which must always be 'llm_group'
            - `named_llm_config_id` string, nullable — If this configuration was resolved from a reusable named LLM configuration, this holds its ID.
            - `named_llm_config_name` string, nullable — If this configuration was resolved from a reusable named LLM configuration, this holds its name.
            - `logical_id` string, nullable — Unique identifier for the LLM Group
            - `llms` union[] — List of LLM configurations, in preferred order of use.
              - …
            - `operation_mode` 'parallel_select_one' | 'sequential_with_proactive'
            - `min_patience_time_ms` integer, nullable — Grace period in milliseconds until which we will unconditionally wait, unless all LLMs have responded.
            - `max_patience_time_ms` integer, nullable — Threshold milliseconds after which we will stop waiting. If no LLM has responded by this time, we will return None.
          - `non_backchannel_response_prefix` string, nullable — If back channel response is being sent, only the LLM output following this prefix will follow the backchannel response
          - `backchannel_llm_config` LLMGroupConfigOutput
            - `type` 'llm_group' — Discriminator field which must always be 'llm_group'
            - `named_llm_config_id` string, nullable — If this configuration was resolved from a reusable named LLM configuration, this holds its ID.
            - `named_llm_config_name` string, nullable — If this configuration was resolved from a reusable named LLM configuration, this holds its name.
            - `logical_id` string, nullable — Unique identifier for the LLM Group
            - `llms` union[] — List of LLM configurations, in preferred order of use.
              - …
            - `operation_mode` 'parallel_select_one' | 'sequential_with_proactive'
            - `min_patience_time_ms` integer, nullable — Grace period in milliseconds until which we will unconditionally wait, unless all LLMs have responded.
            - `max_patience_time_ms` integer, nullable — Threshold milliseconds after which we will stop waiting. If no LLM has responded by this time, we will return None.
          - `backchannel_static_responses` string[] — List of static responses from which one will be selected as a backchannel response.
          - `backchannel_static_responses_selection_mode` 'random' | 'sequence'
          - `backchannel_min_patience_time_ms` integer, nullable — Grace period in milliseconds until which we will unconditionally wait for the main LLM to respond, unless it has already responded.
      - `main_response_config` PromptConfig
        - `prompt` string, nullable — System prompt for the LLM
      - `backchannel_response_config` PromptConfig
        - `prompt` string, nullable — System prompt for the LLM
      - `default_prompt_prefix` string, nullable — If present, this string will be added as prefix to every node's system prompt
      - `default_prompt_suffix` string, nullable — If present, this string will be added as suffix to every node's system prompt
      - `ignore_content_received_during_llm_tool_call_specification` boolean — If true, every LLM node in this workflow behaves as if ignore_content_received_during_llm_tool_call_specification is true, and every tool behaves as if ignore_content_received_during_llm_tool_call_specification is true: free-text content the LLM returns in the same response as one or more tool calls is ignored and treated as empty.
      - `tools_config` ToolsConfig
        - `tools` union[] — List of tool configurations
          - union
            - InlinePythonToolConfig — Configuration for an inline Python tool. The "code" field should contain a self-contained executable Python function. Example value of "code" string could be: def add( a: float, b: float, ) -> float: return float(a + b)
              - …
            - InbuiltFunctionToolConfig — Configuration for an inbuilt function tool. This tool type refers to functions that are already registered in the tools registry. The "tool_id" field must match the ID (decorated with "@tool_id") of a registered tool.
              - …
            - ExternalAPIToolConfig — Configuration for an external API tool. This tool type represents an external API endpoint that the LLM can call.
              - …
            - KnowledgeBaseToolConfig — Configuration for a knowledge base tool. This tool type represents a knowledge base endpoint that the LLM can call.
              - …
      - `mcp_servers` MCPServerConfig[], nullable — List of MCP server connections. Tools discovered from these servers are available to nodes with use_mcp_tools enabled.
        - `name` string, nullable — Display name for this MCP server connection
        - `server_url` string, required — MCP server URL (e.g. 'https://mcp.example.com/mcp')
        - `api_headers` object, nullable — HTTP headers to include when connecting to the MCP server (e.g. {'Authorization': 'Bearer ...'})
      - `global_condition_evaluation_method` 'tool_call' | 'independent_llm_evaluations'
      - `nodes` string[] — List of node configurations in the workflow
      - `edges` string[] — List of edge configurations in the workflow
      - `evaluation_config` EvaluationConfigOutput
        - `evaluator_workflow_id` string, nullable — ID of the workflow to be used as the evaluator
        - `evaluator_workflow_version_number` integer, nullable — Version number of the evaluator workflow to be used. If not specified, the active version will be used.
        - `enable_turn_by_turn_evaluation` boolean — If true, enables turn-by-turn evaluation of the workflow execution
      - `guardrail_strikes_config` GuardrailStrikesConfig
        - `max_guardrail_nodes_before_escalation` integer, nullable — Maximum number of times guardrail nodes may be entered (from a non-guardrail node) before the workflow escalates. None disables the feature.
        - `escalation_node_logical_id` string, nullable — Logical ID of the node to transition to when the escalation threshold is reached. If None (or it does not resolve to a node), the workflow finishes instead.
        - `escalation_message` string, nullable — Message sent to the user just before the workflow finishes when the escalation threshold is reached and no escalation node is configured. Supports dynamic/runtime variable templating. If None, the workflow finishes silently.
      - `miscellaneous` object — Miscellaneous config data that can be used by the workflow
      - `access_config` object, nullable — Access control configuration for the workflow
        - `access_level` 'personal' | 'team' | 'system' — Enum representing different access control levels.
        - `access_list` string[], nullable — List of user IDs that have access to this workflow
    - `node_configs` union[] — List of node configurations for runtime
      - union
        - WorkerLLMNodeConfigOutput
          - `logical_id` string, nullable — Unique identifier for the node
          - `name` string, nullable — Name of the node
          - `description` string, nullable — Description of the node
          - `workflow_id` string, nullable — The DB Object ID of the workflow this entity belongs to
          - `version_number` integer, nullable — Version number of the workflow this entity belongs to. 0 is the initial version (default).
          - `disabled` boolean — If true, this entity will be disabled and will not execute its function. Useful for testing workflows without actually executing this specific entity
          - `miscellaneous` object — Miscellaneous config data that can be used by the entity
          - `primary_category` string, nullable — Primary category of the node
          - `secondary_category` string, nullable — Secondary category of the node
          - `is_start` boolean — Whether this node is the starting node of the workflow
          - `is_guardrail_node` boolean — Whether this node is a guardrail node. When the workflow-level `miscellaneous.no_hopping_between_guardrail_nodes` setting is enabled (the default), the runtime blocks conditional transitions from this guardrail node to any other guardrail node — including regular freeform/expression conditional edges and synthesized global-node edges. Self-edges and self-loops on the same guardrail node remain allowed.
          - `global_node_config` object, nullable — Configuration for when this node is a global node
            - `is_global` boolean — Whether this node is a global node available as a conditional pathway to all nodes in the workflow
            - `condition` ConditionConfig
              - …
            - `global_condition_edge_evaluation_method` 'workflow_default' | 'tool_call' | 'independent_llm_evaluations'
            - `reverse_conditional_edge` ConditionConfig
              - …
          - `self_loop_config` object, nullable — Bounded self-loop / retry policy for a node. When ``enabled``, the node re-executes its functionality repeatedly until ONE of the following happens, whichever comes first: 1. an outgoing conditional edge matches (the loop's exit), or 2. ``max_retries`` re-executions have been performed, or 3. the ``expiry_time`` wall-clock budget for the whole loop elapses. Outgoing conditional edges are re-evaluated after every execution to decide whether to exit (take a matching edge) or run again. When the loop stops without a matching exit edge, the runtime publishes a ``self_loop_outcome`` runtime variable (``"max_retries"`` | ``"expiry_time"``) that authors can branch on with a dedicated "exhausted"/"timeout" conditional edge. This is distinct from the LLM-node ``self_loop: bool`` flag, which governs loop-back while waiting for the next user message and is unaffected by this config.
            - `enabled` boolean — Re-execute this node until a conditional edge matches, max_retries is reached, or expiry_time elapses (whichever comes first).
            - `max_retries` integer, nullable — Maximum number of re-executions after the first attempt (total attempts = max_retries + 1). Leave empty for no bound by count.
            - `expiry_time` integer, nullable — Overall wall-clock budget in seconds for the whole self-loop. An execution still running when this elapses is terminated. Leave empty for no time bound. Note: a CPU-bound inline-Python body with no await points cannot be interrupted mid-execution; expiry reliably bounds I/O-bound work.
            - `time_between_retries` integer — Seconds to wait between the end of one execution and the start of the next.
          - `main_response_config` object, nullable — Main response configuration. Contains either a LLM system prompt or exact static messages
            - `prompt` string, nullable — System prompt for the LLM
          - `attachable_llm_config_id` string, nullable — ID of the named LLM Configuration to use. If provided, overrides inline configuration.
          - `llms_config` union — LLM or a group of LLMs to be used in this node
            - AzureOpenAILLMConfigOutput
              - …
            - OpenAILLMConfigOutput
              - …
            - GoogleLLMConfigOutput
              - …
            - AnthropicLLMConfigOutput
              - …
            - BedrockLLMConfigOutput
              - …
            - CustomLLMConfigOutput
              - …
            - WorkflowDefaultLLMConfigOutput
              - …
            - NoLLMConfigOutput
              - …
            - LLMGroupConfigOutput
              - …
            - LLMGroupWithBackchannelConfigOutput
              - …
          - `tools_config` ToolsConfig
            - `tools` union[] — List of tool configurations
              - …
          - `self_loop` boolean — Whether this node will execute again if not transitioned to another node
          - `wait_for_user_message` boolean — Whether the node should wait for a user message before processing
          - `max_consecutive_tool_calls` integer — Maximum number of consecutive tool calls allowed in a single node execution
          - `default_error_message` string, nullable — Default error message to be returned if the LLM invocation fails
          - `use_mcp_tools` boolean — Whether this node should use tools discovered from workflow-level MCP server connections
          - `ignore_default_prompt_prefix` boolean — If true, the workflow's default_prompt_prefix will not be prepended to this node's prompt.
          - `ignore_default_prompt_suffix` boolean — If true, the workflow's default_prompt_suffix will not be appended to this node's prompt.
          - `ignore_content_received_during_llm_tool_call_specification` boolean — If true, any free-text content this node's LLM returns in the same response as one or more tool calls is ignored: not emitted via AssistantResponseEvent, not added to chat history, and not added to the node's structured output. Implies the tool-level flag for every tool call this node makes.
          - `realtime_overrides` NodeRealtimeOverrides — Per-node realtime settings, applied only while this node is the active one. Everything here is optional and ``None`` means "inherit from the workflow" (D1) — nothing here turns realtime on or off. ``transcription_keywords`` is the field worth knowing about: the classic path has no equivalent. Because the realtime session is re-primed at every node transition, a node that collects a member ID can bias speech recognition toward plan names and digit words *for the span of that node only*, and stop biasing the moment the conversation moves on. That is a quality gain over the classic path, not merely parity with it. A ``verbatim`` flag was designed here and dropped by D2: edge messages are spoken in the model's own words. If exact wording is ever required (a compliance disclosure), §6.4 option 2 is where it goes.
            - `reasoning_effort` string, nullable — Reasoning effort while this node is active — one of minimal, low, medium, high, xhigh. Leave empty to inherit the workflow default. Worth raising on a node that has to choose between several similar-sounding paths; costly to raise everywhere.
            - `voice` string, nullable — Voice for this node only. Rarely useful: changing voice mid-conversation is jarring to a caller, who hears it as being handed to a different person.
            - `preamble_mode` string, nullable — Whether the model may speak a short filler line before a slow answer while this node is active. Leave empty to inherit.
            - `transcription_keywords` string[] — Terms to bias speech recognition toward while this node is active — added to the workflow-wide list rather than replacing it. Use for the identifiers a node actually asks for: plan names, member ID formats, provider names.
            - `turn_detection` object, nullable — Override end-of-speech detection for this node, e.g. to wait longer while a caller reads out a long number. Leave empty to inherit the session default.
          - `type` 'worker_llm' — Type of the node. Must be 'worker_llm'
          - `structured_output_schema` object, nullable — Schema for the structured output of the worker node. Example: { "name": "SearchQuery", "description": "A search query with justification", "input_schema": { "title": "AnswerWithJustification", "type": "object", "properties": { "search_query": { "title": "Search Query", "type": "string", "description": "The field where search query is stored" }, "justification": { "title": "Justification", "type": "string", "description": "The field where justification string is stored" } }, "required": ["search_query", "justification"] } }
          - `backchannel_response_config` PromptConfig
            - `prompt` string, nullable — System prompt for the LLM
        - SayLLMNodeConfigOutput
          - `logical_id` string, nullable — Unique identifier for the node
          - `name` string, nullable — Name of the node
          - `description` string, nullable — Description of the node
          - `workflow_id` string, nullable — The DB Object ID of the workflow this entity belongs to
          - `version_number` integer, nullable — Version number of the workflow this entity belongs to. 0 is the initial version (default).
          - `disabled` boolean — If true, this entity will be disabled and will not execute its function. Useful for testing workflows without actually executing this specific entity
          - `miscellaneous` object — Miscellaneous config data that can be used by the entity
          - `primary_category` string, nullable — Primary category of the node
          - `secondary_category` string, nullable — Secondary category of the node
          - `is_start` boolean — Whether this node is the starting node of the workflow
          - `is_guardrail_node` boolean — Whether this node is a guardrail node. When the workflow-level `miscellaneous.no_hopping_between_guardrail_nodes` setting is enabled (the default), the runtime blocks conditional transitions from this guardrail node to any other guardrail node — including regular freeform/expression conditional edges and synthesized global-node edges. Self-edges and self-loops on the same guardrail node remain allowed.
          - `global_node_config` object, nullable — Configuration for when this node is a global node
            - `is_global` boolean — Whether this node is a global node available as a conditional pathway to all nodes in the workflow
            - `condition` ConditionConfig
              - …
            - `global_condition_edge_evaluation_method` 'workflow_default' | 'tool_call' | 'independent_llm_evaluations'
            - `reverse_conditional_edge` ConditionConfig
              - …
          - `self_loop_config` object, nullable — Bounded self-loop / retry policy for a node. When ``enabled``, the node re-executes its functionality repeatedly until ONE of the following happens, whichever comes first: 1. an outgoing conditional edge matches (the loop's exit), or 2. ``max_retries`` re-executions have been performed, or 3. the ``expiry_time`` wall-clock budget for the whole loop elapses. Outgoing conditional edges are re-evaluated after every execution to decide whether to exit (take a matching edge) or run again. When the loop stops without a matching exit edge, the runtime publishes a ``self_loop_outcome`` runtime variable (``"max_retries"`` | ``"expiry_time"``) that authors can branch on with a dedicated "exhausted"/"timeout" conditional edge. This is distinct from the LLM-node ``self_loop: bool`` flag, which governs loop-back while waiting for the next user message and is unaffected by this config.
            - `enabled` boolean — Re-execute this node until a conditional edge matches, max_retries is reached, or expiry_time elapses (whichever comes first).
            - `max_retries` integer, nullable — Maximum number of re-executions after the first attempt (total attempts = max_retries + 1). Leave empty for no bound by count.
            - `expiry_time` integer, nullable — Overall wall-clock budget in seconds for the whole self-loop. An execution still running when this elapses is terminated. Leave empty for no time bound. Note: a CPU-bound inline-Python body with no await points cannot be interrupted mid-execution; expiry reliably bounds I/O-bound work.
            - `time_between_retries` integer — Seconds to wait between the end of one execution and the start of the next.
          - `main_response_config` object, nullable — Main response configuration. Contains either a LLM system prompt or exact static messages
            - `prompt` string, nullable — System prompt for the LLM
          - `attachable_llm_config_id` string, nullable — ID of the named LLM Configuration to use. If provided, overrides inline configuration.
          - `llms_config` union — LLM or a group of LLMs to be used in this node
            - AzureOpenAILLMConfigOutput
              - …
            - OpenAILLMConfigOutput
              - …
            - GoogleLLMConfigOutput
              - …
            - AnthropicLLMConfigOutput
              - …
            - BedrockLLMConfigOutput
              - …
            - CustomLLMConfigOutput
              - …
            - WorkflowDefaultLLMConfigOutput
              - …
            - NoLLMConfigOutput
              - …
            - LLMGroupConfigOutput
              - …
            - LLMGroupWithBackchannelConfigOutput
              - …
          - `tools_config` ToolsConfig
            - `tools` union[] — List of tool configurations
              - …
          - `self_loop` boolean — Whether this node will execute again if not transitioned to another node
          - `wait_for_user_message` boolean — Whether the node should wait for a user message before processing
          - `max_consecutive_tool_calls` integer — Maximum number of consecutive tool calls allowed in a single node execution
          - `default_error_message` string, nullable — Default error message to be returned if the LLM invocation fails
          - `use_mcp_tools` boolean — Whether this node should use tools discovered from workflow-level MCP server connections
          - `ignore_default_prompt_prefix` boolean — If true, the workflow's default_prompt_prefix will not be prepended to this node's prompt.
          - `ignore_default_prompt_suffix` boolean — If true, the workflow's default_prompt_suffix will not be appended to this node's prompt.
          - `ignore_content_received_during_llm_tool_call_specification` boolean — If true, any free-text content this node's LLM returns in the same response as one or more tool calls is ignored: not emitted via AssistantResponseEvent, not added to chat history, and not added to the node's structured output. Implies the tool-level flag for every tool call this node makes.
          - `realtime_overrides` NodeRealtimeOverrides — Per-node realtime settings, applied only while this node is the active one. Everything here is optional and ``None`` means "inherit from the workflow" (D1) — nothing here turns realtime on or off. ``transcription_keywords`` is the field worth knowing about: the classic path has no equivalent. Because the realtime session is re-primed at every node transition, a node that collects a member ID can bias speech recognition toward plan names and digit words *for the span of that node only*, and stop biasing the moment the conversation moves on. That is a quality gain over the classic path, not merely parity with it. A ``verbatim`` flag was designed here and dropped by D2: edge messages are spoken in the model's own words. If exact wording is ever required (a compliance disclosure), §6.4 option 2 is where it goes.
            - `reasoning_effort` string, nullable — Reasoning effort while this node is active — one of minimal, low, medium, high, xhigh. Leave empty to inherit the workflow default. Worth raising on a node that has to choose between several similar-sounding paths; costly to raise everywhere.
            - `voice` string, nullable — Voice for this node only. Rarely useful: changing voice mid-conversation is jarring to a caller, who hears it as being handed to a different person.
            - `preamble_mode` string, nullable — Whether the model may speak a short filler line before a slow answer while this node is active. Leave empty to inherit.
            - `transcription_keywords` string[] — Terms to bias speech recognition toward while this node is active — added to the workflow-wide list rather than replacing it. Use for the identifiers a node actually asks for: plan names, member ID formats, provider names.
            - `turn_detection` object, nullable — Override end-of-speech detection for this node, e.g. to wait longer while a caller reads out a long number. Leave empty to inherit the session default.
          - `type` 'say_llm' — Type of the node. Must be 'say_llm'
          - `structured_output_schema` object, nullable — Schema for the structured output requested from the say node after it produces a response. Example: { "name": "SearchQuery", "description": "A search query with justification", "input_schema": { "title": "AnswerWithJustification", "type": "object", "properties": { "search_query": { "title": "Search Query", "type": "string", "description": "The field where search query is stored" }, "justification": { "title": "Justification", "type": "string", "description": "The field where justification string is stored" } }, "required": ["search_query", "justification"] } }
          - `backchannel_response_config` PromptConfig
            - `prompt` string, nullable — System prompt for the LLM
        - SayStaticMessageNodeConfigOutput
          - `logical_id` string, nullable — Unique identifier for the node
          - `name` string, nullable — Name of the node
          - `description` string, nullable — Description of the node
          - `workflow_id` string, nullable — The DB Object ID of the workflow this entity belongs to
          - `version_number` integer, nullable — Version number of the workflow this entity belongs to. 0 is the initial version (default).
          - `disabled` boolean — If true, this entity will be disabled and will not execute its function. Useful for testing workflows without actually executing this specific entity
          - `miscellaneous` object — Miscellaneous config data that can be used by the entity
          - `primary_category` string, nullable — Primary category of the node
          - `secondary_category` string, nullable — Secondary category of the node
          - `is_start` boolean — Whether this node is the starting node of the workflow
          - `is_guardrail_node` boolean — Whether this node is a guardrail node. When the workflow-level `miscellaneous.no_hopping_between_guardrail_nodes` setting is enabled (the default), the runtime blocks conditional transitions from this guardrail node to any other guardrail node — including regular freeform/expression conditional edges and synthesized global-node edges. Self-edges and self-loops on the same guardrail node remain allowed.
          - `global_node_config` object, nullable — Configuration for when this node is a global node
            - `is_global` boolean — Whether this node is a global node available as a conditional pathway to all nodes in the workflow
            - `condition` ConditionConfig
              - …
            - `global_condition_edge_evaluation_method` 'workflow_default' | 'tool_call' | 'independent_llm_evaluations'
            - `reverse_conditional_edge` ConditionConfig
              - …
          - `self_loop_config` object, nullable — Bounded self-loop / retry policy for a node. When ``enabled``, the node re-executes its functionality repeatedly until ONE of the following happens, whichever comes first: 1. an outgoing conditional edge matches (the loop's exit), or 2. ``max_retries`` re-executions have been performed, or 3. the ``expiry_time`` wall-clock budget for the whole loop elapses. Outgoing conditional edges are re-evaluated after every execution to decide whether to exit (take a matching edge) or run again. When the loop stops without a matching exit edge, the runtime publishes a ``self_loop_outcome`` runtime variable (``"max_retries"`` | ``"expiry_time"``) that authors can branch on with a dedicated "exhausted"/"timeout" conditional edge. This is distinct from the LLM-node ``self_loop: bool`` flag, which governs loop-back while waiting for the next user message and is unaffected by this config.
            - `enabled` boolean — Re-execute this node until a conditional edge matches, max_retries is reached, or expiry_time elapses (whichever comes first).
            - `max_retries` integer, nullable — Maximum number of re-executions after the first attempt (total attempts = max_retries + 1). Leave empty for no bound by count.
            - `expiry_time` integer, nullable — Overall wall-clock budget in seconds for the whole self-loop. An execution still running when this elapses is terminated. Leave empty for no time bound. Note: a CPU-bound inline-Python body with no await points cannot be interrupted mid-execution; expiry reliably bounds I/O-bound work.
            - `time_between_retries` integer — Seconds to wait between the end of one execution and the start of the next.
          - `type` 'say_static' — Type of the node. Must be 'say_static'
          - `static_messages_config` object, nullable — Configuration for static messages. Contains a list of pre-configured messages
            - `static_messages` string[] — List of pre-configured messages from which one will be emitted
            - `static_messages_selection_mode` 'random' | 'sequence'
        - SuperNodeConfigOutput
          - `logical_id` string, nullable — Unique identifier for the node
          - `name` string, nullable — Name of the node
          - `description` string, nullable — Description of the node
          - `workflow_id` string, nullable — The DB Object ID of the workflow this entity belongs to
          - `version_number` integer, nullable — Version number of the workflow this entity belongs to. 0 is the initial version (default).
          - `disabled` boolean — If true, this entity will be disabled and will not execute its function. Useful for testing workflows without actually executing this specific entity
          - `miscellaneous` object — Miscellaneous config data that can be used by the entity
          - `primary_category` string, nullable — Primary category of the node
          - `secondary_category` string, nullable — Secondary category of the node
          - `is_start` boolean — Whether this node is the starting node of the workflow
          - `is_guardrail_node` boolean — Whether this node is a guardrail node. When the workflow-level `miscellaneous.no_hopping_between_guardrail_nodes` setting is enabled (the default), the runtime blocks conditional transitions from this guardrail node to any other guardrail node — including regular freeform/expression conditional edges and synthesized global-node edges. Self-edges and self-loops on the same guardrail node remain allowed.
          - `global_node_config` object, nullable — Configuration for when this node is a global node
            - `is_global` boolean — Whether this node is a global node available as a conditional pathway to all nodes in the workflow
            - `condition` ConditionConfig
              - …
            - `global_condition_edge_evaluation_method` 'workflow_default' | 'tool_call' | 'independent_llm_evaluations'
            - `reverse_conditional_edge` ConditionConfig
              - …
          - `self_loop_config` object, nullable — Bounded self-loop / retry policy for a node. When ``enabled``, the node re-executes its functionality repeatedly until ONE of the following happens, whichever comes first: 1. an outgoing conditional edge matches (the loop's exit), or 2. ``max_retries`` re-executions have been performed, or 3. the ``expiry_time`` wall-clock budget for the whole loop elapses. Outgoing conditional edges are re-evaluated after every execution to decide whether to exit (take a matching edge) or run again. When the loop stops without a matching exit edge, the runtime publishes a ``self_loop_outcome`` runtime variable (``"max_retries"`` | ``"expiry_time"``) that authors can branch on with a dedicated "exhausted"/"timeout" conditional edge. This is distinct from the LLM-node ``self_loop: bool`` flag, which governs loop-back while waiting for the next user message and is unaffected by this config.
            - `enabled` boolean — Re-execute this node until a conditional edge matches, max_retries is reached, or expiry_time elapses (whichever comes first).
            - `max_retries` integer, nullable — Maximum number of re-executions after the first attempt (total attempts = max_retries + 1). Leave empty for no bound by count.
            - `expiry_time` integer, nullable — Overall wall-clock budget in seconds for the whole self-loop. An execution still running when this elapses is terminated. Leave empty for no time bound. Note: a CPU-bound inline-Python body with no await points cannot be interrupted mid-execution; expiry reliably bounds I/O-bound work.
            - `time_between_retries` integer — Seconds to wait between the end of one execution and the start of the next.
          - `type` 'super_node' — Type of the node. Must be 'super_node'
          - `super_workflow_id` string, nullable — The ID of the workflow encapsulated by this super node
          - `super_workflow_version_number` integer, nullable — Specific version of the encapsulated workflow. If None, the active version is used at execution time.
          - `field_values` object — Values provided by the calling workflow for each of the super node's declared input fields. Keyed by SuperNodeInputField.name.
          - `override_llm_config` boolean — When true, LLM-based nodes inside this super node use the LLM configuration specified here (attachable_llm_config_id or llms_config) instead of their own authored config. When false (the default), interior nodes keep their authored LLM configuration.
          - `override_only_workflow_default_nodes` boolean — Scopes the LLM override. When false (the default), every interior LLM node is overridden. When true, only interior LLM nodes that are themselves set to 'Workflow Default LLM' (i.e. had no explicit config of their own) are overridden; nodes with an explicit inline/named config are left untouched. Only relevant when override_llm_config is true.
          - `attachable_llm_config_id` string, nullable — ID of the named LLM Configuration to apply to the targeted interior LLM nodes. If provided, overrides the inline llms_config. Only relevant when override_llm_config is true.
          - `llms_config` union — Inline LLM configuration applied to the targeted interior LLM nodes. Use 'Workflow Default LLM' to fall back to the base workflow's workflow-level config. Only relevant when override_llm_config is true.
            - AzureOpenAILLMConfigOutput
              - …
            - OpenAILLMConfigOutput
              - …
            - GoogleLLMConfigOutput
              - …
            - AnthropicLLMConfigOutput
              - …
            - BedrockLLMConfigOutput
              - …
            - CustomLLMConfigOutput
              - …
            - WorkflowDefaultLLMConfigOutput
              - …
            - NoLLMConfigOutput
              - …
            - LLMGroupConfigOutput
              - …
            - LLMGroupWithBackchannelConfigOutput
              - …
          - `reverse_edge_scope` 'all_interior_llm_nodes' | 'terminal_nodes' — Controls which inlined sub-workflow nodes receive the super node placeholder's ``global_node_config.reverse_conditional_edge`` when the super node is expanded. The reverse edge is surfaced to the model as a per-turn LLM tool, so in BOTH modes only LLM-capable nodes are targeted — a static / HTTP / EndConversation node could never fire it.
          - `super_node_interface` object, nullable — The interface definition of a super node. Describes what configuration fields callers must provide when instantiating this super node, and how those field values map into the encapsulated sub-workflow's nodes, edges, and dynamic variables.
            - `input_fields` SuperNodeInputField[] — List of input fields exposed by this super node to calling workflows
              - …
          - `encapsulated_workflow_config` object, nullable — Snapshot of the fully-hydrated sub-workflow config at the time this super node was embedded. Used by the expander at runtime instead of a DB fetch. Not user-editable.
            - `workflow_config` WorkflowConfigOutput
              - …
            - `node_configs` union[] — List of node configurations for runtime
              - …
            - `edge_configs` union[] — List of edge configurations for runtime
              - …
            - `dynamic_variables` object — Dynamic variables that can be used across nodes and edges
            - `runtime_variables` object — Runtime variables that can be used across nodes and edges
        - WorkflowRunFetchNodeConfigOutput
          - `logical_id` string, nullable — Unique identifier for the node
          - `name` string, nullable — Name of the node
          - `description` string, nullable — Description of the node
          - `workflow_id` string, nullable — The DB Object ID of the workflow this entity belongs to
          - `version_number` integer, nullable — Version number of the workflow this entity belongs to. 0 is the initial version (default).
          - `disabled` boolean — If true, this entity will be disabled and will not execute its function. Useful for testing workflows without actually executing this specific entity
          - `miscellaneous` object — Miscellaneous config data that can be used by the entity
          - `primary_category` string, nullable — Primary category of the node
          - `secondary_category` string, nullable — Secondary category of the node
          - `is_start` boolean — Whether this node is the starting node of the workflow
          - `is_guardrail_node` boolean — Whether this node is a guardrail node. When the workflow-level `miscellaneous.no_hopping_between_guardrail_nodes` setting is enabled (the default), the runtime blocks conditional transitions from this guardrail node to any other guardrail node — including regular freeform/expression conditional edges and synthesized global-node edges. Self-edges and self-loops on the same guardrail node remain allowed.
          - `global_node_config` object, nullable — Configuration for when this node is a global node
            - `is_global` boolean — Whether this node is a global node available as a conditional pathway to all nodes in the workflow
            - `condition` ConditionConfig
              - …
            - `global_condition_edge_evaluation_method` 'workflow_default' | 'tool_call' | 'independent_llm_evaluations'
            - `reverse_conditional_edge` ConditionConfig
              - …
          - `self_loop_config` object, nullable — Bounded self-loop / retry policy for a node. When ``enabled``, the node re-executes its functionality repeatedly until ONE of the following happens, whichever comes first: 1. an outgoing conditional edge matches (the loop's exit), or 2. ``max_retries`` re-executions have been performed, or 3. the ``expiry_time`` wall-clock budget for the whole loop elapses. Outgoing conditional edges are re-evaluated after every execution to decide whether to exit (take a matching edge) or run again. When the loop stops without a matching exit edge, the runtime publishes a ``self_loop_outcome`` runtime variable (``"max_retries"`` | ``"expiry_time"``) that authors can branch on with a dedicated "exhausted"/"timeout" conditional edge. This is distinct from the LLM-node ``self_loop: bool`` flag, which governs loop-back while waiting for the next user message and is unaffected by this config.
            - `enabled` boolean — Re-execute this node until a conditional edge matches, max_retries is reached, or expiry_time elapses (whichever comes first).
            - `max_retries` integer, nullable — Maximum number of re-executions after the first attempt (total attempts = max_retries + 1). Leave empty for no bound by count.
            - `expiry_time` integer, nullable — Overall wall-clock budget in seconds for the whole self-loop. An execution still running when this elapses is terminated. Leave empty for no time bound. Note: a CPU-bound inline-Python body with no await points cannot be interrupted mid-execution; expiry reliably bounds I/O-bound work.
            - `time_between_retries` integer — Seconds to wait between the end of one execution and the start of the next.
          - `type` 'workflow_run_fetch' — Type of the node. Must be 'workflow_run_fetch'
          - `workflow_run_id` string, nullable — ID of the workflow run to fetch
          - `result_runtime_variable_name` string, nullable — Name of the runtime variable to store the result in
        - WorkflowRunEvalLLMNodeConfigOutput — Configuration for nodes that evaluate workflow runs. Evaluator nodes are used to assess, summarize and score outputs from workflow runs.
          - `logical_id` string, nullable — Unique identifier for the node
          - `name` string, nullable — Name of the node
          - `description` string, nullable — Description of the node
          - `workflow_id` string, nullable — The DB Object ID of the workflow this entity belongs to
          - `version_number` integer, nullable — Version number of the workflow this entity belongs to. 0 is the initial version (default).
          - `disabled` boolean — If true, this entity will be disabled and will not execute its function. Useful for testing workflows without actually executing this specific entity
          - `miscellaneous` object — Miscellaneous config data that can be used by the entity
          - `primary_category` string, nullable — Primary category of the node
          - `secondary_category` string, nullable — Secondary category of the node
          - `is_start` boolean — Whether this node is the starting node of the workflow
          - `is_guardrail_node` boolean — Whether this node is a guardrail node. When the workflow-level `miscellaneous.no_hopping_between_guardrail_nodes` setting is enabled (the default), the runtime blocks conditional transitions from this guardrail node to any other guardrail node — including regular freeform/expression conditional edges and synthesized global-node edges. Self-edges and self-loops on the same guardrail node remain allowed.
          - `global_node_config` object, nullable — Configuration for when this node is a global node
            - `is_global` boolean — Whether this node is a global node available as a conditional pathway to all nodes in the workflow
            - `condition` ConditionConfig
              - …
            - `global_condition_edge_evaluation_method` 'workflow_default' | 'tool_call' | 'independent_llm_evaluations'
            - `reverse_conditional_edge` ConditionConfig
              - …
          - `self_loop_config` object, nullable — Bounded self-loop / retry policy for a node. When ``enabled``, the node re-executes its functionality repeatedly until ONE of the following happens, whichever comes first: 1. an outgoing conditional edge matches (the loop's exit), or 2. ``max_retries`` re-executions have been performed, or 3. the ``expiry_time`` wall-clock budget for the whole loop elapses. Outgoing conditional edges are re-evaluated after every execution to decide whether to exit (take a matching edge) or run again. When the loop stops without a matching exit edge, the runtime publishes a ``self_loop_outcome`` runtime variable (``"max_retries"`` | ``"expiry_time"``) that authors can branch on with a dedicated "exhausted"/"timeout" conditional edge. This is distinct from the LLM-node ``self_loop: bool`` flag, which governs loop-back while waiting for the next user message and is unaffected by this config.
            - `enabled` boolean — Re-execute this node until a conditional edge matches, max_retries is reached, or expiry_time elapses (whichever comes first).
            - `max_retries` integer, nullable — Maximum number of re-executions after the first attempt (total attempts = max_retries + 1). Leave empty for no bound by count.
            - `expiry_time` integer, nullable — Overall wall-clock budget in seconds for the whole self-loop. An execution still running when this elapses is terminated. Leave empty for no time bound. Note: a CPU-bound inline-Python body with no await points cannot be interrupted mid-execution; expiry reliably bounds I/O-bound work.
            - `time_between_retries` integer — Seconds to wait between the end of one execution and the start of the next.
          - `main_response_config` object, nullable — Main response configuration. Contains either a LLM system prompt or exact static messages
            - `prompt` string, nullable — System prompt for the LLM
          - `attachable_llm_config_id` string, nullable — ID of the named LLM Configuration to use. If provided, overrides inline configuration.
          - `llms_config` union — LLM or a group of LLMs to be used in this node
            - AzureOpenAILLMConfigOutput
              - …
            - OpenAILLMConfigOutput
              - …
            - GoogleLLMConfigOutput
              - …
            - AnthropicLLMConfigOutput
              - …
            - BedrockLLMConfigOutput
              - …
            - CustomLLMConfigOutput
              - …
            - WorkflowDefaultLLMConfigOutput
              - …
            - NoLLMConfigOutput
              - …
            - LLMGroupConfigOutput
              - …
            - LLMGroupWithBackchannelConfigOutput
              - …
          - `tools_config` ToolsConfig
            - `tools` union[] — List of tool configurations
              - …
          - `self_loop` boolean — Evaluator nodes should not have self-loops, so this option is disabled
          - `wait_for_user_message` boolean — Evaluator nodes should not wait for user messages to proceed, so this option is disabled
          - `max_consecutive_tool_calls` integer — Maximum number of consecutive tool calls allowed in a single node execution
          - `default_error_message` string, nullable — Evaluator nodes should not have default error messages, so this option is disabled
          - `use_mcp_tools` boolean — Whether this node should use tools discovered from workflow-level MCP server connections
          - `ignore_default_prompt_prefix` boolean — If true, the workflow's default_prompt_prefix will not be prepended to this node's prompt.
          - `ignore_default_prompt_suffix` boolean — If true, the workflow's default_prompt_suffix will not be appended to this node's prompt.
          - `ignore_content_received_during_llm_tool_call_specification` boolean — If true, any free-text content this node's LLM returns in the same response as one or more tool calls is ignored: not emitted via AssistantResponseEvent, not added to chat history, and not added to the node's structured output. Implies the tool-level flag for every tool call this node makes.
          - `realtime_overrides` NodeRealtimeOverrides — Per-node realtime settings, applied only while this node is the active one. Everything here is optional and ``None`` means "inherit from the workflow" (D1) — nothing here turns realtime on or off. ``transcription_keywords`` is the field worth knowing about: the classic path has no equivalent. Because the realtime session is re-primed at every node transition, a node that collects a member ID can bias speech recognition toward plan names and digit words *for the span of that node only*, and stop biasing the moment the conversation moves on. That is a quality gain over the classic path, not merely parity with it. A ``verbatim`` flag was designed here and dropped by D2: edge messages are spoken in the model's own words. If exact wording is ever required (a compliance disclosure), §6.4 option 2 is where it goes.
            - `reasoning_effort` string, nullable — Reasoning effort while this node is active — one of minimal, low, medium, high, xhigh. Leave empty to inherit the workflow default. Worth raising on a node that has to choose between several similar-sounding paths; costly to raise everywhere.
            - `voice` string, nullable — Voice for this node only. Rarely useful: changing voice mid-conversation is jarring to a caller, who hears it as being handed to a different person.
            - `preamble_mode` string, nullable — Whether the model may speak a short filler line before a slow answer while this node is active. Leave empty to inherit.
            - `transcription_keywords` string[] — Terms to bias speech recognition toward while this node is active — added to the workflow-wide list rather than replacing it. Use for the identifiers a node actually asks for: plan names, member ID formats, provider names.
            - `turn_detection` object, nullable — Override end-of-speech detection for this node, e.g. to wait longer while a caller reads out a long number. Leave empty to inherit the session default.
          - `type` 'workflow_run_evaluator' — Type of the node. Must be 'workflow_run_evaluator'
          - `structured_output_schema` object, nullable — Schema for the structured evaluation output. If empty or None, no structured output is expected.
          - `backchannel_response_config` PromptConfig
            - `prompt` string, nullable — System prompt for the LLM
          - `input_runtime_variable_name` string, nullable — Runtime variable name from which to read the input to be evaluated. It is expected to contain the 'WorkflowRun' object to be evaluated.
          - `output_runtime_variable_name` string, nullable — Runtime variable name to store the structured evaluation output
          - `is_turn_by_turn_evaluator` boolean — Indicates if this evaluator is intended to evaluate each turn in a multi-turn workflow run
        - ToolNodeConfigOutput
          - `logical_id` string, nullable — Unique identifier for the node
          - `name` string, nullable — Name of the node
          - `description` string, nullable — Description of the node
          - `workflow_id` string, nullable — The DB Object ID of the workflow this entity belongs to
          - `version_number` integer, nullable — Version number of the workflow this entity belongs to. 0 is the initial version (default).
          - `disabled` boolean — If true, this entity will be disabled and will not execute its function. Useful for testing workflows without actually executing this specific entity
          - `miscellaneous` object — Miscellaneous config data that can be used by the entity
          - `primary_category` string, nullable — Primary category of the node
          - `secondary_category` string, nullable — Secondary category of the node
          - `is_start` boolean — Whether this node is the starting node of the workflow
          - `is_guardrail_node` boolean — Whether this node is a guardrail node. When the workflow-level `miscellaneous.no_hopping_between_guardrail_nodes` setting is enabled (the default), the runtime blocks conditional transitions from this guardrail node to any other guardrail node — including regular freeform/expression conditional edges and synthesized global-node edges. Self-edges and self-loops on the same guardrail node remain allowed.
          - `global_node_config` object, nullable — Configuration for when this node is a global node
            - `is_global` boolean — Whether this node is a global node available as a conditional pathway to all nodes in the workflow
            - `condition` ConditionConfig
              - …
            - `global_condition_edge_evaluation_method` 'workflow_default' | 'tool_call' | 'independent_llm_evaluations'
            - `reverse_conditional_edge` ConditionConfig
              - …
          - `self_loop_config` object, nullable — Bounded self-loop / retry policy for a node. When ``enabled``, the node re-executes its functionality repeatedly until ONE of the following happens, whichever comes first: 1. an outgoing conditional edge matches (the loop's exit), or 2. ``max_retries`` re-executions have been performed, or 3. the ``expiry_time`` wall-clock budget for the whole loop elapses. Outgoing conditional edges are re-evaluated after every execution to decide whether to exit (take a matching edge) or run again. When the loop stops without a matching exit edge, the runtime publishes a ``self_loop_outcome`` runtime variable (``"max_retries"`` | ``"expiry_time"``) that authors can branch on with a dedicated "exhausted"/"timeout" conditional edge. This is distinct from the LLM-node ``self_loop: bool`` flag, which governs loop-back while waiting for the next user message and is unaffected by this config.
            - `enabled` boolean — Re-execute this node until a conditional edge matches, max_retries is reached, or expiry_time elapses (whichever comes first).
            - `max_retries` integer, nullable — Maximum number of re-executions after the first attempt (total attempts = max_retries + 1). Leave empty for no bound by count.
            - `expiry_time` integer, nullable — Overall wall-clock budget in seconds for the whole self-loop. An execution still running when this elapses is terminated. Leave empty for no time bound. Note: a CPU-bound inline-Python body with no await points cannot be interrupted mid-execution; expiry reliably bounds I/O-bound work.
            - `time_between_retries` integer — Seconds to wait between the end of one execution and the start of the next.
          - `type` 'tool_node' — Type of the node. Must be 'tool_node'
          - `tool_config` union — Configuration for the tool to be executed
            - InlinePythonToolConfig — Configuration for an inline Python tool. The "code" field should contain a self-contained executable Python function. Example value of "code" string could be: def add( a: float, b: float, ) -> float: return float(a + b)
              - …
            - InbuiltFunctionToolConfig — Configuration for an inbuilt function tool. This tool type refers to functions that are already registered in the tools registry. The "tool_id" field must match the ID (decorated with "@tool_id") of a registered tool.
              - …
            - ExternalAPIToolConfig — Configuration for an external API tool. This tool type represents an external API endpoint that the LLM can call.
              - …
            - KnowledgeBaseToolConfig — Configuration for a knowledge base tool. This tool type represents a knowledge base endpoint that the LLM can call.
              - …
          - `tool_arguments` object, nullable — Arguments to pass to the tool. Can contain dynamic/runtime variables as strings or inside nested structures.
          - `result_runtime_variable_name` string, nullable — Name of the runtime variable to store the result of the tool execution. Leaving this at 'tool_result' means inherit: if the attached tool names its own result variable, that name is used. Any OTHER name set here overrides the tool. 'tool_result' cannot be used to override a tool that names something else — it is indistinguishable from not having chosen. The success flag and error message follow whichever name wins, as <name>_success and <name>_error.
          - `preserve_argument_types` boolean — When true, a tool_arguments value that is exactly one placeholder (e.g. '[[patient]]' with nothing around it) resolves to the variable's native value — dict, list, int, bool, None — instead of its string form, and an unresolved one becomes None rather than the literal placeholder text. Mixed strings such as 'Hello {{name}}' are interpolated as before. Off by default because it changes the type an existing tool receives.
        - StartConversationNodeConfigOutput
          - `logical_id` string, nullable — Unique identifier for the node
          - `name` string, nullable — Name of the node
          - `description` string, nullable — Description of the node
          - `workflow_id` string, nullable — The DB Object ID of the workflow this entity belongs to
          - `version_number` integer, nullable — Version number of the workflow this entity belongs to. 0 is the initial version (default).
          - `disabled` boolean — If true, this entity will be disabled and will not execute its function. Useful for testing workflows without actually executing this specific entity
          - `miscellaneous` object — Miscellaneous config data that can be used by the entity
          - `primary_category` string, nullable — Primary category of the node
          - `secondary_category` string, nullable — Secondary category of the node
          - `is_start` boolean — Whether this node is the starting node of the workflow
          - `is_guardrail_node` boolean — Whether this node is a guardrail node. When the workflow-level `miscellaneous.no_hopping_between_guardrail_nodes` setting is enabled (the default), the runtime blocks conditional transitions from this guardrail node to any other guardrail node — including regular freeform/expression conditional edges and synthesized global-node edges. Self-edges and self-loops on the same guardrail node remain allowed.
          - `global_node_config` object, nullable — Configuration for when this node is a global node
            - `is_global` boolean — Whether this node is a global node available as a conditional pathway to all nodes in the workflow
            - `condition` ConditionConfig
              - …
            - `global_condition_edge_evaluation_method` 'workflow_default' | 'tool_call' | 'independent_llm_evaluations'
            - `reverse_conditional_edge` ConditionConfig
              - …
          - `self_loop_config` object, nullable — Bounded self-loop / retry policy for a node. When ``enabled``, the node re-executes its functionality repeatedly until ONE of the following happens, whichever comes first: 1. an outgoing conditional edge matches (the loop's exit), or 2. ``max_retries`` re-executions have been performed, or 3. the ``expiry_time`` wall-clock budget for the whole loop elapses. Outgoing conditional edges are re-evaluated after every execution to decide whether to exit (take a matching edge) or run again. When the loop stops without a matching exit edge, the runtime publishes a ``self_loop_outcome`` runtime variable (``"max_retries"`` | ``"expiry_time"``) that authors can branch on with a dedicated "exhausted"/"timeout" conditional edge. This is distinct from the LLM-node ``self_loop: bool`` flag, which governs loop-back while waiting for the next user message and is unaffected by this config.
            - `enabled` boolean — Re-execute this node until a conditional edge matches, max_retries is reached, or expiry_time elapses (whichever comes first).
            - `max_retries` integer, nullable — Maximum number of re-executions after the first attempt (total attempts = max_retries + 1). Leave empty for no bound by count.
            - `expiry_time` integer, nullable — Overall wall-clock budget in seconds for the whole self-loop. An execution still running when this elapses is terminated. Leave empty for no time bound. Note: a CPU-bound inline-Python body with no await points cannot be interrupted mid-execution; expiry reliably bounds I/O-bound work.
            - `time_between_retries` integer — Seconds to wait between the end of one execution and the start of the next.
          - `type` 'start_conversation' — Type of the node. Must be 'start_conversation'
          - `is_voice_conversation` boolean — Whether this conversation is a voice-based conversation
          - `is_outbound_call` boolean — Whether this conversation is an outbound call
          - `bearer_token` string, nullable — The bearer token used for authenticating with the outbound phone call service
          - `assistant_number` string, nullable — The phone number assigned to the assistant to make the call from (in E.164 format)
          - `assistant_id` string, nullable — The ID of the assistant to use for the conversation
          - `user_number` string, nullable — The phone number of the user to call (in E.164 format)
          - `conversation_id` string, nullable — The ID of the conversation to poll. If provided, an outbound call will not be initiated, and the system will instead poll for an existing conversation with this ID.
          - `polling_interval_seconds` integer, nullable — If polling for an existing conversation, the interval (in seconds) at which to poll for updates
        - EndConversationNodeConfigOutput
          - `logical_id` string, nullable — Unique identifier for the node
          - `name` string, nullable — Name of the node
          - `description` string, nullable — Description of the node
          - `workflow_id` string, nullable — The DB Object ID of the workflow this entity belongs to
          - `version_number` integer, nullable — Version number of the workflow this entity belongs to. 0 is the initial version (default).
          - `disabled` boolean — If true, this entity will be disabled and will not execute its function. Useful for testing workflows without actually executing this specific entity
          - `miscellaneous` object — Miscellaneous config data that can be used by the entity
          - `primary_category` string, nullable — Primary category of the node
          - `secondary_category` string, nullable — Secondary category of the node
          - `is_start` boolean — Whether this node is the starting node of the workflow
          - `is_guardrail_node` boolean — Whether this node is a guardrail node. When the workflow-level `miscellaneous.no_hopping_between_guardrail_nodes` setting is enabled (the default), the runtime blocks conditional transitions from this guardrail node to any other guardrail node — including regular freeform/expression conditional edges and synthesized global-node edges. Self-edges and self-loops on the same guardrail node remain allowed.
          - `global_node_config` object, nullable — Configuration for when this node is a global node
            - `is_global` boolean — Whether this node is a global node available as a conditional pathway to all nodes in the workflow
            - `condition` ConditionConfig
              - …
            - `global_condition_edge_evaluation_method` 'workflow_default' | 'tool_call' | 'independent_llm_evaluations'
            - `reverse_conditional_edge` ConditionConfig
              - …
          - `self_loop_config` object, nullable — Bounded self-loop / retry policy for a node. When ``enabled``, the node re-executes its functionality repeatedly until ONE of the following happens, whichever comes first: 1. an outgoing conditional edge matches (the loop's exit), or 2. ``max_retries`` re-executions have been performed, or 3. the ``expiry_time`` wall-clock budget for the whole loop elapses. Outgoing conditional edges are re-evaluated after every execution to decide whether to exit (take a matching edge) or run again. When the loop stops without a matching exit edge, the runtime publishes a ``self_loop_outcome`` runtime variable (``"max_retries"`` | ``"expiry_time"``) that authors can branch on with a dedicated "exhausted"/"timeout" conditional edge. This is distinct from the LLM-node ``self_loop: bool`` flag, which governs loop-back while waiting for the next user message and is unaffected by this config.
            - `enabled` boolean — Re-execute this node until a conditional edge matches, max_retries is reached, or expiry_time elapses (whichever comes first).
            - `max_retries` integer, nullable — Maximum number of re-executions after the first attempt (total attempts = max_retries + 1). Leave empty for no bound by count.
            - `expiry_time` integer, nullable — Overall wall-clock budget in seconds for the whole self-loop. An execution still running when this elapses is terminated. Leave empty for no time bound. Note: a CPU-bound inline-Python body with no await points cannot be interrupted mid-execution; expiry reliably bounds I/O-bound work.
            - `time_between_retries` integer — Seconds to wait between the end of one execution and the start of the next.
          - `type` 'end_conversation' — Type of the node. Must be 'end_conversation'
          - `process_transcript_prompt` PromptConfig
            - `prompt` string, nullable — System prompt for the LLM
          - `process_transcript_llms_config` union — LLM or a group of LLMs to be used for processing the conversation transcript
            - AzureOpenAILLMConfigOutput
              - …
            - OpenAILLMConfigOutput
              - …
            - GoogleLLMConfigOutput
              - …
            - AnthropicLLMConfigOutput
              - …
            - BedrockLLMConfigOutput
              - …
            - CustomLLMConfigOutput
              - …
            - WorkflowDefaultLLMConfigOutput
              - …
            - NoLLMConfigOutput
              - …
            - LLMGroupConfigOutput
              - …
            - LLMGroupWithBackchannelConfigOutput
              - …
        - SendSMSNodeConfigOutput
          - `logical_id` string, nullable — Unique identifier for the node
          - `name` string, nullable — Name of the node
          - `description` string, nullable — Description of the node
          - `workflow_id` string, nullable — The DB Object ID of the workflow this entity belongs to
          - `version_number` integer, nullable — Version number of the workflow this entity belongs to. 0 is the initial version (default).
          - `disabled` boolean — If true, this entity will be disabled and will not execute its function. Useful for testing workflows without actually executing this specific entity
          - `miscellaneous` object — Miscellaneous config data that can be used by the entity
          - `primary_category` string, nullable — Primary category of the node
          - `secondary_category` string, nullable — Secondary category of the node
          - `is_start` boolean — Whether this node is the starting node of the workflow
          - `is_guardrail_node` boolean — Whether this node is a guardrail node. When the workflow-level `miscellaneous.no_hopping_between_guardrail_nodes` setting is enabled (the default), the runtime blocks conditional transitions from this guardrail node to any other guardrail node — including regular freeform/expression conditional edges and synthesized global-node edges. Self-edges and self-loops on the same guardrail node remain allowed.
          - `global_node_config` object, nullable — Configuration for when this node is a global node
            - `is_global` boolean — Whether this node is a global node available as a conditional pathway to all nodes in the workflow
            - `condition` ConditionConfig
              - …
            - `global_condition_edge_evaluation_method` 'workflow_default' | 'tool_call' | 'independent_llm_evaluations'
            - `reverse_conditional_edge` ConditionConfig
              - …
          - `self_loop_config` object, nullable — Bounded self-loop / retry policy for a node. When ``enabled``, the node re-executes its functionality repeatedly until ONE of the following happens, whichever comes first: 1. an outgoing conditional edge matches (the loop's exit), or 2. ``max_retries`` re-executions have been performed, or 3. the ``expiry_time`` wall-clock budget for the whole loop elapses. Outgoing conditional edges are re-evaluated after every execution to decide whether to exit (take a matching edge) or run again. When the loop stops without a matching exit edge, the runtime publishes a ``self_loop_outcome`` runtime variable (``"max_retries"`` | ``"expiry_time"``) that authors can branch on with a dedicated "exhausted"/"timeout" conditional edge. This is distinct from the LLM-node ``self_loop: bool`` flag, which governs loop-back while waiting for the next user message and is unaffected by this config.
            - `enabled` boolean — Re-execute this node until a conditional edge matches, max_retries is reached, or expiry_time elapses (whichever comes first).
            - `max_retries` integer, nullable — Maximum number of re-executions after the first attempt (total attempts = max_retries + 1). Leave empty for no bound by count.
            - `expiry_time` integer, nullable — Overall wall-clock budget in seconds for the whole self-loop. An execution still running when this elapses is terminated. Leave empty for no time bound. Note: a CPU-bound inline-Python body with no await points cannot be interrupted mid-execution; expiry reliably bounds I/O-bound work.
            - `time_between_retries` integer — Seconds to wait between the end of one execution and the start of the next.
          - `type` 'send_sms' — Type of the node. Must be 'send_sms'
          - `destination_phone_number` string, nullable — Destination phone number in E.164 format. Example of E.164 format: +1234567890
          - `message` string, nullable — SMS message to be sent. Can include dynamic and runtime variable placeholders for dynamic content.
        - GoogleDocsNodeConfigOutput
          - `logical_id` string, nullable — Unique identifier for the node
          - `name` string, nullable — Name of the node
          - `description` string, nullable — Description of the node
          - `workflow_id` string, nullable — The DB Object ID of the workflow this entity belongs to
          - `version_number` integer, nullable — Version number of the workflow this entity belongs to. 0 is the initial version (default).
          - `disabled` boolean — If true, this entity will be disabled and will not execute its function. Useful for testing workflows without actually executing this specific entity
          - `miscellaneous` object — Miscellaneous config data that can be used by the entity
          - `primary_category` string, nullable — Primary category of the node
          - `secondary_category` string, nullable — Secondary category of the node
          - `is_start` boolean — Whether this node is the starting node of the workflow
          - `is_guardrail_node` boolean — Whether this node is a guardrail node. When the workflow-level `miscellaneous.no_hopping_between_guardrail_nodes` setting is enabled (the default), the runtime blocks conditional transitions from this guardrail node to any other guardrail node — including regular freeform/expression conditional edges and synthesized global-node edges. Self-edges and self-loops on the same guardrail node remain allowed.
          - `global_node_config` object, nullable — Configuration for when this node is a global node
            - `is_global` boolean — Whether this node is a global node available as a conditional pathway to all nodes in the workflow
            - `condition` ConditionConfig
              - …
            - `global_condition_edge_evaluation_method` 'workflow_default' | 'tool_call' | 'independent_llm_evaluations'
            - `reverse_conditional_edge` ConditionConfig
              - …
          - `self_loop_config` object, nullable — Bounded self-loop / retry policy for a node. When ``enabled``, the node re-executes its functionality repeatedly until ONE of the following happens, whichever comes first: 1. an outgoing conditional edge matches (the loop's exit), or 2. ``max_retries`` re-executions have been performed, or 3. the ``expiry_time`` wall-clock budget for the whole loop elapses. Outgoing conditional edges are re-evaluated after every execution to decide whether to exit (take a matching edge) or run again. When the loop stops without a matching exit edge, the runtime publishes a ``self_loop_outcome`` runtime variable (``"max_retries"`` | ``"expiry_time"``) that authors can branch on with a dedicated "exhausted"/"timeout" conditional edge. This is distinct from the LLM-node ``self_loop: bool`` flag, which governs loop-back while waiting for the next user message and is unaffected by this config.
            - `enabled` boolean — Re-execute this node until a conditional edge matches, max_retries is reached, or expiry_time elapses (whichever comes first).
            - `max_retries` integer, nullable — Maximum number of re-executions after the first attempt (total attempts = max_retries + 1). Leave empty for no bound by count.
            - `expiry_time` integer, nullable — Overall wall-clock budget in seconds for the whole self-loop. An execution still running when this elapses is terminated. Leave empty for no time bound. Note: a CPU-bound inline-Python body with no await points cannot be interrupted mid-execution; expiry reliably bounds I/O-bound work.
            - `time_between_retries` integer — Seconds to wait between the end of one execution and the start of the next.
          - `type` 'google_docs' — Type of the node. Must be 'google_docs'
          - `credentials` union — Credentials for Google Workspace. If not provided, the default credentials will be used.
            - GoogleWorkspaceOAuth2Credentials — Configuration for Google Workspace OAuth2 credentials.
              - …
            - GoogleWorkspaceServiceAccountCredentials — Configuration for Google Workspace service account credentials.
              - …
            - GoogleWorkspaceAPIKeyCredentials — Configuration for Google Workspace API Key credentials.
              - …
          - `operate_document` union — Configuration for operating on a Google Docs document (create, get, or update).
            - GoogleDocsCreateDocumentConfig — Configuration for creating a Google Docs document.
              - …
            - GoogleDocsGetDocumentConfig — Configuration for getting a Google Docs document.
              - …
            - GoogleDocsUpdateDocumentConfig — Configuration for updating a Google Docs document.
              - …
        - HttpRequestNodeConfigOutput
          - `logical_id` string, nullable — Unique identifier for the node
          - `name` string, nullable — Name of the node
          - `description` string, nullable — Description of the node
          - `workflow_id` string, nullable — The DB Object ID of the workflow this entity belongs to
          - `version_number` integer, nullable — Version number of the workflow this entity belongs to. 0 is the initial version (default).
          - `disabled` boolean — If true, this entity will be disabled and will not execute its function. Useful for testing workflows without actually executing this specific entity
          - `miscellaneous` object — Miscellaneous config data that can be used by the entity
          - `primary_category` string, nullable — Primary category of the node
          - `secondary_category` string, nullable — Secondary category of the node
          - `is_start` boolean — Whether this node is the starting node of the workflow
          - `is_guardrail_node` boolean — Whether this node is a guardrail node. When the workflow-level `miscellaneous.no_hopping_between_guardrail_nodes` setting is enabled (the default), the runtime blocks conditional transitions from this guardrail node to any other guardrail node — including regular freeform/expression conditional edges and synthesized global-node edges. Self-edges and self-loops on the same guardrail node remain allowed.
          - `global_node_config` object, nullable — Configuration for when this node is a global node
            - `is_global` boolean — Whether this node is a global node available as a conditional pathway to all nodes in the workflow
            - `condition` ConditionConfig
              - …
            - `global_condition_edge_evaluation_method` 'workflow_default' | 'tool_call' | 'independent_llm_evaluations'
            - `reverse_conditional_edge` ConditionConfig
              - …
          - `self_loop_config` object, nullable — Bounded self-loop / retry policy for a node. When ``enabled``, the node re-executes its functionality repeatedly until ONE of the following happens, whichever comes first: 1. an outgoing conditional edge matches (the loop's exit), or 2. ``max_retries`` re-executions have been performed, or 3. the ``expiry_time`` wall-clock budget for the whole loop elapses. Outgoing conditional edges are re-evaluated after every execution to decide whether to exit (take a matching edge) or run again. When the loop stops without a matching exit edge, the runtime publishes a ``self_loop_outcome`` runtime variable (``"max_retries"`` | ``"expiry_time"``) that authors can branch on with a dedicated "exhausted"/"timeout" conditional edge. This is distinct from the LLM-node ``self_loop: bool`` flag, which governs loop-back while waiting for the next user message and is unaffected by this config.
            - `enabled` boolean — Re-execute this node until a conditional edge matches, max_retries is reached, or expiry_time elapses (whichever comes first).
            - `max_retries` integer, nullable — Maximum number of re-executions after the first attempt (total attempts = max_retries + 1). Leave empty for no bound by count.
            - `expiry_time` integer, nullable — Overall wall-clock budget in seconds for the whole self-loop. An execution still running when this elapses is terminated. Leave empty for no time bound. Note: a CPU-bound inline-Python body with no await points cannot be interrupted mid-execution; expiry reliably bounds I/O-bound work.
            - `time_between_retries` integer — Seconds to wait between the end of one execution and the start of the next.
          - `type` 'http_request' — Type of the node. Must be 'http_request'
          - `url` string, nullable — The URL to send the HTTP request to
          - `method` 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS'
          - `headers` object, nullable — Optional HTTP headers as a dictionary
          - `query_parameters` string, nullable — Query parameters as a dictionary
          - `body_parameters` string, nullable — Body parameters as a dictionary (for POST, PUT, PATCH)
          - `body_content_type` 'application/json' | 'application/x-www-form-urlencoded' | 'multipart/form-data' | 'text/plain'
          - `timeout` integer, nullable — Timeout for the HTTP request in seconds
          - `response_format` 'json' | 'text' | 'binary'
          - `result_runtime_variable_name` string, nullable — Name of the runtime variable to store the result
        - AthenaPatientsSearchNodeConfigOutput
          - `logical_id` string, nullable — Unique identifier for the node
          - `name` string, nullable — Name of the node
          - `description` string, nullable — Description of the node
          - `workflow_id` string, nullable — The DB Object ID of the workflow this entity belongs to
          - `version_number` integer, nullable — Version number of the workflow this entity belongs to. 0 is the initial version (default).
          - `disabled` boolean — If true, this entity will be disabled and will not execute its function. Useful for testing workflows without actually executing this specific entity
          - `miscellaneous` object — Miscellaneous config data that can be used by the entity
          - `primary_category` string, nullable — Primary category of the node
          - `secondary_category` string, nullable — Secondary category of the node
          - `is_start` boolean — Whether this node is the starting node of the workflow
          - `is_guardrail_node` boolean — Whether this node is a guardrail node. When the workflow-level `miscellaneous.no_hopping_between_guardrail_nodes` setting is enabled (the default), the runtime blocks conditional transitions from this guardrail node to any other guardrail node — including regular freeform/expression conditional edges and synthesized global-node edges. Self-edges and self-loops on the same guardrail node remain allowed.
          - `global_node_config` object, nullable — Configuration for when this node is a global node
            - `is_global` boolean — Whether this node is a global node available as a conditional pathway to all nodes in the workflow
            - `condition` ConditionConfig
              - …
            - `global_condition_edge_evaluation_method` 'workflow_default' | 'tool_call' | 'independent_llm_evaluations'
            - `reverse_conditional_edge` ConditionConfig
              - …
          - `self_loop_config` object, nullable — Bounded self-loop / retry policy for a node. When ``enabled``, the node re-executes its functionality repeatedly until ONE of the following happens, whichever comes first: 1. an outgoing conditional edge matches (the loop's exit), or 2. ``max_retries`` re-executions have been performed, or 3. the ``expiry_time`` wall-clock budget for the whole loop elapses. Outgoing conditional edges are re-evaluated after every execution to decide whether to exit (take a matching edge) or run again. When the loop stops without a matching exit edge, the runtime publishes a ``self_loop_outcome`` runtime variable (``"max_retries"`` | ``"expiry_time"``) that authors can branch on with a dedicated "exhausted"/"timeout" conditional edge. This is distinct from the LLM-node ``self_loop: bool`` flag, which governs loop-back while waiting for the next user message and is unaffected by this config.
            - `enabled` boolean — Re-execute this node until a conditional edge matches, max_retries is reached, or expiry_time elapses (whichever comes first).
            - `max_retries` integer, nullable — Maximum number of re-executions after the first attempt (total attempts = max_retries + 1). Leave empty for no bound by count.
            - `expiry_time` integer, nullable — Overall wall-clock budget in seconds for the whole self-loop. An execution still running when this elapses is terminated. Leave empty for no time bound. Note: a CPU-bound inline-Python body with no await points cannot be interrupted mid-execution; expiry reliably bounds I/O-bound work.
            - `time_between_retries` integer — Seconds to wait between the end of one execution and the start of the next.
          - `source_id` string, nullable — Source ID of the node
          - `department_id` integer, nullable — Department ID of the node
          - `api_key` string, nullable — API key for the node
          - `timezone` string, nullable — Timezone in IANA format ex: 'America/New_York'
          - `reminders` boolean, nullable — Whether to send reminders for the node
          - `slotfill_outreach` boolean, nullable — Whether to enable slot fill outreach for the node
          - `working_hours` object, nullable — Working hours for the node
            - `monday` StartEndTimings, required
              - …
            - `tuesday` StartEndTimings, required
              - …
            - `wednesday` StartEndTimings, required
              - …
            - `thursday` StartEndTimings, required
              - …
            - `friday` StartEndTimings, required
              - …
            - `saturday` StartEndTimings, required
              - …
            - `sunday` StartEndTimings, required
              - …
          - `use_cases` UseCase[] — Use cases for the node
          - `type` 'athena_patients_search' — Type of the node. Must be 'athena_patients_search'
          - `phone_number` string, nullable — Phone number of the patient to create
          - `full_name` string, nullable — Full name of the patient to retrieve
          - `birthdate` string, nullable — Birthdate of the patient to retrieve
        - AthenaPatientsCreateNodeConfigOutput
          - `logical_id` string, nullable — Unique identifier for the node
          - `name` string, nullable — Name of the node
          - `description` string, nullable — Description of the node
          - `workflow_id` string, nullable — The DB Object ID of the workflow this entity belongs to
          - `version_number` integer, nullable — Version number of the workflow this entity belongs to. 0 is the initial version (default).
          - `disabled` boolean — If true, this entity will be disabled and will not execute its function. Useful for testing workflows without actually executing this specific entity
          - `miscellaneous` object — Miscellaneous config data that can be used by the entity
          - `primary_category` string, nullable — Primary category of the node
          - `secondary_category` string, nullable — Secondary category of the node
          - `is_start` boolean — Whether this node is the starting node of the workflow
          - `is_guardrail_node` boolean — Whether this node is a guardrail node. When the workflow-level `miscellaneous.no_hopping_between_guardrail_nodes` setting is enabled (the default), the runtime blocks conditional transitions from this guardrail node to any other guardrail node — including regular freeform/expression conditional edges and synthesized global-node edges. Self-edges and self-loops on the same guardrail node remain allowed.
          - `global_node_config` object, nullable — Configuration for when this node is a global node
            - `is_global` boolean — Whether this node is a global node available as a conditional pathway to all nodes in the workflow
            - `condition` ConditionConfig
              - …
            - `global_condition_edge_evaluation_method` 'workflow_default' | 'tool_call' | 'independent_llm_evaluations'
            - `reverse_conditional_edge` ConditionConfig
              - …
          - `self_loop_config` object, nullable — Bounded self-loop / retry policy for a node. When ``enabled``, the node re-executes its functionality repeatedly until ONE of the following happens, whichever comes first: 1. an outgoing conditional edge matches (the loop's exit), or 2. ``max_retries`` re-executions have been performed, or 3. the ``expiry_time`` wall-clock budget for the whole loop elapses. Outgoing conditional edges are re-evaluated after every execution to decide whether to exit (take a matching edge) or run again. When the loop stops without a matching exit edge, the runtime publishes a ``self_loop_outcome`` runtime variable (``"max_retries"`` | ``"expiry_time"``) that authors can branch on with a dedicated "exhausted"/"timeout" conditional edge. This is distinct from the LLM-node ``self_loop: bool`` flag, which governs loop-back while waiting for the next user message and is unaffected by this config.
            - `enabled` boolean — Re-execute this node until a conditional edge matches, max_retries is reached, or expiry_time elapses (whichever comes first).
            - `max_retries` integer, nullable — Maximum number of re-executions after the first attempt (total attempts = max_retries + 1). Leave empty for no bound by count.
            - `expiry_time` integer, nullable — Overall wall-clock budget in seconds for the whole self-loop. An execution still running when this elapses is terminated. Leave empty for no time bound. Note: a CPU-bound inline-Python body with no await points cannot be interrupted mid-execution; expiry reliably bounds I/O-bound work.
            - `time_between_retries` integer — Seconds to wait between the end of one execution and the start of the next.
          - `source_id` string, nullable — Source ID of the node
          - `department_id` integer, nullable — Department ID of the node
          - `api_key` string, nullable — API key for the node
          - `timezone` string, nullable — Timezone in IANA format ex: 'America/New_York'
          - `reminders` boolean, nullable — Whether to send reminders for the node
          - `slotfill_outreach` boolean, nullable — Whether to enable slot fill outreach for the node
          - `working_hours` object, nullable — Working hours for the node
            - `monday` StartEndTimings, required
              - …
            - `tuesday` StartEndTimings, required
              - …
            - `wednesday` StartEndTimings, required
              - …
            - `thursday` StartEndTimings, required
              - …
            - `friday` StartEndTimings, required
              - …
            - `saturday` StartEndTimings, required
              - …
            - `sunday` StartEndTimings, required
              - …
          - `use_cases` UseCase[] — Use cases for the node
          - `type` 'athena_patients_create' — Type of the node. Must be 'athena_patients_create'
          - `first_name` string, nullable — First name of the patient to create
          - `last_name` string, nullable — Last name of the patient to create
          - `phone_number` string, nullable — Phone number of the patient to create
          - `birthdate` string, nullable — Birthdate of the patient to retrieve
          - `gender` '' | 'Female' | 'Male' | 'Non-binary gender identity' | 'Additional gender category or other' | 'Choose not to disclose' | 'Genderqueer (neither exclusively male nor female)' | 'Unknown'
          - `email` string, nullable — Email of the patient to create
          - `notes` string, nullable — Notes about the patient to create
          - `mobile_number` string, nullable — Mobile number of the patient to create
        - AthenaPatientsUpdateNodeConfigOutput
          - `logical_id` string, nullable — Unique identifier for the node
          - `name` string, nullable — Name of the node
          - `description` string, nullable — Description of the node
          - `workflow_id` string, nullable — The DB Object ID of the workflow this entity belongs to
          - `version_number` integer, nullable — Version number of the workflow this entity belongs to. 0 is the initial version (default).
          - `disabled` boolean — If true, this entity will be disabled and will not execute its function. Useful for testing workflows without actually executing this specific entity
          - `miscellaneous` object — Miscellaneous config data that can be used by the entity
          - `primary_category` string, nullable — Primary category of the node
          - `secondary_category` string, nullable — Secondary category of the node
          - `is_start` boolean — Whether this node is the starting node of the workflow
          - `is_guardrail_node` boolean — Whether this node is a guardrail node. When the workflow-level `miscellaneous.no_hopping_between_guardrail_nodes` setting is enabled (the default), the runtime blocks conditional transitions from this guardrail node to any other guardrail node — including regular freeform/expression conditional edges and synthesized global-node edges. Self-edges and self-loops on the same guardrail node remain allowed.
          - `global_node_config` object, nullable — Configuration for when this node is a global node
            - `is_global` boolean — Whether this node is a global node available as a conditional pathway to all nodes in the workflow
            - `condition` ConditionConfig
              - …
            - `global_condition_edge_evaluation_method` 'workflow_default' | 'tool_call' | 'independent_llm_evaluations'
            - `reverse_conditional_edge` ConditionConfig
              - …
          - `self_loop_config` object, nullable — Bounded self-loop / retry policy for a node. When ``enabled``, the node re-executes its functionality repeatedly until ONE of the following happens, whichever comes first: 1. an outgoing conditional edge matches (the loop's exit), or 2. ``max_retries`` re-executions have been performed, or 3. the ``expiry_time`` wall-clock budget for the whole loop elapses. Outgoing conditional edges are re-evaluated after every execution to decide whether to exit (take a matching edge) or run again. When the loop stops without a matching exit edge, the runtime publishes a ``self_loop_outcome`` runtime variable (``"max_retries"`` | ``"expiry_time"``) that authors can branch on with a dedicated "exhausted"/"timeout" conditional edge. This is distinct from the LLM-node ``self_loop: bool`` flag, which governs loop-back while waiting for the next user message and is unaffected by this config.
            - `enabled` boolean — Re-execute this node until a conditional edge matches, max_retries is reached, or expiry_time elapses (whichever comes first).
            - `max_retries` integer, nullable — Maximum number of re-executions after the first attempt (total attempts = max_retries + 1). Leave empty for no bound by count.
            - `expiry_time` integer, nullable — Overall wall-clock budget in seconds for the whole self-loop. An execution still running when this elapses is terminated. Leave empty for no time bound. Note: a CPU-bound inline-Python body with no await points cannot be interrupted mid-execution; expiry reliably bounds I/O-bound work.
            - `time_between_retries` integer — Seconds to wait between the end of one execution and the start of the next.
          - `source_id` string, nullable — Source ID of the node
          - `department_id` integer, nullable — Department ID of the node
          - `api_key` string, nullable — API key for the node
          - `timezone` string, nullable — Timezone in IANA format ex: 'America/New_York'
          - `reminders` boolean, nullable — Whether to send reminders for the node
          - `slotfill_outreach` boolean, nullable — Whether to enable slot fill outreach for the node
          - `working_hours` object, nullable — Working hours for the node
            - `monday` StartEndTimings, required
              - …
            - `tuesday` StartEndTimings, required
              - …
            - `wednesday` StartEndTimings, required
              - …
            - `thursday` StartEndTimings, required
              - …
            - `friday` StartEndTimings, required
              - …
            - `saturday` StartEndTimings, required
              - …
            - `sunday` StartEndTimings, required
              - …
          - `use_cases` UseCase[] — Use cases for the node
          - `type` 'athena_patients_update' — Type of the node. Must be 'athena_patients_update'
          - `patient_id` string, nullable — ID of the patient to update
          - `first_name` string, nullable — First name of the patient to update
          - `last_name` string, nullable — Last name of the patient to update
          - `phone_number` string, nullable — Phone number of the patient to update
          - `birthdate` string, nullable — Birthdate of the patient to update (YYYY-MM-DD)
          - `gender` '' | 'Female' | 'Male' | 'Non-binary gender identity' | 'Additional gender category or other' | 'Choose not to disclose' | 'Genderqueer (neither exclusively male nor female)' | 'Unknown'
          - `email` string, nullable — Email of the patient to update
          - `notes` string, nullable — Notes about the patient to update
          - `notes_action` 'append' | 'replace' — Action to perform on notes field
          - `mobile_number` string, nullable — Mobile number of the patient to update
        - AthenaAppointmentsCreateNodeConfigOutput
          - `logical_id` string, nullable — Unique identifier for the node
          - `name` string, nullable — Name of the node
          - `description` string, nullable — Description of the node
          - `workflow_id` string, nullable — The DB Object ID of the workflow this entity belongs to
          - `version_number` integer, nullable — Version number of the workflow this entity belongs to. 0 is the initial version (default).
          - `disabled` boolean — If true, this entity will be disabled and will not execute its function. Useful for testing workflows without actually executing this specific entity
          - `miscellaneous` object — Miscellaneous config data that can be used by the entity
          - `primary_category` string, nullable — Primary category of the node
          - `secondary_category` string, nullable — Secondary category of the node
          - `is_start` boolean — Whether this node is the starting node of the workflow
          - `is_guardrail_node` boolean — Whether this node is a guardrail node. When the workflow-level `miscellaneous.no_hopping_between_guardrail_nodes` setting is enabled (the default), the runtime blocks conditional transitions from this guardrail node to any other guardrail node — including regular freeform/expression conditional edges and synthesized global-node edges. Self-edges and self-loops on the same guardrail node remain allowed.
          - `global_node_config` object, nullable — Configuration for when this node is a global node
            - `is_global` boolean — Whether this node is a global node available as a conditional pathway to all nodes in the workflow
            - `condition` ConditionConfig
              - …
            - `global_condition_edge_evaluation_method` 'workflow_default' | 'tool_call' | 'independent_llm_evaluations'
            - `reverse_conditional_edge` ConditionConfig
              - …
          - `self_loop_config` object, nullable — Bounded self-loop / retry policy for a node. When ``enabled``, the node re-executes its functionality repeatedly until ONE of the following happens, whichever comes first: 1. an outgoing conditional edge matches (the loop's exit), or 2. ``max_retries`` re-executions have been performed, or 3. the ``expiry_time`` wall-clock budget for the whole loop elapses. Outgoing conditional edges are re-evaluated after every execution to decide whether to exit (take a matching edge) or run again. When the loop stops without a matching exit edge, the runtime publishes a ``self_loop_outcome`` runtime variable (``"max_retries"`` | ``"expiry_time"``) that authors can branch on with a dedicated "exhausted"/"timeout" conditional edge. This is distinct from the LLM-node ``self_loop: bool`` flag, which governs loop-back while waiting for the next user message and is unaffected by this config.
            - `enabled` boolean — Re-execute this node until a conditional edge matches, max_retries is reached, or expiry_time elapses (whichever comes first).
            - `max_retries` integer, nullable — Maximum number of re-executions after the first attempt (total attempts = max_retries + 1). Leave empty for no bound by count.
            - `expiry_time` integer, nullable — Overall wall-clock budget in seconds for the whole self-loop. An execution still running when this elapses is terminated. Leave empty for no time bound. Note: a CPU-bound inline-Python body with no await points cannot be interrupted mid-execution; expiry reliably bounds I/O-bound work.
            - `time_between_retries` integer — Seconds to wait between the end of one execution and the start of the next.
          - `source_id` string, nullable — Source ID of the node
          - `department_id` integer, nullable — Department ID of the node
          - `api_key` string, nullable — API key for the node
          - `timezone` string, nullable — Timezone in IANA format ex: 'America/New_York'
          - `reminders` boolean, nullable — Whether to send reminders for the node
          - `slotfill_outreach` boolean, nullable — Whether to enable slot fill outreach for the node
          - `working_hours` object, nullable — Working hours for the node
            - `monday` StartEndTimings, required
              - …
            - `tuesday` StartEndTimings, required
              - …
            - `wednesday` StartEndTimings, required
              - …
            - `thursday` StartEndTimings, required
              - …
            - `friday` StartEndTimings, required
              - …
            - `saturday` StartEndTimings, required
              - …
            - `sunday` StartEndTimings, required
              - …
          - `use_cases` UseCase[] — Use cases for the node
          - `type` 'athena_appointments_create' — Type of the node. Must be 'athena_appointments_create'
          - `title` string, nullable — Title of the appointment
          - `patient_id` string, nullable — ID of the patient to create the appointment for
          - `practitioner_id` string, nullable — ID of the practitioner for the appointment
          - `start_time` string, nullable — Start time of the appointment
          - `duration_in_minutes` integer, nullable — Duration of the appointment in minutes
        - DeduplicateNodeConfigOutput
          - `logical_id` string, nullable — Unique identifier for the node
          - `name` string, nullable — Name of the node
          - `description` string, nullable — Description of the node
          - `workflow_id` string, nullable — The DB Object ID of the workflow this entity belongs to
          - `version_number` integer, nullable — Version number of the workflow this entity belongs to. 0 is the initial version (default).
          - `disabled` boolean — If true, this entity will be disabled and will not execute its function. Useful for testing workflows without actually executing this specific entity
          - `miscellaneous` object — Miscellaneous config data that can be used by the entity
          - `primary_category` string, nullable — Primary category of the node
          - `secondary_category` string, nullable — Secondary category of the node
          - `is_start` boolean — Whether this node is the starting node of the workflow
          - `is_guardrail_node` boolean — Whether this node is a guardrail node. When the workflow-level `miscellaneous.no_hopping_between_guardrail_nodes` setting is enabled (the default), the runtime blocks conditional transitions from this guardrail node to any other guardrail node — including regular freeform/expression conditional edges and synthesized global-node edges. Self-edges and self-loops on the same guardrail node remain allowed.
          - `global_node_config` object, nullable — Configuration for when this node is a global node
            - `is_global` boolean — Whether this node is a global node available as a conditional pathway to all nodes in the workflow
            - `condition` ConditionConfig
              - …
            - `global_condition_edge_evaluation_method` 'workflow_default' | 'tool_call' | 'independent_llm_evaluations'
            - `reverse_conditional_edge` ConditionConfig
              - …
          - `self_loop_config` object, nullable — Bounded self-loop / retry policy for a node. When ``enabled``, the node re-executes its functionality repeatedly until ONE of the following happens, whichever comes first: 1. an outgoing conditional edge matches (the loop's exit), or 2. ``max_retries`` re-executions have been performed, or 3. the ``expiry_time`` wall-clock budget for the whole loop elapses. Outgoing conditional edges are re-evaluated after every execution to decide whether to exit (take a matching edge) or run again. When the loop stops without a matching exit edge, the runtime publishes a ``self_loop_outcome`` runtime variable (``"max_retries"`` | ``"expiry_time"``) that authors can branch on with a dedicated "exhausted"/"timeout" conditional edge. This is distinct from the LLM-node ``self_loop: bool`` flag, which governs loop-back while waiting for the next user message and is unaffected by this config.
            - `enabled` boolean — Re-execute this node until a conditional edge matches, max_retries is reached, or expiry_time elapses (whichever comes first).
            - `max_retries` integer, nullable — Maximum number of re-executions after the first attempt (total attempts = max_retries + 1). Leave empty for no bound by count.
            - `expiry_time` integer, nullable — Overall wall-clock budget in seconds for the whole self-loop. An execution still running when this elapses is terminated. Leave empty for no time bound. Note: a CPU-bound inline-Python body with no await points cannot be interrupted mid-execution; expiry reliably bounds I/O-bound work.
            - `time_between_retries` integer — Seconds to wait between the end of one execution and the start of the next.
          - `type` 'deduplicate' — Type of the node. Must be 'deduplicate'
          - `input_runtime_variable_name` string, nullable — Name of the runtime variable that holds the list of objects to deduplicate
          - `dedup_key` string, nullable — Dot-notation key path used to identify duplicates (e.g. 'id', 'user.email'). The first object with a given key value is kept; subsequent ones are removed. Objects missing the key are always kept. Ignored if dedup_key_runtime_variable_name is set.
          - `dedup_key_runtime_variable_name` string, nullable — Name of the runtime variable holding the dot-notation key path. When set, this takes priority over the static dedup_key.
          - `output_runtime_variable_name` string, nullable — Name of the runtime variable where the deduplicated list will be stored
        - FieldExtractorNodeConfigOutput
          - `logical_id` string, nullable — Unique identifier for the node
          - `name` string, nullable — Name of the node
          - `description` string, nullable — Description of the node
          - `workflow_id` string, nullable — The DB Object ID of the workflow this entity belongs to
          - `version_number` integer, nullable — Version number of the workflow this entity belongs to. 0 is the initial version (default).
          - `disabled` boolean — If true, this entity will be disabled and will not execute its function. Useful for testing workflows without actually executing this specific entity
          - `miscellaneous` object — Miscellaneous config data that can be used by the entity
          - `primary_category` string, nullable — Primary category of the node
          - `secondary_category` string, nullable — Secondary category of the node
          - `is_start` boolean — Whether this node is the starting node of the workflow
          - `is_guardrail_node` boolean — Whether this node is a guardrail node. When the workflow-level `miscellaneous.no_hopping_between_guardrail_nodes` setting is enabled (the default), the runtime blocks conditional transitions from this guardrail node to any other guardrail node — including regular freeform/expression conditional edges and synthesized global-node edges. Self-edges and self-loops on the same guardrail node remain allowed.
          - `global_node_config` object, nullable — Configuration for when this node is a global node
            - `is_global` boolean — Whether this node is a global node available as a conditional pathway to all nodes in the workflow
            - `condition` ConditionConfig
              - …
            - `global_condition_edge_evaluation_method` 'workflow_default' | 'tool_call' | 'independent_llm_evaluations'
            - `reverse_conditional_edge` ConditionConfig
              - …
          - `self_loop_config` object, nullable — Bounded self-loop / retry policy for a node. When ``enabled``, the node re-executes its functionality repeatedly until ONE of the following happens, whichever comes first: 1. an outgoing conditional edge matches (the loop's exit), or 2. ``max_retries`` re-executions have been performed, or 3. the ``expiry_time`` wall-clock budget for the whole loop elapses. Outgoing conditional edges are re-evaluated after every execution to decide whether to exit (take a matching edge) or run again. When the loop stops without a matching exit edge, the runtime publishes a ``self_loop_outcome`` runtime variable (``"max_retries"`` | ``"expiry_time"``) that authors can branch on with a dedicated "exhausted"/"timeout" conditional edge. This is distinct from the LLM-node ``self_loop: bool`` flag, which governs loop-back while waiting for the next user message and is unaffected by this config.
            - `enabled` boolean — Re-execute this node until a conditional edge matches, max_retries is reached, or expiry_time elapses (whichever comes first).
            - `max_retries` integer, nullable — Maximum number of re-executions after the first attempt (total attempts = max_retries + 1). Leave empty for no bound by count.
            - `expiry_time` integer, nullable — Overall wall-clock budget in seconds for the whole self-loop. An execution still running when this elapses is terminated. Leave empty for no time bound. Note: a CPU-bound inline-Python body with no await points cannot be interrupted mid-execution; expiry reliably bounds I/O-bound work.
            - `time_between_retries` integer — Seconds to wait between the end of one execution and the start of the next.
          - `type` 'field_extractor' — Type of the node. Must be 'field_extractor'
          - `input_runtime_variable_name` string, nullable — Name of the runtime variable that holds the input JSON to be filtered
          - `keys_to_retain` string[] — Static list of key paths to retain in the output. Supports dot notation for nested keys (e.g. 'address.city'), bracket notation for arrays (e.g. 'orders[].id' for all elements, 'orders[1].id' for a specific index). Ignored if keys_to_retain_runtime_variable_name is set.
          - `keys_to_retain_runtime_variable_name` string, nullable — Name of the runtime variable holding the list of key paths to retain. When set, this takes priority over the static keys_to_retain list.
          - `output_runtime_variable_name` string, nullable — Name of the runtime variable where the extracted result will be stored
        - NoOpNodeConfigOutput — A node that runs and succeeds without doing anything else. Use it as a placeholder for an unbuilt step, as a fan-in junction so several branches can converge on a single outgoing edge, or as a deterministic zero-cost stand-in in tests. This is not the same as setting ``disabled=True``. A disabled node is skipped entirely and emits no events at all, so downstream conditional edges have nothing to branch on. A no-op node runs: it emits the usual start/end node events and writes a success flag to the thread state.
          - `logical_id` string, nullable — Unique identifier for the node
          - `name` string, nullable — Name of the node
          - `description` string, nullable — Description of the node
          - `workflow_id` string, nullable — The DB Object ID of the workflow this entity belongs to
          - `version_number` integer, nullable — Version number of the workflow this entity belongs to. 0 is the initial version (default).
          - `disabled` boolean — If true, this entity will be disabled and will not execute its function. Useful for testing workflows without actually executing this specific entity
          - `miscellaneous` object — Miscellaneous config data that can be used by the entity
          - `primary_category` string, nullable — Primary category of the node
          - `secondary_category` string, nullable — Secondary category of the node
          - `is_start` boolean — Whether this node is the starting node of the workflow
          - `is_guardrail_node` boolean — Whether this node is a guardrail node. When the workflow-level `miscellaneous.no_hopping_between_guardrail_nodes` setting is enabled (the default), the runtime blocks conditional transitions from this guardrail node to any other guardrail node — including regular freeform/expression conditional edges and synthesized global-node edges. Self-edges and self-loops on the same guardrail node remain allowed.
          - `global_node_config` object, nullable — Configuration for when this node is a global node
            - `is_global` boolean — Whether this node is a global node available as a conditional pathway to all nodes in the workflow
            - `condition` ConditionConfig
              - …
            - `global_condition_edge_evaluation_method` 'workflow_default' | 'tool_call' | 'independent_llm_evaluations'
            - `reverse_conditional_edge` ConditionConfig
              - …
          - `self_loop_config` object, nullable — Bounded self-loop / retry policy for a node. When ``enabled``, the node re-executes its functionality repeatedly until ONE of the following happens, whichever comes first: 1. an outgoing conditional edge matches (the loop's exit), or 2. ``max_retries`` re-executions have been performed, or 3. the ``expiry_time`` wall-clock budget for the whole loop elapses. Outgoing conditional edges are re-evaluated after every execution to decide whether to exit (take a matching edge) or run again. When the loop stops without a matching exit edge, the runtime publishes a ``self_loop_outcome`` runtime variable (``"max_retries"`` | ``"expiry_time"``) that authors can branch on with a dedicated "exhausted"/"timeout" conditional edge. This is distinct from the LLM-node ``self_loop: bool`` flag, which governs loop-back while waiting for the next user message and is unaffected by this config.
            - `enabled` boolean — Re-execute this node until a conditional edge matches, max_retries is reached, or expiry_time elapses (whichever comes first).
            - `max_retries` integer, nullable — Maximum number of re-executions after the first attempt (total attempts = max_retries + 1). Leave empty for no bound by count.
            - `expiry_time` integer, nullable — Overall wall-clock budget in seconds for the whole self-loop. An execution still running when this elapses is terminated. Leave empty for no time bound. Note: a CPU-bound inline-Python body with no await points cannot be interrupted mid-execution; expiry reliably bounds I/O-bound work.
            - `time_between_retries` integer — Seconds to wait between the end of one execution and the start of the next.
          - `type` 'no_op' — Type of the node. Must be 'no_op'
          - `note` string, nullable — Free-text note explaining why this placeholder is here (e.g. 'TODO: replace with the eligibility check'). Never read at runtime.
          - `output_runtime_variable_name` string, nullable — Base name for the runtime variables written by this node. '<name>' is set to None and '<name>_success' is set to the run outcome, so conditional edges can branch on this node.
          - `delay_seconds` number, nullable — Testing only. Number of seconds to wait before finishing, used to simulate a slow node. Leave at 0 for a real placeholder.
          - `simulate_failure` boolean — Testing only. When true the node still completes normally but reports success=False, so failure branches can be exercised without a real failing integration. The workflow is never aborted by this flag.
    - `edge_configs` union[] — List of edge configurations for runtime
      - union
        - DirectEdgeConfigOutput
          - `logical_id` string, nullable — Unique identifier for the edge
          - `name` string, nullable — Name of the edge
          - `description` string, nullable — Description of the edge
          - `workflow_id` string, nullable — The DB Object ID of the workflow this entity belongs to
          - `version_number` integer, nullable — Version number of the workflow this entity belongs to. 0 is the initial version (default).
          - `disabled` boolean — If true, this entity will be disabled and will not execute its function. Useful for testing workflows without actually executing this specific entity
          - `miscellaneous` object — Miscellaneous config data that can be used by the entity
          - `source_node_logical_id` string, nullable — Logical ID of the source node for this edge
          - `destination_node_logical_id` string, nullable — Logical ID of the target node for this edge
          - `type` 'direct' — Type of the edge. Expected to be always 'direct' for this base config
          - `companion_thread_config` CompanionThreadConfig — Compound companion-thread settings for a direct edge, grouping the two related fields so their relationship is explicit in the authoring UI and the stored config.
            - `is_companion_thread` boolean — When a node has multiple outgoing direct edges, edges with this flag set to True spawn companion threads that run alongside the single main thread (the one edge with this flag False). Companion threads keep executing and emitting events while the main thread waits for user input, and never receive UI user messages. A lone direct edge always continues the main thread regardless of this flag.
            - `thread_id` string, nullable — Author-chosen id for the forked companion thread. Other threads read this companion's runtime variables via [[thread_<thread_id>.<var>]], and the companion reads the main thread via [[thread_0.<var>]]. Must be unique across the workflow's companion edges, non-empty, and use only [A-Za-z0-9_-] (no '.', no '_companion_', and not the reserved id '0'). Optional: if omitted, a uuid is generated at fork time and the companion is not addressable via a cross-thread reference.
        - ConditionalEdgeConfigOutput
          - `logical_id` string, nullable — Unique identifier for the edge
          - `name` string, nullable — Name of the edge
          - `description` string, nullable — Description of the edge
          - `workflow_id` string, nullable — The DB Object ID of the workflow this entity belongs to
          - `version_number` integer, nullable — Version number of the workflow this entity belongs to. 0 is the initial version (default).
          - `disabled` boolean — If true, this entity will be disabled and will not execute its function. Useful for testing workflows without actually executing this specific entity
          - `miscellaneous` object — Miscellaneous config data that can be used by the entity
          - `source_node_logical_id` string, nullable — Logical ID of the source node for this edge
          - `destination_node_logical_id` string, nullable — Logical ID of the target node for this edge
          - `type` 'conditional' — Type of the edge. Expected to be always 'conditional' for this config
          - `condition` ConditionConfig
            - `condition_freeform` string, nullable — Condition (expressed in natural language) that determines whether this path is taken
            - `condition_expression` string, nullable — Condition (expressed in a structured equation with variables) that determines whether this path is taken
            - `args_schema` object, nullable — JSON Schema describing the arguments that will be passed when condition_freeform is evaluated
            - `static_messages_config` StaticMessagesConfig
              - …
            - `dynamic_messages_config` DynamicMessagesConfig
              - …
          - `evaluate_while_waiting_config` EvaluateWhileWaitingConfig — Opt-in: evaluate this conditional edge's ``condition_expression`` while the SOURCE node is parked waiting for a user message, and take the edge if it becomes True — with no user message required. Without this config a conditional edge is evaluated at exactly one moment: immediately after each execution of its source node. A ``say_llm`` node with ``self_loop`` + ``wait_for_user_message`` therefore parks indefinitely, and a runtime variable that flips in the background (e.g. written by a polling node in a companion thread) cannot move the conversation forward on its own. Only valid on an edge whose condition uses ``condition_expression``; ``condition_freeform`` conditions need an LLM call per evaluation and are rejected rather than silently ignored. See ``WorkflowRuntime._validate_waiting_evaluated_edges`` for the full validation matrix.
            - `enabled` boolean — When True, this edge is also evaluated while its source node is parked waiting for user input, and is taken if the expression becomes True.
            - `trigger_mode` 'on_node_completion' | 'on_every_background_tick' — What arms an evaluation of a conditional edge while its source node waits for user input.
            - `trigger_node_logical_ids` string[] — Node logical ids whose completion arms one evaluation of this edge. Required when trigger_mode is 'on_node_completion'. Nodes may live in any thread — typically a companion-thread node that updates the runtime variable this expression reads.
            - `min_seconds_between_evaluations` number, nullable — Debounce: an armed evaluation waits until this many seconds after the previous one. REQUIRED (and must be > 0) when trigger_mode is 'on_every_background_tick', because that mode is always armed — without a debounce it would evaluate on every background pass, spinning the driver loop and flooding the run record. Optional for 'on_node_completion', which is already bounded by how often the trigger node completes. 0 means no debounce and is only meaningful for 'on_node_completion'.
            - `max_transitions_per_wait` integer — Hard bound on how many times this edge may fire during a single uninterrupted wait (reset when a user message is received). Guards against background hop loops in which no user is ever given a turn.
        - CompanionEdgeConfigOutput
          - `logical_id` string, nullable — Unique identifier for the edge
          - `name` string, nullable — Name of the edge
          - `description` string, nullable — Description of the edge
          - `workflow_id` string, nullable — The DB Object ID of the workflow this entity belongs to
          - `version_number` integer, nullable — Version number of the workflow this entity belongs to. 0 is the initial version (default).
          - `disabled` boolean — If true, this entity will be disabled and will not execute its function. Useful for testing workflows without actually executing this specific entity
          - `miscellaneous` object — Miscellaneous config data that can be used by the entity
          - `source_node_logical_id` string, nullable — Logical ID of the source node for this edge
          - `destination_node_logical_id` string, nullable — Logical ID of the target node for this edge
          - `type` 'companion' — Type of the edge. Expected to be always 'companion' for this config
    - `dynamic_variables` object — Dynamic variables that can be used across nodes and edges
    - `runtime_variables` object — Runtime variables that can be used across nodes and edges

## Other responses

- `422` — Validation Error

## Changes

- **2026-08-27** `35cbea12a781` — 4 info
  - the `llms_config` response's property default value changed from `{"logical_id":"llm_9dec1f99-a33e-4abe-b971-8f3e409cc617","provider":"default_provider","streaming":false,"max_retries":3,"max_parse_retries":3,"model_kwargs":{},"do_not_split_sentences":false,"type":"no_llm"}` to `{"logical_id":"llm_bbd2f738-3c3d-42f0-baaf-293ac91c24c4","provider":"default_provider","streaming":false,"max_retries":3,"max_parse_retries":3,"model_kwargs":{},"do_not_split_sentences":false,"type":"no_llm"}` for the status `200`
  - the `llms_config` response's property default value changed from `{"logical_id":"llm_f4d38a71-aa7d-4005-9e67-e4d4415852f6","provider":"default_provider","streaming":false,"max_retries":3,"max_parse_retries":3,"model_kwargs":{},"do_not_split_sentences":false,"type":"global_default_llm"}` to `{"logical_id":"llm_a7f2c24c-3ce7-4519-b8bc-78f17f76968e","provider":"default_provider","streaming":false,"max_retries":3,"max_parse_retries":3,"model_kwargs":{},"do_not_split_sentences":false,"type":"global_default_llm"}` for the status `200`
  - the `llms_config` response's property default value changed from `{"logical_id":"llm_f4d38a71-aa7d-4005-9e67-e4d4415852f6","provider":"default_provider","streaming":false,"max_retries":3,"max_parse_retries":3,"model_kwargs":{},"do_not_split_sentences":false,"type":"global_default_llm"}` to `{"logical_id":"llm_a7f2c24c-3ce7-4519-b8bc-78f17f76968e","provider":"default_provider","streaming":false,"max_retries":3,"max_parse_retries":3,"model_kwargs":{},"do_not_split_sentences":false,"type":"global_default_llm"}` for the status `200`
  - the `llms_config` response's property default value changed from `{"logical_id":"llm_f4d38a71-aa7d-4005-9e67-e4d4415852f6","provider":"default_provider","streaming":false,"max_retries":3,"max_parse_retries":3,"model_kwargs":{},"do_not_split_sentences":false,"type":"global_default_llm"}` to `{"logical_id":"llm_a7f2c24c-3ce7-4519-b8bc-78f17f76968e","provider":"default_provider","streaming":false,"max_retries":3,"max_parse_retries":3,"model_kwargs":{},"do_not_split_sentences":false,"type":"global_default_llm"}` for the status `200`
- …earlier changes not shown

[Full history](https://skmtc.dev/interactly/apis/interactly-api-3/changes/workflows/v1/super-nodes/:workflow_id/get.md)

---

[API](https://skmtc.dev/interactly/apis/interactly-api-3.md) · [All operations](https://skmtc.dev/interactly/apis/interactly-api-3/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/interactly/interactly-api-3/revisions/35cbea12a781/schema)
