Slack Events API webhook
The address a Slack app posts workspace events to.
POST /v1/integrations/slack/events
| Address | https://api.hanzo.ai/v1/integrations/slack/events |
| Method | POST |
| Operation | post_integrations_slack_events |
| Auth | Authorization: Bearer $HANZO_API_KEY |
The address a Slack app posts workspace events to. It answers Slack's url_verification handshake with the challenge, and routes an @mention or a direct message to an agent turn that replies in the same thread. The turn holds the product's own tools, so a request to change code starts a sandbox run because the model chose to — there is no prefix and no second path.
The raw body and its timestamp are verified against the app's signing secret before anything is read from them. Hanzo's own bot messages are dropped, so a reply cannot trigger another reply.
The caller here is the PLATFORM, not a Hanzo tenant, so there is no bearer and no principal. The signature check IS the authentication, and it fails closed. The tenant is never read from the payload either: it is resolved from the verified platform identifier through the connection map, so an event from a workspace nobody connected does nothing. Refusals are written with their own status rather than being flattened to a 500, so a rejected signature reads as 401 and a malformed body as 400.
The answer is acknowledged immediately and the work happens afterwards, because every one of these platforms times out a slow webhook. Duplicate deliveries are absorbed durably, so a platform retry of an event that already ran never runs it a second time or bills for it twice. When the agent pool is full nothing at all is recorded and the delivery is refused as retriable, so the message is re-delivered later rather than being lost or half-processed.
Request
The document declares no body for POST /v1/integrations/slack/events. The handler is typed in cloud but its shape is not yet emitted, so the fields are not listed here — ask the MCP door's describe for post_integrations_slack_events, which answers from the running route.
Response
The document declares no response body for this operation. It answers 200 on success and the platform error shape on failure — see Errors.
Examples
hanzo integrations slack eventsimport { Configuration, IntegrationsApi } from 'hanzoai';
const api = new IntegrationsApi(new Configuration({ accessToken: process.env.HANZO_API_KEY }));
const { data } = await api.postIntegrationsSlackEvents();from hanzoai.cloud import ApiClient, Configuration
from hanzoai.cloud.api import IntegrationsApi
client = ApiClient(Configuration(access_token=os.environ["HANZO_API_KEY"]))
result = IntegrationsApi(client).post_integrations_slack_events()cfg := cloud.NewConfiguration()
cfg.AddDefaultHeader("Authorization", "Bearer "+os.Getenv("HANZO_API_KEY"))
client := cloud.NewAPIClient(cfg)
resp, _, err := client.IntegrationsAPI.PostIntegrationsSlackEvents(context.Background()).Execute()
if err != nil {
return err
}use hanzo_cloud::apis::{configuration::Configuration, integrations_api};
let mut cfg = Configuration::new();
cfg.bearer_access_token = std::env::var("HANZO_API_KEY").ok();
let result = integrations_api::post_integrations_slack_events(&cfg, Default::default()).await?;import ai.hanzo.cloud.ApiClient;
import ai.hanzo.cloud.api.IntegrationsApi;
ApiClient client = new ApiClient();
client.setRequestInterceptor(b -> b.header("Authorization", "Bearer " + System.getenv("HANZO_API_KEY")));
var result = new IntegrationsApi(client).postIntegrationsSlackEvents();curl -X POST https://api.hanzo.ai/v1/integrations/slack/events \
-H "Authorization: Bearer $HANZO_API_KEY"The door reaches integrations through the integrations tool, which names its 45 operations with its own verbs — this one among them, under a name only the door declares. describe explains any of them:
curl -X POST https://api.hanzo.ai/v1/mcp \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "describe",
"arguments": {
"op": "list_connectors"
}
}
}'How is this guide?