Skip to content

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.


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

Send a POST request with a JSON body:

Terminal window
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"
}'
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)

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
}
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

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.


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

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

// 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);

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)

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


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."
]
}