# Getting started

Textbelt is an SMS API that is built for developers who just want to send and receive SMS.  Sending an SMS is a simple thing.  Our goal is to provide an API that is correspondingly simple, without requiring account configuration, logins, or extra recurring billing.

## Send an SMS using HTTP POST

The **`https://textbelt.com/text`** endpoint accepts a POST request with the following parameters:

* **phone:** A phone number.  If you're in the U.S. or Canada, 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](/faq#how-should-i-format-my-phone-numbers) with your country code.&#x20;
* **message:** The content of your SMS.
* **key:** Your API key (use `textbelt` to send a free message).
* **sender:** Optionally, the name of the business/organization you represent.  This field is for regulatory purposes and *is not visible to the end user* in most countries.\
  \
  If not set, sender will default to your account-wide sender name.  See [Compliance](/compliance#sender-identification) for more detail.

Every programming language has a way to send an HTTP POST request.  Instead of installing a special Textbelt library, just send a POST request using your preferred method.  Below are some examples in common languages.

### Examples

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

```bash
curl -X POST https://textbelt.com/text \
     --data-urlencode phone='5555555555' \
     --data-urlencode message='Hello world' \
     -d key=textbelt
```

{% 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/text', {
  'phone': '5555555555',
  'message': 'Hello world',
  'key': 'textbelt',
})
print(resp.json())
```

{% endtab %}

{% tab title="Ruby" %}

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

uri = URI.parse("https://textbelt.com/text")
Net::HTTP.post_form(uri, {
  :phone => '5555555555',
  :message => 'Hello world',
  :key => 'textbelt',
})
```

{% endtab %}

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

```javascript
// Using request
const request = require('request');
request.post('https://textbelt.com/text', {
  form: {
    phone: '5555555555',
    message: 'Hello world',
    key: 'textbelt',
  },
}, (err, httpResponse, body) => {
  console.log(JSON.parse(body));
});

// Using axios
const axios = require('axios');
axios.post('https://textbelt.com/text', {
  phone: '5555555555',
  message: 'Hello world',
  key: 'textbelt',
}).then(response => {
  console.log(response.data);
})
```

{% 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',
    message: 'Hello world',
    key: 'textbelt',
  }),
}).then(response => {
  return response.json();
}).then(data => {
  console.log(data);
});
```

{% endtab %}

{% tab title="PHP" %}

```php
$ch = curl_init('https://textbelt.com/text');
$data = array(
  'phone' => '5555555555',
  'message' => 'Hello world',
  'key' => 'textbelt',
);

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" },
    { "message", "Hello world" },
    { "key", "textbelt" },
  });

  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("message", "Hello world"),
    new BasicNameValuePair("key", "textbelt")
};
HttpClient httpClient = HttpClients.createMinimal();
HttpPost httpPost = new HttpPost("https://textbelt.com/text");
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"},
    "message": {"Hello world"},
    "key": {"textbelt"},
  }

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

{% endtab %}

{% tab title="PSH" %}

```bash
$body = @{
  "phone"="5555555555"
  "message"="Hello World"
  "key"="textbelt"
}
$submit = Invoke-WebRequest -Uri https://textbelt.com/text -Body $body -Method Post
```

{% endtab %}
{% endtabs %}

**Note:** Regulations require that you state the name of your business/organization in SMS messages. If you are sending recurring SMS, opt-out language is required (e.g. *"Reply STOP to opt-out"*. We automatically handle STOP replies).

### Response

The `/text` endpoint will respond with JSON:

* **success:** Whether the message was successfully sent (true/false).
* **quotaRemaining:** The amount of credit remaining on your key.
* **textId:** The ID of the sent message, used for looking up its status.  Only present when success=true.  Use this to [check SMS delivery status](/other-api-endpoints#checking-sms-delivery-status).
* **error:** A string describing the problem.  Only present when success=false.

An example of a message successfully sent:

```javascript
{"success": true, "quotaRemaining": 40, "textId": 12345}
```

Here's an example of when you've run out of quota:

```javascript
{"success": false, "quotaRemaining": 0, "error": "Out of quota"}
```

Or when you're missing a required variable such as **phone**, **message**, or **key**:

```javascript
{"success": false, "error": "Incomplete request"}
```

If you're getting the above message even though you're specifying the variable, you should make sure that you're sending the request correctly as an HTTP POST request.

### Testing this API

If you want to validate your key without actually using your text quota, **append "`_test`" to your key** and you will receive a response from the `/text` endpoint confirming that a text would send.  However, **credit will not be deducted from your account.**

## Receiving SMS replies

**U.S. phone numbers only:** Textbelt lets you receive replies to SMS you've sent. Replies are sent by webhook, meaning you will have to set up an HTTP or HTTPS route on your website that will process inbound SMS.

&#x20;Add a `replyWebhookUrl` parameter to your send message request.  This is the same as the examples above, except it includes **replyWebhookUrl**.  For example:

```bash
curl -X POST https://textbelt.com/text \
     --data-urlencode phone='5555555555' \
     --data-urlencode message='Hello?' \
     -d replyWebhookUrl='https://my.site/api/handleSmsReply' \
     -d key=textbelt
```

This will send an SMS.  If the recipient responds, Textbelt will send an HTTP POST request to the specified endpoint (in this case, `https://my.site/api/handleSmsReply`).

The webhook payload is `application/json` encoded.  Your server must interpret it like any other HTTP POST request with a JSON payload.  The JSON payload contains the following:

* **textId:** The ID of the original text that began the conversation.
* **fromNumber:**  The phone number of the user that sent the reply (you can use this, for example, to send them a response depending on their reply).
* **text:** The content of their reply

Here's an example payload:

```javascript
{
  "textId": "123456",
  "fromNumber": "+1555123456",
  "text": "Here is my reply"
}
```

{% hint style="info" %}
Note: SMS replies cannot be received on the free `textbelt` key.
{% endhint %}

#### Verifying the webhook

It is best practice to verify the incoming POST request to make sure it is not forged.  The POST request contains a header `X-textbelt-signature`, which is an HMAC that authenticates the JSON payload using a SHA-256 hash function.

The header `X-textbelt-timestamp` contains a UNIX timestamp (in seconds).  You should ensure that this timestamp is not more than 15 minutes out of date.

To verify that the request is valid, take the timestamp + raw JSON payload and sign it with your API key.  The result should be equal to the signature. &#x20;

For example, in Javascript:

```javascript
const crypto = require("crypto");

function verify(apiKey, timestamp, requestSignature, requestPayload) {
  const mySignature = crypto
    .createHmac("sha256", apiKey)
    .update(timestamp + requestPayload)
    .digest("hex");
    
  return crypto.timingSafeEqual(
    Buffer.from(requestSignature),
    Buffer.from(mySignature)
  );
}
```

And in Python:

```python
import hmac
import hashlib

def verify(api_key, timestamp, request_signature, request_payload):
    my_signature = hmac.new(api_key.encode('utf-8'), (timestamp + request_payload).encode('utf-8'), hashlib.sha256).hexdigest()
    return hmac.compare_digest(request_signature, my_signature)
```

#### Including custom data

The `/text` endpoint supports a `webhookData` field.  This data is passed as `data` in the webhook request.

For example:

```bash
curl -X POST https://textbelt.com/text \
     --data-urlencode phone='5555555555' \
     --data-urlencode message='Hello?' \
     -d replyWebhookUrl='https://my.site/api/handleSmsReply' \
     -d webhookData='my custom data'
     -d key=textbelt
```

Produces a response:

```javascript
{
  "textId": "123456",
  "fromNumber": "+1555123456",
  "text": "Here is my reply"
  "data": "my custom data"
}
```

There is a maximum length of 100 characters in the `webhookData` field.

## Get an API key

[Create an API key](https://textbelt.com/create-key/) to start sending and receiving SMS!


# OTP/Mobile verification

In addition to [sending SMS](/#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#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#sending-an-sms-verification-code).  To learn how to verify an OTP, see [Verifying a user code](/otp-mobile-verification#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.


# Other API endpoints

Here are some other potentially useful endpoints you can use.

## Checking SMS delivery status

If you are given a **textId** and want to check its delivery status, send an HTTP GET request to `https://textbelt.com/status/:textId`.

For example, if you textId is `12345`, go to <https://textbelt.com/status/12345> in your browser or load it programmatically:

```bash
curl https://textbelt.com/status/12345
```

The response is a JSON object that contains a single **status** field.  For example:

```bash
{"status": "DELIVERED"}
```

Possible return values include:

* `DELIVERED` - Carrier has confirmed sending
* `SENT` - Sent to carrier but confirmation receipt not available
* `SENDING` - Queued or dispatched to carrier
* `FAILED` - Not received
* `UNKNOWN` - Could not determine status

Delivery statuses can be retrieved up to 1 week after the message was sent.

**Delivery statuses are not standardized between mobile carriers.**  Some carriers will report SMS as "delivered" when they attempt transmission to the handset while other carriers actually report delivery receipts from the handsets.  Some carriers do not have a way of tracking delivery, so all their messages will be marked "SENT".

## Checking your credit balance

You may want to know how much quota or credit you have left on a key.  You check this by sending an HTTP GET request to `https://textbelt.com/quota/:key`.

For example, if you key is `abc123`, just load <https://textbelt.com/quota/abc123> in your browser or programmatically:

```bash
curl https://textbelt.com/quota/abc123
```

The response contains a JSON object with two attributes:

* **success:** Whether or not we were able to look up this key
* **quotaRemaining:** The amount of SMS credit remaining on this key

For example:

```bash
{"success": true, "quotaRemaining": 98}
```


# Compliance

Textbelt is implementing changes in response to regulatory and compliance requirements.  These changes are effective January 3rd, 2023.

### Sender identification

A "sender name" is the name of the business, organization, or person you're representing when you send an SMS.  *Every SMS conversation must include the sender name*.

{% hint style="warning" %}
If an SMS message does not contain your sender name the first time you message someone, the sender name will be automatically appended to your message.
{% endhint %}

There are two ways to set the sender name:

* **Account-wide:** Set a default sender name by going to `https://textbelt.com/account?key=<your key>`
* **Per-message:** Set the `sender` parameter in your POST request.

Sender name is *not* appended if it appears elsewhere in your message, or if you are sending follow-up messages.

{% hint style="warning" %}
Sender name value is used strictly for compliance purposes.  It does *not* override the "From" number for the SMS sender.
{% endhint %}

### Opt-out

An "opt-out" is a way for the customer to block future SMS.  Textbelt handles opt-outs automatically, but regulations require senders to include opt-out information in their SMS.

The standard form of opt-out is "Reply STOP to unsubscribe".  This opt-out is appended automatically the first time you message a new user.  It is *not* appended if "STOP" appears elsewhere in your message.

#### Opt-in

To opt back in, the recipient must send "START" in reply.  There is no way to force the recipient to opt back in.  Only the original recipient can opt-in.


# FAQ

## Sections:

* [Sending and receiving messages](/faq/sending-and-receiving-messages)
* [Textbelt platform and policies](/faq/textbelt-platform-and-policies)
* [Subscription and payments](/faq/subscription-and-payments)
* [Troubleshooting](/faq/troubleshooting)

###

##


# Sending & receiving messages

### How should I format my phone numbers?

It's best to use E.164 format whenever possible.  An E.164 number has three parts:

* The prefix "+"
* A 1-3 digit country code
* A subscriber number

For example, the numbers +5511912345678, +447712345678 and +15558838530 can be broken down as follows:

| Prefix | Country code  | Subscriber number |
| ------ | ------------- | ----------------- |
| +      | 55 (Brazil)   | 11 91234 5678     |
| +      | 44 (UK)       | 7712 345678       |
| +      | 1 (US/Canada) | 555 883 8530      |

If you're texting in the U.S. or Canada, you can just send a 10 digit phone number with area code instead of E.164 format.  We also parse phone numbers from string inputs like `(555) 883-8530`.

### I'm using E.164 format but it's rejecting my number. What's wrong?

One common pitfall is that if you're sending a "+" sign in POST data, it must be URL encoded. Otherwise, the plus sign will be stripped or converted to a space when it's sent to the server.&#x20;

The process for encoding a URL will vary based on language and library support. Most HTTP libraries will handle encoding for you. If you need help, please contact us.

### Which carriers/countries are supported?

We support SMS destinations for 221 countries around the world.  Our services are most commonly used in the U.S., Canada, European countries (UK, France, Germany, Spain, etc), South Korea, Taiwan, Brazil, India, and Mexico.

You can always try sending a text to your foreign number using the free `textbelt` key to determine if it's already supported. Or, email us and let us know what country you're in - we'd be happy to help.

### How do I send a text internationally?

By default, texts are sent in the U.S. (country code +1). To text internationally, append the country code to your phone number.

Use the E.164 format. For example, to text someone in France (country code +33), set the number param to +33509758351.

### How do I send texts from a specific phone number?

Textbelt SMS are sent from a very large shared pool of phone numbers. Whenever possible, our service makes sure that you are represented to your recipients as a single unique phone number.

This allows us to keep the API and service very straightforward. If you are doing a large volume of SMS, you can request a dedicated phone number or pool of phone numbers at no additional charge.

### Is there a way to send multiple texts at the same time?

No. You should send multiple HTTP requests in order to send multiple texts.

### Is there any rate limiting?

You shouldn't send more than 1-2 SMS per second. There isn't strict rate limiting and the API won't cut you off, but you're advised to not exceed this limit as it could impact delivery on the mobile carrier side.

### How are long texts handled?

Texts up to a certain length (as of writing, 256 bytes) are automatically broken into segmented texts. Text segment length can vary based on carrier but is usually 120. If a long text is broken up into segments, it is delivered to the recipient as multiple texts. You will be charged for the number of individual SMS messages sent to the carrier.

### Why was my text counted as multiple texts?

Textbelt quota corresponds to the number of SMS segments that you send. If you send a long message, it will be broken into multiple SMS.

The maximum size of a text is 140 bytes. The most efficient encoding for SMS is GSM-7, which is a limited character set that uses 7 bits for each character.  This means you can send 140\*8/7 = *160 characters*.  If you use non-GSM characters (eg. unicode) your message may be limited to *70 characters*, because unicode characters are 2 bytes each.

If you're using more SMS quota than you expected and you don't think your message is unicode encoded, closely inspect your message for sneaky unicode characters such as unicode whitespace, apostrophes, and quotation marks.

Use [this page](https://chadselph.github.io/smssplit/) to test your messages to see how many SMS segments they will use.

### If I send a message and status is not "delivered" or "sending", does it count against my quota?

Yes, we can't retroactively refund texts that aren't successfully delivered. There are many explanations for a text not being delivered, but the most common explanation is that it's a bad number. Please make sure you know who you're texting!

If you are consistently having trouble sending texts to a number you know is valid, please reach out and we'll investigate and refund if necessary.

### Why do my SMS include "STOP" instructions?

Regulations require us to include opt-out language on initial contact with new recipients.  If you wish to customize opt-out language, including the word "stop" will suppress automatic opt-out instructions.


# Textbelt platform & policies

### Can I use Textbelt for emergency purposes?

No, you may not offer emergency services through Textbelt, or any service that impacts life safety. Textbelt is not reliable enough for these purposes and cannot accept this liability.

### How does this differ from Textbelt Open Source?

Textbelt Open Source is a free project that uses email-to-SMS gateways. This allows people to text for free with medium reliability and more carrier restrictions.

Textbelt.com is a service that costs money because we pay carriers around the world to accept and deliver SMS. It does not use potentially unreliable email-to-SMS gateways.

Originally, Textbelt was just the open source project. Carriers began blocking the publicly hosted open source version because it was too popular. We recognized the need for a more reliable service and began working with carriers to ensure text delivery. This eventually led to the paid Textbelt.com service.

### How long does my quota last?

If you purchased quota before April 14, 2017, it lasts forever. If you purchase quota after that date, it will expire if 365 days go by without any usage on your key. If you send just one text every year, your quota will never expire.

We added this policy because everlasting, seemingly abandoned quotas are an outstanding liability.  Other services don't face this problem because they keep a cash balance, but we like the simplicity of having one text = one quota. We avoid this uncertainty by capping quotas to a year of inactivity, which shouldn't be a problem for active users of the service.

### What kinds of texts are not allowed?

The recipients of your texts should have opted in to receiving your messages. Textbelt is not for bulk advertising or spam.

Any messages that break the law in the United States (eg. scams and fraud) or any sort of harassment are prohibited.

Due to abuse, sending text messages containing URLs requires whitelist permissions.  These requests are processed extremely quickly.  Send an email to support to get URL sending enabled on your account, or go to <https://textbelt.com/whitelist?key=yourkey>.

### Can you give me more information on privacy/record retention?

Under no circumstances are your phone numbers shared or sold.  Phone numbers and SMS contents of new accounts may appear in our logs which are temporarily stored in order to identify spam/abuse, debug potential SMS delivery issues, and allow you to look up delivery status. Access to these records is permitted on an as-needed basis. All access is monitored and logged. After 60 days, records are wiped permanently. &#x20;

You may also be interested in our [Privacy Policy](https://textbelt.com/privacy/).  If you need a custom data retention policy for your account, please email us to discuss.


# Subscription & payments

### How does the money-back guarantee work?

If you decide that the Textbelt service is not satisfactory within 30 days of your original purchase, we'll give you a refund (prorated by the texts that you've sent). Email us and let us know the email address you signed up with, key, date of purchase, purchase amount, and why you'd like a refund.

### Is there a subscription or automatic refill option?

Yes. It requires purchase by credit card, not Paypal. Get in touch at <support@textbelt.com> to request auto-refill enabled.


# Troubleshooting

### I'm getting an error: "sslv3 alert handshake failure"

We don't support SSLv3 due to a security vulnerability: [disablessl3.com](https://disablessl3.com/).

You can force SSLv2 by using the --sslv2 flag with curl on most systems.

You can also just POST to **http**://textbelt.com/text, as opposed to https\://. This will solve the problem, but traffic will not be encrypted (you might be ok with this for hobby projects because [SMS is not secure](http://www.cybersecuritytrend.com/topics/cyber-security/articles/424266-nist-has-it-right-sms-not-secure.htm) to begin with).

### Can I use Textbelt via Tor?

No, because of too much spam/abuse coming through Tor.

### Can I use Textbelt with Postman?

Yes. Here's a screenshot of a Postman configuration that works: <img src="https://i.imgur.com/CVmzH25.png" alt="" data-size="original">

### Why isn't my VOIP number receiving SMS?

Unfortunately, Textbelt does not support sending SMS to VOIP numbers.

## See also

The [Sending & receiving messages](/faq/sending-and-receiving-messages) section has more information on common questions, including questions like "Why did my SMS take 2 credits" and how to customize opt-out language.

## Still having problems?

Contact us directly at <support@textbelt.com>.


# Supported countries

Below is a list of countries supported by our network and the networks of our partners.

Note that SMS sending requirements may vary by country according to local regulations. Some countries require pre-registration and approval of SMS use cases, which we can facilitate.

### Country list

```
Afghanistan
Albania
Algeria
American Samoa
Andorra
Angola
Anguilla
Antigua and Barbuda
Argentina
Armenia
Aruba
Australia
Austria
Azerbaijan
Bahamas
Bahrain
Bangladesh
Barbados
Belarus
Belgium
Benin
Bermuda
Bhutan
Bolivia
Bosnia and Herzegovina
Botswana
Brazil
Brunei
Bulgaria
Burkina Faso
Burundi
Cambodia
Cameroon
Canada
Cape Verde
Cayman Islands
Central Africa
Chad
Chile
China
Colombia
Comoros
Congo
Cook Islands
Costa Rica
Croatia
Cuba
Cyprus
Czech Republic
DR Congo
Denmark
Djibouti
Dominica
Dominican Republic
East Timor
Ecuador
Egypt
El Salvador
Equatorial Guinea
Eritrea
Estonia
Ethiopia
Falkland Islands
Faroe Islands
Fiji
Finland
France
French Guiana
French Polynesia
Gabon
Gambia
Georgia
Germany
Ghana
Gibraltar
Greece
Greenland
Grenada
Guadeloupe
Guam
Guatemala
Guernsey
Guinea
Guinea-Bissau
Guyana
Haiti
Honduras
Hong Kong
Hungary
Iceland
India
Indonesia
Iraq
Ireland
Israel
Italy
Ivory Coast
Jamaica
Japan
Jersey
Jordan
Kazakhstan
Kenya
Kiribati
Korea Republic of
Kosovo
Kuwait
Kyrgyzstan
Laos PDR
Latvia
Lebanon
Lesotho
Liberia
Libya
Liechtenstein
Lithuania
Luxembourg
Macau
Macedonia
Madagascar
Malawi
Malaysia
Maldives
Mali
Malta
Marshall Islands
Martinique
Mauritania
Mauritius
Mexico
Micronesia
Moldova
Monaco
Mongolia
Montenegro
Montserrat
Morocco
Mozambique
Myanmar
Namibia
Nepal
Netherlands
Netherlands Antilles
New Caledonia
New Zealand
Nicaragua
Niger
Nigeria
Niue
Norfolk Island
Northern Mariana Islands
Norway
Oman
Pakistan
Palau
Palestinian Territory
Panama
Papua New Guinea
Paraguay
Peru
Philippines
Poland
Portugal
Puerto Rico
Qatar
Reunion/Mayotte
Romania
Russia
Rwanda
Samoa
San Marino
Sao Tome and Principe
Senegal
Serbia
Seychelles
Sierra Leone
Singapore
Slovakia
Slovenia
Solomon Islands
Somalia
South Africa
South Sudan
Spain
Sri Lanka
St Kitts and Nevis
St Lucia
St Pierre and Miquelon
St Vincent Grenadines
Sudan
Suriname
Swaziland
Sweden
Switzerland
Syria
Taiwan
Tajikistan
Tanzania
Thailand
Togo
Tonga
Trinidad and Tobago
Tunisia
Turkey
Turkmenistan
Turks and Caicos Islands
Tuvalu
Uganda
Ukraine
United Kingdom
United States
Uruguay
Uzbekistan
Vanuatu
Venezuela
Vietnam
Virgin Islands, British
Virgin Islands, U.S.
Wallis and Futuna
Yemen
Zambia
Zimbabwe
```


# Sending SMS from the command line

There are two broad approaches to sending text messages via the command line: email-SMS gateways and SMS gateway APIs.

### Email <a href="#email" id="email"></a>

Most phone networks provide email-to-SMS gateways.  For example, Verizon will route emails to `<phone number>@vtext.com` as text messages to that phone number.  Not all carriers support this, but most do.

Here are the benefits of the SMS via email approach:

* Easy to use
* Can use common email tools, libraries, and clients

Here are the downsides:

* You must know the carrier associated with the phone number (this is becoming harder as it's much easier to transfer numbers between carriers these days).
* Some carriers append cruft to the message ("Sent via Email at xyz.com" or similar).
* Emails are not handled in a standard way (e.g. some carriers will include the subject, some won't).
* Carriers restrict email to personal messages and very low volume (if you send many emails over time, expect them to start bouncing).
* Your email address is exposed to recipients.

In my opinion, the easiest and most beginner-friendly way to send mail from the command line is `mutt`.  [Mutt](https://web.archive.org/web/20200807183335/http://www.mutt.org/) offers a command-line GUI to help with message sending, but you can also construct command-line one-liners to include in scripts.   In its simplest form, you can do the following:

```
echo "my message" | mutt -s "my subject" abc@gmail.com
```

If you're a purist or you don't want the fanciness of mutt, you might use `ssmtp` to send mail via SMTP mail hub, or if you want to just send raw mail, use `sendmail`.

In all cases, you will probably have to configure your mailer so that it won't be rejected by spam filters.  Doing so is beyond the scope of this article.

[Textbelt Open Source](https://web.archive.org/web/20200807183335/https://github.com/typpo/textbelt) is a free MIT-licensed library that abstracts many of these issues with using email-to-SMS gateways.  However, it still requires your own email setup (it used to be available as a free online service, but it was abused by spammers and taken offline after about 5 years of operation).

Rolling your own email setup can be tricky.  Usually it's best to use something like Mailgun, Sendgrid, etc.  Textbelt uses [Nodemailer](https://web.archive.org/web/20200807183335/https://nodemailer.com/about/) which supports standard SMTP as well as email APIs.

### SMS services <a href="#sms-services" id="sms-services"></a>

The next best way to send SMS from the command line is through text message APIs.  Textbelt offers a paid SMS API in addition to the free open-source offering.  There are many paid offerings in this space and I encourage you to shop around.

However, Textbelt's is probably the simplest API to work with.  It was built with command-line use cases in mind.  A `curl` request to Textbelt is simple:

```
curl -X POST https://textbelt.com/text \
       --data-urlencode phone='5557727420' \
       --data-urlencode message='Hello world' \
       -d key=textbelt
```

It's often useful to save this as an alias.  On most Unix-based systems this can be done in your `~/.bashrc` file:

```
text() {
  curl https://textbelt.com/text --data-urlencode number="$1" --data-urlencode "message=$2" -d key=textbelt
} 
```

For example, you can chain a long-running job to notify you via SMS when it completes (I used to do this when I worked at Google and building [Google Web Server](https://web.archive.org/web/20200807183335/https://en.wikipedia.org/wiki/Google_Web_Server) took forever):

```
./my_long_running_command.sh && text 5551234567
```

## Deciding your approach <a href="#deciding-your-approach" id="deciding-your-approach"></a>

If you're just texting yourself from the command line, it's cheap (free) and relatively easy to use the email-to-SMS gateway of your mobile carrier.  You can send this email either manually or via the [open source project](https://web.archive.org/web/20200807183335/https://github.com/typpo/textbelt).

If you want to skip the headache of maintaining a local email setup, you may use [Textbelt's hosted service](https://web.archive.org/web/20200807183335/https://textbelt.com/) or some other SMS provider.  Textbelt lets you send one SMS per day for free, and you can buy quota if you think you'll be sending more.

Any questions?  Email [support@textbelt.com](https://web.archive.org/web/20200807183335/mailto:support@textbelt.com) about this blog post and I'll get your message.  Happy coding!


# How to set up Synology NAS SMS notifications

This page explains how to set up Synology NAS DSM 7.x SMS notifications using Textbelt.

1. Create a Textbelt API key. Copy the key and save it.
2. Open DSM and go to Control Panel
3. Select the SMS tab
4. Click "Enable SMS Notifications"
5. Click "Add SMS Service Provider" and supply any name
6. Add the following SMS URL, replacing `ABC123` with your API key and supplying your phone number: [`https://textbelt.com/text?key=ABC123&phone=5555555555&message=Hello+world`](https://textbelt.com/text?key=ABC123\&phone=5555555555\&message=Hello+world)
7. Select `GET` as the HTTP method and click Next

   !\[Graphical user interface, text, application

   Description automatically generated]\(<https://lh4.googleusercontent.com/dwFlogG41HKqtoCeZDnOtSx0c5Wqir_N6rPmbz-6a5LClwNYcJdOLMLhjjvhTfT5ogWR0IgFsz0onJ1lFAce11OWxN9jMT2w9pFQB60Daa-sjpenoRqtT_JqpSpnRp0rJkvwqv-WeG4feJ_tMg>)
8. Click Next on the HTTP request header page (nothing to edit here)

   !\[Graphical user interface, text, application

   Description automatically generated]\(<https://lh6.googleusercontent.com/vrvdA3lWDdnxaOfN-bpPun1OCpUg29apdLIdfBCH4Mn4_SarZ1FrIsmbFp4UvOO3ruwak5M-6pzdoMSeQgd5kYwrbj_T99gSwKt2Gttq55C-kGzqvV8tsJvT8Ard9JA2AZ_Ta5YT1ycI-MmUXQ>)
9. You will see on the left; key, phone, message. On the right use the drop down and select the correct category for each.  Then click Done.

   !\[Graphical user interface, text, application

   Description automatically generated]\(<https://lh6.googleusercontent.com/tJRSt2Sx1G0FNlUF_0KjBgoGft78THZJapE11LscS5cLHorQugpuer1u1uNgSovExoqySgZZYLiH90dTqb-blk-i2Wsgf8wAQ4upnUOnYccM17CmSYzgWV-Ag--zvDOvWptQKa_zVSgojrKZpQ>)
10. Enter your API key and the phone number that will receive the text.

    !\[Graphical user interface, text

    Description automatically generated]\(<https://lh3.googleusercontent.com/bUauJYPlKVz0h0_5T5o0vR2qW-CtAZeKojyrSRm2JY7dPnsRAJNvwamgDwEQi-C--9iKm_ivsINKxuAxEe5ysk_MTT5RWX_MkH4oBwlfp9_YE7r8il_iKdPpVPIuddwUTY8i9plAXqTN3pdnxA>)
11. Click "Send a Test SMS Message".  That's it!


