Two Factor Authentication API

This is the part of the API that provides the Two Factor Authentication. The flow of 2FA is:

  • The User specifies his number in your App.

  • Your App sends a 2FA request via API.

  • The platform sends a text message to the specified recipient.

  • User receives the PIN via text message

  • User enters the PIN in your App.

  • Your App sends the 2FA verify via API and receives the authorization or an invalid pin error.

The text message is sent with the highest quality on a preferred route, to guarantee a quick delivery.

Remember to provide the authentication HTTP headers as described in the Authenticate using a session key and the Authenticate using a user tokeny sections.
All the query string parameters in URL must be UTF-8 URL Encoded.

Request a 2FA Pin

Request a Two Factor Authentication via text message. This method generates a pin and sends it via text message to the user.

HTTP Headers

user_key / Session_key

HTTP Method

POST

HTTP Request

https://app.gateway.smsend.it/API/v1.0/REST/2fa/request

Body Fields

Parameter Type Description Required Default
recipient String The phone number of the user. The format must be +1111111111 or 001111111111 Yes -
senderName String The sender name or number for the text message No Preferred Sender Name
expiry Integer The expiration time of the PIN, in minutes No 60
messageBody String The message body.
PIN position in the text can be specified using the %PIN% placeholder.
If the placeholder is not provided the pin will be added at the end of message body.
No A default message body per language.

Returns

Code Description
200 Pin has been successfully sent via text message.
400 [Bad request] Invalid recipient, senderName, expiry, or sending errors like not enough credit.
401 [Unauthorized] User_key, Token or Session_key are invalid or not provided
404 [Not found] The User_key was not found
Copy code
# Session Key example
curl -XPOST 'https://app.gateway.smsend.it/API/v1.0/REST/2fa/request' -H 'Content-Type: application/json' \
-H 'user_key: USER_KEY' -H 'Session_key: SESSION_KEY' -d'
{
    "recipient": "+393471234567"
}
'

# Access token example
curl -XPOST 'https://app.gateway.smsend.it/API/v1.0/REST/2fa/request' -H 'Content-Type: application/json' \
 -H 'user_key: USER_KEY' -H 'Access_token: ACCESS_TOKEN' -d'
{
    "recipient": "+393471234567"
}
'
On success, the above command returns the following response:
{
  "status": "OK"
}
On failure, the above command returns the following response:
{
  "status": "ERROR",
  "error": "Error cause"
}
Copy code
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.io.OutputStream;
import java.net.URL;

public class Main {
    public static void main(String[] args) {
        try {
            URL url = new URL("https://app.gateway.smsend.it/API/v1.0/REST/2fa/request");
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();

            conn.setRequestProperty("user_key", "USER_KEY");

            // Use this when using Session Key authentication
            conn.setRequestProperty("Session_key", "SESSION_KEY");
            // When using Access Token authentication, use this instead:
            // conn.setRequestProperty("Access_token", "UserParam{access_token}");

            conn.setRequestMethod("POST");

            conn.setRequestProperty("Accept", "application/json");
            conn.setRequestProperty("Content-type", "application/json");
            conn.setDoOutput(true);

            String payload = "{" + 
              "    \"recipient\": \"+393471234567\"" + 
              "}";

            OutputStream os = conn.getOutputStream();
            os.write(payload.getBytes());
            os.flush();

            if (conn.getResponseCode() != 200) {
                // Print the possible error contained in body response
                String error = "";
                String output;
                BufferedReader errorbuffer = new BufferedReader(new InputStreamReader(conn.getErrorStream(), "UTF-8"));
                while ((output = errorbuffer.readLine()) != null) {
                    error += output;
                }
                System.out.println("Error! HTTP error code : " + conn.getResponseCode() +
                                   ", Body message : " + error);
                throw new RuntimeException("Failed : HTTP error code : " + conn.getResponseCode());
            }
            BufferedReader br =
                new BufferedReader(new InputStreamReader(conn.getInputStream()));

            String response = "";
            String output;
            while ((output = br.readLine()) != null) {
                response += output;
            }
            // You can parse the response using Google GSON or similar.
            // MyObject should be a class that reflect the JSON
            // structure of the response

            GsonBuilder builder = new GsonBuilder();
            Gson gson = builder.create();
            MyObject responseObj = gson.fromJson(response, MyObject.class);
            conn.disconnect();
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }
}
On success, the above command returns the following response:
{
  "status": "OK"
}
On failure, the above command returns the following response:
{
  "status": "ERROR",
  "error": "Error cause"
}
Copy code
<?php

$payload = '{' . 
  '    "recipient": "+393471234567"' . 
  '}';

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://app.gateway.smsend.it/API/v1.0/REST/2fa/request');
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    'Content-type: application/json',
    'user_key: USER_KEY',
    // Use this when using session key authentication
    'Session_key: SESSION_KEY',
    // When using Access Token authentication, use this instead:
    // 'Access_token: UserParam{access_token}'
));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
$response = curl_exec($ch);
$info = curl_getinfo($ch);
curl_close($ch);

if ($info['http_code'] != 200) {
    echo('Error! http code: ' . $info['http_code'] . ', body message: ' . $response);
}
else {

    $obj = json_decode($response);
    print_r($obj);
}
?>
On success, the above command returns the following response:
{
  "status": "OK"
}
On failure, the above command returns the following response:
{
  "status": "ERROR",
  "error": "Error cause"
}
Copy code
# pip install requests
import requests
import json
# Use this when using Session Key authentication
headers = { 'user_key': 'USER_KEY', 'Session_key' : 'SESSION_KEY', 'Content-type' : 'application/json' }
# When using Access Token authentication, use this instead:
# headers = { 'user_key': 'UserParam{user_key}', 'Access_token' : 'UserParam{access_token}', 'Content-type' : 'application/json' }
payload = """{
    "recipient": "+393471234567"
}"""

r = requests.post("https://app.gateway.smsend.it/API/v1.0/REST/2fa/request", headers=headers, data=payload)

if r.status_code != 200:
    print("Error! http code: " + str(r.status_code) + ", body message: " + str(r.content))
else:
    response = r.text

    obj = json.loads(response)
    print(unicode(obj))
On success, the above command returns the following response:
{
  "status": "OK"
}
On failure, the above command returns the following response:
{
  "status": "ERROR",
  "error": "Error cause"
}
Copy code
// Uses https://github.com/request/request
// npm install [-g] request

var request = require('request');

request({
    url: 'https://app.gateway.smsend.it/API/v1.0/REST/2fa/request',
    method: 'POST',
    headers: { 'user_key' : 'USER_KEY', 'Session_key' : 'SESSION_KEY' },

    json: true,
    body:     {
        "recipient": "+393471234567"
    },

    callback: function (error, responseMeta, response) {
        if (!error && responseMeta.statusCode == 200) {

        }
        else {
            console.log('Error! http code: ' + responseMeta.statusCode + ', body message: ' + response)
        }
    }
});
On success, the above command returns the following response:
{
  "status": "OK"
}
On failure, the above command returns the following response:
{
  "status": "ERROR",
  "error": "Error cause"
}
Copy code
require 'net/http'
require 'uri'
require 'json'

uri = URI.parse("https://app.gateway.smsend.it/API/v1.0/REST/2fa/request")
payload =     {
        "recipient": "+393471234567"
    }

# Create the HTTP objects
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true

request = Net::HTTP::Post.new(uri.request_uri)
request['Content-type'] = 'application/json'
request['user_key'] = 'USER_KEY'
request['Session_key'] = 'SESSION_KEY'
request.body = payload.to_json

# Send the request
responseData = http.request(request)
if responseData.code == "200"
  response = responseData.body

  obj = JSON.parse(response)
  puts obj
else
  puts "Error! http code: " + responseData.code + ", body message: " + responseData.body
end
On success, the above command returns the following response:
{
  "status": "OK"
}
On failure, the above command returns the following response:
{
  "status": "ERROR",
  "error": "Error cause"
}
Copy code
using System;
using System.IO;
using System.Text;
using System.Net;
using System.Collections.Specialized;

// We are using JSON.NET (http://www.newtonsoft.com/json)
using Newtonsoft.Json;

/*
 * The following code has been compiled and tested using the MONO
 * project.
 *
 * To compile using MONO:
 * mcs -r:Newtonsoft.Json.dll example.cs
 */
namespace RestApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            using (var wb = new WebClient())
            {
                // Setting the encoding is required when sending UTF8 characters!
                wb.Encoding = System.Text.Encoding.UTF8;

                try {
                    wb.Headers.Set(HttpRequestHeader.ContentType, "application/json");
                    wb.Headers.Add("user_key", "USER_KEY");
                    wb.Headers.Add("Session_key", "SESSION_KEY");

                String payload = "{" + 
                  "    \"recipient\": \"+393471234567\"" + 
                  "}";

                    String response = wb.UploadString("https://app.gateway.smsend.it/API/v1.0/REST/2fa/request", "POST", payload);

                    dynamic obj = JsonConvert.DeserializeObject(response);
                    Console.WriteLine(obj);
                } catch (WebException ex) {
                    var statusCode = ((HttpWebResponse)ex.Response).StatusCode;
                    var errorResponse = new StreamReader(ex.Response.GetResponseStream()).ReadToEnd();
                    Console.WriteLine("Error!, http code: " + statusCode + ", body message: ");
                    Console.WriteLine(errorResponse);
                }
            }
        }
    }
}
On success, the above command returns the following response:
{
  "status": "OK"
}
On failure, the above command returns the following response:
{
  "status": "ERROR",
  "error": "Error cause"
}
Copy code
#!/usr/bin/env perl

use warnings;
use strict;
use LWP::UserAgent;

# Install using Cpan: "cpan JSON URI"
use JSON;
use URI::Escape;

my $ua = LWP::UserAgent->new;

my $server_endpoint = "https://app.gateway.smsend.it/API/v1.0/REST/2fa/request";

my $req = HTTP::Request->new(POST => $server_endpoint);

$req->header('Content_type' => 'application/json');

# IMPORTANT: Not adding the ':' before 'user_key' and
# 'Session_key' will result in perl to automatically rewrite the
# headers as 'User-Key' and 'Session-Key', which is not supported
# by our API.
$req->header(':user_key' => $auth->[0],
             ':Session_key' => $auth->[1]);
my $payload = {
    "recipient" => "+393471234567"
};

$req->content(to_json($payload));
my $resp = $ua->request($req);
if ($resp->is_success && $resp->code == 200) {
  my $response = $resp->decoded_content;
  my $obj = from_json($response);

} else {
    my $error = $resp->decoded_content;
    my $code = $resp->code;
    print "Error!, http code: $code, body message: $error ";
}
						    
On success, the above command returns the following response:
{
  "status": "OK"
}
On failure, the above command returns the following response:
{
  "status": "ERROR",
  "error": "Error cause"
}

Verify a 2FA Pin

Verify that the pin inserted by the user is valid.

HTTP Headers

user_key / Session_key

HTTP Method

POST

HTTP Request

https://app.gateway.smsend.it/API/v1.0/REST/2fa/verify

Body Fields

Parameter Type Description Required Default
recipient String The phone number of the user. The format must be +1111111111 or 001111111111 Yes -
pin String The pin inserted by the user Yes -

Returns

Code Description
200 If status is OK the 2FA is valid, if status is ERROR the passed pin is wrong and the response includes the number of tries remaining.
400 [Bad request] Invalid recipient
401 [Unauthorized] User_key, Token or Session_key are invalid or not provided
404 [Not found] The User_key was not found
Copy code
# Session Key example
curl -XPOST 'https://app.gateway.smsend.it/API/v1.0/REST/2fa/request' -H 'Content-Type: application/json' \
-H 'user_key: USER_KEY' -H 'Session_key: SESSION_KEY' -d'
{
    "recipient": "+393471234567", 
    "pin": "12345"
}
'

# Access token example
curl -XPOST 'https://app.gateway.smsend.it/API/v1.0/REST/2fa/request' -H 'Content-Type: application/json' \
 -H 'user_key: USER_KEY' -H 'Access_token: ACCESS_TOKEN' -d'
{
    "recipient": "+393471234567", 
    "pin": "12345"
}
'
On success, the above command returns the following response:
{
  "status": "OK"
}
On wrong pin, the above command returns the following response:
{
  "status": "ERROR",
  "error": "Wrong pin",
  "triesRemaining": 2
}
On failure, the above command returns the following response:
{
  "status": "ERROR",
  "error": "Error cause"
}
Copy code
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.io.OutputStream;
import java.net.URL;

public class Main {
    public static void main(String[] args) {
        try {
            URL url = new URL("https://app.gateway.smsend.it/API/v1.0/REST/2fa/request");
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();

            conn.setRequestProperty("user_key", "USER_KEY");

            // Use this when using Session Key authentication
            conn.setRequestProperty("Session_key", "SESSION_KEY");
            // When using Access Token authentication, use this instead:
            // conn.setRequestProperty("Access_token", "UserParam{access_token}");

            conn.setRequestMethod("POST");

            conn.setRequestProperty("Accept", "application/json");
            conn.setRequestProperty("Content-type", "application/json");
            conn.setDoOutput(true);

            String payload = "{" + 
              "    \"recipient\": \"+393471234567\", " + 
              "    \"pin\": \"12345\"" + 
              "}";

            OutputStream os = conn.getOutputStream();
            os.write(payload.getBytes());
            os.flush();

            if (conn.getResponseCode() != 200) {
                // Print the possible error contained in body response
                String error = "";
                String output;
                BufferedReader errorbuffer = new BufferedReader(new InputStreamReader(conn.getErrorStream(), "UTF-8"));
                while ((output = errorbuffer.readLine()) != null) {
                    error += output;
                }
                System.out.println("Error! HTTP error code : " + conn.getResponseCode() +
                                   ", Body message : " + error);
                throw new RuntimeException("Failed : HTTP error code : " + conn.getResponseCode());
            }
            BufferedReader br =
                new BufferedReader(new InputStreamReader(conn.getInputStream()));

            String response = "";
            String output;
            while ((output = br.readLine()) != null) {
                response += output;
            }
            // You can parse the response using Google GSON or similar.
            // MyObject should be a class that reflect the JSON
            // structure of the response

            GsonBuilder builder = new GsonBuilder();
            Gson gson = builder.create();
            MyObject responseObj = gson.fromJson(response, MyObject.class);
            conn.disconnect();
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }
}
On success, the above command returns the following response:
{
  "status": "OK"
}
On wrong pin, the above command returns the following response:
{
  "status": "ERROR",
  "error": "Wrong pin",
  "triesRemaining": 2
}
On failure, the above command returns the following response:
{
  "status": "ERROR",
  "error": "Error cause"
}
Copy code
<?php

$payload = '{' . 
  '    "recipient": "+393471234567", ' . 
  '    "pin": "12345"' . 
  '}';

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://app.gateway.smsend.it/API/v1.0/REST/2fa/request');
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    'Content-type: application/json',
    'user_key: USER_KEY',
    // Use this when using session key authentication
    'Session_key: SESSION_KEY',
    // When using Access Token authentication, use this instead:
    // 'Access_token: UserParam{access_token}'
));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
$response = curl_exec($ch);
$info = curl_getinfo($ch);
curl_close($ch);

if ($info['http_code'] != 200) {
    echo('Error! http code: ' . $info['http_code'] . ', body message: ' . $response);
}
else {

    $obj = json_decode($response);
    print_r($obj);
}
?>
On success, the above command returns the following response:
{
  "status": "OK"
}
On wrong pin, the above command returns the following response:
{
  "status": "ERROR",
  "error": "Wrong pin",
  "triesRemaining": 2
}
On failure, the above command returns the following response:
{
  "status": "ERROR",
  "error": "Error cause"
}
Copy code
# pip install requests
import requests
import json
# Use this when using Session Key authentication
headers = { 'user_key': 'USER_KEY', 'Session_key' : 'SESSION_KEY', 'Content-type' : 'application/json' }
# When using Access Token authentication, use this instead:
# headers = { 'user_key': 'UserParam{user_key}', 'Access_token' : 'UserParam{access_token}', 'Content-type' : 'application/json' }
payload = """{
    "recipient": "+393471234567", 
    "pin": "12345"
}"""

r = requests.post("https://app.gateway.smsend.it/API/v1.0/REST/2fa/request", headers=headers, data=payload)

if r.status_code != 200:
    print("Error! http code: " + str(r.status_code) + ", body message: " + str(r.content))
else:
    response = r.text

    obj = json.loads(response)
    print(unicode(obj)) 
On success, the above command returns the following response:
{
  "status": "OK"
}
On wrong pin, the above command returns the following response:
{
  "status": "ERROR",
  "error": "Wrong pin",
  "triesRemaining": 2
}
On failure, the above command returns the following response:
{
  "status": "ERROR",
  "error": "Error cause"
}
Copy code
// Uses https://github.com/request/request
// npm install [-g] request

var request = require('request');

request({
    url: 'https://app.gateway.smsend.it/API/v1.0/REST/2fa/request',
    method: 'POST',
    headers: { 'user_key' : 'USER_KEY', 'Session_key' : 'SESSION_KEY' },

    json: true,
    body:     {
        "recipient": "+393471234567", 
        "pin": "12345"
    },

    callback: function (error, responseMeta, response) {
        if (!error && responseMeta.statusCode == 200) {

        }
        else {
            console.log('Error! http code: ' + responseMeta.statusCode + ', body message: ' + response)
        }
    }
});
						    
On success, the above command returns the following response:
{
  "status": "OK"
}
On wrong pin, the above command returns the following response:
{
  "status": "ERROR",
  "error": "Wrong pin",
  "triesRemaining": 2
}
On failure, the above command returns the following response:
{
  "status": "ERROR",
  "error": "Error cause"
}
Copy code
require 'net/http'
require 'uri'
require 'json'

uri = URI.parse("https://app.gateway.smsend.it/API/v1.0/REST/2fa/request")
payload =     {
        "recipient": "+393471234567", 
        "pin": "12345"
    }

# Create the HTTP objects
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true

request = Net::HTTP::Post.new(uri.request_uri)
request['Content-type'] = 'application/json'
request['user_key'] = 'USER_KEY'
request['Session_key'] = 'SESSION_KEY'
request.body = payload.to_json

# Send the request
responseData = http.request(request)
if responseData.code == "200"
  response = responseData.body

  obj = JSON.parse(response)
  puts obj
else
  puts "Error! http code: " + responseData.code + ", body message: " + responseData.body
end
On success, the above command returns the following response:
{
  "status": "OK"
}
On wrong pin, the above command returns the following response:
{
  "status": "ERROR",
  "error": "Wrong pin",
  "triesRemaining": 2
}
On failure, the above command returns the following response:
{
  "status": "ERROR",
  "error": "Error cause"
}
Copy code
using System;
using System.IO;
using System.Text;
using System.Net;
using System.Collections.Specialized;

// We are using JSON.NET (http://www.newtonsoft.com/json)
using Newtonsoft.Json;

/*
 * The following code has been compiled and tested using the MONO
 * project.
 *
 * To compile using MONO:
 * mcs -r:Newtonsoft.Json.dll example.cs
 */
namespace RestApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            using (var wb = new WebClient())
            {
                // Setting the encoding is required when sending UTF8 characters!
                wb.Encoding = System.Text.Encoding.UTF8;

                try {
                    wb.Headers.Set(HttpRequestHeader.ContentType, "application/json");
                    wb.Headers.Add("user_key", "USER_KEY");
                    wb.Headers.Add("Session_key", "SESSION_KEY");

                String payload = "{" + 
                  "    \"recipient\": \"+393471234567\", " + 
                  "    \"pin\": \"12345\"" + 
                  "}";

                    String response = wb.UploadString("https://app.gateway.smsend.it/API/v1.0/REST/2fa/request", "POST", payload);

                    dynamic obj = JsonConvert.DeserializeObject(response);
                    Console.WriteLine(obj);
                } catch (WebException ex) {
                    var statusCode = ((HttpWebResponse)ex.Response).StatusCode;
                    var errorResponse = new StreamReader(ex.Response.GetResponseStream()).ReadToEnd();
                    Console.WriteLine("Error!, http code: " + statusCode + ", body message: ");
                    Console.WriteLine(errorResponse);
                }
            }
        }
    }
}
On success, the above command returns the following response:
{
  "status": "OK"
}
On wrong pin, the above command returns the following response:
{
  "status": "ERROR",
  "error": "Wrong pin",
  "triesRemaining": 2
}
On failure, the above command returns the following response:
{
  "status": "ERROR",
  "error": "Error cause"
}
Copy code
#!/usr/bin/env perl

use warnings;
use strict;
use LWP::UserAgent;

# Install using Cpan: "cpan JSON URI"
use JSON;
use URI::Escape;

my $ua = LWP::UserAgent->new;

my $server_endpoint = "https://app.gateway.smsend.it/API/v1.0/REST/2fa/request";

my $req = HTTP::Request->new(POST => $server_endpoint);

$req->header('Content_type' => 'application/json');

# IMPORTANT: Not adding the ':' before 'user_key' and
# 'Session_key' will result in perl to automatically rewrite the
# headers as 'User-Key' and 'Session-Key', which is not supported
# by our API.
$req->header(':user_key' => $auth->[0],
             ':Session_key' => $auth->[1]);
my $payload = {
    "recipient" => "+393471234567", 
    "pin" => "12345"
};

$req->content(to_json($payload));
my $resp = $ua->request($req);
if ($resp->is_success && $resp->code == 200) {
  my $response = $resp->decoded_content;
  my $obj = from_json($response);

} else {
    my $error = $resp->decoded_content;
    my $code = $resp->code;
    print "Error!, http code: $code, body message: $error ";
}
On success, the above command returns the following response:
{
  "status": "OK"
}
On wrong pin, the above command returns the following response:
{
  "status": "ERROR",
  "error": "Wrong pin",
  "triesRemaining": 2
}
On failure, the above command returns the following response:
{
  "status": "ERROR",
  "error": "Error cause"
}