---
title: "Execute Tool Inline"
method: POST
path: "/workflows/v1/tools/execute"
tags: ["Tools"]
---

# Execute Tool Inline

`POST /workflows/v1/tools/execute`

Execute a fully inline tool config (not yet persisted) against the supplied argument values and
return its output.

Runtime failures (bad args, thrown exceptions, timeouts) are returned as HTTP 200 with
``success=False`` and a clean ``error`` message rather than a 500, so callers can render them inline.

Note: inline-Python tools run their code via ``exec`` server-side and are not sandboxed. This endpoint
is intended for authoring/debugging within a team's own workspace.

## Request body

- ToolExecuteInlineRequest
  - `tool_config` union, required — Full tool config to execute inline, before any tool record is persisted.
    - 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)
      - `logical_id` string, nullable — Unique identifier for the tool
      - `tool_id` string, nullable — Reference to the tool already created in the Workflow System. If not provided, the tool config is assumed to be provided inline here.
      - `name` string, nullable — Name for the tool
      - `description` string, nullable — Human friendly description for the tool (not used by AI)
      - `category` string, nullable — Category for the tool. E.g math, ehr, etc
      - `side_effect` string, nullable — Side-effect classification used by the test-tool feature to decide whether the tool can be safely executed directly, or must be dry-run / confirmation-gated first. One of 'none', 'reads', 'writes', 'sends', 'unknown'. When not set, it is inferred from the tool type.
      - `signature` string, nullable — Docstring or signature for the tool used by AI. If provided and there is a default signature already, it will override the default signature.
      - `args_schema` object, nullable — Schema for the arguments that the tool accepts. This should be a JSON schema dictionary. Information provided here will override any default arguments schema.
      - `static_messages_config` StaticMessagesConfig
        - `static_messages` string[] — List of pre-configured messages from which one will be emitted
        - `static_messages_selection_mode` 'random' | 'sequence'
      - `result_runtime_variable_name` string, nullable — Name of the runtime variable to store the result from this tool call
      - `ignore_content_received_during_llm_tool_call_specification` boolean — If true, any free-text content the LLM returns in the same response as a call to this tool is ignored: not emitted via AssistantResponseEvent, not added to chat history, and not added to the node's structured output. When a response contains multiple tool calls, the text is ignored only if every tool call targets a tool for which this flag is set.
      - `timeout_seconds` integer, nullable — Wall-clock ceiling in seconds for one invocation of this tool. Leave empty to use the platform default. Raise it for a tool that is legitimately slow (a large EHR sync, say) rather than letting it be cut off. Note: an inline-Python body that is CPU-bound with no await points cannot be interrupted - the timeout frees the conversation to continue, but the work carries on in the background.
      - `variable_arguments` ToolVariableArgument[] — Arguments supplied to this tool from the workflow's runtime/dynamic variables, resolved at invocation time and passed as native Python values. Use this instead of embedding [[variables]] in an inline tool's source code: the value keeps its type, and it is passed as an argument rather than spliced into the code.
        - `argument_name` string, required — The keyword argument name passed to the tool function.
        - `source` 'auto' | 'runtime' | 'dynamic' | 'literal' — Which namespace a variable-bound tool argument is read from.
        - `variable_path` string, nullable — Path to the value, e.g. 'patient_record', 'patient_record.dob', 'items[0].id', or a node-qualified key such as 'Collect Insurance.dob'. Required unless source is 'literal'.
        - `literal_value` unknown
        - `default` unknown
        - `required` boolean — When true, a missing variable fails the tool call with a named error instead of passing the default. Use for arguments the tool genuinely cannot run without.
        - `expose_to_llm` boolean — When false (the default) this argument is stripped from the args_schema the model sees, so the model is never asked for it and cannot supply it. Set true only when the model should be able to override the bound value.
        - `override_provided_value` boolean — When true the bound value replaces anything the caller (the model, or the node's tool_arguments) supplied under the same name. When false the bound value acts as a fallback used only if the caller omitted the argument.
      - `result_variable_mappings` ToolResultVariableMapping[] — Assigns parts of this tool's return value to named runtime variables, so a tool that returns a dict can populate several variables at once.
        - `target_variable_name` string, required — Runtime variable to write. Readable downstream as [[<name>]]. Must be a plain name: letters, digits and underscores, not starting with a digit or an underscore.
        - `result_path` string, nullable — Path into the returned value, e.g. 'score', 'patient.dob' or 'rows[0].id'. Leave empty to assign the whole return value.
        - `scope` 'thread' | 'workflow' — Which variable store a mapped tool result is written to.
        - `default` unknown
        - `required` boolean — When true, a missing result_path marks the tool call as failed and records the reason in <result_runtime_variable_name>_error, instead of writing the default.
      - `expand_result_into_runtime_variables` boolean — When true and the tool returns a dict, every top-level key is also written as a runtime variable of the same name. A convenience alternative to listing every mapping explicitly; explicit result_variable_mappings win on a name collision.
      - `type` 'inline_python' — Type of the tool. Must be 'inline_python'
      - `code` string, nullable — Python code to be executed by the tool. It should define a function with proper signature and descriptions for its parameters.
    - 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.
      - `logical_id` string, nullable — Unique identifier for the tool
      - `tool_id` string, nullable — Reference to the tool already created in the Workflow System. If not provided, the tool config is assumed to be provided inline here.
      - `name` string, nullable — Name for the tool
      - `description` string, nullable — Human friendly description for the tool (not used by AI)
      - `category` string, nullable — Category for the tool. E.g math, ehr, etc
      - `side_effect` string, nullable — Side-effect classification used by the test-tool feature to decide whether the tool can be safely executed directly, or must be dry-run / confirmation-gated first. One of 'none', 'reads', 'writes', 'sends', 'unknown'. When not set, it is inferred from the tool type.
      - `signature` string, nullable — Docstring or signature for the tool used by AI. If provided and there is a default signature already, it will override the default signature.
      - `args_schema` object, nullable — Schema for the arguments that the tool accepts. This should be a JSON schema dictionary. Information provided here will override any default arguments schema.
      - `static_messages_config` StaticMessagesConfig
        - `static_messages` string[] — List of pre-configured messages from which one will be emitted
        - `static_messages_selection_mode` 'random' | 'sequence'
      - `result_runtime_variable_name` string, nullable — Name of the runtime variable to store the result from this tool call
      - `ignore_content_received_during_llm_tool_call_specification` boolean — If true, any free-text content the LLM returns in the same response as a call to this tool is ignored: not emitted via AssistantResponseEvent, not added to chat history, and not added to the node's structured output. When a response contains multiple tool calls, the text is ignored only if every tool call targets a tool for which this flag is set.
      - `timeout_seconds` integer, nullable — Wall-clock ceiling in seconds for one invocation of this tool. Leave empty to use the platform default. Raise it for a tool that is legitimately slow (a large EHR sync, say) rather than letting it be cut off. Note: an inline-Python body that is CPU-bound with no await points cannot be interrupted - the timeout frees the conversation to continue, but the work carries on in the background.
      - `variable_arguments` ToolVariableArgument[] — Arguments supplied to this tool from the workflow's runtime/dynamic variables, resolved at invocation time and passed as native Python values. Use this instead of embedding [[variables]] in an inline tool's source code: the value keeps its type, and it is passed as an argument rather than spliced into the code.
        - `argument_name` string, required — The keyword argument name passed to the tool function.
        - `source` 'auto' | 'runtime' | 'dynamic' | 'literal' — Which namespace a variable-bound tool argument is read from.
        - `variable_path` string, nullable — Path to the value, e.g. 'patient_record', 'patient_record.dob', 'items[0].id', or a node-qualified key such as 'Collect Insurance.dob'. Required unless source is 'literal'.
        - `literal_value` unknown
        - `default` unknown
        - `required` boolean — When true, a missing variable fails the tool call with a named error instead of passing the default. Use for arguments the tool genuinely cannot run without.
        - `expose_to_llm` boolean — When false (the default) this argument is stripped from the args_schema the model sees, so the model is never asked for it and cannot supply it. Set true only when the model should be able to override the bound value.
        - `override_provided_value` boolean — When true the bound value replaces anything the caller (the model, or the node's tool_arguments) supplied under the same name. When false the bound value acts as a fallback used only if the caller omitted the argument.
      - `result_variable_mappings` ToolResultVariableMapping[] — Assigns parts of this tool's return value to named runtime variables, so a tool that returns a dict can populate several variables at once.
        - `target_variable_name` string, required — Runtime variable to write. Readable downstream as [[<name>]]. Must be a plain name: letters, digits and underscores, not starting with a digit or an underscore.
        - `result_path` string, nullable — Path into the returned value, e.g. 'score', 'patient.dob' or 'rows[0].id'. Leave empty to assign the whole return value.
        - `scope` 'thread' | 'workflow' — Which variable store a mapped tool result is written to.
        - `default` unknown
        - `required` boolean — When true, a missing result_path marks the tool call as failed and records the reason in <result_runtime_variable_name>_error, instead of writing the default.
      - `expand_result_into_runtime_variables` boolean — When true and the tool returns a dict, every top-level key is also written as a runtime variable of the same name. A convenience alternative to listing every mapping explicitly; explicit result_variable_mappings win on a name collision.
      - `type` 'inbuilt_function' — Type of the tool. Must be 'inbuilt_function'
      - `configurable_key` string, nullable — Stable key identifying which configurable inbuilt tool this is (e.g. 'call_forward'). None for plain static inbuilt references.
      - `extra_config` object, nullable — Tool-specific user configuration values. Schema is defined per configurable key.
    - ExternalAPIToolConfig — Configuration for an external API tool. This tool type represents an external API endpoint that the LLM can call.
      - `logical_id` string, nullable — Unique identifier for the tool
      - `tool_id` string, nullable — Reference to the tool already created in the Workflow System. If not provided, the tool config is assumed to be provided inline here.
      - `name` string, nullable — Name for the tool
      - `description` string, nullable — Human friendly description for the tool (not used by AI)
      - `category` string, nullable — Category for the tool. E.g math, ehr, etc
      - `side_effect` string, nullable — Side-effect classification used by the test-tool feature to decide whether the tool can be safely executed directly, or must be dry-run / confirmation-gated first. One of 'none', 'reads', 'writes', 'sends', 'unknown'. When not set, it is inferred from the tool type.
      - `signature` string, nullable — Docstring or signature for the tool used by AI. If provided and there is a default signature already, it will override the default signature.
      - `args_schema` object, nullable — Schema for the arguments that the tool accepts. This should be a JSON schema dictionary. Information provided here will override any default arguments schema.
      - `static_messages_config` StaticMessagesConfig
        - `static_messages` string[] — List of pre-configured messages from which one will be emitted
        - `static_messages_selection_mode` 'random' | 'sequence'
      - `result_runtime_variable_name` string, nullable — Name of the runtime variable to store the result from this tool call
      - `ignore_content_received_during_llm_tool_call_specification` boolean — If true, any free-text content the LLM returns in the same response as a call to this tool is ignored: not emitted via AssistantResponseEvent, not added to chat history, and not added to the node's structured output. When a response contains multiple tool calls, the text is ignored only if every tool call targets a tool for which this flag is set.
      - `timeout_seconds` integer, nullable — Wall-clock ceiling in seconds for one invocation of this tool. Leave empty to use the platform default. Raise it for a tool that is legitimately slow (a large EHR sync, say) rather than letting it be cut off. Note: an inline-Python body that is CPU-bound with no await points cannot be interrupted - the timeout frees the conversation to continue, but the work carries on in the background.
      - `variable_arguments` ToolVariableArgument[] — Arguments supplied to this tool from the workflow's runtime/dynamic variables, resolved at invocation time and passed as native Python values. Use this instead of embedding [[variables]] in an inline tool's source code: the value keeps its type, and it is passed as an argument rather than spliced into the code.
        - `argument_name` string, required — The keyword argument name passed to the tool function.
        - `source` 'auto' | 'runtime' | 'dynamic' | 'literal' — Which namespace a variable-bound tool argument is read from.
        - `variable_path` string, nullable — Path to the value, e.g. 'patient_record', 'patient_record.dob', 'items[0].id', or a node-qualified key such as 'Collect Insurance.dob'. Required unless source is 'literal'.
        - `literal_value` unknown
        - `default` unknown
        - `required` boolean — When true, a missing variable fails the tool call with a named error instead of passing the default. Use for arguments the tool genuinely cannot run without.
        - `expose_to_llm` boolean — When false (the default) this argument is stripped from the args_schema the model sees, so the model is never asked for it and cannot supply it. Set true only when the model should be able to override the bound value.
        - `override_provided_value` boolean — When true the bound value replaces anything the caller (the model, or the node's tool_arguments) supplied under the same name. When false the bound value acts as a fallback used only if the caller omitted the argument.
      - `result_variable_mappings` ToolResultVariableMapping[] — Assigns parts of this tool's return value to named runtime variables, so a tool that returns a dict can populate several variables at once.
        - `target_variable_name` string, required — Runtime variable to write. Readable downstream as [[<name>]]. Must be a plain name: letters, digits and underscores, not starting with a digit or an underscore.
        - `result_path` string, nullable — Path into the returned value, e.g. 'score', 'patient.dob' or 'rows[0].id'. Leave empty to assign the whole return value.
        - `scope` 'thread' | 'workflow' — Which variable store a mapped tool result is written to.
        - `default` unknown
        - `required` boolean — When true, a missing result_path marks the tool call as failed and records the reason in <result_runtime_variable_name>_error, instead of writing the default.
      - `expand_result_into_runtime_variables` boolean — When true and the tool returns a dict, every top-level key is also written as a runtime variable of the same name. A convenience alternative to listing every mapping explicitly; explicit result_variable_mappings win on a name collision.
      - `type` 'external_api' — Type of the tool. Must be 'external_api'
      - `api_endpoint` string, nullable — The endpoint URL of the external API
      - `api_method` 'GET' | 'POST' | 'PUT' | 'DELETE' — Enumeration of HTTP methods for API calls.
      - `api_headers` object — HTTP headers to include with the API request (e.g., authorization, content-type)
      - `api_body` union — The request body payload for the API call. Usually applicable for POST/PUT methods.
        - object
        - string
      - `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.
    - KnowledgeBaseToolConfig — Configuration for a knowledge base tool. This tool type represents a knowledge base endpoint that the LLM can call.
      - `logical_id` string, nullable — Unique identifier for the tool
      - `tool_id` string, nullable — Reference to the tool already created in the Workflow System. If not provided, the tool config is assumed to be provided inline here.
      - `name` string, nullable — Name for the tool
      - `description` string, nullable — Human friendly description for the tool (not used by AI)
      - `category` string, nullable — Category for the tool. E.g math, ehr, etc
      - `side_effect` string, nullable — Side-effect classification used by the test-tool feature to decide whether the tool can be safely executed directly, or must be dry-run / confirmation-gated first. One of 'none', 'reads', 'writes', 'sends', 'unknown'. When not set, it is inferred from the tool type.
      - `signature` string, nullable — Docstring or signature for the tool used by AI. If provided and there is a default signature already, it will override the default signature.
      - `args_schema` object, nullable — Schema for the arguments that the tool accepts. This should be a JSON schema dictionary. Information provided here will override any default arguments schema.
      - `static_messages_config` StaticMessagesConfig
        - `static_messages` string[] — List of pre-configured messages from which one will be emitted
        - `static_messages_selection_mode` 'random' | 'sequence'
      - `result_runtime_variable_name` string, nullable — Name of the runtime variable to store the result from this tool call
      - `ignore_content_received_during_llm_tool_call_specification` boolean — If true, any free-text content the LLM returns in the same response as a call to this tool is ignored: not emitted via AssistantResponseEvent, not added to chat history, and not added to the node's structured output. When a response contains multiple tool calls, the text is ignored only if every tool call targets a tool for which this flag is set.
      - `timeout_seconds` integer, nullable — Wall-clock ceiling in seconds for one invocation of this tool. Leave empty to use the platform default. Raise it for a tool that is legitimately slow (a large EHR sync, say) rather than letting it be cut off. Note: an inline-Python body that is CPU-bound with no await points cannot be interrupted - the timeout frees the conversation to continue, but the work carries on in the background.
      - `variable_arguments` ToolVariableArgument[] — Arguments supplied to this tool from the workflow's runtime/dynamic variables, resolved at invocation time and passed as native Python values. Use this instead of embedding [[variables]] in an inline tool's source code: the value keeps its type, and it is passed as an argument rather than spliced into the code.
        - `argument_name` string, required — The keyword argument name passed to the tool function.
        - `source` 'auto' | 'runtime' | 'dynamic' | 'literal' — Which namespace a variable-bound tool argument is read from.
        - `variable_path` string, nullable — Path to the value, e.g. 'patient_record', 'patient_record.dob', 'items[0].id', or a node-qualified key such as 'Collect Insurance.dob'. Required unless source is 'literal'.
        - `literal_value` unknown
        - `default` unknown
        - `required` boolean — When true, a missing variable fails the tool call with a named error instead of passing the default. Use for arguments the tool genuinely cannot run without.
        - `expose_to_llm` boolean — When false (the default) this argument is stripped from the args_schema the model sees, so the model is never asked for it and cannot supply it. Set true only when the model should be able to override the bound value.
        - `override_provided_value` boolean — When true the bound value replaces anything the caller (the model, or the node's tool_arguments) supplied under the same name. When false the bound value acts as a fallback used only if the caller omitted the argument.
      - `result_variable_mappings` ToolResultVariableMapping[] — Assigns parts of this tool's return value to named runtime variables, so a tool that returns a dict can populate several variables at once.
        - `target_variable_name` string, required — Runtime variable to write. Readable downstream as [[<name>]]. Must be a plain name: letters, digits and underscores, not starting with a digit or an underscore.
        - `result_path` string, nullable — Path into the returned value, e.g. 'score', 'patient.dob' or 'rows[0].id'. Leave empty to assign the whole return value.
        - `scope` 'thread' | 'workflow' — Which variable store a mapped tool result is written to.
        - `default` unknown
        - `required` boolean — When true, a missing result_path marks the tool call as failed and records the reason in <result_runtime_variable_name>_error, instead of writing the default.
      - `expand_result_into_runtime_variables` boolean — When true and the tool returns a dict, every top-level key is also written as a runtime variable of the same name. A convenience alternative to listing every mapping explicitly; explicit result_variable_mappings win on a name collision.
      - `type` 'knowledge_base' — Type of the tool. Must be 'knowledge_base'
      - `target_knowledge_base_ids` string[] — The IDs of the knowledge bases to query
  - `args` object — Argument values to invoke the tool with, keyed by the tool's parameter names.
  - `dry_run` boolean — When True, side-effecting tools (writes/sends/unknown) are validated but NOT executed - no external effect occurs and a simulated result is returned. Pure/read-only tools run normally.
  - `dynamic_variables` object — Test values for {{dynamic}} placeholders in the tool config (endpoint/headers/body/code). Resolved before execution to mirror the live workflow runtime. The team's global variables are applied automatically, exactly as the live runtime does; values supplied here override them.
  - `runtime_variables` object — Test values for [[runtime]] placeholders in the tool config (endpoint/headers/body/code). Resolved before execution to mirror the live workflow runtime.

## Response `200`

Successful Response

- ToolExecuteResponse — The API's name for :class:`ToolExecutionResult`. Subclassed rather than aliased so the published OpenAPI schema keeps its name while the shape itself lives in the framework, shared with every other caller that executes a tool.
  - `success` boolean, required
  - `result` unknown
  - `error` string, nullable — Full human-readable error description when success is False. Always set on failure.
  - `latency_ms` integer, nullable — Wall-clock execution time in milliseconds.
  - `dry_run` boolean — Whether this run was a validate-only dry run.
  - `side_effect` string, nullable — The tool's side-effect classification (none/reads/writes/sends/unknown).
  - `error_type` string, nullable — Error category: validation | timeout | runtime | connection | http_status | not_found.
  - `error_code` string, nullable — Machine-readable error code: HTTP status (e.g. '404') for external API tools, or the exception class name (e.g. 'ValueError') otherwise.
  - `field_errors` object, nullable — Per-argument validation messages keyed by the offending field name.
  - `truncated` boolean — Whether the result was truncated because it was too large.

## Other responses

- `422` — Validation Error

## Changes

- **2026-08-19** `68e88496bf11` — 17 info
  - added the new optional request property `tool_config/oneOf[subschema #1: Inline Python Tool]/expand_result_into_runtime_variables`
  - added the new optional request property `tool_config/oneOf[subschema #1: Inline Python Tool]/result_variable_mappings`
  - added the new optional request property `tool_config/oneOf[subschema #1: Inline Python Tool]/timeout_seconds`
  - added the new optional request property `tool_config/oneOf[subschema #1: Inline Python Tool]/variable_arguments`
  - …13 more
- **2026-07-21** `d276be705570` — 13 info
  - added the new optional request property `dry_run`
  - added the new optional request property `dynamic_variables`
  - added the new optional request property `runtime_variables`
  - added the new optional request property `tool_config/oneOf[subschema #1: Inline Python Tool]/side_effect`
  - …9 more

[Change history](https://skmtc.dev/interactly/apis/interactly-api-3/changes/workflows/v1/tools/execute/post.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/68e88496bf11/schema)
