Skip to main content

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.

PurposeMethod and path
Capability manifestGET /agent/delegations/capabilities
Generate or replay an answerPOST /agent/delegations/respond
Mark a response as deliveredPOST /agent/delegations/delivery
Record user feedbackPOST /agent/delegations/feedback
Answer action-plan questionsPOST /agent/delegations/plans/{id}/respond
Confirm an action planPOST /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:

FieldRequiredMeaning
conversation.external_thread_keyRequired for durable thread memoryStable key for the customer-bot conversation, such as bananabot:T123:C456:1711738800.000100.
conversation.external_message_keyRequired for request idempotencyStable key for the user message being answered, such as the Slack message timestamp.
response_keyRequired for delivery and feedbackStable 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_key is still processing, StatiBeat returns transport_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 with transport_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_directive is delegation_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.