> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orbit.devotel.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Nachrichten senden und empfangen

> Senden Sie Ihre erste SMS- oder WhatsApp-Nachricht über die Orbit API und empfangen Sie eingehende Antworten per Webhook – in einer kompletten End-to-End-Anleitung zum Quickstart mit Code.

# Nachrichten senden und empfangen

Diese Anleitung führt Sie von einem API-Schlüssel zu einem funktionierenden Zwei-Wege-Nachrichtenfluss: eine ausgehende Nachricht senden, die Zustellung verfolgen und die Antwort auf Ihrem eigenen Server empfangen. Das Beispiel nutzt SMS – dasselbe Dreischrittmuster (senden → verfolgen → empfangen) gilt auch für WhatsApp, RCS, Viber und E-Mail, jeweils über einen eigenen Endpunkt.

**Das werden Sie tun:**

1. [Eine Nachricht senden](#1-nachricht-senden)
2. [Die Zustellung verfolgen](#2-zustellung-verfolgen)
3. [Eingehende Nachrichten empfangen](#3-eingehende-nachrichten-empfangen)
4. [Auf eine eingehende Nachricht antworten](#4-auf-eine-eingehende-nachricht-antworten)

## Voraussetzungen

* Ein API-Schlüssel aus **Einstellungen → API-Schlüssel**. Verwenden Sie beim Erstellen einen Sandbox-Schlüssel (`dv_test_sk_…`) – Sandbox-Versende sind kostenlos und simuliert, und liefern deterministische Zustellbelege, sodass Sie sowohl den Erfolgs- als auch den Fehlerpfad durchspielen können. Für Produktion wechseln Sie auf einen Live-Schlüssel (`dv_live_sk_…`).
* Eine Absendernummer, die auf Ihrem Kanal senden darf. Für SMS ist das eine SMS-fähige Nummer, die Sie besitzen (per [Numbers API](/api-reference/numbers) oder über **Dashboard → Numbers** suchen und kaufen). Lassen Sie `from` weg, dann wählt Orbit einen zum Ziel passenden Absender.
* Eine öffentliche HTTPS-URL für den [Empfangsschritt](#3-eingehende-nachrichten-empfangen). Während der Entwicklung eignet sich jedes Tunneling-Tool.

Alle Anfragen gehen an eine einzige Basis-URL – Sandbox verwendet denselben Host; die Auswahl erfolgt über Ihren Schlüssel, nicht über eine andere Domain:

```
https://api.orbit.devotel.io/api/v1
```

Jede Anfrage trägt Ihren Schlüssel im `X-API-Key`-Header.

## 1. Eine Nachricht senden

Senden Sie eine SMS mit `POST /messages/sms`. Nur `to` und `body` sind erforderlich; `from` ist optional.

```bash theme={null}
curl -X POST https://api.orbit.devotel.io/api/v1/messages/sms \
  -H "X-API-Key: dv_test_sk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order-conf-98421" \
  -d '{
    "to": "+14155552671",
    "from": "+18005551234",
    "body": "Your order #1234 has shipped. Reply STATUS for tracking."
  }'
```

Die Antwort lautet `202 Accepted` – die Nachricht ist persistiert und zur Zustellung in der Warteschlange eingeordnet, noch nicht an den Mobilfunkanbieter übergeben. Die Felder liegen unter `data`; `meta` trägt die `request_id`, die Sie für den Support loggen sollten.

```json theme={null}
{
  "data": {
    "id": "msg_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6",
    "status": "queued",
    "channel": "sms",
    "direction": "outbound",
    "segments": 1
  },
  "meta": {
    "request_id": "req_xyz789",
    "timestamp": "2026-07-20T00:00:00Z"
  }
}
```

Die `id` (`msg_` gefolgt von 32 Hex-Zeichen) ist der Verweis für alle Folgeaufrufe – Statusabfragen, Zustell-Webhooks und der Message-Trace richten sich daran aus. Sandbox-Antworten fügen `meta` ein `"test_mode": true` hinzu.

<Note>
  Senden Sie bei jeder Sendung einen `Idempotency-Key`. Wenn Sie denselben Schlüssel und denselben Body innerhalb von 24 Stunden erneut senden, erhalten Sie die ursprüngliche Antwort zurück statt eine Duplikat-Sendung; bei einem anderen Body wird `409 IDEMPOTENCY_KEY_REUSED` zurückgegeben.
</Note>

### Weitere Kanäle

Jeder Kanal hat unter der `/messages`-Präfix einen eigenen Endpunkt mit einer für diesen Kanal ausgelegten Body-Form. Es gibt keinen einzigen kanal-polymorphen Route – wählen Sie den Endpunkt, der zu Ihrem Kanal passt:

| Kanal    | Endpunkt                  | Referenz                                            |
| -------- | ------------------------- | --------------------------------------------------- |
| SMS      | `POST /messages/sms`      | [Messaging API](/api-reference/endpoints/messaging) |
| WhatsApp | `POST /messages/whatsapp` | [WhatsApp-Kanal](/channels/whatsapp)                |
| RCS      | `POST /messages/rcs`      | [RCS-Kanal](/channels/rcs)                          |
| Viber    | `POST /messages/viber`    | [Viber-Kanal](/channels/viber)                      |
| E-Mail   | `POST /messages/email`    | [E-Mail-Kanal](/channels/email)                     |

## 2. Die Zustellung verfolgen

Eine in der Warteschlange befindliche Nachricht durchläuft einen Status-Lebenszyklus, bevor sie den Empfänger erreicht:

```
queued → sending → sent → delivered   (or failed / undelivered)
```

Es gibt zwei Wege, ihm zu folgen:

**Abfragen** (Poll) Sie die Nachricht per ID:

```bash theme={null}
curl https://api.orbit.devotel.io/api/v1/messages/msg_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6 \
  -H "X-API-Key: dv_test_sk_YOUR_KEY"
```

**Webhooks abonnieren** (empfohlen – ohne Polling). Pro Statusübergang wird ein Ereignis ausgelöst; jedes trägt die Nachrichten-`id` und den neuen `status`:

* `message.sent` – vom Mobilfunkanbieter angenommen
* `message.delivered` – dem Gerät zugestellt bestätigt
* `message.failed` – endgültiger Fehler (der `status` in der Nutzlast unterscheidet `failed`, `undelivered`, `expired` und `submitted_no_receipt`; `error_code` / `error_message` tragen ggf. den Providergrund)

Registrieren Sie einen Webhook-Endpunkt ein Mal, danach fließen die Ereignisse:

```bash theme={null}
curl -X POST https://api.orbit.devotel.io/api/v1/webhooks \
  -H "X-API-Key: dv_test_sk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://yourapp.com/webhooks/orbit",
    "events": ["message.sent", "message.delivered", "message.failed", "message.received"],
    "secret": "whsec_your_signing_secret"
  }'
```

Ein Zustellereignis sieht so aus:

```json theme={null}
{
  "id": "evt_abc123",
  "type": "message.delivered",
  "created_at": "2026-07-20T12:00:00Z",
  "data": {
    "message_id": "msg_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6",
    "channel": "sms",
    "status": "delivered",
    "is_terminal": true,
    "timestamp": "2026-07-20T12:00:00Z"
  }
}
```

Prüfen Sie den `X-Orbit-Signature`-Header, bevor Sie einer Nutzlast vertrauen, und deduplizieren anhand der Ereignis-`id` – die Zustellung erfolgt mindestens ein Mal (at-least-once). Siehe [Webhook-Sicherheit](/webhooks/security) für das Verifikations-Snippet.

## 3. Eingehende Nachrichten empfangen

Wenn jemand auf Ihre Nummer antwortet (oder Ihnen zuerst schreibt), zeichnet Orbit eine eingehende Nachricht auf und – falls Sie im Schritt oben `message.received` abonniert haben – sendet sie als POST an Ihre Webhook-URL:

```json theme={null}
{
  "id": "evt_def456",
  "type": "message.received",
  "created_at": "2026-07-20T12:01:00Z",
  "data": {
    "message_id": "msg_inb_9f8e7d6c5b4a3f2e1d0c9b8a7f6e5d4c",
    "channel": "sms",
    "from": "+14155552671",
    "to": "+18005551234",
    "body": "STATUS"
  }
}
```

Die eingehende Nachricht ist auch abfragbar – listen Sie alles Empfangene mit dem Filter `direction=inbound`:

```bash theme={null}
curl "https://api.orbit.devotel.io/api/v1/messages?direction=inbound&channel=sms" \
  -H "X-API-Key: dv_test_sk_YOUR_KEY"
```

<Note>
  Das eingehende Routing ist automatisch für Nummern, die Sie auf Orbit besitzen – eine Antwort auf eine Ihrer Absendernummern wird erfasst und bei `message.received`-Abonnement an Ihren Webhook zugestellt. Eine eigene Eingangs-URL-Kabelverlegung pro Nummer ist nicht erforderlich.
</Note>

## 4. Auf eine eingehende Nachricht antworten

Antworten ist nur ein weiterer Sendeaufruf, adressiert zurück an den eingehenden `from`. Tauschen Sie `to` und `from` und rufen Sie `POST /messages/sms` erneut auf:

```bash theme={null}
curl -X POST https://api.orbit.devotel.io/api/v1/messages/sms \
  -H "X-API-Key: dv_test_sk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+14155552671",
    "from": "+18005551234",
    "body": "Order #1234 is out for delivery, arriving today by 5pm."
  }'
```

Beide Nachrichten teilen eine Konversation, sodass Sie – sobald der Thread existiert – den vollständigen Rücklauf mit dem Filter `conversation_id` auf `GET /messages` ziehen können.

## Häufige Fehler

Jeder Fehler nutzt dieselbe Form – matchen Sie auf `error.code` (eine GROSSBUCHSTABEN-Konstante) und loggen Sie `meta.request_id`:

| Code                   | HTTP | Bedeutung                                                     | Lösung                                        |
| ---------------------- | ---- | ------------------------------------------------------------- | --------------------------------------------- |
| `INVALID_API_KEY`      | 401  | Schlüssel widerrufen, falsche Umgebung oder Tippfehler        | Prüfen Sie **Einstellungen → API-Schlüssel**  |
| `INVALID_PHONE_NUMBER` | 422  | `to` ist kein gültiges E.164 oder nicht erreichbar            | Validieren Sie die Nummer vor dem Senden      |
| `NOT_SMS_CAPABLE`      | 422  | Der Absender ist nicht SMS-fähig (z. B. toll-free ohne 10DLC) | Nummer registrieren oder wechseln             |
| `INSUFFICIENT_BALANCE` | 402  | Guthaben unter dem Kanalmindest                               | Wallet aufladen                               |
| `RATE_LIMITED`         | 429  | Zu viele Sendungen                                            | Beachten Sie `details.retry_after` (Sekunden) |
| `VALIDATION_ERROR`     | 422  | Body-Form ungültig                                            | Lesen Sie `details.issues` pro Feld           |

Vollständige Liste: [Fehlercodes](/reference/error-codes).

## Nächste Schritte

* [Messaging API-Referenz](/api-reference/endpoints/messaging) – jeder Nachrichtenendpunkt und jedes Feld
* [Nachrichtenstatus-Lebenszyklus](/api-reference/messages-status-lifecycle) – die vollständige Statusmenge je Kanal
* [Webhooks-Übersicht](/webhooks/overview) – Wiederholungen, Zustellgarantien und der Ereigniskatalog
* [API-Integration](/guides/api-integration) – Sandbox, Idempotenz, Paginierung und SDKs für jeden Kanal
* [Ratenlimits](/guides/rate-limits) – pro-Kanal-Grenzen und Wiederholungs-Header
