## API-URL
URL, an die HTTP-Anfragen gesendet werden:
```url
https://portal.bulkgate.com/api/1.0/otp/send
```

> [!NOTE]
> Wenn die Anfrage ihr Ziel nicht erreicht, wiederholen Sie sie auf dem [Backup-Server](https://www.bulkgate.com/de/dokumentation/api-verwaltung-und-tokens/backup-server/) `backup1.bulkgate.com`.

## Unterstützte HTTP-Methoden

- `POST` - `application/json`

```http
POST /api/1.0/otp/send HTTP/1.1
Host: portal.bulkgate.com
Content-Type: application/json
```

> [!IMPORTANT]
> Zusätzlich zu `request_quota_number` gilt für den Endpunkt ein **kontoweites Limit von 60 Anfragen pro Minute**. Bei Überschreitung wird `the_quota_of_send_per_minute_has_been_exceeded` zurückgegeben.

## Parametertabelle

| PARAMETERNAME                 | WERT | PFLICHT | STANDARDWERT |
|:------------------------------|:-----|:--------|:-------------|
| application_id                | [Anwendungs-ID](https://www.bulkgate.com/de/dokumentation/api-verwaltung-und-tokens/api-verwaltung/) | **Ja** | - |
| application_token             | [Anwendungstoken](https://www.bulkgate.com/de/dokumentation/api-verwaltung-und-tokens/api-tokens/)	 | **Ja** | - |
| number                        | Telefonnummer, an die der Verifizierungscode gesendet wird | **Ja** | - |
| country                       | Ländercode der Telefonnummer | nein | Der Wert wird aus dem Profil übernommen. |
| language                      | Sprache des Nachrichtentextes, einer der 100 unterstützten ISO-Codes. Ein unbekannter Code führt zur Ablehnung der Anfrage. Ohne Angabe wird die Sprache anhand der Telefonnummer ermittelt. | nein | `null` |
| code_type                     | Typ des Codes. (`string`, `int` oder `combined`) | nein | `int` |
| code_length                   | Länge des Verifizierungscodes (4–100). | nein | 6 |
| request_quota_number          | Anzahl der Anfragen pro Minute für `request_quota_identification` | nein | 1 |
| request_quota_identification  | Identifikation des „OTP-Nutzers / Anfragenden“, für den das Kontingent `request_quota_number` pro Minute gilt. Wir empfehlen, dafür eine IP-Adresse zu verwenden. | **Ja** | - |
| trials_available_resend       | Limit der verfügbaren [erneuten Sendungen](https://www.bulkgate.com/de/dokumentation/otp-api/einmalpasswort-erneut-senden/) | nein | `null` - unbegrenzt |
| trials_available_verification | Limit der verfügbaren [Verifizierungen](https://www.bulkgate.com/de/dokumentation/otp-api/einmalpasswort-verifizieren/) | nein | `null` - unbegrenzt |
| daily_limit                   | Limit der verfügbaren Anfragen pro Tag (gleitend über die letzten 24 Stunden) | nein | `null` - unbegrenzt |
| daily_limit_country           | Tageslimit pro Land als Map `{"cz": 100, "sk": 50}`. Ist es ausgefüllt, sind **nur** die aufgeführten Länder erlaubt — jedes andere Land schlägt mit `country_is_disabled` fehl. | nein | `null` - unbegrenzt |
| expiration                    | Ablaufzeit der OTP-Anfrage in Sekunden; nach Ablauf dieser Zeit ist die Anfrage nicht mehr möglich. Ein Wert unter `60` wird ignoriert und der Standardwert verwendet. | nein | `604800` - 7 Tage |
| channel                       | Alternative Kanäle. Die Kanäle sind in einer Kaskade angeordnet: Kann Ihre Nachricht nicht über den Kanal mit der höchsten Priorität zugestellt werden, werden die weiter unten in der Kaskade aufgeführten Kanäle verwendet. Gelingt die Zustellung über keinen von ihnen, wird stattdessen SMS verwendet. | nein | [SMS](#sms-objekt), [Viber](#viber-objekt), [RCS](#rcs-objekt), [WhatsApp](#whatsapp-objekt) oder [Text2Voice](#text2voice-objekt) |


## Kanäle

Das Objekt `channel` legt fest, über welche Kanäle der Code zugestellt wird und in welcher Reihenfolge. **Die Reihenfolge der Schlüssel in der Anfrage ist die Reihenfolge der Kaskade** — kann der erste Kanal den Code nicht zustellen, wird der nächste versucht. Gelingt es keinem von ihnen, wird SMS verwendet.

### SMS-Objekt
| PARAMETERNAME   | WERT | PFLICHT | STANDARDWERT |
|:----------------|:-----|:--------|:-------------|
| sender_id       | Absenderkennung, siehe [Typ der Absenderkennung](https://www.bulkgate.com/de/dokumentation/simple-api/simple-transactional/) | nein | `gSystem` |
| sender_id_value | Wert des Absenders - `gOwn` (z. B. „420 777 777 777“), `gText` (z. B. „BulkGate“), `gProfile` (z. B. „423“), `gMobile` oder `gPush` [(KEY)](https://www.bulkgate.com/de/hilfe-center/mobile-connect/mobile-connect-installation/) | nein | `null` |
| domain          | URL einer Website, die [WebOTP](https://developer.mozilla.org/en-US/docs/Web/API/WebOTP_API) für die automatische Eingabe des empfangenen Codes nutzt. | nein | `null` |



### Viber-Objekt
| PARAMETERNAME  | WERT | PFLICHT | STANDARDWERT |
|:---------------|:-----|:--------|:-------------|
| sender         | Name Ihres registrierten [Absenders für Viber](https://www.bulkgate.com/de/hilfe-center/viber/registrierung-viber-absender/) | **Ja** | - |
| expiration     | Sekunden, die gewartet wird, bevor ein anderer Kanal versucht wird | nein | 60 |
| code_type      | Von Viber verlangter Codetyp, angegeben in der genehmigten OTP-Vorlage. | nein | `null` |
| code_reason    | Grund für das Senden des Codes, von Viber verlangt. | nein | `null` |
| business_name  | In der Nachricht angezeigter Firmenname. | nein | `null` |

### RCS-Objekt
| PARAMETERNAME  | WERT | PFLICHT | STANDARDWERT |
|:---------------|:-----|:--------|:-------------|
| sender         | Textabsender für RCS. Er muss zuerst registriert werden — wenden Sie sich zur Registrierung an [unseren Support](https://www.bulkgate.com/de/kontaktieren-sie-uns/). | **Ja** | - |
| expiration     | Sekunden, die gewartet wird, bevor ein anderer Kanal versucht wird | nein | 60 |
| use_card       | Sendet den Code als Karte statt als reinen Text. | nein | `false` |

### WhatsApp-Objekt

| PARAMETERNAME  | WERT | PFLICHT | STANDARDWERT |
|:---------------|:-----|:--------|:-------------|
| sender         | Ihr registrierter [WhatsApp-Absender](https://www.bulkgate.com/de/hilfe-center/whatsapp/registrierung-whatsapp-absender/) | **Ja** | - |
| template       | Name der genehmigten WhatsApp-Vorlage, über die der Code zugestellt wird. | Nein | `verification_code` |
| language       | Sprache der Vorlage. Ohne Angabe wird `language` aus der Anfrage verwendet. | Nein | `null` |
| expiration     | Sekunden, die gewartet wird, bevor ein anderer Kanal der Kaskade versucht wird. Minimum `60`. | Nein | `180` |

### Text2Voice-Objekt

Der Code wird vorgelesen. Die Nachricht kann wiederholt werden, damit der Empfänger ihn notieren kann.

| PARAMETERNAME    | WERT | PFLICHT | STANDARDWERT |
|:-----------------|:-----|:--------|:-------------|
| sender           | Ihre registrierte Anrufernummer. | **Ja** | - |
| language         | Sprache der Stimme, einer der 47 unterstützten ISO-Codes. Ohne Angabe wird `language` aus der Anfrage verwendet. | Nein | `null` |
| prefer_gender    | Bevorzugte Stimme - `male` oder `female`. | Nein | `male` |
| safety_statement | Stellt dem Anruf einen Sicherheitshinweis voran. | Nein | `true` |
| repeat           | Wie oft der Code während des Anrufs wiederholt wird. | Nein | `1` |
| expiration       | Sekunden, die gewartet wird, bevor ein anderer Kanal der Kaskade versucht wird. Minimum `60`. | Nein | `180` |

## Beispielanfrage

```json
{
  "application_id": 451,
  "application_token": "NKN02TWE6NfBkfl-your-secret-token-Wf05GaqLIWLW4aBj",
  "number": "420777777777",
  "country": "de",
  "language": "de",
  "code_type": "string",
  "code_length": 7,
  "request_quota_number": 1,
  "request_quota_identification": "127.0.0.1",
  "trials_available_resend": 2,
  "trials_available_verification": 5,
  "daily_limit": 100,
  "daily_limit_country": {"cz": 150, "sk": 50},
  "expiration": 3600,
  "channel": {
    "rcs": {
      "sender": "Lt. Hagan",
      "expiration": 100
    },
    "viber": {
      "sender": "Lt. Hagan",
      "expiration": 100
    },
    "sms": {
      "sender_id": "gText",
      "sender_id_value": "Lt-Hagan",
      "unicode": true
    }
  }
}
```

## Antwort

**Bei Erfolg:**
```json
{
    "data": {
        "id": "otp-65cca8b4b6a6a2.24308291",
        "message": {
          "status": "accepted",
          "message_id": "cascade-xjyjzh7thor3",
          "part_id": [
            "cascade-xjyjzh7thor3"  
          ],
          "number": "420777777777",
          "channel": "whatsapp"
        }
    }
}
```

**Bei einem Fehler:**
```json
{
    "type": "unknown_identity",
    "code": 400,
    "error": "Unknown identity",
    "detail": null
}
```

```json
{
    "type": "invalid_input_parameters",
    "code": 400,
    "error": "Invalid input parameters",
    "detail": null
}
```

Dabei gilt:

- **type** und **error** (Beschreibung des Fehlers) finden Sie in der [Tabelle der Fehlertypen](https://www.bulkgate.com/de/dokumentation/api-verwaltung-und-tokens/api-fehlertypen/)
- **code** steht für den HTTP-Fehler
- **detail** enthält zusätzliche Informationen zum Fehler

### Fehlertypen der OTP API

Zusätzlich zu den [allgemeinen Typen](https://www.bulkgate.com/de/dokumentation/api-verwaltung-und-tokens/api-fehlertypen/) gibt die OTP API eigene Typen zurück:

| TYP                                                          | WANN ER AUFTRITT |
|:-------------------------------------------------------------|:-----------------|
| `the_quota_of_send_per_minute_has_been_exceeded`             | Das Sendekontingent pro Minute ist ausgeschöpft. |
| `the_quota_of_one_additional_resend_per_minute_has_been_exceeded` | Erneutes Senden früher als 60 s nach dem vorherigen. |
| `the_quota_of_one_additional_resend_has_been_exceeded`       | `trials_available_resend` ist ausgeschöpft. |
| `the_quota_of_one_additional_verification_has_been_exceeded` | `trials_available_verification` ist ausgeschöpft. |
| `daily_limit_reached`                                        | `daily_limit` ist ausgeschöpft. |
| `country_is_disabled`                                        | Das Land der Nummer ist in `daily_limit_country` nicht aufgeführt. |
| `country_daily_limit_exceeded`                               | Das Tageslimit für dieses Land ist ausgeschöpft. |
| `invalid_phone_number`                                       | Die Nummer konnte nicht erkannt werden. |
| `invalid_code`                                               | Der verifizierte Code stimmt nicht überein. |
| `unknown_channel`                                            | Die Kaskade enthält einen Kanal, den die OTP API nicht kennt. |
| `request_can_not_be_created`                                 | Die Anfrage konnte nicht erstellt werden. |
