Skip to content

API-Dokumentation

Übersicht

Die BotBell-API ermöglicht es deinen Programmen und Skripten, Push-Benachrichtigungen an deine Apple-Geräte zu senden und Antworten zu empfangen. Kein SDK erforderlich — nur einfache HTTP-Anfragen.

Base URL: https://api.botbell.app

So funktioniert es

  1. Erstelle einen Bot in der BotBell-App und kopiere seine Push-URL
  2. Sende eine JSON-Nachricht per POST an die Push-URL aus beliebiger Sprache oder Tool
  3. Erhalte eine sofortige Push-Benachrichtigung auf all deinen Geräten
  4. Optional: Empfange deine Antworten über den Antwort-URL-Callback oder die Polling-API

Antwortformat

Alle API-Antworten verwenden denselben JSON-Umschlag. Ein Code von 0 bedeutet Erfolg; jeder andere Code zeigt einen Fehler an.

// Success
{
  "code": 0,
  "message": "success",
  "data": { ... }
}

// Error
{
  "code": 40001,
  "message": "Invalid bot token"
}

Nachricht Senden

Sende eine Benachrichtigung von deinem Bot an die BotBell-App. Die Push-URL deines Bots enthält bereits den Authentifizierungstoken — sende einfach einen POST daran.

Endpunkt

POST https://api.botbell.app/v1/push/<your_bot_token>

Kein Authorization-Header erforderlich. Der Token in der URL ist deine Authentifizierung.

Alternativ kannst du POST /v1/messages/push mit dem X-Bot-Token: <token>-Header verwenden.

Anfragekörper (JSON)

FeldTypErforderlichBeschreibung
messagestringJaDer Nachrichtentext (max. 4.096 Zeichen)
titlestringNeinTitel, der über der Nachricht angezeigt wird (max. 256 Zeichen)
urlstringNeinEin antippbarer Link, der an die Benachrichtigung angehängt wird
imageUrlstringNeinURL eines Bildes, das in der Benachrichtigung angezeigt wird

Beispielanfrage

curl
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"
  }'

Antwort

{
  "code": 0,
  "message": "success",
  "data": {
    "message_id": "msg_abc123",
    "delivered": true,
    "timestamp": 1709827200
  }
}
FeldBeschreibung
message_idEindeutige ID für diese Nachricht
deliveredtrue, wenn die Push-Benachrichtigung erfolgreich an APNs gesendet wurde; false, wenn kein Gerät registriert ist
timestampUnix-Zeitstempel (Sekunden), wann die Nachricht erstellt wurde

Jetzt ausprobieren

Füge deinen Bot-Token ein und sende eine echte Push-Benachrichtigung an dein Gerät.


Antworten Empfangen

Wenn du einem Bot in der App antwortest, kann BotBell deine Antwort automatisch an deinen Server weiterleiten. Dies ist optional — du benötigst dies nur, wenn dein Bot bidirektionale Konversationen unterstützt.

Antwort-URL Einrichten

Gehe in der BotBell-App zu den Einstellungen deines Bots und gib eine Antwort-URL ein (z.B. https://dein-server.com/botbell/reply). BotBell sendet deine Antworten per POST an diese URL, sobald sie eingehen.

Callback-Payload

Wenn du antwortest, sendet BotBell eine POST-Anfrage an deine Antwort-URL im folgenden Format:

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
}

Signaturverifizierung

Jeder Callback enthält eine HMAC-SHA256-Signatur, damit du überprüfen kannst, ob er von BotBell stammt. Der Signaturschlüssel ist das Webhook-Secret in deinen Bot-Einstellungen.

signature = HMAC-SHA256(
  key:     <your_webhook_secret>,
  message: "<timestamp>.<raw_request_body>"
)

So verifizierst du die Signatur:

  1. Extrahiere die Header X-Webhook-Timestamp und X-Webhook-Signature
  2. Überprüfe, ob der Zeitstempel innerhalb von 5 Minuten der aktuellen Zeit liegt (um Replay-Angriffe zu verhindern)
  3. Berechne HMAC-SHA256 über den String "<timestamp>.<raw_body>" mit deinem Webhook-Secret als Schlüssel
  4. Vergleiche den berechneten Wert mit der Signatur nach dem Präfix "sha256="

Antwort deines Servers

Gib einen beliebigen HTTP-2xx-Statuscode zurück, um den Empfang zu bestätigen. Nicht-2xx-Antworten oder Timeouts (5 Sekunden) werden als Fehler behandelt — die Antwort wird 24 Stunden in der Polling-Warteschlange gespeichert, damit du sie später abrufen kannst.


Antworten Abrufen

Wenn du keinen öffentlichen Server für Callbacks hast, kannst du stattdessen Antworten per Polling abrufen. Dies ist auch nützlich als Fallback, wenn deine Antwort-URL vorübergehend nicht erreichbar ist.

Endpunkt

GET https://api.botbell.app/v1/messages/poll
Headers:
  X-Bot-Token: <your_bot_token>

Abfrageparameter

FeldTypStandardBeschreibung
sinceinteger-Nur Nachrichten nach diesem Unix-Zeitstempel zurückgeben
limitinteger20Anzahl der zurückzugebenden Nachrichten (max. 100)

Antwort

{
  "code": 0,
  "message": "success",
  "data": {
    "messages": [
      {
        "message_id": "msg_xyz789",
        "content": "Got it, thanks!",
        "timestamp": 1709827300
      }
    ],
    "has_more": false
  }
}

Hinweis: Abgerufene Nachrichten werden als gelesen markiert und nicht erneut zurückgegeben. Nicht abgerufene Nachrichten verfallen nach 24 Stunden.


Fehlercodes

CodeHTTP-StatusBeschreibung
40001401Ungültiger oder fehlender Bot-Token
40010400Anfrage-Validierung fehlgeschlagen (z.B. fehlendes message-Feld, Body zu groß)
40029429Ratenlimit überschritten — zu viele Anfragen pro Minute
40030429Monatliches Nachrichtenkontingent erschöpft
40031403Bot-Limit für deinen Plan erreicht
50000500Interner Serverfehler

Ratenlimits & Kontingente

LimitWert
Push-Rate (pro Bot)60
Nachrichtentext (Zeichen)4,096
Titel (Zeichen)256
Kostenloses monatliches Kontingent300 Nachrichten / Bot
Aufbewahrung abgerufener Nachrichten24h
Antwort-URL-Timeout5s

Der Ratenlimit-Status wird in den Antwort-Headern zurückgegeben:

X-RateLimit-Limit: 60
X-RateLimit-Remaining: 58
X-RateLimit-Reset: 1709827260

Code-Beispiele

Nachrichten Senden

curl
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"}'
Python
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": "...", ...}}
JavaScript / Node.js
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);
Go
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
<?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);

Antwort-Signaturen Verifizieren

Python
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)
Node.js
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),
  );
}