# outrnk WhatsApp API — Vollständige Anleitung
> Kopiervorlage für Menschen **und** KI-Assistenten. Alles was du brauchst, um Nachrichten und
> Dateien über WhatsApp zu versenden, steht hier.
**Base URL (immer diese, niemals eine Server-IP):**
```
https://wa.outrnk.io
```
## Dein Zugang
Du erhältst von outrnk einen **API Key** (`wapi_…`). Er gehört **fest zu genau einer
WhatsApp-Nummer** — die Instanz ergibt sich aus dem Key und wird nicht im Request gewählt.
Damit kannst du: Nachrichten und Dateien senden, den Verbindungsstatus abfragen, den
QR-Code holen und prüfen, ob eine Nummer WhatsApp nutzt.
---
## Authentifizierung
Jeder Request braucht den API Key im Header:
```
Authorization: Bearer DEIN_API_KEY
```
## ⚠️ Wichtigste Regel: Erfolg steht im Body, nicht im HTTP-Status
Das Gateway antwortet bei Fehlern **immer mit HTTP 500** — teilweise sogar dann, wenn die
Nachricht tatsächlich zugestellt wurde. **Der HTTP-Status ist nicht verlässlich.**
**So wertest du korrekt aus:**
| Prüfung | Bedeutung |
|---------|-----------|
| `body.success === true` | ✅ Zugestellt |
| `body.success === false` | ❌ Nicht zugestellt (Grund in `body.error`) |
| HTTP-Status | ⚠️ Ignorieren — nur `body.success` zählt |
**Niemals automatisch neu senden, wenn du eine Antwort bekommen hast** — auch nicht bei
`success: false`. Die Nachricht kann trotzdem angekommen sein; ein Retry erzeugt Duplikate.
Erneut senden nur, wenn **gar keine Antwort** kam (Netzwerkfehler/Timeout ohne Response).
```javascript
const res = await fetch(url, options);
const body = await res.json();
if (body.success) {
// zugestellt
} else {
// nicht zugestellt: body.error auswerten, NICHT automatisch wiederholen
}
```
## Telefonnummern-Format
| Eingabe | Ergebnis |
|---------|----------|
| `+491701234567` | ✅ empfohlen (international) |
| `491701234567` | ✅ funktioniert |
| `01701234567` | ✅ wird automatisch zu `49170...` korrigiert |
| `chatId: "491701234567@c.us"` | ✅ direkt möglich (auch `@lid`) |
**Nie an die eigene Nummer der Instanz senden** — das bringt die WhatsApp-Web-Session zum
Absturz. Zum Testen immer eine andere Nummer verwenden.
---
## `POST /api/send-message` — Textnachricht
```bash
curl -X POST https://wa.outrnk.io/api/send-message \
-H "Authorization: Bearer DEIN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"phone": "+491701234567",
"message": "Hallo aus der API!"
}'
```
| Feld | Pflicht | Beschreibung |
|------|---------|--------------|
| `phone` | ja¹ | Empfängernummer |
| `chatId` | ja¹ | Alternative zu `phone` (`...@c.us` / `...@lid`) |
| `message` | ja | Nachrichtentext |
¹ Entweder `phone` **oder** `chatId`.
**Antwort:**
```json
{
"success": true,
"data": { "messageId": "true_49170...@c.us_ABC", "phone": "+491701234567", "status": "sent" }
}
```
---
## `POST /api/send-media` — Datei senden (PDF, Bild, Dokument)
Zwei Varianten: **URL** (empfohlen, Gateway lädt die Datei) oder **Base64**.
### Variante A — per URL
```bash
curl -X POST https://wa.outrnk.io/api/send-media \
-H "Authorization: Bearer DEIN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"phone": "+491701234567",
"mediaUrl": "https://example.com/rechnung.pdf",
"filename": "Rechnung.pdf",
"caption": "Deine Rechnung"
}'
```
### Variante B — per Base64
```bash
curl -X POST https://wa.outrnk.io/api/send-media \
-H "Authorization: Bearer DEIN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"phone": "+491701234567",
"mediaBase64": "JVBERi0xLjQKJcfs...",
"mimetype": "application/pdf",
"filename": "Rechnung.pdf",
"caption": "Deine Rechnung"
}'
```
| Feld | Pflicht | Beschreibung |
|------|---------|--------------|
| `phone` / `chatId` | ja | Empfänger |
| `mediaUrl` | ja¹ | Öffentlich erreichbare URL der Datei |
| `mediaBase64` | ja¹ | Base64-Daten **ohne** `data:`-Präfix |
| `mimetype` | bei Base64 | z. B. `application/pdf`, `image/png`, `image/jpeg` |
| `filename` | nein | Dateiname beim Empfänger |
| `caption` | nein | Text, der mit der Datei erscheint |
¹ Entweder `mediaUrl` **oder** `mediaBase64` (+ `mimetype`).
**Unterstützt:** PDF, PNG, JPG, GIF, MP4, MP3, DOCX, XLSX u. a. (WhatsApp-Limit: 64 MB, Bilder 5 MB)
**Antwort:**
```json
{
"success": true,
"data": { "messageId": "...", "phone": "+491701234567", "status": "sent", "type": "media" }
}
```
---
## `POST /api/send-bulk` — mehrere Nachrichten
Nachrichten werden in eine Warteschlange gelegt und mit 1,5–3 s Abstand versendet
(Spam-Schutz). Die Antwort bestätigt nur die **Annahme**, nicht die Zustellung.
```bash
curl -X POST https://wa.outrnk.io/api/send-bulk \
-H "Authorization: Bearer DEIN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"messages": [
{ "phone": "+491701234567", "message": "Nachricht 1" },
{ "phone": "+491709876543", "message": "Nachricht 2" }
]
}'
```
**Antwort:**
```json
{
"success": true,
"data": { "queued": 2, "messages": [ { "phone": "+491701234567", "status": "queued" } ] }
}
```
---
## `GET /api/status` — Verbindungsstatus
```bash
curl https://wa.outrnk.io/api/status \
-H "Authorization: Bearer DEIN_API_KEY"
```
```json
{
"success": true,
"data": {
"status": "connected",
"phoneNumber": "491701234567",
"connected": true,
"queue": { "sent": 42, "failed": 0, "queued": 0, "pending": 0 },
"messages": { "totalMessages": 1516, "totalChats": 51 }
}
}
```
| `status` | Bedeutung |
|----------|-----------|
| `connected` | ✅ Betriebsbereit |
| `initializing` | Startet gerade |
| `authenticated` | Angemeldet, noch nicht bereit |
| `waiting_qr` | ⚠️ QR-Code muss gescannt werden |
| `error` | Fehler, Neustart läuft |
**Vor dem Senden prüfen:** nur bei `connected` senden.
---
## `GET /api/qr` — QR-Code zum Verbinden
```bash
curl https://wa.outrnk.io/api/qr \
-H "Authorization: Bearer DEIN_API_KEY"
```
Nicht verbunden → `{"success":true,"data":{"qr":"data:image/png;base64,...","status":"waiting_qr"}}`
(direkt als `
` anzeigbar).
Bereits verbunden → `{"success":true,"data":{"status":"connected","phoneNumber":"4917..."}}`
---
## `GET /api/check-number/:phone` — Ist die Nummer bei WhatsApp?
```bash
curl https://wa.outrnk.io/api/check-number/491701234567 \
-H "Authorization: Bearer DEIN_API_KEY"
```
```json
{ "success": true, "data": { "phone": "491701234567", "registered": true, "whatsappId": "87041941463108@lid" } }
```
`registered: false` → Nummer hat kein WhatsApp, Senden ist zwecklos.
---
## Fehler (Instanz-API)
| HTTP | `code` | Ursache | Lösung |
|------|--------|---------|--------|
| 401 | `UNAUTHORIZED` | Header fehlt/falsch | `Authorization: Bearer KEY` setzen |
| 401 | `INVALID_API_KEY` | Key unbekannt | Key prüfen |
| 503 | `INSTANCE_OFFLINE` | Instanz nicht online | `/api/status` prüfen, ggf. QR scannen |
| 400 | — | Pflichtfeld fehlt | Request-Body prüfen |
| 500 | — | Sende-/Validierungsfehler | `body.error` lesen — **nicht** automatisch wiederholen |
Häufige `error`-Texte:
| Text | Bedeutung |
|------|-----------|
| `Number not registered on WhatsApp` | Empfänger hat kein WhatsApp |
| `WhatsApp not connected` | Instanz nicht verbunden (QR?) |
| `detached Frame` / `reading 'id'` | Interne Session-Störung; Instanz startet sich selbst neu |
---
# Öffentlich (ohne Auth)
## `GET /health` — Systemstatus
```bash
curl https://wa.outrnk.io/health
```
```json
{
"success": true,
"service": "WhatsApp Multi-Session API",
"version": "1.0.0",
"instances": { "total": 5, "online": 4, "offline": 0 }
}
```
---
# Vollständiges Beispiel (Node.js)
```javascript
const API = 'https://wa.outrnk.io';
const KEY = process.env.WHATSAPP_API_KEY;
async function call(path, body) {
const res = await fetch(`${API}${path}`, {
method: 'POST',
headers: { 'Authorization': `Bearer ${KEY}`, 'Content-Type': 'application/json' },
body: JSON.stringify(body),
});
// Erfolg steht im Body, nicht im HTTP-Status:
const data = await res.json().catch(() => null);
return { ok: data?.success === true, error: data?.error, data: data?.data };
}
// Text senden
const t = await call('/api/send-message', {
phone: '+491701234567',
message: 'Hallo!',
});
// PDF senden
const p = await call('/api/send-media', {
phone: '+491701234567',
mediaUrl: 'https://example.com/rechnung.pdf',
filename: 'Rechnung.pdf',
caption: 'Deine Rechnung',
});
if (!t.ok) console.error('Nicht zugestellt:', t.error); // NICHT automatisch wiederholen
```
---
# Checkliste für Integrationen
- [ ] Base URL `https://wa.outrnk.io` verwenden (keine Server-IP, kein Port)
- [ ] `Authorization: Bearer ` in jedem Request
- [ ] Erfolg **ausschließlich** an `body.success` festmachen
- [ ] Bei Antwort mit `success: false` **nicht** automatisch neu senden (Duplikatgefahr)
- [ ] Vor Massenversand `/api/status` prüfen (`connected`)
- [ ] Nummern international (`+49...`) senden
- [ ] Nie an die eigene Nummer der Instanz senden