Building Reactive Agent Workflows with Anima Webhooks
Learn how to build event-driven AI agent architectures using Anima's webhook system for email, SMS, and voice events.
AI agents shouldn't just poll for data. They need to react to real-world events in real-time. Anima provides a robust webhook infrastructure that allows your agents to respond to inbound communication triggers immediately.
Event Types and Payload Structure#
Anima emits events for every major interaction within your agent's identity stack. Each payload follows a consistent schema, including an event type, a timestamp, and a data object containing the resource state.
Common event types include:
email.received: Triggered when an agent receives an email.sms.received: Triggered when an inbound SMS arrives.voice.inbound: Triggered on incoming voice calls to an agent's number.voice.completed: Emitted when an outbound voice call ends.vault.read: Emitted when a stored credential is accessed.
Example Payload: email.received#
{
"id": "evt_12345",
"type": "email.received",
"created_at": "2025-12-20T10:00:00Z",
"data": {
"id": "msg_abc123",
"from": "sender@example.com",
"to": "agent@useanima.sh",
"subject": "Invoice for services",
"body_text": "Please find the attached invoice...",
"thread_id": "thread_xyz"
}
}Implementing the Webhook Handler#
To process these events, you need a publicly accessible endpoint. Using the @anima/sdk, you can verify the authenticity of the request to ensure it originated from our servers.
import { Anima } from '@anima/sdk';
const am = new Anima(process.env.ANIMA_API_KEY);
export async function POST(req: Request) {
const payload = await req.text();
const signature = req.headers.get('x-anima-signature');
try {
const event = am.webhooks.constructEvent(
payload,
signature,
process.env.WEBHOOK_SECRET
);
switch (event.type) {
case 'email.received':
await handleInboundEmail(event.data);
break;
case 'voice.completed':
await handleVoiceCallEnd(event.data);
break;
default:
console.log(`Unhandled event type: ${event.type}`);
}
return new Response('OK', { status: 200 });
} catch (err) {
return new Response('Webhook signature verification failed', { status: 400 });
}
}Security and Verification#
Anima signs every webhook request using a shared secret. We use HMAC-SHA256 signatures to prevent tampering and replay attacks. Always verify the signature before processing any data, especially for sensitive events like vault.read or voice.completed.
Retry Policies and Error Handling#
Webhooks can fail due to network issues or downtime. Anima implements an exponential backoff retry policy. If your endpoint returns anything other than a 2xx status code, we will retry the delivery up to 12 times over 24 hours.
Your handlers should be idempotent. If an agent receives the same email.received event twice, it should recognize the event ID and avoid duplicate processing. This ensures your agentic workflows remain stable even in the face of delivery retries.