Webhooks
List supported webhook events and manage the delivery portal.
AgentStack supports these event types: contact.created, contact.updated, conversation.note_created, and form.submitted. When an integration needs the current list of event types, retrieve the public event-type endpoint. Then configure delivery through the portal URL for that agent. You need an admin-scoped REST key to create this portal URL. Generate the key only from a trusted backend, or from an administrative tool.
POST /agents/{id}/webhooks/portal-url returns 404 AGENT_NOT_FOUND when the agent is unavailable to the organization or scheduled for deletion. A failure to generate the managed portal URL returns 500 INTERNAL_ERROR. Retry a 500 with backoff. Do not replace the agent ID only because the portal provider failed.
The agent's webhook application provisions delivery only when needed. The application sends each event immediately. It does not wait for the source operation to finish. The source operation does not wait for delivery to finish either.
As a result, a contact or a form submission can succeed even when a downstream endpoint later fails. Monitor delivery in the portal. Make each receiving endpoint retry safely on its own.
Event payloads use a { type, timestamp, data } envelope. Contact data varies by source. Inspect real test deliveries. Do not assume that one schema fits every contact.
A form.submitted payload includes the form name, submission time, values, and a verified flag. Treat the verified flag as server-side webhook information, not as proof from a browser callback. Before you change downstream records, verify requests with the mechanism that the delivery provider supports.
Check delivery health
Two read routes show the webhook setup of an agent and how recent deliveries went, without the portal. GET /mcp/agents/{agentId}/webhooks/endpoints lists each endpoint of the agent: its id, its url, whether it is disabled, and its filterTypes. null filter types mean that the endpoint receives every event type. It returns 100 endpoints per page; when hasMore is true, pass nextCursor back as cursor for the next page. GET /mcp/agents/{agentId}/webhooks/attempts lists the recent delivery attempts of the agent, newest first, 50 per page. Each attempt gives the endpointId, the eventType, the responseStatusCode that the endpoint answered, the status (success, pending, fail, sending, or canceled), and the timestamp.
Neither route returns a payload body or the response body of your endpoint. Use the portal to inspect one delivery in full.
Give endpointId to read one endpoint and page through it. When you omit it and the agent has exactly one endpoint, you get the pages of that endpoint. When the agent has two or more endpoints, you get the newest 50 attempts across its first 10 endpoints. That merged list has no next page, so nextCursor is null; give endpointId to see more. To get the next page, pass nextCursor as cursor. The cursor remembers its endpoint. An agent that never had webhooks set up returns an empty list. These routes never set webhooks up.
Both routes need an admin-scoped REST key, like the portal URL. They are also the MCP tools list_webhook_endpoints and list_webhook_attempts, which need an admin role. An unknown agent returns 404 AGENT_NOT_FOUND. An endpointId that is not on the agent returns 404 NOT_FOUND. A malformed cursor, a cursor that belongs to a different endpointId, or a cursor or endpointId that the delivery provider rejects returns 400 INVALID_INPUT. A failure at the delivery provider returns 500 INTERNAL_ERROR, never an empty list. Retry a 500 with backoff. Both routes are reads and spend no credits.
Changes
- 2026-09-24 — New route
GET /mcp/agents/{agentId}/webhooks/endpointslists the webhook endpoints of an agent. - 2026-09-24 — New route
GET /mcp/agents/{agentId}/webhooks/attemptslists recent delivery attempts of an agent, without payloads.