## URL da API
URL utilizado para enviar pedidos HTTP:
```url
https://portal.bulkgate.com/api/1.0/otp/send
```

> [!NOTE]
> Se o pedido não chegar ao destino, repita-o no [servidor de reserva](https://www.bulkgate.com/pt/documentacao/administracao-da-api/servidor-de-reserva/) `backup1.bulkgate.com`.

## Métodos HTTP suportados

- `POST` - `application/json`

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

> [!IMPORTANT]
> Além de `request_quota_number`, o endpoint aplica um **limite de 60 pedidos por minuto para toda a conta**. Ao ultrapassá-lo, é devolvido `the_quota_of_send_per_minute_has_been_exceeded`.

## Tabela de parâmetros

| NOME DO PARÂMETRO | VALOR | OBRIGATÓRIO | VALOR PREDEFINIDO |
|:------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:----------|:--------------------------------------------------------------------------------------------------------------------------------------------|
| application_id                | [Application ID](https://www.bulkgate.com/pt/documentacao/administracao-da-api/administracao-de-apis/) | **Sim**   | - |
| application_token             | [Application token](https://www.bulkgate.com/pt/documentacao/administracao-da-api/tokens-de-api/) | **Sim**   | - |
| number                        | Número de telefone para o qual é enviado o código de verificação | **Sim**   | - |
| country                       | Código do país do número de telefone | não        | O valor é obtido a partir do perfil. |
| language                      | Idioma do texto da mensagem, um dos 100 códigos ISO suportados. Um código desconhecido faz com que o pedido seja rejeitado. Sem ele, o idioma é detetado a partir do número de telefone. | não        | `null` |
| code_type                     | Tipo de código. (`string`, `int` ou `combined`) | não        | `int` |
| code_length                   | Comprimento do código de verificação (4-100). | não        | 6 |
| request_quota_number          | O número de pedidos por minuto para `request_quota_identification` | não        | 1 |
| request_quota_identification  | Identificação do "utilizador / requerente do OTP" a que se aplica a quota por minuto `request_quota_number`. Recomendamos utilizar um endereço IP para esta identificação. | **Sim**   | - |
| trials_available_resend       | Limite de [reenvios](https://www.bulkgate.com/pt/documentacao/otp-api/reenvio-de-codigo-de-utilizacao-unica/) disponíveis | não        | `null` - ilimitado |
| trials_available_verification | Limite de [verificações](https://www.bulkgate.com/pt/documentacao/otp-api/verificacao-de-codigo-de-utilizacao-unica/) disponíveis | não        | `null` - ilimitado |
| daily_limit                   | Limite de pedidos disponíveis por dia (contínuo, para as últimas 24 horas) | não        | `null` - ilimitado |
| daily_limit_country           | Limite diário por país sob a forma de um mapa `{"cz": 100, "sk": 50}`. Quando preenchido, são permitidos **apenas** os países indicados — qualquer outro falha com `country_is_disabled`. | não        | `null` - ilimitado |
| expiration                    | Expiração do pedido de OTP em segundos; decorrido este tempo, o pedido deixa de ser possível. Um valor inferior a `60` é ignorado e é utilizado o valor predefinido. | não        | `604800` - 7 dias |
| channel                       | Canais alternativos. Os canais são indicados em cascata: se não for possível entregar a mensagem pelo canal de maior prioridade, são utilizados os canais seguintes da cascata. Se nenhum deles conseguir entregar a mensagem, é utilizado o SMS. | não        | [SMS](#objeto-sms), [Viber](#objeto-viber), [RCS](#objeto-rcs), [WhatsApp](#objeto-whatsapp) ou [Text2Voice](#objeto-text2voice) |


## Canais

O objeto `channel` determina os canais que entregam o código e por que ordem. **A ordem das chaves no pedido é a ordem da cascata** — se o primeiro canal não conseguir entregar o código, é tentado o seguinte. Se nenhum conseguir, é utilizado o SMS.

### Objeto SMS
| NOME DO PARÂMETRO | VALOR | OBRIGATÓRIO | VALOR PREDEFINIDO |
|:----------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------|:----------|:--------------|
| sender_id       | ID do remetente, consulte [tipo de ID do remetente](https://www.bulkgate.com/pt/documentacao/simple-api/simple-transactional/) | não        | `gSystem`     |
| sender_id_value | Valor do remetente - `gOwn` (por exemplo, "420 777 777 777"), `gText` (por exemplo, "BulkGate"), `gProfile` (por exemplo, "423"), `gMobile` ou `gPush` [(KEY)](https://www.bulkgate.com/pt/centro-de-ajuda/mobile-connect/instalacao-do-mobile-connect/) | não        | `null`        |
| domain          | URL de um website que utiliza [WebOTP](https://developer.mozilla.org/en-US/docs/Web/API/WebOTP_API) para o preenchimento automático do código recebido. | não        | `null`        |



### Objeto Viber
| NOME DO PARÂMETRO | VALOR | OBRIGATÓRIO | VALOR PREDEFINIDO |
|:---------------|:-------------------------------------------------------------------------------|:----------|:--------------|
| sender         | Nome do seu [remetente registado para Viber](https://www.bulkgate.com/pt/centro-de-ajuda/viber/registo-de-remetente-viber/) | **Sim**   | -             |
| expiration     | Segundos de espera antes de tentar outro canal | não        | 60            |
| code_type      | Tipo de código exigido pelo Viber, indicado no modelo de OTP aprovado. | não        | `null`        |
| code_reason    | Motivo do envio do código, exigido pelo Viber. | não        | `null`        |
| business_name  | Nome da empresa apresentado na mensagem. | não        | `null`        |

### Objeto RCS
| NOME DO PARÂMETRO | VALOR | OBRIGATÓRIO | VALOR PREDEFINIDO |
|:---------------|:-------------------------------------------------------------------------------|:----------|:--------------|
| sender         | Remetente de texto para RCS. Tem de ser registado previamente — para o registar, contacte o [nosso suporte](https://www.bulkgate.com/pt/contacto/). | **Sim**   | -             |
| expiration     | Segundos de espera antes de tentar outro canal | não        | 60            |
| use_card       | Envia o código como cartão em vez de texto simples. | não        | `false`       |

### Objeto WhatsApp

| NOME DO PARÂMETRO | VALOR | OBRIGATÓRIO | VALOR PREDEFINIDO |
|:---------------|:---------------------------------------------------------------------------------------------|:----------|:--------------------|
| sender         | O seu [remetente de WhatsApp](https://www.bulkgate.com/pt/centro-de-ajuda/whatsapp/registo-de-remetente-whatsapp/) registado | **Sim**   | -                   |
| template       | Nome do modelo de WhatsApp aprovado utilizado para entregar o código. | Não        | `verification_code` |
| language       | Idioma do modelo. Sem ele, é utilizado o `language` do pedido. | Não        | `null`              |
| expiration     | Segundos de espera antes de tentar outro canal da cascata. Mínimo `60`. | Não        | `180`               |

### Objeto Text2Voice

O código é lido em voz alta. A mensagem pode ser repetida para que o destinatário a possa anotar.

| NOME DO PARÂMETRO | VALOR | OBRIGATÓRIO | VALOR PREDEFINIDO |
|:-----------------|:--------------------------------------------------------------------------------|:----------|:--------------|
| sender           | O seu número de chamada registado. | **Sim**   | -             |
| language         | Idioma da voz, um dos 47 códigos ISO suportados. Sem ele, é utilizado o `language` do pedido. | Não | `null` |
| prefer_gender    | Voz preferida - `male` ou `female`. | Não        | `male`        |
| safety_statement | Acrescenta um aviso de segurança no início da chamada. | Não        | `true`        |
| repeat           | Quantas vezes o código é repetido durante a chamada. | Não        | `1`           |
| expiration       | Segundos de espera antes de tentar outro canal da cascata. Mínimo `60`. | Não        | `180`         |

## Exemplo de pedido

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

## Resposta

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

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

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

Em que:

- **type** e **error** (descrição do erro) encontram-se na [tabela de tipos de erro](https://www.bulkgate.com/pt/documentacao/administracao-da-api/tipos-de-erro-api/)
- **code** representa o erro HTTP
- **detail** é uma informação adicional sobre o erro

### Tipos de erro da OTP API

Além dos [tipos comuns](https://www.bulkgate.com/pt/documentacao/administracao-da-api/tipos-de-erro-api/), a OTP API devolve os seus próprios:

| TIPO                                                         | QUANDO OCORRE                                                      |
|:-------------------------------------------------------------|:----------------------------------------------------------------------|
| `the_quota_of_send_per_minute_has_been_exceeded`             | A quota de envios por minuto está esgotada. |
| `the_quota_of_one_additional_resend_per_minute_has_been_exceeded` | Um reenvio menos de 60 s após o anterior. |
| `the_quota_of_one_additional_resend_has_been_exceeded`       | `trials_available_resend` está esgotado. |
| `the_quota_of_one_additional_verification_has_been_exceeded` | `trials_available_verification` está esgotado. |
| `daily_limit_reached`                                        | `daily_limit` está esgotado. |
| `country_is_disabled`                                        | O país do número não consta de `daily_limit_country`. |
| `country_daily_limit_exceeded`                               | O limite diário para esse país está esgotado. |
| `invalid_phone_number`                                       | Não foi possível reconhecer o número. |
| `invalid_code`                                               | O código verificado não corresponde. |
| `unknown_channel`                                            | A cascata contém um canal que a OTP API não conhece. |
| `request_can_not_be_created`                                 | Não foi possível criar o pedido. |
