Make Your Agent Async
Enable async execution with webhooks.
When to Use Async Execution
Agentfield supports both synchronous and asynchronous execution patterns. Choose based on your workload characteristics:
| Factor | Use Sync (/execute/) | Use Async (/execute/async/) |
|---|---|---|
| Duration | < 90 seconds | Any duration (no timeout) |
| Response | Need immediate result | Can wait or use webhooks |
| Workflow | Sequential dependencies | Fire-and-forget, batch jobs |
| Connection | Can hold HTTP open | Avoid blocking connections |
| Use Case | Quick translations, validations | LLM reasoning, data processing, multi-step workflows |
Rule of thumb: If it involves LLM reasoning or takes > 10 seconds, use async.
Three Execution Patterns
Pattern 1: Synchronous - Immediate Results
Use for quick operations where you need the result before proceeding.
curl -X POST http://localhost:8080/api/v1/execute/hello-world.greet \
-H "Content-Type: application/json" \
-d '{
"input": {
"name": "Alice"
}
}'Response (HTTP 200, blocks until complete):
{
"execution_id": "exec_abc123",
"run_id": "run_xyz789",
"status": "succeeded",
"result": {
"greeting": "Hello, Alice!"
},
"duration_ms": 450,
"finished_at": "2025-01-15T10:30:00Z"
}Timeout: 90 seconds. Use async for longer tasks.
Pattern 2: Async + Webhooks - Event-Driven (Recommended)
Use for long-running tasks. Your endpoint receives the result when complete.
curl -X POST http://localhost:8080/api/v1/execute/async/research-agent.deep_analysis \
-H "Content-Type: application/json" \
-d '{
"input": {
"topic": "quantum computing applications"
},
"webhook": {
"url": "https://your-app.com/api/webhooks/agentfield",
"secret": "your-webhook-secret-key",
"headers": {
"X-Custom-ID": "request-123"
}
}
}'Immediate Response (HTTP 202):
{
"execution_id": "exec_abc123",
"run_id": "run_xyz789",
"status": "queued",
"target": "research-agent.deep_analysis",
"webhook_registered": true
}Your Webhook Receives (when complete):
{
"event": "execution.completed",
"execution_id": "exec_abc123",
"status": "succeeded",
"result": {
"analysis": "Quantum computing enables...",
"sources": [...]
},
"duration_ms": 45000
}Webhook Handler Example (Python/Flask):
import hmac
import hashlib
from flask import request, jsonify
@app.route('/api/webhooks/agentfield', methods=['POST'])
def handle_agentfield_webhook():
# Verify signature
signature = request.headers.get('X-AgentField-Signature')
payload = request.get_data()
expected_sig = "sha256=" + hmac.new(
b"your-webhook-secret-key",
payload,
hashlib.sha256
).hexdigest()
if not hmac.compare_digest(signature, expected_sig):
return jsonify({"error": "invalid signature"}), 401
# Process result
data = request.json
execution_id = data["execution_id"]
result = data["result"]
# Your business logic here
process_research_analysis(execution_id, result)
return jsonify({"received": True}), 200Why webhooks?
- No polling overhead
- Instant notification
- Scales to thousands of concurrent executions
- Production-grade (retries, signatures, delivery tracking)
See Webhooks Documentation for security best practices.
Pattern 3: Async + Polling - Simple Integration
Use when you can't expose a webhook endpoint (firewalls, local development).
# 1. Start execution
curl -X POST http://localhost:8080/api/v1/execute/async/doc-processor.analyze \
-H "Content-Type: application/json" \
-d '{
"input": {
"document_url": "https://example.com/report.pdf"
}
}'Response:
{
"execution_id": "exec_abc123",
"status": "queued"
}# 2. Poll for status (every 2-5 seconds)
curl http://localhost:8080/api/v1/executions/exec_abc123While Running:
{
"execution_id": "exec_abc123",
"status": "running",
"started_at": "2025-01-15T10:29:00Z"
}When Complete:
{
"execution_id": "exec_abc123",
"status": "succeeded",
"result": {
"summary": "Document contains...",
"entities": [...]
},
"duration_ms": 12000,
"completed_at": "2025-01-15T10:29:12Z"
}Polling with Exponential Backoff (JavaScript):
async function pollExecution(executionId, maxAttempts = 60) {
let attempt = 0;
let delay = 1000; // Start with 1s
while (attempt < maxAttempts) {
const response = await fetch(
`http://localhost:8080/api/v1/executions/${executionId}`
);
const data = await response.json();
if (data.status === 'succeeded') {
return data.result;
}
if (data.status === 'failed') {
throw new Error(data.error);
}
// Still running, wait and retry
await new Promise(resolve => setTimeout(resolve, delay));
delay = Math.min(delay * 1.5, 10000); // Cap at 10s
attempt++;
}
throw new Error('Execution timeout');
}
// Usage
const result = await pollExecution('exec_abc123');Batch Status Check:
curl -X POST http://localhost:8080/api/v1/executions/batch-status \
-H "Content-Type: application/json" \
-d '{
"execution_ids": ["exec_1", "exec_2", "exec_3"]
}'Response:
{
"exec_1": {"status": "succeeded", "result": {...}},
"exec_2": {"status": "running"},
"exec_3": {"status": "failed", "error": "timeout"}
}Error Handling
All execution patterns return consistent status values:
| Status | Meaning | Action |
|---|---|---|
queued | Waiting in worker queue | Poll or wait for webhook |
running | Currently executing | Poll or wait for webhook |
succeeded | Completed successfully | Use result field |
failed | Execution error | Check error field |
timeout | Exceeded time limit | Retry or redesign |
cancelled | Manually stopped | No result available |
Sync Execution Errors:
{
"error": "Agent timeout",
"details": "Execution exceeded 90 second limit",
"execution_id": "exec_abc123"
}Async Webhook Failure Event:
{
"event": "execution.failed",
"execution_id": "exec_abc123",
"status": "failed",
"error": "LLM API rate limit exceeded",
"timestamp": "2025-01-15T10:30:00Z"
}Webhook Delivery Tracking:
curl http://localhost:8080/api/v1/executions/exec_abc123{
"execution_id": "exec_abc123",
"status": "succeeded",
"webhook_registered": true,
"webhook_events": [
{
"attempt": 1,
"http_status": 500,
"timestamp": "2025-01-15T10:30:00Z"
},
{
"attempt": 2,
"http_status": 200,
"timestamp": "2025-01-15T10:30:05Z"
}
]
}Webhooks retry up to 5 times with exponential backoff. Check webhook_events if you're not receiving callbacks.
Quick Start Checklist
-
Choose your pattern:
- Fast task? → Sync
- Long task + production? → Async + webhooks
- Long task + development? → Async + polling
-
For webhooks:
- Expose HTTPS endpoint
- Verify HMAC-SHA256 signature
- Return 200 OK quickly (process async internally)
- Handle both
execution.completedandexecution.failedevents
-
For polling:
- Use exponential backoff (start 1s, max 10s)
- Check batch status for multiple executions
- Set reasonable timeout (e.g., 60 attempts = ~10 minutes)
-
Error handling:
- Check
statusfield - Handle
failedandtimeoutstates - Log
execution_idfor debugging
- Check
Next Steps
- Async Execution Example - Complete working implementation
- REST API Reference - Full endpoint documentation
- Webhooks Guide - Security and best practices
- Core Concepts - Architecture deep dive