SMS API Reference
Dive into our full API Reference Documentation and seamlessly integrate SMS functionalities into your website or application.
Our APIs use HTTP verbs and a RESTful endpoint structure. An access key and secret are used as the API Authorization framework. Request and response payloads are formatted as JSON, using UTF-8 encoding and URL encoded values.
API Endpoint
In order to use 2FA.link APIs, you need to first sign up for free at app.2fa.link
https://api.2fa.link/sms
Credentials
All requests to 2FA.link’s REST API need to be authenticated using HTTP Basic Authentication.
API key/secret pair are credentials you can create and revoke in the admin dashboard. These are typically easier to work with for your projects. You can quickly delete them to revoke access if they are compromised or create mutiple key/secret pairs for different use cases. You can also suspend an API key if neccesary to temporary block access.
API Key | API Secret |
---|---|
Username | Password |
One of the most common mistakes that is made with API keys is to inadvertently check them into public repositories on platforms such as GitHub. From these public repositories, fraudsters can search and steal your API access key and use it to send Spam messages and also drain your account balance. The main takeaway is don’t hard-code your API access key and don’t check it into a public code repository.
HTTP Method
2FA.link only support the POST HTTP methods on various resources.
You can create or query a resource using the HTTP POST method on a resource URI. All you need is to provide the relevant fields in JSON! Here’s a POST request that will create a Verify Request using the 2FA.link API.
Send SMS
Use this to create a new SMS request.

curl -X POST "https://API_KEY:API_SECRET@https://api.2fa.link/sms"
-H "accept: application/json"
-H "Content-Type: application/json; charset=utf-8"
-d '{
"from":"2FA",
"to":"6598765432",
"mode":"sms",
"content":"This is a SMS send from 2FA.link"
}'
$fields = [
'from' => '2FA',
'to' => '6598765432',
'mode' => 'sms',
'content' => 'This is a test SMS from 2FA.link'
];
$headers = [
'Accept: application/json',
'Content-Type: application/json; charset=utf-8'
];
$url = "https://API_KEY:API_SECRET@api.2fa.link/sms";
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($fields));
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($curl);
curl_close($curl);
Request-body (content-type: application/json)
Key | Mandatory | Accepted Format | Description |
---|---|---|---|
mode | Yes | “sms” | Mode of operation |
from | No |
[A-Za-z0-9 ]{2,11}
|
Sender ID (Default: “2FA”) |
to | Yes |
[0-9]{10,15}
|
Receiver in E.164 Format |
content | No | string | SMS Content |
base64 | No | 0 or 1 | Content is base64 encoded (Default: 0) |
udh | No | string | User Data Header (Advance usage) |
base64 encoded content: This is recommended to avoid encoding issue for non-latin characters.
Response-body (Positive)
{
"errorcode":100,
"errormsg":"Success",
"request_id":"600EC8DB-FFMRSQGCNG"
}
Response-body (Negative)
{
"errorcode":207,
"errormsg":"Incorrect MODE Field Format"
}
Response-body
Key | Description |
---|---|
errorcode | Error code of Verify request |
errormsg | Error message of Verify request |
request_id | ID for SMS request |
SMS Status Query
Use this API call to query SMS delivery status.
curl -X POST "https://API_KEY:API_SECRET@https://api.2fa.link/sms"
-H "accept: application/json"
-H "Content-Type: application/json; charset=utf-8"
-d '{
"request_id":"600CCE4E-PKUXGZIHYJ",
"mode":"query"
}'
$fields = [
'request_id' => '600CCE4E-PKUXGZIHYJ',
'mode' => 'query'
];
$headers = [
'Accept: application/json',
'Content-Type: application/json; charset=utf-8'
];
$url = "https://API_KEY:API_SECRET@api.2fa.link/sms";
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($fields));
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($curl);
curl_close($curl);
Request-body (content-type: application/json)
Key | Mandatory | Accepted | Description |
---|---|---|---|
mode | Yes | “query” | Mode of operation |
request_id | Yes |
–
|
ID of SMS request |
Response-body (Positive)
{
"request_id":"600CCE4E-PKUXGZIHYJ",
"from":"2FA",
"to":"6598765432",
"app_name":"SMS Only",
"status":"SMS Delivered",
"statuscode":"701",
"msg_count":"1",
"price":"-0.05",
"timestamp_submitted":"2021-01-24T01:33:03+00:00",
"timestamp_finalized":"2021-01-24T01:33:10+00:00"
}
Response-body (Negative)
{
"request_id":"600EC8DB-FFMRSQGCNG",
"status":"SMS Expired",
"statuscode":"704"
}
Response-body
Key | Description |
---|---|
request_id | ID for Verify request |
from | Sender Name |
to | Receiver |
app_name | Application Name |
status | Status of SMS request |
statuscode | Status code |
msg_count | Messages sent |
price | Price charged (in EURO) |
timestamp_submitted | Timestamp of Verify request |
timestamp_finalized | Timestamp of Final status |
Status
statuscode | status | Description |
---|---|---|
700 | SMS Sent | SMS Sent to user, pending DLR |
701 | SMS Delivered | SMS Delivered to user |
702 | SMS Undelivered | SMS Undelivered |
703 | SMS Rejected | SMS Rejected by destination operator |
704 | SMS Expired | SMS delivery failed due to VP expired |
705 | Unknown | Status unknown |
706 | Not Found | SMS request not found |
SMS Feedback
Use this API call to feedback if SMS is received.
curl -X POST "https://API_KEY:API_SECRET@https://api.2fa.link/sms"
-H "accept: application/json"
-H "Content-Type: application/json; charset=utf-8"
-d '{
"request_id":"600CCE4E-PKUXGZIHYJ",
"mode":"feedback"
}'
$fields = [
'request_id' => '600CCE4E-PKUXGZIHYJ',
'mode' => 'feedback'
];
$headers = [
'Accept: application/json',
'Content-Type: application/json; charset=utf-8'
];
$url = "https://API_KEY:API_SECRET@api.2fa.link/sms";
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($fields));
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($curl);
curl_close($curl);
Request-body (content-type: application/json)
Key | Mandatory | Accepted | Description |
---|---|---|---|
mode | Yes | “feedback” | Mode of operation |
request_id | Yes |
–
|
ID of Verify request |
Response-body (Positive)
{
"request_id":"600ED8FE-YEQJDVLLQI",
"status":"Success",
"statuscode":"600"
}
Status
statuscode | status | Description |
---|---|---|
600 | Success | Delivery feedback received |
DLR Callback
A callback would be POST to your provided webhook when Delivery Receipt (DLR) is received from the carrier’s network. For security, you can whitelist traffic from only our IP address (168.119.166.186). Do note that more sites may be added in the future and you would be informed accordingly.

Request-body (DLR)
{
"request_id":"60098C02-BMYUEJQIAN",
"sender":"2FA",
"msisdn":"6587654321",
"status":"SMS delivered",
"statuscode":"701",
"timestamp":"2021-01-21T14:13:26+00:00"
}
Request-body (content-type: application/json)
Key | Description |
---|---|
request_id | ID of SMS Request |
sender | Sender Name |
msisdn | Receiver |
status | DLR Status |
statuscode | Status code |
timestamp | Timestamp of DLR |
Status
statuscode | status | Description |
---|---|---|
701 | SMS Delivered | SMS Delivered to user |
702 | SMS Undelivered | SMS Undelivered |
703 | SMS Rejected | SMS Rejected by destination operator |
704 | SMS Expired | SMS delivery failed due to VP expired |
705 | Unknown | Status unknown |
Error Codes
errorcode | errormsg |
---|---|
100 | Success |
101 | Invalid API Key or Secret |
102 | Invalid Account |
103 | Rate Limit Reached |
104 | Insufficient Credit in Account |
201 | Missing Mandatory Field(s) for Requested Mode |
202 | Invalid API Key or Secret Format |
203 | Incorrect TO Field Format |
204 | Incorrect FROM Field Format |
207 | Incorrect MODE Field Format |
209 | Incorrect BASE64 Field Format |
210 | Incorrect UDH Field Format |
211 | Incorrect REQUEST_ID Field Format |
301 | SMS Rejected |
401 | Temporary Error, Please try again later! |