# Android setup

TextLink is a platform that allows you to freely use your phone number to send SMS via our API, tools and No-code integrations, without having to rely on a centralized provider like Twilio, which requires a complex setup process for actually being able to send messages (e.g. A2P), and reserves the right to close your account at any time (even if that disrupts your business activities).&#x20;

In order to use our tools , you need a spare Android phone with the stable internet connection and power supply, which you are going to set up to send SMS for you.

{% embed url="<https://www.youtube.com/watch?v=koabZVvF8R0>" %}

## How it works?

For the setup to work, you first need to install our android app on your phone, and enable us to send SMS through it. Now, our server can send data to your application, about the messages that need to be sent, using Google's notification services.&#x20;

## Prerequisites

The setup usually takes around 10 minutes. Here is the list of required items for the setup to be effective:

* **Android** phone - Our app does not support IOS devices. It is recommended to use spare device, since the service stability depends on it.&#x20;
* **SIM card** or an **eSIM** - We recommend you to buy SMS packages, since they can be much cheaper. We do not support virtual SIM cards.&#x20;
* Stable **internet** connection

## Instructions

1. [Create a TextLink account](https://textlinksms.com/signup)
2. [Download the app](https://textlinksms.com/download-app) on your android phone, install it, and enable all the permissions that it asks for. It is necessary for all of the app's components to work as expected.
3. For android >13, you may also need to [enable access to restricted settings](https://youtu.be/koabZVvF8R0?si=7P6-h3-UjHN7d4Gz\&t=44) before enabling TextLink the required permissions.
4. In the downloaded app, log in to the same account that you created in the step 1
5. You should now be able to send SMS to your SIM card's country. You can test the integration [here](https://textlinksms.com/dashboard/test).&#x20;
6. To make sure your Android OS does not restrict app's base functionality, you need to disable battery optimizations for the TextLink app. You can see the example [here](https://www.youtube.com/watch?v=QEkSJgurosE). Note that this step can be different depending on your device.
7. If you also need to receive SMS besides just sending them (e.g. for triggering custom workflows on received message), you need to [make TextLink your default SMS app](https://youtu.be/koabZVvF8R0?si=VOvi2KW9PfTTVwtQ\&t=190). This process also differs based on your device. You can find the example here. To learn more about custom workflows, head over to the [API](/api) or [GHL](/gohighlevel) page.
8. (Optional) If you require sending messages to another country, go to your [Devices overview](https://textlinksms.com/dashboard/your-devices/overview), click the *Configure* button next to your device, and select the SIM card that you want to configure. A new page will open, where you can add/remove as many countries as you want for that SIM card.

## Best practices

To get the most of your setup, you should keep your phone on charger, always connected to the internet with the app open and the screen on at all times.&#x20;

## Troubleshooting

* If you can send SMS, but can not receive SMS, you need to make sure that TextLink is your default SMS app (Step 7)
* If sending SMS does not work on your phone, and your phone is newer (Android 13+), make sure to follow the setup in step 3 thoroughly


# TextLink dashboard

Once you have [created an account](https://textlinksms.com/signup), you can access the TextLink dashboard on this [link](https://textlinksms.com/dashboard), or from the main page. Note that some options can be hidden from if you have logged in through a subaccount.

<figure><img src="https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2FYiTBhCYyffauBJmnA2YM%2Fimage.png?alt=media&amp;token=9ad881e1-8349-48ba-b0ef-37f80dbef085" alt=""><figcaption></figcaption></figure>

You can find the navigation menu on the left side. As you can see, we have a few pages there, but don't worry, it's not complicated, you probably won't be needing every one of these, and everything is going to be explained down below.&#x20;

## Test Services

![](https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2FHog4S8433R05hHz0JMAl%2FTest_Services.png?alt=media\&token=f17f9e7a-c850-4c3f-8b3a-1f58c9b1274a)

Test if sending SMS from your SIM cards works.

<figure><img src="https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2F5rjApDRpVhma7U4ib0Bm%2Fimage.png?alt=media&amp;token=5e7bde30-c0b8-4609-a37c-521f4cadd251" alt=""><figcaption></figcaption></figure>

## Chat App

![](https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2FtLKQHgdF6BUCNAh8azyO%2FChat_App.png?alt=media\&token=e4559fb4-8d96-4d7b-9a49-29df835a6895)

Access all the messages you have sent, create contacts and chat with them.

<figure><img src="https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2FCjYKHs597dA5CrTOw3We%2Fimage.png?alt=media&amp;token=fdaf243d-d584-4b88-900e-5734fbd4b5ec" alt=""><figcaption></figcaption></figure>

## No-Code SMS outreach

![](https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2Feh9Me4KpAGXIJljhQ7gO%2Fimage.png?alt=media\&token=fd2189b5-6106-497d-93b5-1793a8ba2ba3)

Run Bulk SMS campaigns on your list of qualified leads. Note that spam and random online lists can result in your SIM card getting banned by carrier.

<figure><img src="https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2Ft5bYqUEnlLuoJsYoqRDG%2Fimage.png?alt=media&amp;token=26be414b-050e-4c40-947b-51e9613ad3f2" alt=""><figcaption></figcaption></figure>

## Api & Hooks

![](https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2FwJs79GHCUC6T4d701b4f%2FAPI_and_Hooks.png?alt=media\&token=151279e7-9e66-470d-97af-60d04f797556)

Manage your API key and webhooks for receiving SMS, tracking SMS status and tracking contacts' tags.

<figure><img src="https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2Fo8o5dutxgQEeE5bVoD9I%2Fimage.png?alt=media&amp;token=d00927e7-0b21-4b5f-a851-341c728cd588" alt=""><figcaption></figcaption></figure>

## GoHighLevel

![](https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2FOi9Khmt1l2DxOacsnP0F%2FGoHighLevel.png?alt=media\&token=1d9b6ce1-8959-4103-a377-2ef64da316d2)

An interactive step-by-step guide on connecting your Account to use it with GHL for conversation provider features.

<figure><img src="https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2FtALBwoXxO2ro13VU2VLv%2Fimage.png?alt=media&amp;token=6621dc14-3acf-4206-ac46-040cfb148283" alt=""><figcaption></figcaption></figure>

## Devices and Setup

![](https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2FSQeiNfHZBknduNv3MQYk%2Fimage.png?alt=media\&token=defe4b74-dd7a-425a-afe8-bf35a49b0200)

You can learn how to set up your Android device to work with TextLink on the **Tutorial** page, and on the **Dashboard** page, you can manage your devices, delete the unused ones, and configure which destinations can your SIM cards send messages to.

<figure><img src="https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2Fm1IVFeldGmVvaRejhRGV%2Fimage.png?alt=media&amp;token=0dc7a982-6e58-4bf9-8616-299c79242ac1" alt=""><figcaption></figcaption></figure>

## Team

![](https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2FHtK7TlfImebXK1KM9hfL%2FTeam.png?alt=media\&token=746e0f4d-1fe3-44f5-81c8-a0ba6bde91b0)

Manage and create new subaccounts. You can learn more about this on the [Team documentation page](/team).&#x20;

<figure><img src="https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2F87g2InKLM9YtY4QRxT5c%2Fimage.png?alt=media&amp;token=b26d40c0-6446-4183-a4dd-d5fc8b9620c7" alt=""><figcaption></figcaption></figure>

## Account

![](https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2FWXjBvC2yQBkvcPfnXYzA%2FAccount.png?alt=media\&token=0d14d120-bf82-4da4-a797-67180a2a72f5)

Account settings, change or reset password, contact support, delete account

<figure><img src="https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2F706xIObT8NlFvD5vntix%2Fimage.png?alt=media&amp;token=ec5a1ebd-39fc-4afb-be65-5ea942f58151" alt=""><figcaption></figcaption></figure>

## Plans & Billing

![](https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2FlKsG0NHkWzUSBQPuMGrq%2FPlans_and_Billing.png?alt=media\&token=b52ac14d-fbb0-4fee-bfcd-1c6722f0120a)

Manage and upgrade your current billing plan. You have 300 free SMS to test out TextLink, but are limited to 1 SIM card for testing purposes. If you want to have more SIM cards, or when you reach your limit, you will need to upgrade your plan to continue using TextLink.

<figure><img src="https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2FrxrCEOjCohco1OGT0JN6%2Fimage.png?alt=media&amp;token=2fe8b79c-cb65-4d85-9fc2-9373ce3017d4" alt=""><figcaption></figcaption></figure>

## Affiliate

![](https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2FC0nfTXgdTmrEPD4qUYY4%2FAffiliate.png?alt=media\&token=084500a7-c10f-4d52-912e-19dc6dcb9d0b)

Create your invite code, and invite someone to use TextLink. You will earn 40% of subscriptions for everyone that uses your invite code.&#x20;

<figure><img src="https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2FsRoqDulQg8PvW5qDVqyF%2Fimage.png?alt=media&amp;token=e33f0cbe-e0b3-4be3-af09-b98c8ba52dc8" alt=""><figcaption></figcaption></figure>

## Balance and Analytics

![](https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2FxXW5j2lhlPT5yF1AN0Eo%2FBalance_and_Analytics.png?alt=media\&token=c79cdea9-4c89-40b2-94de-c6d33fc336ad)

You can see your monthly usage analytics, as well as your current plan usage.&#x20;

<figure><img src="https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2FGTnrcAmsKrRSMvz60yEA%2Fimage.png?alt=media&amp;token=c41f0353-dd14-4ecc-b12f-ccdc79c3bc55" alt=""><figcaption></figcaption></figure>

## Help & Resources

![](https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2FpjIA761ltc03UGBsQfXT%2FHelp_and_Resources.png?alt=media\&token=bd97b8b6-d534-4fb3-b054-d65744102fae)

Access the list of the most commonly asked questions, and if you can't find what you are looking for, you can contact us using the button at the bottom of the page.

<figure><img src="https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2Fk8SO6l3cFrWF9eLw4kAs%2Fimage.png?alt=media&amp;token=6587557b-1358-4263-8c48-cd500899c482" alt=""><figcaption></figcaption></figure>

## Tutorials

![](https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2FDGE6HQGqbwCor9itXnuN%2FTutorials_Resources.png?alt=media\&token=c09f0049-fca4-46b9-b7b8-1208ed762f48)

You can find some of the most popular of our tutorials here, and the rest on our [YouTube channel](https://www.youtube.com/@TextLink).

<figure><img src="https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2FJY7hXLFvssDeq8g4Pk5q%2Fimage.png?alt=media&amp;token=b2392591-ed94-4d47-b722-1193df48390d" alt=""><figcaption></figcaption></figure>

## Suggest a Feature

![](https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2FAdzsQCB2mGcMzLj1sBK8%2FSuggest_a_Feature.png?alt=media\&token=71c3ec5c-b1b7-4435-a097-02aa5f2c26c7)

If you feel like TextLink is missing an important feature or something that would help you use it, feel free to suggest it using this form.

<figure><img src="https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2FfeRtJAjERR3P2zA6kaxZ%2Fimage.png?alt=media&amp;token=280e8c6c-5a70-4ee1-8ed5-5bfc5649d402" alt=""><figcaption></figcaption></figure>


# Chat App

<figure><img src="https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2F3NNdJPZh4R5pOcZBSbRQ%2Fimage.png?alt=media&amp;token=966191b0-ea4f-44bb-b18b-59c2e141c42d" alt=""><figcaption><p>Chat app</p></figcaption></figure>

This is TextLink Chat app. You can use it to communicate with your contacts and see data about all the messages that your account has sent or received. You can find the detailed instructions about how to use it below.&#x20;

<figure><img src="https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2FR7NKgH7ufjjmbgx17D2p%2Fimage.png?alt=media&amp;token=27d3d4b8-ab18-4be6-8498-4334f91d976d" alt=""><figcaption><p>Two tabs for admin account</p></figcaption></figure>

As you can see, there are a multiple tabs on this page:

1. **All chats** - This is the list of all messages you have sent and received using Chat app, GHL, API and other No-code tools.&#x20;
2. **All contacts** - It is a list of contacts that you or any of your team members have created using the "Create contact" button on the top-left, or the contact menu of the phone number that is not a contact. Note that contacts are shared between admin account and subaccounts.
3. **My contacts** - It only exists for subaccounts, and it represents that team member's favorite contacts. It can be used to personalize experience for team members that use subaccount (e.g. for dispatch communications). Every subaccount can have its own list of favorite contacts.&#x20;

Note that "All contacts" page is not visible until you have created at least one contact.

<figure><img src="https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2FVbFRPIuCyzWaBtRuzU3B%2Fimage.png?alt=media&amp;token=720d1462-773e-427b-a257-3d6349ee132d" alt=""><figcaption><p>Contact options</p></figcaption></figure>

As you can see, there are two more things not mentioned above:

1. **Group options (add / remove)** - It is a part of our [No-code SMS outreach tool](https://textlinksms.com/dashboard/bulksms-dashboard).  It allows you to add your contacts to the Outreach groups.
2. **Contact tag** - Custom tag for your contacts. See the following page for the details about usage: \
   [API](/api) / [GoHighLevel](/gohighlevel) / [Webhooks](/webhooks)

As you can see below, you also have the ability to filter contacts by name and phone number, and to choose which SIM card you want to use when sending SMS.&#x20;

When you send an SMS to a contact, the further messages you send to it will use the same SIM card as the first message, so it looks like one chat on its phone (unless you explicitly specify that you want to send messages from another SIM card, and in that case messages to that user will default to newly selected SIM card).&#x20;

<figure><img src="https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2FQmunDwosmxpr6IUHLCkV%2Fimage.png?alt=media&amp;token=662a413a-f3f0-4a15-82d4-192bb3057f8d" alt=""><figcaption></figcaption></figure>


# API

TextLink API enables developers to send SMS in a very straightforward and user-friendly way.&#x20;

## Getting an API key

To be able to use TextLink for sending an SMS or user verification, you first have to [register an account](https://textlinksms.com/signup), after that you are going to get 300 free messages, which you can use to test our API.

After you have registered an account, your API key will be available in the[ API console](https://textlinksms.com/dashboard/api).&#x20;

## Sending an SMS

To send an SMS, you can send the following POST request with tool of your choice (like Postman), or use any of the programming languages that support REST API calls.

### Using API

<mark style="color:green;">`POST`</mark> `https://textlinksms.com/api/send-sms`

#### Headers

| Name                                            | Type | Description                                                                                                                                                |
| ----------------------------------------------- | ---- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Content-Type<mark style="color:red;">\*</mark>  |      | The value should be "application/json"                                                                                                                     |
| Authorization<mark style="color:red;">\*</mark> |      | The value should be "Bearer API\_KEY", where API\_KEY is the API key that you have registered in  the[ API Console](https://textlinksms.com/dashboard/api) |

#### Request Body

| Name                                            | Type   | Description                                                                                                                                                                                                                  |
| ----------------------------------------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| phone\_number<mark style="color:red;">\*</mark> | String | Recipient phone number, with country prefix. E.g. **+11234567890**                                                                                                                                                           |
| text<mark style="color:red;">\*</mark>          | String | Message body                                                                                                                                                                                                                 |
| sim\_card\_id                                   | Number | (Optional) Id of the SIM card that you want to send the message from. Can be found in the [Devices Console](https://textlinksms.com/dashboard/your-devices/overview), by clicking on the device having the SIM card you need |
| custom\_id                                      | String | (Optional) Custom id that you want us to send to you in our [failed message webhook](/webhooks#failed-message)                                                                                                               |

{% tabs %}
{% tab title="200: OK Message successfully sent" %}

```javascript
{
  ok: true
}
```

{% endtab %}

{% tab title="200: OK Message sending failed" %}

```javascript
{
  ok: false,
  message: "Reason string"
}
```

{% endtab %}

{% tab title="200: OK Message queued (all senders busy, should be sent soon)" %}

```javascript
{
  ok: true,
  queued: true
}
```

{% endtab %}
{% endtabs %}

### Using our official packages

{% tabs %}
{% tab title="Node.js" %}

<pre class="language-javascript"><code class="lang-javascript">// Firstly, install the helper library using <a data-footnote-ref href="#user-content-fn-1">npm</a> or <a data-footnote-ref href="#user-content-fn-2">yarn</a>

const textlink = require("textlink-sms");
textlink.useKey("YOUR_API_KEY"); // Replace with your API key

<strong>textlink.sendSMS("+381611231234", "Dummy message text...");
</strong></code></pre>

{% endtab %}

{% tab title="TypeScript" %}

<pre class="language-typescript"><code class="lang-typescript">// Firstly, install the helper library using <a data-footnote-ref href="#user-content-fn-1">npm</a> or <a data-footnote-ref href="#user-content-fn-2">yarn</a>

import TextLink from "textlink-sms";
TextLink.useKey("YOUR_API_KEY"); // Replace with your API key

<strong>TextLink.sendSMS("+381611231234", "Dummy message text...");
</strong></code></pre>

{% endtab %}

{% tab title="Python" %}

<pre class="language-python"><code class="lang-python"># Firstly, install the helper library using <a data-footnote-ref href="#user-content-fn-3">pip</a>

import textlink as tl

tl.useKey("YOUR_API_KEY") # Replace with your API key

<strong>result = tl.sendSMS("+381637443242", "Your message text...")
</strong>print(result)
</code></pre>

{% endtab %}
{% endtabs %}

## OTP / Phone verification

Besides [sending SMS](#sending-an-sms), TextLink API can automate one-time-password (OTP) verification for phone numbers. The pricing for OTP verification is the same as sending a normal SMS, but we give OTP messages higher priority and faster delivery times.

The main perk of using our solution for verifying phone number is the removal of need to store the valid codes in your database, since we can verify codes for you.

<figure><img src="https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2FhdI76LiC7C9a7deyNwhS%2Fimage.png?alt=media&amp;token=9bd03932-2584-475e-b8a5-72a93608407f" alt=""><figcaption></figcaption></figure>

To send a verification SMS, you can send the following POST request with tool of your choice (like Postman), or use any of the programming languages that support REST API calls.

### Using API&#x20;

<mark style="color:green;">`POST`</mark> `https://textlinksms.com/api/send-code`

#### Headers

| Name                                            | Type | Description                                                                                                                                               |
| ----------------------------------------------- | ---- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Content-Type<mark style="color:red;">\*</mark>  |      | The value should be "application/json"                                                                                                                    |
| Authorization<mark style="color:red;">\*</mark> |      | The value should be "Bearer API\_KEY", where API\_KEY is the API key that you have registered on the[ API Console](https://textlinksms.com/dashboard/api) |

#### Request Body

| Name                                            | Type   | Description                                                                                                                                                                                                                  |
| ----------------------------------------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| phone\_number<mark style="color:red;">\*</mark> | String | Recipient phone number, with country prefix. E.g. **+11234567890**                                                                                                                                                           |
| service\_name                                   | String | Your name to be shown in the message                                                                                                                                                                                         |
| sim\_card\_id                                   | Number | (Optional) Id of the SIM card that you want to send the message from. Can be found in the [Devices Console](https://textlinksms.com/dashboard/your-devices/overview), by clicking on the device having the SIM card you need |
| custom\_id                                      | String | (Optional) Custom id that you want us to send to you in our [failed message webhook](/webhooks#failed-message)                                                                                                               |

{% tabs %}
{% tab title="200: OK Message successfully sent" %}

```javascript
{
  ok: true,
  code: "123456" // The code sent
}
```

{% endtab %}

{% tab title="200: OK Message sending failed" %}

```javascript
{
  ok: false,
  message: "Reason string"
}
```

{% endtab %}
{% endtabs %}

### Using our official packages

{% tabs %}
{% tab title="Node.js" %}

<pre class="language-javascript"><code class="lang-javascript">// Firstly, install the helper library using <a data-footnote-ref href="#user-content-fn-4">npm</a> or <a data-footnote-ref href="#user-content-fn-5">yarn</a>

const textlink = require("textlink-sms");
textlink.useKey("YOUR_API_KEY"); // Replace with your API key

const verificationOptions = {
    service_name: "Tribal"
}; // This is optional

<strong>await textlink.sendVerificationSMS("+11234567890", verificationOptions);
</strong></code></pre>

{% endtab %}

{% tab title="TypeScript" %}

<pre class="language-typescript"><code class="lang-typescript">// Firstly, install the helper library using <a data-footnote-ref href="#user-content-fn-4">npm</a> or <a data-footnote-ref href="#user-content-fn-5">yarn</a>

import TextLink from "textlink-sms";
TextLink.useKey("YOUR_API_KEY");

const verificationOptions = {
    service_name: "Tribal"
}; // This is optional

<strong>await TextLink.sendVerificationSMS("+11234567890", verificationOptions);
</strong></code></pre>

{% endtab %}

{% tab title="Python" %}

<pre class="language-python"><code class="lang-python"># Firstly, install the helper library using <a data-footnote-ref href="#user-content-fn-6">pip</a>

import textlink as tl

tl.useKey("YOUR_API_KEY") # Replace with your API key

<strong>result = tl.sendVerificationSMS("+11234567890", service_name="Tribal")
</strong>print(result)
</code></pre>

{% endtab %}
{% endtabs %}

## Check if the code is valid

After you have sent the one-time-password to your user, you can prompt him to enter the code in your website or application. After he has entered the code, you can use the **`/verify-code`** endpoint, to check if it is valid, without having to store the code locally.&#x20;

### Using API

<mark style="color:green;">`POST`</mark> `https://textlinksms.com/api/verify-code`

#### Headers

| Name                                            | Type | Description                                                                                                                                               |
| ----------------------------------------------- | ---- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Content-Type<mark style="color:red;">\*</mark>  |      | The value should be "application/json"                                                                                                                    |
| Authorization<mark style="color:red;">\*</mark> |      | The value should be "Bearer API\_KEY", where API\_KEY is the API key that you have registered on the[ API Console](https://textlinksms.com/dashboard/api) |

#### Request Body

| Name                                            | Type   | Description                                    |
| ----------------------------------------------- | ------ | ---------------------------------------------- |
| phone\_number<mark style="color:red;">\*</mark> | String | The phone number that you would like to verify |
| code                                            | String | The OTP code to verify                         |

{% tabs %}
{% tab title="200: OK Code verified successfully" %}

```javascript
{
  ok: true
}
```

{% endtab %}

{% tab title="200: OK Verification failed" %}

```javascript
{
  ok: false,
  message: "Reason string"
}
```

{% endtab %}
{% endtabs %}

### Using our official packages

{% tabs %}
{% tab title="Node.js" %}

<pre class="language-javascript"><code class="lang-javascript"><strong>const result = await textlink.verifyCode("+11234567890", "USER_ENTERED_CODE"); 
</strong>//if `result.ok` is true, then the phone number is verified. 
</code></pre>

{% endtab %}

{% tab title="TypeScript" %}

<pre class="language-typescript"><code class="lang-typescript"><strong>const result = await TextLink.verifyCode("+11234567890", "USER_ENTERED_CODE"); 
</strong>//if `result.ok` is true, then the phone number is verified. 
</code></pre>

{% endtab %}

{% tab title="Python" %}

<pre class="language-python"><code class="lang-python"><strong>result = tl.verifyCode("+11234567890", "USER_ENTERED_CODE")
</strong># if `result.ok` is true, then the phone number is verified.
</code></pre>

{% endtab %}
{% endtabs %}

## Update contact tag

You can use TextLink API to update contact tags. Contact tags allows you to track status of communication with them (e.g. cold/warm), and can be shown in the Chat app. Besides the chat app, they are also received as a part of [Received Message Webhook](/webhooks), and each change of tag triggers the [Tag Update Webhook](/webhooks).

<figure><img src="https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2F0Qxc4qRP1fjyq6vbJ1bY%2Fimage.png?alt=media&amp;token=eaa75058-3327-49f6-9dc2-b9fda12ef0f6" alt=""><figcaption><p>This contact has "VIP" tag</p></figcaption></figure>

### Using API

<mark style="color:green;">`POST`</mark> `https://textlinksms.com/api/update-contect-tag`

#### Headers

| Name                                            | Type | Description                                                                                                                                               |
| ----------------------------------------------- | ---- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Content-Type<mark style="color:red;">\*</mark>  |      | The value should be "application/json"                                                                                                                    |
| Authorization<mark style="color:red;">\*</mark> |      | The value should be "Bearer API\_KEY", where API\_KEY is the API key that you have registered on the[ API Console](https://textlinksms.com/dashboard/api) |

#### Request Body

| Name                                            | Type   | Description                                                |
| ----------------------------------------------- | ------ | ---------------------------------------------------------- |
| phone\_number<mark style="color:red;">\*</mark> | String | The phone number that you would like to update the tag for |
| tag                                             | String | Tag to set for your contact                                |

{% tabs %}
{% tab title="200: OK Code verified successfully" %}

```javascript
{
  ok: true
}
```

{% endtab %}
{% endtabs %}

[^1]: npm install textlink-sms

[^2]: yarn add textlink-sms

[^3]: pip install textlink

[^4]: ```
    npm install textlink-sms
    ```

[^5]: ```
    yarn addtextlink-sms
    ```

[^6]: ```
    pip install textlink
    ```


# GoHighLevel

With TextLink, you can connect your own SIM card and your own android device to use with GoHighLevel locations. This approach significantly reduces cost per message by more than 10 times, while bypassing the complexity and requirements of A2P registration. In 10 minutes, you'll be fully setup and ready to use the service within your CRM.&#x20;

TextLink allows you to use a **single SIM card across multiple locations**. We ensure there are no conflicts, and everything functions smoothly.

## Setup tutorial

{% embed url="<https://www.youtube.com/watch?v=Fiv1HMRunDM>" %}

Before you begin, you will firstly need to create a TextLink account and [complete the setup tutorial](/), because it is needed in order to be able to use TextLink in the first place. After creating an account, you can then use [GoHighLevel setup page](https://textlinksms.com/dashboard/gohighlevel-setup) to track your progress, and to check if you have done everything correctly.

<figure><img src="https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2FWSa8JLhiBfU2b6qtdTE7%2Fimage.png?alt=media&amp;token=646aa012-8c71-47b5-a4cc-9637fec23123" alt=""><figcaption><p>GoHighLevel setup page</p></figcaption></figure>

### Step 0: Connect Your Devices

If you have completed the [setup tutorial](/), this should be marked as done, and you are ready to proceed to the next step.

### Step 1: Create a Team Member for Each GHL Location

For the next step, you will need to create a team member account for each location that you would like to use with GoHighLevel. You can do so in the [Team Mangement page](https://textlinksms.com/dashboard/team), and there is also a full tutorial on team management available on [this page](/team).

You just need to create a simple team member account, and you are ready to proceed to the next step.&#x20;

<figure><img src="https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2FlwKmUvI3SfiP1WpQSC2Z%2Fimage.png?alt=media&amp;token=2604c3c3-450d-4cc6-a917-a96daa3d237b" alt=""><figcaption></figcaption></figure>

### Step 2: Link GHL Locations to Subaccounts

Click the *Connect GHL* button on the [GHL page](https://textlinksms.com/dashboard/gohighlevel-setup), which will open our GHL app listing. You will be prompted to install TextLink Conversation provider. Scroll down to the end of the page and click *Next*.

On the next page, choose the location (GHL Subaccount) that you wish to connect. After that, make sure that you tick the box next to the TextLink SMS conversation provider, and click the *Proceed* button.

Now wait for the loading to complete and stay on the opened GHL page showing the API Key input field.&#x20;

Go to the [Team Manaegement page](https://textlinksms.com/dashboard/team) on the TextLink dashboard, and click Copy button for the API key of the Team member account that you want to connect. Next, go back to the GHL page that you have left open, and paste the API key in the input field, and click the *Save API Key* button.

<figure><img src="https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2FI5m17qkbFXhBtcOTZQIx%2Fimage.png?alt=media&amp;token=b9d6685a-114f-4b05-9a53-75c2cd22d090" alt=""><figcaption></figcaption></figure>

### Step 3: **Link SIM Cards to GHL Locations**

Now you have successfully connected your TextLink subaccount to your GHL location. The next step is to enable your team member to actually use your SIM cards (if they have not registered their own SIM card or you have not already done that for them). Go to the  [Team Manaegement page](https://textlinksms.com/dashboard/team), and click the gear icon next to their subaccount (if they don't have a password set, you will have to set it prior to device configuration by clicking *Set password* for that subaccount). You can then click the gear icon, and, on the newly opened page, in the lower left, click the SIM card that you want to add for your subaccount, and click *Save all*. That's it. Two more steps to go.&#x20;

<figure><img src="https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2Fix6BolFBzfKeump1j8wv%2Fimage.png?alt=media&amp;token=a0d5026b-c88c-4805-849b-e75b762425fb" alt=""><figcaption></figcaption></figure>

### Step 4: Set TextLink as Conversation Provider

Now that TextLink is all set up, you only need to go to each of your subaccounts' settings page on GHL → Phone Numbers → Advanced settings, and under there, select TextLink as the conversation provider.&#x20;

<figure><img src="https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2F9KMEG3n66fYXGsmTwWAw%2Fimage.png?alt=media&amp;token=943e017d-9ff5-47af-a2fe-47aba935bf36" alt=""><figcaption></figcaption></figure>


# Zapier

{% embed url="<https://www.youtube.com/watch?v=Owc1V5n9MUE>" %}

To use TextLink for your Zapier workflows (Zaps), you firstly need to create an account and finish the [device setup](/).&#x20;

## Trigger for receiving SMS

You can use [TextLink webhooks](/webhooks) to trigger a workflow in Zapier. In this example, you will learn how to setup the trigger for received SMS, but other triggers can be done almost identically ().&#x20;

1. When choosing the trigger for your workflow, select  ![](https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2FijLCfJuLcAr8ZxBzYVC1%2Fimage.png?alt=media\&token=54865da7-3df7-4381-b6dd-27114b08bcaa), and under *Trigger event*, select *Catch Hook*:\
   ![](https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2F4K4usrHwieZf3sr14AbP%2Fimage.png?alt=media\&token=8cd944bb-e8cd-4b68-9296-2abc1c06ae4c)
2. In the Configure step, you can safely click *Continue*, and skip to the next step
3. Click the *Copy* button next to the generated URL:

   ![](https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2FOLTthRTF5X0g9xEiG2pJ%2Fimage.png?alt=media\&token=b9334d03-28a3-4b6f-b266-bb3474eeb2ae)
4. Go to [TextLink API dashboard](https://textlinksms.com/dashboard/api) ("API & Hooks" page), and paste the copied URL into the input for the action that you would like to use to trigger your webhook (in our case Receive SMS action). Also if you have not set a webhook secret, click the *Generate* button next to the webhook secret. That secret is only known to you and our servers, and you can use it to authorize requests if needed. \
   ![](https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2FvkCFbvyUHvlQUEKxS7jg%2Fimage.png?alt=media\&token=5c141ffb-efb6-481a-9c78-484af32464b0)
5. Click *Save* and then *Test webhooks*. If everything is working, you should get the following confirmation:\
   ![](https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2F3y8PgKMCbZHELEWVfDJ5%2Fimage.png?alt=media\&token=d2efebf8-7fee-4b2e-93f7-55fccaff10bd)
6. Go back to Zapier, and click the *Test trigger* button. You should now see the test request. Click *Continue with selected record*\
   ![](https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2FjVimlUtCZln3mlZlLVkW%2Fimage.png?alt=media\&token=291ff2e7-9544-4255-a533-39b9d4873164)
7. Congratulations! You have completed the trigger setup. You can now easily use the Webhook data in next steps. \
   ![](https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2F2jFTZcqwLndQd8M45oOe%2Fimage.png?alt=media\&token=771a2b61-491b-4872-aaf7-dcf1a8c01a8d)

### (Optional) Webhook authorization

As mentioned earlier, you can specify a secret in your Webhook configuration. Only you and our server knows that secret. You can confirm that the request is coming from our server by adding the ![](https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2F37xbANzm0pZBswsSKrls%2Fimage.png?alt=media\&token=ee54c005-e64f-4d54-a5c9-d5b66342df59) component at the beginning of your workflow. On the *Configure & test* tab, for the first value, select `Secret` field from the previous steps, for the second value select `(Text) Exactly matches`, and paste your webhook secret into the third value. \
![](https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2F9SoDiitRSG0b5XuO02at%2Fimage.png?alt=media\&token=c51a12d8-b145-4907-b25f-aa31ca6eb0e4)

## Using the API (Sending an SMS + More)

You can call any endpoint defined on the [API page](/api) from Zapier. This example shows how to create a send SMS action.

1. When choosing the app for your action, select  ![](https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2FijLCfJuLcAr8ZxBzYVC1%2Fimage.png?alt=media\&token=54865da7-3df7-4381-b6dd-27114b08bcaa), and under *Action events*, choose POST:\
   ![](https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2FHrQjuyZ9ISx9K8iRyS0S%2Fimage.png?alt=media\&token=18e3836d-44a9-471f-bb0d-4613f1196528)
2. On the configure tab, enter the API url, select JSON for payload type, and enter the data required by the endpoint (you can click + to reuse data from previous steps). For `send-sms`, required fields are `phone_number` and `text`.\
   ![](https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2FUgypnL2inhSeZ051aZ1x%2Fimage.png?alt=media\&token=2c53be63-2297-404e-ad2c-232414f00f98)
3. Don't wrap request in array, don't insert any file, unflatten is optional and don't use basic auth. Add one Header called `Authorization`, and its value should be `Bearer YOUR_API_KEY`, where YOUR\_API\_KEY can be found in the [API dashboard](https://textlinksms.com/dashboard/api).\
   \
   ![](https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2Fq2XD1di3kYSxF5QY7lJb%2Fimage.png?alt=media\&token=0237543a-a475-4b84-b334-4b551852bdbe)
4. That's it! You can trigger other API endpoints similar way.&#x20;


# Make.com

Once you have signed in to [Make.com](https://make.com/), click the ![](https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2F4mZZCKie5ohBcAwpM0UZ%2Fimage.png?alt=media\&token=b4295e55-dba1-40f3-bd3a-16f940162d7d) button to get started working on your workflow. Note that you need to have a working TextLink account, and follw the [device setup tutorial](/) in order to be able to actually use TextLink.&#x20;

## Creating an SMS trigger

{% embed url="<https://youtu.be/4Oc6yjlg9V8?si=ZnVj_KblIyY0s6kj>" %}

In this tutorial, you will learn how to create a trigger for receiving SMS, but other triggers can be done identically. For list of other triggers, check the [Webhooks](/webhooks) page.

1. Select *Webhooks* as the  trigger for your workflow\
   ![](https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2F3PDq41FEEtR8L2MWiagh%2Fimage.png?alt=media\&token=592ed522-1342-4a6d-a7d8-e247172c46b3)
2. And then choose *Custom webhook*\
   &#x20;![](https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2Ff5Q9cdplz6SpFag9kyOw%2Fimage.png?alt=media\&token=8ee5e508-2585-44ec-a6f4-9d4d3c52e096)&#x20;
3. Create a new webhook, give it a name (anything you want), and click *Save*.\
   ![](https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2Ffbycwgchix2eONuPHbAV%2Fimage.png?alt=media\&token=5374d193-7039-4dad-b0b7-a6ca3bbd39c7)
4. Click the *Copy address to clipboard* button:\
   ![](https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2FDeZ9e5N7tj3PknpJp09K%2Fimage.png?alt=media\&token=3cf4a908-36fb-4d79-9f50-a1dc298fcbc9)
5. Go to [TextLink API dashboard](https://textlinksms.com/dashboard/api) ("API & Hooks" page), and paste the copied URL into the input for the action that you would like to use to trigger your webhook (in our case Receive SMS action). Also if you have not set a webhook secret, click the *Generate* button next to the webhook secret. That secret is only known to you and our servers, and you can use it to authorize requests if needed. \
   ![](https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2FC0ePNUYg4aavJEmQEMnL%2Fimage.png?alt=media\&token=04d37b0d-7609-4da8-8f74-9465eaf65384)
6. Click *Save* and then *Test webhooks*. If everything is working, you should get the following confirmation:\
   ![](https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2F3y8PgKMCbZHELEWVfDJ5%2Fimage.png?alt=media\&token=d2efebf8-7fee-4b2e-93f7-55fccaff10bd)
7. Go back to Make.com, and click the *Save* button (can also be called *Ok*). You should now see the test request. Click *Continue with selected record*\
   ![](https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2Fkg2xj2bQzx5D7uLnfSmI%2Fimage.png?alt=media\&token=8f76548f-b797-4bbc-9d7c-ef4d2c5523f0)
8. Congratulations! You have completed the trigger setup. You can now easily use the Webhook data in next steps.&#x20;

### (Optional) Webhook authorization

As mentioned earlier, you can specify a secret in your Webhook configuration (step 4). Only you and our server knows that secret. You can confirm that the request is coming from our server by adding the *Router* component at the beginning of your workflow, as shown below.

1. Click + to add a new component to your workflow. Select a router\
   ![](https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2Fdutobl9iEuhguHAGPBFo%2Fimage.png?alt=media\&token=2f7a8e19-3977-48ce-bce4-6bcea85e0b84)
2. Now you can see that it created two branches. We are safe to ignore the request if the secret is invalid, so we can delete the second branch by right clicking on it:\
   ![](https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2F3aprZdVpCQmolkzpavkS%2Fimage.png?alt=media\&token=8ee17921-049b-4f60-b69b-7e952fd829bf)
3. Click the dots between the router element and the next element (1st) to set up your filter. Enter any label. For condition, configure it so it checks whether the secret field provided in the webhook is your webhook secret, pasted from the step 4 in webhook creation.<br>

   <figure><img src="https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2FHbrlThV5YjeLt52liLvk%2Fimage.png?alt=media&amp;token=f9933f96-95c3-4b52-883b-e3128286479a" alt=""><figcaption></figcaption></figure>

## Using the API (Sending an SMS + More)

{% embed url="<https://www.youtube.com/watch?v=2OU3KNbn9PY>" %}

You can call any endpoint defined on the [API page](/api) from Make. This example shows how to create a send SMS action. To get started, click the + button to add an action after your webhook or your filter (as seen in previous step).&#x20;

1. Select the HTTP App\
   ![](https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2FgP86LHWrLqxwGgITsA0n%2Fimage.png?alt=media\&token=c50948ba-2c87-4d74-b4ca-1103d7a61c4b)<br>
2. Select *Make a request* action\
   ![](https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2FdERQmUhSBOAojtapinQo%2Fimage.png?alt=media\&token=ec9a3fb1-5fc8-41e9-a850-1f3d61311aad)
3. Fill out the URL, Method and Headers using the specification of the API call that you want to use (`send-sms` in our example). Make sure that the vaule of the Authorization header is `Bearer YOUR_API_KEY`, where you can find your API key in [TextLink API dashboard](https://textlinksms.com/dashboard/api). \
   ![](https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2FYYh1w0vn0MYBjqfoi5mj%2Fimage.png?alt=media\&token=bd358026-86fa-4bdb-a91c-734fdae71b81)
4. For *Body type*, select `Raw`. For *Content type*, select `JSON (application/json)`. For request content, you need to use this base form (you need to specify other fields based on the API endpoint specification):&#x20;

   ```
   {"phone_number": "", "text": ""}
   ```

   And you can then reuse all the other fields in your workflow by clicking them in the pop-up menu to the right. You can see that we are sending "Hello there" to the phone number  from the trigger Webhook.&#x20;

   <figure><img src="https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2F6WxtKCEjTJlp6XLd5vtp%2Fimage.png?alt=media&amp;token=490425ce-9fb1-4718-bbf2-6fe10c8cba01" alt=""><figcaption></figcaption></figure>
5. That's it! You can trigger other API endpoints similar way.&#x20;


# Webhooks (handle received SMS + more)

There are 4 webhooks that we can send to your custom server (or custom no-code workflow):

1. Received messages - Triggered whenever you receive a message.&#x20;
2. Sent messages - Triggered whenever you dispatch an action for sending SMS.&#x20;
3. Failed messages - Triggered whenever a message fails (in case of failed messages you firstly get a Sent message webhook, and then failed message webhook)
4. Changed contact tag - Triggered whenever a contact tag is changed (E.g. Cold -> Warm)

<figure><img src="https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2FWt79GRpZOZqfHggolQXm%2Fimage.png?alt=media&amp;token=57be8d67-c596-41de-bd39-a4be34bc9969" alt=""><figcaption></figcaption></figure>

## How it works

To make TextLink send request to your webhook, you just need to plug it in the corresponding webhook url field in  [our API console](https://textlinksms.com/dashboard/api), and click save. You can click *Test webhooks* button to get a sample request to each of your webhooks and to see if they are working. Maximum length of webhook string is 300 characters.

Webhook request contains JSON body  like this:

```
{
  "secret": "YOUR_WEBHOOK_SECRET",
  "phone_number": "+11234567890",
  "text": "Working!",
  "timestamp": 1748455363370
}
```

Though fields can differ based on webhook type.&#x20;

If your webhook does not return status 200, we will assume that the request was not successful, and we will notify you about it via e-mail.

### (Optional) Webhook authorization

If you specified a secret, we will send it to you in each request, so you can verify the request is coming from TextLink's servers. Make sure it is a secret string that only you know.&#x20;

You can see it in the sample body above, and for [Make](/make#optional-webhook-authorization) and [Zapier](/zapier#optional-webhook-authorization), we have a specific section on their corresponding documentation pages.

## Creating a custom server (coding solution)

To handle our HTTP POST request, you can use any web application framework, such as Laravel, Django, Express.js, Spring or ASP.NET.

Here is the example of the endpoint definition for Express.js:

```javascript
const express = require("express");
const app = express()
app.use(express.json())

app.post("/webhook-endpoint", (req, res) => {
    if (req.body.secret != "YOUR_WEBHOOK_SECRET")
        return res.status(401).json({ ok: false });
    
    const { phone_number/* ... other fields */ } = req.body;
    res.status(200).json({ ok: true });
})

app.listen(80);
```

## Using no-code workflows

You can see the example of using [Zapier](/zapier#trigger-for-receiving-sms) and [Make.com](/make#creating-an-sms-trigger) on their documentation pages. The other no-code tools function the similar way. If you need any help with other integrations, please feel free to reach us at [help@textlinksms.com](mailto://help@textlinksms.com)

## Example payloads

### Received message

```json
{
  "secret": "YOUR_WEBHOOK_SECRET",
  "phone_number": "+381690156360",
  "text": "General Kenobi",
  "tag": "Cold",
  "name": "Aleksandar Spremo",
  "sim_card_id": 123
}
```

Where `tag` is the custom tag defined in the [Chat App](/chat-app) or [update tag API request](/api#update-contact-tag), and `name` is the name of the contact (if you have created a contact for that phone number).

### Message dispatch (sent message)

```json
{
  "secret": "YOUR_WEBHOOK_SECRET",
  "phone_number": "+381690156360",
  "text": "Hello there",
  "portal": true,
  "timestamp": 1748463114559,
  "sim_card_id": 123
}
```

`portal` is true if message is sent through [Chat app](/chat-app), and `sim_card_id` is the id of the SIM card that the message was dispatched to.&#x20;

### Failed message

```json
{
  "secret": "YOUR_WEBHOOK_SECRET",
  "phone_number": "+381690156360",
  "text": "Hello there",
  "portal": true,
  "timestamp": 1748463114559,
  "textlink_id": 100123,
  "custom_id": "1234"
  "sim_card_id": 123
}
```

`portal` is true if message is sent through [Chat app](/chat-app), and `sim_card_id` is the id of the SIM card that the message was dispatched to. `custom_id` is the custom id you have provided in the send SMS API if you provided it, and `textlink_id` is the message ID in the TextLink database.

### Tag change

```json
{
  "name": "Aleksandar Spremo",
  "phone_number": "+381690156360",
  "tag": "Warm",
  "subuser_id": 6
}
```

`name`  the name of the contact (if you have created a contact for that phone number), `tag` is the name of the new tag, and `subuser_id` is optional parameter that shows your TextLink subuser ID that received the webhook, if it was sent to a subuser and not to the admin account.\
&#x20;


# Team management (subaccounts)

{% embed url="<https://www.youtube.com/watch?v=fPUEaO963aA>" %}

Team member accounts (subaccounts) can be used for various cases, such as private team member chats, multiple clients for agencies, and when you want someone else to set up an account for you and you don't want to give them access to your full TextLink account.&#x20;

Subaccount (or team member) is a TextLink account that can sign in to TextLink on its own, but has restricted features you can fully customize for it (including SMS limits, access to chats and access to your SIM cards).

<figure><img src="https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2FvKa3YH7i4ywmsIWylkZp%2Fimage.png?alt=media&amp;token=d06b8e07-fba9-47c6-818b-0e7e5be95242" alt=""><figcaption><p>A list of team member accounts</p></figcaption></figure>

To create a team member account, just click create new. It will generate a random email (or you can enter its email your own). If you enter the email, that address will get a registration email, like you did when registering for TextLink.&#x20;

<figure><img src="https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2FYYZr8soS4OQooCfqtY48%2Fimage.png?alt=media&amp;token=7c1f2b16-d54c-45f6-804a-ced871e74440" alt=""><figcaption><p>Subaccount dashboard</p></figcaption></figure>

Subaccounts have restricted dashboards (less account management, can't delete devices, restricted chat access). However, they can still use our tools, including chat app, no-code bulk SMS and API.&#x20;

<figure><img src="https://3572457912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjN6C63NXU3nkbh40PVoq%2Fuploads%2FHf66mLaVi0PyyWbDkJ9K%2Fimage.png?alt=media&amp;token=c830bbb6-fa86-4ddf-9218-7d4de854defd" alt=""><figcaption><p>Manage subaccount permissions</p></figcaption></figure>

When you click the gear next to the team member's account, you can manage its permissions.&#x20;

You can set custom limits for daily, monthly and total usage. When one of those limit is reached, subaccount can't send more messages until you reset or increase it, day passes for daily, or month passes for a monthly limit.

You can also choose which of SIM cards a subaccount can use. By default, it has access only to SIM cards that that account registered, and does not have access to other SIM cards on your account.&#x20;

Finally, you can choose which contacts can subaccount chat with, and see their chat history. Note that chat history is shared on account level, so two subaccounts can simultaneously chat with the same contact. By default, subuser only has access to contacts it sent messages to, and you can manually enable or disable access to it as you want.

&#x20;When you allow all SIM cards / communication with all contacts to a subaccount, it gets access to all SIMs/contacts available to you, even the future ones.


# iMessage-specific API

You can use all TextLink tools, integrations and APIs for your [Blububl](https://blububl.com) devices. Blububl is an iMessage automation solution that allows you to utilize iMessage for personalized / automated communication with your leads. You can see how it works [on this page](https://blububl.com/demo).&#x20;

Onboarding to BluBubl is custom for each customer, and you need to contact Blububl directly in order to use the service.

BluBubl is a cloud service, and you **can't** set it up yourself like you do with TextLink devices.

This section covers the specific APIs for iMessage, including the API for checking if number has IMessage, and the APIs for sending a media message.. You can also use the basic SMS functionalities like [sending](/api#sending-an-sms) and [receiving](/webhooks) messages the same way as using normal TextLink.&#x20;

## Checking if phone number has iMessage

To check if phone number uses iMessage, you can send the following POST request with tool of your choice (like Postman), or use any of the programming languages that support REST API calls.

You can only do that if you have an iMessage device (that can only be set up by BluBubl team).

### Using API

<mark style="color:green;">`POST`</mark> `https://textlinksms.com/api/check-imessage`

#### Headers

| Name                                            | Type | Description                                                                                                                                        |
| ----------------------------------------------- | ---- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| Content-Type<mark style="color:red;">\*</mark>  |      | The value should be "application/json"                                                                                                             |
| Authorization<mark style="color:red;">\*</mark> |      | The value should be "Bearer API\_KEY", where API\_KEY is the API key that you can see in  the[ API Console](https://textlinksms.com/dashboard/api) |

#### Request Body

| Name                                            | Type   | Description                                                                                                                                                                                                                               |
| ----------------------------------------------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| phone\_number<mark style="color:red;">\*</mark> | String | Phone number that you want to check. International format, with prefix, like **+11234567890**                                                                                                                                             |
| sim\_card\_id                                   | Number | (Optional) Id of the iMessage virtual SIM card that you want to use for the check. Can be found in the [Devices Console](https://textlinksms.com/dashboard/your-devices/overview), by clicking on the device having the SIM card you need |

{% tabs %}
{% tab title="200: OK iMessage number" %}

```javascript
{
  ok: true,
  imessage: true
}
```

{% endtab %}

{% tab title="200: OK Number can't use iMessage" %}

```javascript
{
  ok: true,
  imessage: false
}
```

{% endtab %}

{% tab title="200: NOT OK" %}

```javascript
{
  ok: false,
  message: "Reason string"
}
```

{% endtab %}
{% endtabs %}

## Sending a voice note (using audio file)

Sending media messages, including voice notes, uses multipart form data for request body encoding, instead of JSON. It needs to be that way because it allows binary content, such as media, documents and other files.

### Using API

<mark style="color:green;">`POST`</mark> `https://textlinksms.com/media/send-voice`

#### Headers

| Name                                            | Type | Description                                                                                                                                        |
| ----------------------------------------------- | ---- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| Content-Type<mark style="color:red;">\*</mark>  |      | The value should be "multipart/form-data"                                                                                                          |
| Authorization<mark style="color:red;">\*</mark> |      | The value should be "Bearer API\_KEY", where API\_KEY is the API key that you can see in  the[ API Console](https://textlinksms.com/dashboard/api) |

#### Request Body (As multipart form data)

| Name                                            | Type   | Description                                                                                                                                                                                                                               |
| ----------------------------------------------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| phone\_number<mark style="color:red;">\*</mark> | String | Phone number that you want to check. International format, with prefix, like **+11234567890**                                                                                                                                             |
| voice<mark style="color:red;">\*</mark>         | File   | Audio file (MP3, WAV, etc.) to send. The form‐field name must be `voice`.                                                                                                                                                                 |
| sim\_card\_id                                   | Number | (Optional) Id of the iMessage virtual SIM card that you want to use for the check. Can be found in the [Devices Console](https://textlinksms.com/dashboard/your-devices/overview), by clicking on the device having the SIM card you need |
| custom\_id                                      | String | (Optional) Custom id that you want us to send to you in our [failed message webhook](/webhooks#failed-message)                                                                                                                            |

{% tabs %}
{% tab title="200: OK Message successfully sent" %}

```javascript
{
    ok: true,
    price: 0,
    sim_card_id: 1088
}
```

{% endtab %}

{% tab title="200: OK Message sending failed" %}

```javascript
{
  ok: false,
  message: "Reason string"
}
```

{% endtab %}
{% endtabs %}

### Code snippets

{% tabs %}
{% tab title="Node.js" %}

```javascript
// Install dependencies first:
// npm install axios form-data

const axios = require('axios');
const FormData = require('form-data');
const fs = require('fs');
const path = require('path');

async function test() {
    const form = new FormData();
    form.append('phone_number', PHONE_NUMBER);
    form.append('voice', fs.createReadStream(path.resolve(FILE_PATH)));
    form.append('sim_card_id', SIM_CARD_ID);

    try {
        const response = await axios.post(
            'https://textlinksms.com/media/send-voice',
            form,
            {
                headers: {
                    'Authorization': 'Bearer ' + API_KEY,
                    ...form.getHeaders(),
                },
                maxBodyLength: Infinity,
            }
        );
        console.log('Response data:', response.data);
    } catch (err) {
        console.log(err);
    }
}

test()
```

{% endtab %}

{% tab title="Python" %}

```python
# Install dependencies first:
# pip install requests

import requests

def send_voice():
    url = "https://textlinksms.com/media/send-voice"
    headers = {
        "Authorization": f"Bearer {API_KEY}"
    }
    data = {
        "phone_number": PHONE_NUMBER,
        "sim_card_id": SIM_CARD_ID
    }
    with open(FILE_PATH, "rb") as voice_file:
        files = {
            "voice": voice_file
        }
        response = requests.post(url, headers=headers, data=data, files=files)
    
    try:
        response.raise_for_status()
        print("Response data:", response.json())
    except requests.HTTPError as e:
        # If the API returns a non-2xx status code, print the error response
        print(f"Error sending voice: {e}\n{response.text}")

if __name__ == "__main__":
    send_voice()
```

{% endtab %}
{% endtabs %}

## Sending a picture

Sending media messages, including images, uses multipart form data for request body encoding, instead of JSON. It needs to be that way because it allows binary content, such as media, documents and other files.

### Using API

<mark style="color:green;">`POST`</mark> `https://textlinksms.com/media/send-image`

#### Headers

| Name                                            | Type | Description                                                                                                                                        |
| ----------------------------------------------- | ---- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| Content-Type<mark style="color:red;">\*</mark>  |      | The value should be "multipart/form-data"                                                                                                          |
| Authorization<mark style="color:red;">\*</mark> |      | The value should be "Bearer API\_KEY", where API\_KEY is the API key that you can see in  the[ API Console](https://textlinksms.com/dashboard/api) |

#### Request Body (As multipart form data)

| Name                                            | Type   | Description                                                                                                                                                                                                                               |
| ----------------------------------------------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| phone\_number<mark style="color:red;">\*</mark> | String | Phone number that you want to check. International format, with prefix, like **+11234567890**                                                                                                                                             |
| image<mark style="color:red;">\*</mark>         | File   | Image file (JPG, PNG, etc.) to send. The form‐field name must be `image`.                                                                                                                                                                 |
| sim\_card\_id                                   | Number | (Optional) Id of the iMessage virtual SIM card that you want to use for the check. Can be found in the [Devices Console](https://textlinksms.com/dashboard/your-devices/overview), by clicking on the device having the SIM card you need |
| custom\_id                                      | String | (Optional) Custom id that you want us to send to you in our [failed message webhook](/webhooks#failed-message)                                                                                                                            |

{% tabs %}
{% tab title="200: OK Message successfully sent" %}

```javascript
{
    ok: true,
    price: 0,
    sim_card_id: 1088
}
```

{% endtab %}

{% tab title="200: OK Message sending failed" %}

```javascript
{
  ok: false,
  message: "Reason string"
}
```

{% endtab %}
{% endtabs %}

### Code snippets

{% tabs %}
{% tab title="Node.js" %}

```javascript
// Install dependencies first:
// npm install axios form-data

const axios = require('axios');
const FormData = require('form-data');
const fs = require('fs');
const path = require('path');

async function test() {
    const form = new FormData();
    form.append('phone_number', PHONE_NUMBER);
    form.append('image', fs.createReadStream(path.resolve(FILE_PATH)));
    form.append('sim_card_id', SIM_CARD_ID);

    try {
        const response = await axios.post(
            'https://textlinksms.com/media/send-image',
            form,
            {
                headers: {
                    'Authorization': 'Bearer ' + API_KEY,
                    ...form.getHeaders(),
                },
                maxBodyLength: Infinity,
            }
        );
        console.log('Response data:', response.data);
    } catch (err) {
        console.log(err);
    }
}

test()
```

{% endtab %}

{% tab title="Python" %}

```python
# Install dependencies first:
# pip install requests

import requests

def send_image():
    url = "https://textlinksms.com/media/send-image"
    headers = {
        "Authorization": f"Bearer {API_KEY}"
    }
    data = {
        "phone_number": PHONE_NUMBER,
        "sim_card_id": SIM_CARD_ID
    }
    with open(FILE_PATH, "rb") as image_file:
        files = {
            "image": image_file
        }
        response = requests.post(url, headers=headers, data=data, files=files)
    
    try:
        response.raise_for_status()
        print("Response data:", response.json())
    except requests.HTTPError as e:
        # If the API returns a non-2xx status code, print the error response
        print(f"Error sending image: {e}\n{response.text}")

if __name__ == "__main__":
    send_image()
```

{% endtab %}
{% endtabs %}

## Sending a video

Sending media messages, including videos, uses multipart form data for request body encoding, instead of JSON. It needs to be that way because it allows binary content, such as media, documents and other files.

### Using API

<mark style="color:green;">`POST`</mark> `https://textlinksms.com/media/send-video`

#### Headers

| Name                                            | Type | Description                                                                                                                                        |
| ----------------------------------------------- | ---- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| Content-Type<mark style="color:red;">\*</mark>  |      | The value should be "multipart/form-data"                                                                                                          |
| Authorization<mark style="color:red;">\*</mark> |      | The value should be "Bearer API\_KEY", where API\_KEY is the API key that you can see in  the[ API Console](https://textlinksms.com/dashboard/api) |

#### Request Body (As multipart form data)

| Name                                            | Type   | Description                                                                                                                                                                                                                               |
| ----------------------------------------------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| phone\_number<mark style="color:red;">\*</mark> | String | Phone number that you want to check. International format, with prefix, like **+11234567890**                                                                                                                                             |
| video<mark style="color:red;">\*</mark>         | File   | Video file (MP4, MKV, etc.) to send. The form‐field name must be `video`.                                                                                                                                                                 |
| sim\_card\_id                                   | Number | (Optional) Id of the iMessage virtual SIM card that you want to use for the check. Can be found in the [Devices Console](https://textlinksms.com/dashboard/your-devices/overview), by clicking on the device having the SIM card you need |
| custom\_id                                      | String | (Optional) Custom id that you want us to send to you in our [failed message webhook](/webhooks#failed-message)                                                                                                                            |

{% tabs %}
{% tab title="200: OK Message successfully sent" %}

```javascript
{
    ok: true,
    price: 0,
    sim_card_id: 1088
}
```

{% endtab %}

{% tab title="200: OK Message sending failed" %}

```javascript
{
  ok: false,
  message: "Reason string"
}
```

{% endtab %}
{% endtabs %}

### Code snippets

{% tabs %}
{% tab title="Node.js" %}

```javascript
// Install dependencies first:
// npm install axios form-data

const axios = require('axios');
const FormData = require('form-data');
const fs = require('fs');
const path = require('path');

async function test() {
    const form = new FormData();
    form.append('phone_number', PHONE_NUMBER);
    form.append('video', fs.createReadStream(path.resolve(FILE_PATH)));
    form.append('sim_card_id', SIM_CARD_ID);

    try {
        const response = await axios.post(
            'https://textlinksms.com/media/send-video',
            form,
            {
                headers: {
                    'Authorization': 'Bearer ' + API_KEY,
                    ...form.getHeaders(),
                },
                maxBodyLength: Infinity,
            }
        );
        console.log('Response data:', response.data);
    } catch (err) {
        console.log(err);
    }
}

test()
```

{% endtab %}

{% tab title="Python" %}

```python
# Install dependencies first:
# pip install requests

import requests

def send_video():
    url = "https://textlinksms.com/media/send-video"
    headers = {
        "Authorization": f"Bearer {API_KEY}"
    }
    data = {
        "phone_number": PHONE_NUMBER,
        "sim_card_id": SIM_CARD_ID
    }
    with open(FILE_PATH, "rb") as video_file:
        files = {
            "video": video_file
        }
        response = requests.post(url, headers=headers, data=data, files=files)
    
    try:
        response.raise_for_status()
        print("Response data:", response.json())
    except requests.HTTPError as e:
        # If the API returns a non-2xx status code, print the error response
        print(f"Error sending video: {e}\n{response.text}")

if __name__ == "__main__":
    send_video()
```

{% endtab %}
{% endtabs %}

## Sending a file

Sending media and file messages uses multipart form data for request body encoding, instead of JSON. It needs to be that way because it allows binary content, such as media, documents and other files.

### Using API

<mark style="color:green;">`POST`</mark> `https://textlinksms.com/media/send-file`

#### Headers

| Name                                            | Type | Description                                                                                                                                        |
| ----------------------------------------------- | ---- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| Content-Type<mark style="color:red;">\*</mark>  |      | The value should be "multipart/form-data"                                                                                                          |
| Authorization<mark style="color:red;">\*</mark> |      | The value should be "Bearer API\_KEY", where API\_KEY is the API key that you can see in  the[ API Console](https://textlinksms.com/dashboard/api) |

#### Request Body (As multipart form data)

| Name                                            | Type   | Description                                                                                                                                                                                                                               |
| ----------------------------------------------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| phone\_number<mark style="color:red;">\*</mark> | String | Phone number that you want to check. International format, with prefix, like **+11234567890**                                                                                                                                             |
| file<mark style="color:red;">\*</mark>          | File   | Any file (PDF, PPTX, etc.) to send. The form‐field name must be `file`.                                                                                                                                                                   |
| sim\_card\_id                                   | Number | (Optional) Id of the iMessage virtual SIM card that you want to use for the check. Can be found in the [Devices Console](https://textlinksms.com/dashboard/your-devices/overview), by clicking on the device having the SIM card you need |
| custom\_id                                      | String | (Optional) Custom id that you want us to send to you in our [failed message webhook](/webhooks#failed-message)                                                                                                                            |

{% tabs %}
{% tab title="200: OK Message successfully sent" %}

```javascript
{
    ok: true,
    price: 0,
    sim_card_id: 1088
}
```

{% endtab %}

{% tab title="200: OK Message sending failed" %}

```javascript
{
  ok: false,
  message: "Reason string"
}
```

{% endtab %}
{% endtabs %}

### Code snippets

{% tabs %}
{% tab title="Node.js" %}

```javascript
// Install dependencies first:
// npm install axios form-data

const axios = require('axios');
const FormData = require('form-data');
const fs = require('fs');
const path = require('path');

async function test() {
    const form = new FormData();
    form.append('phone_number', PHONE_NUMBER);
    form.append('file', fs.createReadStream(path.resolve(FILE_PATH)));
    form.append('sim_card_id', SIM_CARD_ID);

    try {
        const response = await axios.post(
            'https://textlinksms.com/media/send-file',
            form,
            {
                headers: {
                    'Authorization': 'Bearer ' + API_KEY,
                    ...form.getHeaders(),
                },
                maxBodyLength: Infinity,
            }
        );
        console.log('Response data:', response.data);
    } catch (err) {
        console.log(err);
    }
}

test()
```

{% endtab %}

{% tab title="Python" %}

```python
# Install dependencies first:
# pip install requests

import requests

def send_file():
    url = "https://textlinksms.com/media/send-file"
    headers = {
        "Authorization": f"Bearer {API_KEY}"
    }
    data = {
        "phone_number": PHONE_NUMBER,
        "sim_card_id": SIM_CARD_ID
    }
    with open(FILE_PATH, "rb") as my_file:
        files = {
            "file": my_file
        }
        response = requests.post(url, headers=headers, data=data, files=files)
    
    try:
        response.raise_for_status()
        print("Response data:", response.json())
    except requests.HTTPError as e:
        # If the API returns a non-2xx status code, print the error response
        print(f"Error sending file: {e}\n{response.text}")

if __name__ == "__main__":
    send_file()
```

{% endtab %}
{% endtabs %}

## Receiving media messages

When you receive a media message, a [normal receive SMS webhook](/webhooks#received-message) is triggered, and the text of the message includes filename, and is formatted like this:

1. For voice messages: <https://textlinksms.com/uploads/voice/e022e743-8e0e-4ea1-8a29-d6404a85eaef.mp3>
2. For images: <https://textlinksms.com/uploads/images/5e2d687a-4640-424b-bd35-7e2e19a17a27.heic>
3. For videos: <https://textlinksms.com/uploads/videos/38471392-f2d8-4935-acf4-a0d7760d5079.mov>
4. For files: <https://textlinksms.com/uploads/files/b14d17cb-17ad-48e4-8495-2fa446151299-file_example_MP3_700KB.mp3>


