## URL de la API
URL a la que se envían las solicitudes HTTP:
```url
https://portal.bulkgate.com/api/1.0/otp/send
```

> [!NOTE]
> Si la solicitud no llega a su destino, repítala en el [servidor de respaldo](https://www.bulkgate.com/es/documentacion/administracion-de-la-api/servidor-de-respaldo/) `backup1.bulkgate.com`.

## Métodos HTTP admitidos

- `POST` - `application/json`

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

> [!IMPORTANT]
> Además de `request_quota_number`, el endpoint aplica un **límite de 60 solicitudes por minuto para toda la cuenta**. Si se supera, se devuelve `the_quota_of_send_per_minute_has_been_exceeded`.

## Tabla de parámetros

| NOMBRE DEL PARÁMETRO          | VALOR | OBLIGATORIO | VALOR PREDETERMINADO |
|:------------------------------|:------|:------------|:---------------------|
| application_id                | [Application ID](https://www.bulkgate.com/es/documentacion/administracion-de-la-api/administracion-api/) | **Sí** | - |
| application_token             | [Application token](https://www.bulkgate.com/es/documentacion/administracion-de-la-api/tokens-de-api/) | **Sí** | - |
| number                        | Número de teléfono al que se envía el código de verificación | **Sí** | - |
| country                       | Código de país del número de teléfono | no | El valor se toma del perfil. |
| language                      | Idioma del texto del mensaje, uno de los 100 códigos ISO admitidos. Un código desconocido hace que se rechace la solicitud. Si no se indica, el idioma se detecta a partir del número de teléfono. | no | `null` |
| code_type                     | Tipo de código. (`string`, `int` o `combined`) | no | `int` |
| code_length                   | Longitud del código de verificación (4-100). | no | 6 |
| request_quota_number          | Número de solicitudes por minuto para `request_quota_identification` | no | 1 |
| request_quota_identification  | Identificación del «usuario / solicitante de OTP» al que se aplicará la cuota por minuto `request_quota_number`. Recomendamos utilizar una dirección IP para esta identificación. | **Sí** | - |
| trials_available_resend       | Límite de [reenvíos](https://www.bulkgate.com/es/documentacion/otp-api/reenvio-de-codigo-de-un-solo-uso/) disponibles | no | `null` - ilimitado |
| trials_available_verification | Límite de [verificaciones](https://www.bulkgate.com/es/documentacion/otp-api/verificacion-de-codigo-de-un-solo-uso/) disponibles | no | `null` - ilimitado |
| daily_limit                   | Límite de solicitudes disponibles al día (ventana móvil de las últimas 24 horas) | no | `null` - ilimitado |
| daily_limit_country           | Límite diario por país como mapa `{"cz": 100, "sk": 50}`. Si se rellena, **solo** se permiten los países indicados; cualquier otro falla con `country_is_disabled`. | no | `null` - ilimitado |
| expiration                    | Caducidad de la solicitud OTP en segundos; transcurrido este tiempo, la solicitud ya no es posible. Un valor inferior a `60` se ignora y se utiliza el valor predeterminado. | no | `604800` - 7 días |
| channel                       | Canales alternativos. Los canales se indican en cascada: si no conseguimos entregar su mensaje por el canal de mayor prioridad, se utilizan los canales situados más abajo en la cascada. Si ninguno de ellos consigue entregarlo, se utilizará SMS. | no | [SMS](#objeto-sms), [Viber](#objeto-viber), [RCS](#objeto-rcs), [WhatsApp](#objeto-whatsapp) o [Text2Voice](#objeto-text2voice) |


## Canales

El objeto `channel` decide qué canales entregan el código y en qué orden. **El orden de las claves en la solicitud es el orden de la cascada**: si el primer canal no puede entregar el código, se intenta con el siguiente. Si ninguno puede, se utiliza SMS.

### Objeto SMS
| NOMBRE DEL PARÁMETRO | VALOR | OBLIGATORIO | VALOR PREDETERMINADO |
|:----------------|:------|:------------|:---------------------|
| sender_id       | ID de remitente, consulte [tipo de ID de remitente](https://www.bulkgate.com/es/documentacion/simple-api/simple-transactional/) | no | `gSystem` |
| sender_id_value | Valor del remitente - `gOwn` (p. ej. "420 777 777 777"), `gText` (p. ej. "BulkGate"), `gProfile` (p. ej. "423"), `gMobile` o `gPush` [(KEY)](https://www.bulkgate.com/es/centro-de-ayuda/mobile-connect/instalacion-de-mobile-connect/) | no | `null` |
| domain          | URL de un sitio web que utiliza [WebOTP](https://developer.mozilla.org/en-US/docs/Web/API/WebOTP_API) para introducir automáticamente el código recibido. | no | `null` |



### Objeto Viber
| NOMBRE DEL PARÁMETRO | VALOR | OBLIGATORIO | VALOR PREDETERMINADO |
|:---------------|:------|:------------|:---------------------|
| sender         | Nombre de su [remitente registrado para Viber](https://www.bulkgate.com/es/centro-de-ayuda/viber/registro-de-remitente-de-viber/) | **Sí** | - |
| expiration     | Segundos de espera antes de intentarlo por otro canal | no | 60 |
| code_type      | Tipo de código exigido por Viber, indicado en la plantilla OTP aprobada. | no | `null` |
| code_reason    | Motivo del envío del código, exigido por Viber. | no | `null` |
| business_name  | Nombre de la empresa que se muestra en el mensaje. | no | `null` |

### Objeto RCS
| NOMBRE DEL PARÁMETRO | VALOR | OBLIGATORIO | VALOR PREDETERMINADO |
|:---------------|:------|:------------|:---------------------|
| sender         | Remitente de texto para RCS. Primero debe registrarse: para registrarlo, póngase en contacto con [nuestro soporte](https://www.bulkgate.com/es/contacto/). | **Sí** | - |
| expiration     | Segundos de espera antes de intentarlo por otro canal | no | 60 |
| use_card       | Envía el código como tarjeta en lugar de texto sin formato. | no | `false` |

### Objeto WhatsApp

| NOMBRE DEL PARÁMETRO | VALOR | OBLIGATORIO | VALOR PREDETERMINADO |
|:---------------|:------|:------------|:---------------------|
| sender         | Su [remitente de WhatsApp](https://www.bulkgate.com/es/centro-de-ayuda/whatsapp/registro-de-remitente-de-whatsapp/) registrado | **Sí** | - |
| template       | Nombre de la plantilla de WhatsApp aprobada con la que se entrega el código. | No | `verification_code` |
| language       | Idioma de la plantilla. Si no se indica, se utiliza el `language` de la solicitud. | No | `null` |
| expiration     | Segundos de espera antes de intentarlo por otro canal de la cascada. Mínimo `60`. | No | `180` |

### Objeto Text2Voice

El código se lee en voz alta. El mensaje puede repetirse para que el destinatario pueda anotarlo.

| NOMBRE DEL PARÁMETRO | VALOR | OBLIGATORIO | VALOR PREDETERMINADO |
|:-----------------|:------|:------------|:---------------------|
| sender           | Su número de llamada registrado. | **Sí** | - |
| language         | Idioma de la voz, uno de los 47 códigos ISO admitidos. Si no se indica, se utiliza el `language` de la solicitud. | No | `null` |
| prefer_gender    | Voz preferida - `male` o `female`. | No | `male` |
| safety_statement | Antepone un aviso de seguridad a la llamada. | No | `true` |
| repeat           | Cuántas veces se repite el código durante la llamada. | No | `1` |
| expiration       | Segundos de espera antes de intentarlo por otro canal de la cascada. Mínimo `60`. | No | `180` |

## Ejemplo de solicitud

```json
{
  "application_id": 451,
  "application_token": "NKN02TWE6NfBkfl-your-secret-token-Wf05GaqLIWLW4aBj",
  "number": "420777777777",
  "country": "cz",
  "language": "es",
  "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
    }
  }
}
```

## Respuesta

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

**En caso de error:**
```json
{
    "type": "unknown_identity",
    "code": 400,
    "error": "Unknown identity",
    "detail": null
}
```

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

Donde:

- **type** y **error** (descripción del error) se encuentran en la [tabla de tipos de error](https://www.bulkgate.com/es/documentacion/administracion-de-la-api/tipos-de-error/)
- **code** representa el error HTTP
- **detail** es información adicional sobre el error

### Tipos de error de la OTP API

Además de los [tipos comunes](https://www.bulkgate.com/es/documentacion/administracion-de-la-api/tipos-de-error/), la OTP API devuelve los suyos propios:

| TIPO                                                         | CUÁNDO SE PRODUCE                                                     |
|:-------------------------------------------------------------|:----------------------------------------------------------------------|
| `the_quota_of_send_per_minute_has_been_exceeded`             | Se ha agotado la cuota de envíos por minuto.                          |
| `the_quota_of_one_additional_resend_per_minute_has_been_exceeded` | Un reenvío antes de que pasen 60 s desde el anterior.            |
| `the_quota_of_one_additional_resend_has_been_exceeded`       | Se ha agotado `trials_available_resend`.                              |
| `the_quota_of_one_additional_verification_has_been_exceeded` | Se ha agotado `trials_available_verification`.                        |
| `daily_limit_reached`                                        | Se ha agotado `daily_limit`.                                          |
| `country_is_disabled`                                        | El país del número no figura en `daily_limit_country`.                |
| `country_daily_limit_exceeded`                               | Se ha agotado el límite diario para ese país.                         |
| `invalid_phone_number`                                       | No se ha podido reconocer el número.                                  |
| `invalid_code`                                               | El código verificado no coincide.                                     |
| `unknown_channel`                                            | La cascada contiene un canal que la OTP API no conoce.                |
| `request_can_not_be_created`                                 | No se ha podido crear la solicitud.                                   |
