> For the complete documentation index, see [llms.txt](https://docs.textbelt.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.textbelt.com/otp-mobile-verification.md).

# OTP/Mobile verification

In addition to [sending SMS](/master.md#send-an-sms-using-http-post), Textbelt automates one-time password (OTP) and mobile verification use cases. &#x20;

There is no extra charge for sending and verifying OTPs compared to sending normal SMS.  For this reason, Textbelt is very cost-effective compared to other solutions.

## Sending an SMS verification code

The `https://textbelt.com/otp/generate` HTTP POST endpoint will create a one-time code and send it to the user's phone.

![](/files/-MOU-cAx4CmdifKMSP2Y)

The `/otp/generate` endpoint requires the following parameters:

* **phone:** A phone number.  If you're in the U.S., you can just send a normal 10-digit phone number with area code.  Outside the U.S., it is best to send the phone number in E.164 format with your country code.  For example, a British phone number is +447712345678.
* **userid:** An id that is unique to your user.  This can be any string.
* **key:** Your Textbelt API key (use `example_otp_key` to test).

Optional parameters:

* **message:** The content of your SMS.  Replaces the default message "Your verification code is XXX".  Use the $OTP variable to include the OTP in your message.
* **lifetime:** Determines how many seconds the OTP is valid for. Defaults to 180, or 3 minutes.
* **length:** The number of digits in your OTP.  Defaults to 6.

### Examples

Here are basic examples that use only the required parameters:

{% tabs %}
{% tab title="Bash" %}

```bash
curl -X POST https://textbelt.com/otp/generate \
     --data-urlencode phone='5555555555' \
     --data-urlencode userid='myuser@site.com' \
     -d key=example_otp_key
```

{% endtab %}

{% tab title="Python" %}
Using the popular [requests](http://docs.python-requests.org/en/master/) library:

```python
import requests

resp = requests.post('https://textbelt.com/otp/generate', {
  'phone': '5555555555',
  'userid': 'myuser@site.com',
  'key': 'example_otp_key',
})
print(resp.json())
```

{% endtab %}

{% tab title="Ruby" %}

```ruby
require 'net/http'
require 'uri'

uri = URI.parse("https://textbelt.com/otp/generate")
Net::HTTP.post_form(uri, {
  :phone => '5555555555',
  :userid => 'myuser@site.com',
  :key => 'example_otp_key',
})
```

{% endtab %}

{% tab title="Node" %}
Using the popular [request](https://www.npmjs.com/package/request) library:

```javascript
const request = require('request');
request('https://textbelt.com/otp/generate', {
  body: {
    phone: '5555555555',
    userid: 'myuser@site.com',
    key: 'example_otp_key',
  },
})
```

{% endtab %}

{% tab title="Javascript" %}
Using the browser [Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch) and a [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) request:

```javascript
fetch('https://textbelt.com/text', {
  method: 'post',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    phone: '5555555555',
    userid: 'myuser@site.com',
    key: 'example_otp_key',
  }),
}).then(response => {
  return response.json();
}).then(data => {
  console.log(data);
});
```

{% endtab %}

{% tab title="PHP" %}

```php
$ch = curl_init('https://textbelt.com/otp/generate');
$data = array(
  'phone' => '5555555555',
  'userid' => 'myuser@site.com',
  'key' => 'example_otp_key',
);

curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$response = curl_exec($ch);
curl_close($ch);
```

{% endtab %}

{% tab title="C#" %}

```csharp
using System;
using System.Collections.Specialized;
using System.Net;

using (WebClient client = new WebClient())
{
  byte[] response = client.UploadValues("http://textbelt.com/text", new NameValueCollection() {
    { "phone", "5555555555" },
    { "userid", "myuser@site.com" },
    { "key", "example_otp_key" },
  });

  string result = System.Text.Encoding.UTF8.GetString(response);
}
```

{% endtab %}

{% tab title="Java" %}
Using the popular [Apache HttpComponents](https://hc.apache.org/) library:

```java
final NameValuePair[] data = {
    new BasicNameValuePair("phone", "5555555555"),
    new BasicNameValuePair("userid", "myuser@site.com"),
    new BasicNameValuePair("key", "example_otp_key")
};
HttpClient httpClient = HttpClients.createMinimal();
HttpPost httpPost = new HttpPost("https://textbelt.com/otp/generate");
httpPost.setEntity(new UrlEncodedFormEntity(Arrays.asList(data)));
HttpResponse httpResponse = httpClient.execute(httpPost);

String responseString = EntityUtils.toString(httpResponse.getEntity());
JSONObject response = new JSONObject(responseString);
```

{% endtab %}

{% tab title="Go" %}

```go
import (
  "net/http"
  "net/url"
)

func main() {
  values := url.Values{
    "phone": {"5555555555"},
    "userid": {"myuser@site.com"},
    "key": {"example_otp_key"},
  }

  http.PostForm("https://textbelt.com/text", values)
}
```

{% endtab %}

{% tab title="Powershell" %}

```bash
$body = @{
  "phone"="5555555555"
  "userid"="myuser@site.com"
  "key"="example_otp_key"
}
$submit = Invoke-WebRequest -Uri https://textbelt.com/text -Body $body -Method Post
```

{% endtab %}
{% endtabs %}

Include optional parameters to customize your OTP:

```bash
curl -X POST https://textbelt.com/otp/generate \
     --data-urlencode phone='5557727420' \
     --data-urlencode userid='myuser@site.com' \
     --data-urlencode message='Nuclear launch code: $OTP! Use it to login.' \
     -d lifetime=120 \
     -d length=4 \
     -d key=example_otp_key
```

### Response

The `/otp/generate` endpoint returns a JSON response with the following attributes:

* **success:** Whether the otp was successfully sent.
* **textId:**&#x54;he ID of the text message sent, so you can track its delivery.  Use this to [check SMS delivery status](/other-api-endpoints.md#checking-sms-delivery-status).
* **quotaRemaining:** The amount of credit left on your key.
* **otp:** The one-time verification code sent to the user.

&#x20;Here's an example API response from the OTP generation endpoint `/otp/generate`:

```bash
{"success": true, "textId": "1234", "quotaRemaining": 70, "otp": "672383"}
```

Here's an example response when you are out of SMS credits or used an invalid key in your request:

```bash
{"success": false, "quotaRemaining": 0, "otp": ""}
```

## Verifying a user code

Once you've sent the one-time code, your user will enter a code on your website or application.  You can use Textbelt to confirm that the code is valid.

This is done via HTTP GET request to the `/otp/verify` endpoint.  Supply the following parameters:

* **otp:**&#x54;he code entered by the user.
* **userid**: The ID of the user.  Should match the id that you used in the prior `/otp/generate` step.
* **key:** Your Textbelt API key.

Here's an example URL:

&#x20;<https://textbelt.com/otp/verify?**otp**=123456&**userid**=myuser@site.com&**key**=example\\_otp\\_key&#x20>;

You can request it via a simple HTTP GET request in any language of your choosing:

```bash
user_entered_code=12345
userid=myuser@site.com
key=example_otp_key

curl "https://textbelt.com/otp/verify?otp=${user_entered_code}&userid=${userid}&key=${key}"
```

The response contains the following:

* **success:** Whether the request was successfully received and processed.  True or false.
* **isValidOtp:** Whether the OTP is correct for the given userid.  True or false.

Use **isValidOtp** to decide whether to let the user into your app!

Here's an example response for a valid OTP:

```bash
{"success": true, "isValidOtp": true}
```

Here's an example response for an invalid OTP:

```bash
{"success": true, "isValidOtp": false}
```

## Understanding the OTP flow

Mobile verification with a OTP is a three-step process.  In the example below, a web application implements mobile verification by using Textbelt to **send an OTP** directly to a user via SMS, and subsequently to **verify an OTP** submitted by a user.

To learn how to build an API request to send an OTP, see [Sending an SMS verification code](/otp-mobile-verification.md#sending-an-sms-verification-code).  To learn how to verify an OTP, see [Verifying a user code](/otp-mobile-verification.md#verifying-a-user-code).

![](/files/-MOU-jBZzvBtuaYn9OF7)

## Get an API key

&#x20;OTP keys are the same as normal Textbelt keys. This means you can mix and match your quota to send OTPs and normal text messages. [Create an API key](https://textbelt.com/create-key/) to start sending and receiving SMS.
