BotsPlatform GuidesCustom Webhook

Custom Webhook

The custom webhook lets you connect an Aerostack bot to any platform, application, or service that can make HTTP requests. There is no platform-specific adapter — you send a JSON payload and receive a structured JSON response.


Webhook URL

POST https://api.aerostack.dev/api/bots/webhook/custom/:botId

Request Format

Send a POST request with a JSON body:

curl -X POST https://api.aerostack.dev/api/bots/webhook/custom/bt_YOUR_BOT_ID \
  -H "Content-Type: application/json" \
  -d '{
    "text": "What is the status of order #12345?",
    "user_id": "user_abc123",
    "channel_id": "channel_main",
    "user_name": "Jane Doe"
  }'

Request Body Fields

FieldRequiredDescription
textYesThe message text to process
user_idYesA unique identifier for the user. Used for conversation tracking.
channel_idYesA channel/context identifier. Different channels maintain separate conversations.
user_nameNoDisplay name for the user (passed to the LLM as context)

Response Format

The custom webhook returns a structured JSON response (unlike other platforms that send responses asynchronously):

{
  "response": "Order #12345 is currently being shipped. It was dispatched on March 14th and the estimated delivery is March 17th.",
  "tool_calls": [
    {
      "toolName": "orders__get_order",
      "arguments": { "order_id": "12345" },
      "result": { "status": "shipped", "dispatched_at": "2026-03-14" },
      "latencyMs": 230,
      "success": true
    }
  ],
  "tokens": { "input": 485, "output": 42 },
  "cost_cents": 1,
  "latency_ms": 2340
}

Response Fields

FieldTypeDescription
responsestringThe bot’s text response
tool_callsarrayList of MCP tools called during processing, with arguments and results
tokensobjectToken usage breakdown (input and output)
cost_centsnumberCost in cents (0 for BYOK mode)
latency_msnumberTotal processing time in milliseconds

Conversation Tracking

The custom webhook uses user_id + channel_id to track conversations, just like other platforms:

  • Messages from the same user_id in the same channel_id are part of the same conversation
  • Conversations expire after conversation_ttl_hours (default 24 hours)
  • After expiry, a new conversation starts automatically

Use different channel_id values to maintain separate conversation threads for the same user.


No Built-In Verification

⚠️

The custom webhook has no built-in signature verification. Anyone who knows your bot ID and the webhook URL can send messages. Implement your own authentication layer if this endpoint is exposed publicly.

If you expose the custom webhook publicly, consider:

  1. Proxy through your own server — validate requests before forwarding to Aerostack
  2. Use obscure bot IDs — bot IDs include a UUID component, making them hard to guess
  3. Set a spending cap — limit the bot’s total spend to contain abuse
  4. Monitor analytics — watch for unusual patterns via the analytics endpoint

Use Cases

The custom webhook is ideal for:

  • Internal tools — Embed AI chat in admin dashboards or internal portals
  • Custom chat UIs — Build your own chat interface with Aerostack as the backend
  • IoT devices — Connect voice assistants or smart displays
  • Other messaging platforms — Any platform not natively supported (e.g., Matrix, IRC, LINE)
  • Testing and development — Quick integration testing without setting up a full platform

Example: Simple Chat Client

// Simple Node.js chat client
async function chat(botId: string, message: string, userId: string) {
  const response = await fetch(
    `https://api.aerostack.dev/api/bots/webhook/custom/${botId}`,
    {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        text: message,
        user_id: userId,
        channel_id: 'default',
      }),
    }
  );
 
  const data = await response.json();
  return data.response;
}
 
// Usage
const reply = await chat('bt_abc123', 'Hello!', 'user_1');
console.log(reply);

Example: Python Integration

import requests
 
def chat(bot_id: str, message: str, user_id: str) -> str:
    response = requests.post(
        f"https://api.aerostack.dev/api/bots/webhook/custom/{bot_id}",
        json={
            "text": message,
            "user_id": user_id,
            "channel_id": "default",
        },
    )
    return response.json()["response"]
 
reply = chat("bt_abc123", "What can you help with?", "user_1")
print(reply)

Rate Limits

Custom webhooks are rate-limited at 60 requests per minute per bot, the same as Telegram and WhatsApp.


Platform Config

The custom platform requires no platform-specific configuration. You can leave platform_config as {} or omit it entirely.

When activating a custom bot, the response includes a warning reminding you that no built-in verification exists:

{
  "status": "active",
  "webhook_url": "https://api.aerostack.dev/api/bots/webhook/custom/bt_abc123",
  "warnings": [
    "Custom platform has no built-in webhook verification. Implement HMAC signature checking in your sender."
  ]
}