Async and the response node

Topologies run asynchronously. A command is fire-and-forget, but a query needs to send a result back to the caller once the process finishes. Pulse handles this with a response node and a pair of reply headers.

Command vs query #

kind is derived from the topology, not declared:

  • A topology that contains a response node is a query. It returns data.
  • A topology without one is a command. It is fire-and-forget.

The response node #

Add a response node as the terminal step of a topology when you want it to return a payload. When the process reaches the response node, the data at that point is sent back to whoever started the run.

flowchart LR
  Start["Event start"] --> Work["Worker nodes"]
  Work --> Resp["Response node"]
  Resp --> Caller["Reply to the caller"]

Reply headers #

When you run a query, pass a callback so Pulse knows where to deliver the result:

curl -X POST https://your-instance.example.com/mcp/run \
  -H "X-Auth: <AGENT_API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{
    "tool": "topology:weather-report",
    "args": { "city": "Brno" },
    "reply_to": "https://your-agent.example.com/pulse/callback",
    "reply_id": "req-42"
  }'
FieldPurpose
reply_toWhere the response node posts the result.
reply_idYour correlation id, echoed back so you can match the response to the request.

The initial run response returns status: "pending". The actual payload arrives later, at reply_to, carrying your reply_id.

reply-to and reply-id travel as protected headers through the whole topology, so they survive every hop and reach the response node unchanged.

Output is returned verbatim #

By default a query result is returned as the topology produced it. It is not sent back through the model. A response can carry sensitive data, so any formatting should happen inside the topology. See output handling for the opt-in exception.

Where to go next #

© 2025 Orchesty Solutions. All rights reserved.