Documentação da API
Visão Geral
A API do BotBell permite que seus programas e scripts enviem notificações push para seus dispositivos Apple e recebam respostas. Não é necessário SDK — apenas requisições HTTP simples.
Base URL: https://api.botbell.appComo Funciona
- Crie um bot no app BotBell e copie sua URL de push
- Envie uma mensagem JSON via POST para a URL de push a partir de qualquer linguagem ou ferramenta
- Receba uma notificação push instantânea em todos os seus dispositivos
- Opcionalmente, receba suas respostas via callback da URL de resposta ou API de polling
Formato da Resposta
Todas as respostas da API usam o mesmo envelope JSON. Um code igual a 0 significa sucesso; qualquer outro code indica um erro.
// Success
{
"code": 0,
"message": "success",
"data": { ... }
}
// Error
{
"code": 40001,
"message": "Invalid bot token"
}Enviar uma Mensagem
Envie uma notificação do seu bot para o app BotBell. A URL de push do seu bot já contém o token de autenticação — basta enviar um POST.
Endpoint
POST https://api.botbell.app/v1/push/<your_bot_token>Nenhum cabeçalho de autorização necessário. O token na URL é sua autenticação.
Alternativamente, você pode usar POST /v1/messages/push com o cabeçalho X-Bot-Token: <token>.
Corpo da Requisição (JSON)
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
message | string | Sim | O texto da mensagem (máx. 4.096 caracteres) |
title | string | Não | Título exibido acima da mensagem (máx. 256 caracteres) |
url | string | Não | Um link clicável anexado à notificação |
imageUrl | string | Não | URL de uma imagem para exibir na notificação |
Exemplo de Requisição
curl -X POST https://api.botbell.app/v1/push/bt_your_token \
-H "Content-Type: application/json" \
-d '{
"message": "Server CPU is at 95%!",
"title": "Alert",
"url": "https://grafana.example.com/dashboard"
}'Resposta
{
"code": 0,
"message": "success",
"data": {
"message_id": "msg_abc123",
"delivered": true,
"timestamp": 1709827200
}
}| Campo | Descrição |
|---|---|
message_id | ID único desta mensagem |
delivered | true se a notificação push foi enviada ao APNs com sucesso; false se nenhum dispositivo está registrado |
timestamp | Timestamp Unix (segundos) de quando a mensagem foi criada |
Experimente agora
Cole seu token de bot e envie uma notificação push real para seu dispositivo.
Recebendo Respostas
Quando você responde a um bot no app, o BotBell pode encaminhar sua resposta para o seu servidor automaticamente. Isso é opcional — você só precisa disso se o seu bot lida com conversas bidirecionais.
Configurando uma URL de Resposta
No app BotBell, vá para as configurações do seu bot e insira uma URL de resposta (ex: https://seu-servidor.com/botbell/reply). O BotBell enviará suas respostas via POST para esta URL conforme acontecerem.
Payload do Callback
Quando você responde, o BotBell envia uma requisição POST para sua URL de resposta com o seguinte formato:
POST https://your-server.com/botbell/reply
Headers:
Content-Type: application/json
X-Webhook-Signature: sha256=abc123...
X-Webhook-Timestamp: 1709827300
Body:
{
"event": "user_reply",
"bot_id": "bot_abc123",
"message_id": "msg_xyz789",
"content": "Got it, thanks!",
"timestamp": 1709827300
}Verificação de Assinatura
Cada callback inclui uma assinatura HMAC-SHA256 para que você possa verificar que veio do BotBell. A chave de assinatura é o Webhook Secret mostrado nas configurações do seu bot.
signature = HMAC-SHA256(
key: <your_webhook_secret>,
message: "<timestamp>.<raw_request_body>"
)Para verificar a assinatura:
- Extraia os cabeçalhos X-Webhook-Timestamp e X-Webhook-Signature
- Verifique se o timestamp está dentro de 5 minutos do horário atual (para prevenir ataques de repetição)
- Calcule o HMAC-SHA256 sobre a string "<timestamp>.<raw_body>" usando seu Webhook Secret como chave
- Compare o valor calculado com a assinatura após o prefixo "sha256="
Resposta do Seu Servidor
Retorne qualquer código de status HTTP 2xx para confirmar o recebimento. Respostas não-2xx ou timeouts (5 segundos) são tratados como falhas — a resposta será armazenada na fila de polling por 24 horas para que você possa recuperá-la depois.
Polling de Respostas
Se você não tem um servidor público para receber callbacks, pode consultar as respostas via polling. Isso também é útil como fallback quando sua URL de resposta está temporariamente indisponível.
Endpoint
GET https://api.botbell.app/v1/messages/poll
Headers:
X-Bot-Token: <your_bot_token>Parâmetros de Consulta
| Campo | Tipo | Padrão | Descrição |
|---|---|---|---|
since | integer | - | Retornar apenas mensagens após este timestamp Unix |
limit | integer | 20 | Número de mensagens a retornar (máx. 100) |
Resposta
{
"code": 0,
"message": "success",
"data": {
"messages": [
{
"message_id": "msg_xyz789",
"content": "Got it, thanks!",
"timestamp": 1709827300
}
],
"has_more": false
}
}Nota: Mensagens consultadas são marcadas como lidas e não serão retornadas novamente. Mensagens não consultadas expiram após 24 horas.
Códigos de Erro
| Código | Status HTTP | Descrição |
|---|---|---|
| 40001 | 401 | Token de bot inválido ou ausente |
| 40010 | 400 | Validação da requisição falhou (ex: campo message ausente, corpo muito grande) |
| 40029 | 429 | Limite de taxa excedido — muitas requisições por minuto |
| 40030 | 429 | Cota mensal de mensagens esgotada |
| 40031 | 403 | Limite de bots atingido para o seu plano |
| 50000 | 500 | Erro interno do servidor |
Limites de Taxa e Cotas
| Limite | Valor |
|---|---|
| Taxa de push (por bot) | 60 |
| Corpo da mensagem (caracteres) | 4,096 |
| Título (caracteres) | 256 |
| Cota mensal gratuita | 300 mensagens / bot |
| Retenção de mensagens de polling | 24h |
| Timeout da URL de resposta | 5s |
O status do limite de taxa é retornado nos cabeçalhos da resposta:
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 58
X-RateLimit-Reset: 1709827260Exemplos de Código
Enviando Mensagens
curl -X POST https://api.botbell.app/v1/push/bt_your_token \
-H "Content-Type: application/json" \
-d '{"message":"Server CPU at 95%","title":"Alert"}'import requests
resp = requests.post(
"https://api.botbell.app/v1/push/bt_your_token",
json={
"message": "Build #42 succeeded",
"title": "CI/CD",
"url": "https://ci.example.com/builds/42",
},
)
print(resp.json()) # {"code": 0, "data": {"message_id": "...", ...}}const resp = await fetch("https://api.botbell.app/v1/push/bt_your_token", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
message: "New order received!",
title: "E-Commerce",
}),
});
const data = await resp.json();
console.log(data);package main
import (
"bytes"
"encoding/json"
"net/http"
)
func main() {
body, _ := json.Marshal(map[string]string{
"message": "Disk usage above 90%",
"title": "Alert",
})
http.Post(
"https://api.botbell.app/v1/push/bt_your_token",
"application/json",
bytes.NewReader(body),
)
}<?php
$ch = curl_init('https://api.botbell.app/v1/push/bt_your_token');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_POSTFIELDS => json_encode([
'message' => 'Payment received: $49.99',
'title' => 'Stripe',
]),
CURLOPT_RETURNTRANSFER => true,
]);
$response = curl_exec($ch);
curl_close($ch);Verificando Assinaturas de Resposta
import hmac, hashlib
def verify_signature(payload: bytes, timestamp: str, signature: str, secret: str) -> bool:
message = f"{timestamp}.{payload.decode()}"
expected = hmac.new(secret.encode(), message.encode(), hashlib.sha256).hexdigest()
return hmac.compare_digest(f"sha256={expected}", signature)const crypto = require("crypto");
function verifySignature(payload, timestamp, signature, secret) {
const message = `${timestamp}.${payload}`;
const expected = crypto.createHmac("sha256", secret).update(message).digest("hex");
return crypto.timingSafeEqual(
Buffer.from(`sha256=${expected}`),
Buffer.from(signature),
);
}