Callback webhooks allow Agent Loops to send results to external systems when execution completes. Use callbacks to integrate agent workflows with your applications, trigger subsequent actions, or deliver reports.
Overview
A callback is an HTTP POST request sent to your specified endpoint when an Agent Loop finishes:
Agent Loop Executes → Completes Task → Sends POST to Your Webhook
Your webhook receives the agent’s output and can process it however needed.
Configuring Callbacks
Create/Edit Agent Loop
Open the agent loop you want to configure.
Find Callback Section
Scroll to the Callback Webhook configuration section.
Enter Webhook URL
Provide your webhook endpoint: https://your-domain.com/agent-results
Add Headers (Optional)
Include authentication or custom headers: Authorization: Bearer YOUR_TOKEN
X-Custom-Header: value
Save
Click Save to enable callbacks.
Callback Payload
Your webhook receives a POST request with this JSON structure:
{
"agent_loop_id" : "loop_abc123" ,
"agent_loop_name" : "Daily Sales Report" ,
"execution_id" : "exec_xyz789" ,
"status" : "completed" ,
"result" : {
"output" : "Sales Report for January 15, 2024 \n\n Total Revenue: $12,450..." ,
"iterations_used" : 5 ,
"tool_calls" : 3
},
"metadata" : {
"started_at" : "2024-01-15T10:00:00Z" ,
"completed_at" : "2024-01-15T10:02:30Z" ,
"duration_seconds" : 150 ,
"model" : "gpt-4" ,
"tokens_used" : 1250
},
"error" : null
}
Payload Fields
Field Type Description agent_loop_idstring Unique agent loop identifier agent_loop_namestring Display name of the agent loop execution_idstring Unique execution identifier statusstring completed, failed, or timeoutresult.outputstring The agent’s final response result.iterations_usednumber Reasoning steps taken result.tool_callsnumber Tools used during execution metadataobject Execution timing and stats errorstring/null Error message if failed
Status Values
completed : Agent successfully finished the task
{
"status" : "completed" ,
"result" : { "output" : "..." },
"error" : null
}
failed : Agent encountered an error
{
"status" : "failed" ,
"result" : null ,
"error" : "Tool call failed: HTTP 500 from API"
}
timeout : Execution exceeded time limit
{
"status" : "timeout" ,
"result" : { "output" : "Partial result..." },
"error" : "Execution timeout after 300 seconds"
}
Implementing a Callback Webhook
Example: Node.js/Express
const express = require ( 'express' );
const app = express ();
app . use ( express . json ());
app . post ( '/agent-results' , ( req , res ) => {
const {
agent_loop_id ,
agent_loop_name ,
status ,
result ,
error
} = req . body ;
console . log ( `Agent Loop " ${ agent_loop_name } " ${ status } ` );
if ( status === 'completed' ) {
// Process successful result
const output = result . output ;
// Example: Send to Slack
sendToSlack ({
text: `Agent Report: \n\n ${ output } `
});
// Example: Save to database
database . saveReport ({
agent_loop_id ,
output ,
created_at: new Date ()
});
} else if ( status === 'failed' ) {
// Handle error
console . error ( `Agent failed: ${ error } ` );
// Send alert
sendAlert ({
title: 'Agent Loop Failed' ,
message: error
});
}
// Acknowledge receipt
res . json ({ received: true });
});
app . listen ( 3000 );
Example: Python/Flask
from flask import Flask, request, jsonify
import requests
app = Flask( __name__ )
@app.route ( '/agent-results' , methods = [ 'POST' ])
def agent_callback ():
data = request.json
agent_name = data[ 'agent_loop_name' ]
status = data[ 'status' ]
if status == 'completed' :
output = data[ 'result' ][ 'output' ]
# Send to Slack
slack_webhook_url = 'https://hooks.slack.com/services/YOUR/WEBHOOK/URL'
requests.post(slack_webhook_url, json = {
'text' : f 'Agent Report from { agent_name } : \n\n { output } '
})
# Log to file
with open ( 'agent_reports.txt' , 'a' ) as f:
f.write( f ' \n\n === { agent_name } === \n { output } \n ' )
elif status == 'failed' :
error = data[ 'error' ]
print ( f 'Agent { agent_name } failed: { error } ' )
return jsonify({ 'received' : True })
if __name__ == '__main__' :
app.run( port = 3000 )
Response Expected
Your webhook should return a JSON response with HTTP 200 status:
Optional fields:
{
"received" : true ,
"processed" : true ,
"message" : "Report saved successfully"
}
If your webhook returns an error status (4xx or 5xx), the callback will be retried (coming soon).
Use Cases
Forward agent results to Slack, Teams, or Discord:
async function sendToSlack ( output ) {
await fetch ( process . env . SLACK_WEBHOOK_URL , {
method: 'POST' ,
headers: { 'Content-Type' : 'application/json' },
body: JSON . stringify ({
text: output ,
username: 'Agent Bot' ,
icon_emoji: ':robot_face:'
})
});
}
Save to Database
Store results for historical tracking:
async function saveToDatabase ( data ) {
await db . agentResults . insert ({
agent_loop_id: data . agent_loop_id ,
execution_id: data . execution_id ,
output: data . result . output ,
status: data . status ,
created_at: new Date ( data . metadata . completed_at )
});
}
Trigger Workflows
Start additional workflows based on results:
if ( result . output . includes ( 'ERROR' )) {
// Trigger incident response
await createIncident ({
title: 'Agent Loop Error Detected' ,
description: result . output
});
}
Send Emails
Email reports to stakeholders:
if ( status === 'completed' ) {
await sendEmail ({
to: 'team@company.com' ,
subject: `Daily Report from ${ agent_loop_name } ` ,
body: result . output
});
}
Security
Use HTTPS Always use HTTPS endpoints for callbacks
Authenticate Requests Verify requests come from Chatbot Platform
Validate Payload Check payload structure before processing
Rate Limiting Implement rate limits on your endpoint
Authenticating Callbacks
Add a secret token to callback headers:
Agent Loop Configuration :
Callback URL: https://your-domain.com/agent-results
Headers:
X-Webhook-Secret: your-secret-token-here
Your Webhook :
app . post ( '/agent-results' , ( req , res ) => {
const secret = req . headers [ 'x-webhook-secret' ];
if ( secret !== process . env . WEBHOOK_SECRET ) {
return res . status ( 401 ). json ({ error: 'Unauthorized' });
}
// Process callback...
});
Request Signature (Coming Soon)
Future support for HMAC-SHA256 signature verification:
X-Signature: sha256=abc123...
Your webhook would verify the signature matches the payload.
Testing Callbacks
Manual Testing
Use a service like webhook.site:
Configure Agent Loop
Set the webhook.site URL as your callback URL.
Run Agent Loop
Execute the agent loop manually.
View Request
Check webhook.site to see the callback payload.
Local Testing with Ngrok
Test with your local development server:
Use Ngrok URL
Configure agent loop with the ngrok URL: https://abc123.ngrok.io/agent-results
Run Agent
Execute and receive callback on your local server.
Troubleshooting
Callback Not Received
Check :
Callback URL is correct and accessible
Your endpoint is running
Firewall allows incoming requests
Agent loop completed successfully
Callback Failed
Check :
Endpoint returns 200 status
Response is valid JSON
No timeout on your endpoint
Check execution logs for details
Duplicate Callbacks
If you receive multiple callbacks:
Check for retry logic (future feature)
Verify webhook is not called multiple times in your code
Use execution_id to deduplicate
Best Practices
Always respond with HTTP 200 status quickly. Process the callback data asynchronously if it takes time.
Do :
Return 200 immediately
Process data in background jobs
Log all callbacks for debugging
Validate payload structure
Handle errors gracefully
Don’t :
Perform long operations synchronously
Return errors for non-critical issues
Skip authentication
Assume payload structure won’t change
Async Processing Pattern
app . post ( '/agent-results' , async ( req , res ) => {
const data = req . body ;
// Immediately acknowledge
res . json ({ received: true });
// Process asynchronously
processCallback ( data ). catch ( err => {
console . error ( 'Callback processing failed:' , err );
});
});
async function processCallback ( data ) {
// Long-running operations here
await saveToDatabase ( data );
await sendNotifications ( data );
await triggerWorkflows ( data );
}
Next Steps
Getting Started Create your first agent loop
MCP Servers Add tools to your agents