# 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 `<img src="...">` 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 <API_KEY>` 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
