Skip to main content
Use callbacks to invoke a tool when specific events occur during an agentic workflow. Callbacks are fire-and-forget, the workflow engine invokes the registered tool and ignores its return value. Callbacks are part of the workflow specification and are serialized into the compiled flow JSON. The tools that you register as callbacks must already be deployed in watsonx Orchestrate, since they are not runtime Python callables. To configure a callback, call the add_callback() method on your Flow instance. The method creates a FlowCallback object, appends it to the workflow specification, and returns Self to support method chaining. Call add_callback() multiple times to register separate callbacks for different event sets.
string
required
The identifier of the deployed tool to invoke when the callback fires. Use one of the following formats:
  • tool_name: The tool name only.
  • tool_name:tool_uuid: The tool name with a specific instance UUID.
  • toolkit:tool_name: The tool scoped to a toolkit.
  • toolkit:tool_name:tool_uuid: The toolkit-scoped tool with a specific instance UUID.
List[FlowCallbackEventKind]
required
The lifecycle events that trigger this callback. Specify at least one value. For all available values, see Events reference.
int
The time, in milliseconds, that the engine waits to accumulate events before it dispatches a single batched invocation. If you omit this parameter, the server default applies.

Batching rules

The flow engine batches callback events before it invokes the registered tool. The following rules govern how and when the engine dispatches a batch:
  • The engine accumulates events for the duration specified by batch_interval before it dispatches a single invocation. If you omit batch_interval, the server default applies.
  • When a blocking event is dispatched, the engine immediately flushes all events that are currently queued for that callback. If the callback tool is registered for both blocking and non-blocking events, the queued non-blocking events are dispatched at flush time regardless of whether the batch timer has elapsed.

Events reference

The following FlowCallbackEventKind members and their wire values are available. Pass any combination to add_callback(events=[...]).
flow:on_flow_start
The flow started execution.
flow:on_flow_end
The flow completed successfully.
flow:on_flow_error
The flow failed with an error.
flow:on_flow_abort
An external action aborted the flow instance.
flow:on_flow_delete
The flow instance was deleted.
task:on_task_wait
A task is waiting for user input (elicitation). The callback payload includes an elicitation object that describes the required input.
task:on_task_error
A task failed during execution.
task:on_task_message
A task generated a message.

Callback event payload

The flow engine calls the registered tool and passes a FlowCallbackEventsPayload object as input.

FlowCallbackEventsPayload

List[FlowCallbackEventPayload]
required
One or more event payloads delivered in this callback invocation.

FlowCallbackEventPayload

EventMetadata
required
Metadata that describes the event: its kind, when it occurred, the flow instance it belongs to, and any task or error context.
dict
The flow output value. Present only when state is completed.
ElicitationDetails
Details of the pending user input request. Present only when state is input_required, which corresponds to ON_TASK_WAIT events.

EventMetadata

string
required
A unique identifier for this event occurrence.
string
required
One of the wire strings listed in the Events reference.
string
required
An ISO 8601 timestamp that records when the event occurred.
string
required
A unique identifier for the running flow instance that generated this event.
string
required
The name of the flow.
string
required
The environment where the flow is running, for example draft or live.
string
required
The execution state of the flow when the event fired. Valid values are working, input_required, completed, failed, aborted, and deleted.
string
The parent flow instance ID. Present only when this flow is a child flow.
string
The parent flow name. Present only when this flow is a child flow.
string
The task ID. Present only for ON_TASK_* events.
string
The internal task name. Present only for ON_TASK_* events.
string
The human-readable task name. Present only for ON_TASK_* events.
ErrorDetails
Details of the error that caused the flow or task to fail. Present only for ON_FLOW_ERROR and ON_TASK_ERROR events. Contains message (string, required) and code (string, optional).

ElicitationDetails

Present only when state is input_required.
string
required
The elicitation mode. Currently always "form".
string
required
A message that describes the input that the user must provide.
string
required
A unique identifier for this elicitation request. The value is the same as task_id.
dict
required
A JSON Schema object that defines the expected structure, types, and validation rules for the user input.
string
required
The user ID or email address of the user who must provide the input.
list
required
An array of ResponseItem objects, where each object describes one input field. Supported response_type values: text, number, option, date, datetime, time, file_upload, file_download, object, and forms.

Building a compatible callback tool

The flow engine identifies compatible callback tools by matching the tool’s input schema against the FlowCallbackEventsPayload structure. You can register any of the following tool types as a callback: Python, OpenAPI, MCP, or Flow.
When you use a Flow tool as a callback, the callback flow must not contain user activity nodes. Callback flows run asynchronously and do not have access to the originating user’s chat thread, so the system cannot deliver user interactions inside a callback flow.
For more information, see Flow callback example.

FlowCallback direct construction

To build a callback object separately before you attach it, construct a FlowCallback directly and append it to aflow.spec.callbacks. The FlowCallback model mirrors the parameters of add_callback() exactly.
Flow.add_callback() is the preferred, higher-level API. Use direct FlowCallback construction only when you need to manipulate the spec list explicitly.

Example

The following example registers two callbacks on the same flow. The first callback handles flow-level lifecycle events and uses the server default batch interval. The second handles task-level events with a custom 30-second interval.
Python
For the full example and complete code, see Flow callback example.