Agent Gateway
The agent gateway lets a customer-owned bot or agent call the StatiBeat admin agent and return the answer through the customer's own surface. For example, a Slack bot named @bananabot can receive a user request, call StatiBeat, and post the StatiBeat answer itself. Users interact with one bot, while StatiBeat still provides the grounded response, action plans, citations, and safety checks.
The gateway is designed for server-to-server delegation. Do not make one Slack bot mention another Slack bot in a user-visible thread. Instead, the customer bot should call the delegated agent API with stable external thread and message keys.
Endpoint Summary
All examples below use a scoped page admin API base:
https://status.example.com/api/v1/orgs/{org_id}/pages/{page_id}/admin
On a page or custom domain, the equivalent /api/v1/admin/... routes are also available.
| Purpose | Method and path |
|---|---|
| Capability manifest | GET /agent/delegations/capabilities |
| Generate or replay an answer | POST /agent/delegations/respond |
| Mark a response as delivered | POST /agent/delegations/delivery |
| Record user feedback | POST /agent/delegations/feedback |
| Answer action-plan questions | POST /agent/delegations/plans/{id}/respond |
| Confirm an action plan | POST /agent/delegations/plans/{id}/confirm |
Use bearer-token authentication for these calls:
Authorization: Bearer <page-admin-api-token>
Content-Type: application/json
Identity and Authorization
In v1, the API token or authenticated StatiBeat session is the execution authority. The external actor fields identify the user who interacted with the customer bot, but they do not grant permissions by themselves.
Use a page-scoped API token with the narrowest permissions that the delegated bot should have. If the bot needs to confirm write plans, the token must have the underlying manage permission, such as incident, maintenance, Beat, or settings management. If the token only has read permissions, the gateway can still answer read-oriented questions and draft plans, but confirmation fails when the plan requires a write permission.
The actor metadata is still useful. StatiBeat stores and passes it through for audit context, customer support, and future actor-mapping workflows. The managed StatiBeat Slack app has a separate Slack-user impersonation path; external customer bots should not depend on that mechanism unless they are explicitly provisioned for it.
Required Idempotency Keys
The customer bot must send stable keys for each delegated thread and message:
| Field | Required | Meaning |
|---|---|---|
conversation.external_thread_key | Required for durable thread memory | Stable key for the customer-bot conversation, such as bananabot:T123:C456:1711738800.000100. |
conversation.external_message_key | Required for request idempotency | Stable key for the user message being answered, such as the Slack message timestamp. |
response_key | Required for delivery and feedback | Stable key for the bot's posted response, such as the Slack response message timestamp. |
Retry behavior is based on these keys:
- If the same
external_message_keyis still processing, StatiBeat returnstransport_directive: "delegation_noop". - If StatiBeat already generated an answer but no delivery has been recorded, a retry returns the cached answer so the proxy can post it.
- If delivery was recorded with a
response_key, a retry returns the cached answer withtransport_directive: "delegation_noop"so the proxy does not post a duplicate.
Basic Bananabot Flow
First, Bananabot receives a Slack message. It calls StatiBeat:
{
"query": "what is happening with checkout?",
"surface": "slack_delegated_bot",
"delegating_agent": {
"name": "bananabot",
"provider": "slack",
"slack_app_id": "A123"
},
"actor": {
"slack_team_id": "T123",
"slack_user_id": "U789"
},
"conversation": {
"external_thread_key": "bananabot:T123:C456:1711738800.000100",
"external_message_key": "1711738812.000200"
},
"slack_context": {
"team_id": "T123",
"channel_id": "C456",
"channel_type": "channel",
"thread_ts": "1711738800.000100",
"message_ts": "1711738812.000200"
}
}
The response includes the structured admin-agent payload plus a Slack-ready markdown field:
{
"outcome": "guided",
"thread_title": "Checkout incident",
"summary": "Checkout API is degraded.",
"markdown": "*Checkout incident*\n\nCheckout API is degraded."
}
Bananabot posts markdown to Slack. After Slack returns the posted message timestamp, Bananabot records delivery:
{
"response_key": "1711738814.000300",
"surface": "slack_delegated_bot",
"delegating_agent": {
"name": "bananabot",
"provider": "slack",
"slack_app_id": "A123"
},
"conversation": {
"external_thread_key": "bananabot:T123:C456:1711738800.000100",
"external_message_key": "1711738812.000200"
},
"slack_context": {
"team_id": "T123",
"channel_id": "C456",
"thread_ts": "1711738800.000100"
}
}
Feedback
If the customer bot renders a feedback control, send the posted response key:
{
"response_key": "1711738814.000300",
"rating": "negative",
"reason": "wrong_intent",
"surface": "slack_delegated_bot",
"conversation": {
"external_thread_key": "bananabot:T123:C456:1711738800.000100",
"external_message_key": "1711738812.000200"
}
}
The feedback endpoint records the rating on the matching turn. It does not automatically post a repair response for delegated bots; the customer bot controls follow-up UX.
Action Plans
When a gateway answer includes plan, render the plan preview and any confirmation controls in the customer bot. To answer clarification questions:
{
"answers": {
"scheduled_start_time": "2026-05-17T10:00:00Z"
},
"surface": "slack_delegated_bot",
"conversation": {
"external_thread_key": "bananabot:T123:C456:1711738800.000100",
"external_message_key": "1711738812.000200"
}
}
Then call:
POST /agent/delegations/plans/{id}/respond
To execute a ready plan, call:
POST /agent/delegations/plans/{id}/confirm
Confirmation uses the same StatiBeat action-plan stale checks, permissions, and execution rules as the native app. The external bot should display conflicts or permission errors to the user instead of assuming the write succeeded.
Reference Adapter
The Slack bot repository includes a small reference adapter in slack-bot/internal/agentgateway. It demonstrates the expected harness behavior:
- build a delegated request from a Slack message
- call
POST /agent/delegations/respond - skip posting when
transport_directiveisdelegation_noop - post the returned markdown through the customer bot
- record delivery with the posted Slack timestamp
- send feedback and action-plan follow-ups through the delegated endpoints
Treat this adapter as a reference implementation for a customer harness, not as a requirement to use the managed StatiBeat Slack app.