# Codes à usage unique (OTP)

> Index de la documentation : https://wahasend.com/docs/fr/llms.txt · Tout en un fichier : https://wahasend.com/docs/fr.md · URL de base de l'API : https://app.wahasend.com/api/v1

Envoyez un code de vérification par WhatsApp et vérifiez ce que la personne a tapé. Codes aléatoires, stockés hachés, valables 5 minutes, 3 essais. Inclus dans **Developer** (fonction `otp`).

<a id="otp-send"></a>

### Envoyer un code

`POST /api/v1/otp/send`

Génère un code et l'envoie tout de suite (sans file d'attente). Gardez `requestId` pour la vérification.

- Débloqué par: Developer (`otp`)
- Clé de numéro : oui

> Des limites, pour que personne ne puisse inonder un numéro via votre application (voir [Limites OTP](https://wahasend.com/docs/fr/errors.md#otp-limits)) : vers un même numéro, un code toutes les 30 secondes, 3 par 10 minutes et 10 par 24 heures ; 60 codes par minute pour toute l'organisation. Au-delà : 429 `OTP_RATE_LIMITED` avec `Retry-After` et `details` `{ scope: "phone" | "organization", reason: "cooldown" | "window" | "day" | "organization", limit, retryAfterSeconds }`. Un code compte dès qu'il est envoyé, même si WhatsApp le refuse ensuite.

**Corps de la requête**

| Champ | Type | Obligatoire | Description |
| --- | --- | --- | --- |
| `phone` | string | oui | Numéro international, 8 à 20 caractères (`+22212345678`). Les identifiants `@lid` ne sont pas acceptés ici. |
| `template` | string | non | Votre texte, 500 caractères max. Doit contenir `{{code}}` (sinon 400 `OTP_TEMPLATE_MISSING_CODE`) : chaque `{{code}}` devient le code et chaque `{{expiry}}` les minutes. Par défaut : « Your verification code is: *{{code}}* … ». |
| `length` | integer | non | Chiffres, 4 à 8. Par défaut 6. |
| `containerId` | uuid | non | Lequel de vos numéros WhatsApp utiliser ; il l'emporte toujours. Par défaut : votre numéro par défaut (sinon un numéro connecté), ou un numéro du groupe quand [plusieurs numéros](https://wahasend.com/docs/fr/phone-numbers.md#several-numbers) est activé. Ignoré avec une clé de numéro, qui utilise toujours son numéro. |

**Exemple**

curl:

```bash
curl -X POST https://app.wahasend.com/api/v1/otp/send \
  -H "X-API-Key: $WAHASEND_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "phone": "+22212345678",
  "template": "Your Kaba Shop code: {{code}}. It expires in {{expiry}} minutes.",
  "length": 6
}'
```

JavaScript:

```js
const res = await fetch('https://app.wahasend.com/api/v1/otp/send', {
  method: 'POST',
  headers: { 'X-API-Key': process.env.WAHASEND_API_KEY, 'Content-Type': 'application/json' },
  body: JSON.stringify({
    "phone": "+22212345678",
    "template": "Your Kaba Shop code: {{code}}. It expires in {{expiry}} minutes.",
    "length": 6
  }),
});
const data = await res.json();
```

Python:

```python
import os
import requests

r = requests.post(
    "https://app.wahasend.com/api/v1/otp/send",
    headers={"X-API-Key": os.environ["WAHASEND_API_KEY"]},
    json={
        "phone": "+22212345678",
        "template": "Your Kaba Shop code: {{code}}. It expires in {{expiry}} minutes.",
        "length": 6,
    },
)
print(r.json())
```

**Réponse 201**

```json
{
  "success": true,
  "requestId": "0b8e4d2a-7c1f-4a95-b3e6-9d2c5f8a1e47",
  "phone": "+22212345678",
  "expiresAt": "2026-09-30T10:05:00.000Z",
  "expiresInSeconds": 300
}
```

**Erreurs possibles**

- [`VALIDATION_ERROR`](https://wahasend.com/docs/fr/errors.md#validation_error) (400): Validation failed. Check the details for specific field errors.
- [`OTP_TEMPLATE_MISSING_CODE`](https://wahasend.com/docs/fr/errors.md#otp_template_missing_code) (400): The message template must contain {{code}}, where the code goes.
- [`OTP_RATE_LIMITED`](https://wahasend.com/docs/fr/errors.md#otp_rate_limited) (429): Too many verification codes for this number or this account. Wait before sending another one.
- [`NO_SESSION_CONFIGURED`](https://wahasend.com/docs/fr/errors.md#no_session_configured) (400): This account has no connected WhatsApp number.
- [`WAHA_ERROR`](https://wahasend.com/docs/fr/errors.md#waha_error) (502): WhatsApp could not complete the request. Try again.
- [`WAHA_SESSION_ERROR`](https://wahasend.com/docs/fr/errors.md#waha_session_error) (503): WhatsApp is not connected.

<a id="otp-verify"></a>

### Vérifier un code

`POST /api/v1/otp/verify`

Répond `verified: true` une seule fois. Un mauvais code consomme un des 3 essais.

- Débloqué par: Developer (`otp`)
- Clé de numéro : oui

> Un mauvais code répond 400 `OTP_INVALID_CODE` avec `details.attemptsRemaining`.

**Corps de la requête**

| Champ | Type | Obligatoire | Description |
| --- | --- | --- | --- |
| `requestId` | uuid | oui | Celui de l'envoi. |
| `code` | string | oui | Ce que la personne a tapé, 4 à 8 caractères. |

**Exemple**

curl:

```bash
curl -X POST https://app.wahasend.com/api/v1/otp/verify \
  -H "X-API-Key: $WAHASEND_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "requestId": "0b8e4d2a-7c1f-4a95-b3e6-9d2c5f8a1e47",
  "code": "482913"
}'
```

JavaScript:

```js
const res = await fetch('https://app.wahasend.com/api/v1/otp/verify', {
  method: 'POST',
  headers: { 'X-API-Key': process.env.WAHASEND_API_KEY, 'Content-Type': 'application/json' },
  body: JSON.stringify({
    "requestId": "0b8e4d2a-7c1f-4a95-b3e6-9d2c5f8a1e47",
    "code": "482913"
  }),
});
const data = await res.json();
```

Python:

```python
import os
import requests

r = requests.post(
    "https://app.wahasend.com/api/v1/otp/verify",
    headers={"X-API-Key": os.environ["WAHASEND_API_KEY"]},
    json={
        "requestId": "0b8e4d2a-7c1f-4a95-b3e6-9d2c5f8a1e47",
        "code": "482913",
    },
)
print(r.json())
```

**Réponse 200**

```json
{
  "success": true,
  "verified": true,
  "phone": "+22212345678"
}
```

**Erreurs possibles**

- [`OTP_INVALID_CODE`](https://wahasend.com/docs/fr/errors.md#otp_invalid_code) (400): Invalid code.
- [`OTP_EXPIRED`](https://wahasend.com/docs/fr/errors.md#otp_expired) (410): OTP has expired. Request a new code.
- [`OTP_MAX_ATTEMPTS`](https://wahasend.com/docs/fr/errors.md#otp_max_attempts) (429): Maximum verification attempts exceeded. Request a new code.
- [`OTP_ALREADY_VERIFIED`](https://wahasend.com/docs/fr/errors.md#otp_already_verified) (400): OTP has already been verified.
- [`NOT_FOUND`](https://wahasend.com/docs/fr/errors.md#not_found) (404): Not found.
