How to perform a two step verification

The 2 step verification service is used to confirm a user's claimed identity by utilizing a combination of two different components: a code and a phone number.

You can use this service for any authentication in any portal or mobile application.

In this example, we want to verify a user with mobile +306932XXXXXX, by sending a 4-digit code with SMS. We want the verification to remain active for 10 minutes and the maximum allowed retries to be 2.

Your Header should contain authorization and content type:

KEYVALUE
AuthorizationBearer {access_token}
Content-Typeapplication/json

The example request is shown below:

curl -X POST \
  https://connect.routee.net/2step \
  -H 'authorization: Bearer 12dc9fe4-7df4-4786-8d7a-a46d307687f4' \
  -H 'content-type: application/json' \
  -d '{
 "method":"sms",
 "type":"code",
 "recipient":"+306932XXXXXX",
 "template":"Your pin is @@pin",
 "lifetimeInSeconds":600,
 "maxRetries":2,
 "digits":4
}'
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "{\n \"method\":\"sms\",\n \"type\":\"code\",\n \"recipient\":\"+306932XXXXXX\",\n \"template\":\"Your pin is @@pin\",\n \"lifetimeInSeconds\":600,\n \"maxRetries\":2,\n \"digits\":4\n}");
Request request = new Request.Builder()
  .url("https://connect.routee.net/2step")
  .post(body)
  .addHeader("authorization", "Bearer 12dc9fe4-7df4-4786-8d7a-a46d307687f4")
  .addHeader("content-type", "application/json")
  .build();

Response response = client.newCall(request).execute();
var client = new RestClient("https://connect.routee.net/2step");
var request = new RestRequest(Method.POST);
request.AddHeader("content-type", "application/json");
request.AddHeader("authorization", "Bearer 12dc9fe4-7df4-4786-8d7a-a46d307687f4");
request.AddParameter("application/json", "{\n \"method\":\"sms\",\n \"type\":\"code\",\n \"recipient\":\"+306932XXXXXX\",\n \"template\":\"Your pin is @@pin\",\n \"lifetimeInSeconds\":600,\n \"maxRetries\":2,\n \"digits\":4\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://connect.routee.net/2step",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "{\n \"method\":\"sms\",\n \"type\":\"code\",\n \"recipient\":\"+306932XXXXXX\",\n \"template\":\"Your pin is @@pin\",\n \"lifetimeInSeconds\":600,\n \"maxRetries\":2,\n \"digits\":4\n}",
  CURLOPT_HTTPHEADER => array(
    "authorization: Bearer 12dc9fe4-7df4-4786-8d7a-a46d307687f4",
    "content-type: application/json"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("connect.routee.net")

payload = "{\n \"method\":\"sms\",\n \"type\":\"code\",\n \"recipient\":\"+306932XXXXXX\",\n \"template\":\"Your pin is @@pin\",\n \"lifetimeInSeconds\":600,\n \"maxRetries\":2,\n \"digits\":4\n}"

headers = {
    'authorization': "Bearer 12dc9fe4-7df4-4786-8d7a-a46d307687f4",
    'content-type': "application/json"
    }

conn.request("POST", "/2step", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
require 'uri'
require 'net/http'

url = URI("https://connect.routee.net/2step")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Post.new(url)
request["authorization"] = 'Bearer 12dc9fe4-7df4-4786-8d7a-a46d307687f4'
request["content-type"] = 'application/json'
request.body = "{\n \"method\":\"sms\",\n \"type\":\"code\",\n \"recipient\":\"+306932XXXXXX\",\n \"template\":\"Your pin is @@pin\",\n \"lifetimeInSeconds\":600,\n \"maxRetries\":2,\n \"digits\":4\n}"

response = http.request(request)
puts response.read_body
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://connect.routee.net/2step",
  "method": "POST",
  "headers": {
    "authorization": "Bearer 12dc9fe4-7df4-4786-8d7a-a46d307687f4",
    "content-type": "application/json"
  },
  "processData": false,
  "data": "{\n \"method\":\"sms\",\n \"type\":\"code\",\n \"recipient\":\"+306932XXXXXX\",\n \"template\":\"Your pin is @@pin\",\n \"lifetimeInSeconds\":600,\n \"maxRetries\":2,\n \"digits\":4\n}"
}	
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
#import <Foundation/Foundation.h>

NSDictionary *headers = @{ @"authorization": @"Bearer 12dc9fe4-7df4-4786-8d7a-a46d307687f4",
                           @"content-type": @"application/json" };
NSDictionary *parameters = @{ @"method": @"sms",
                              @"type": @"code",
                              @"recipient": @"+306932XXXXXX",
                              @"template": @"Your pin is @@pin",
                              @"lifetimeInSeconds": @600,
                              @"maxRetries": @2,
                              @"digits": @4 };

NSData *postData = [NSJSONSerialization dataWithJSONObject:parameters options:0 error:nil];

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://connect.routee.net/2step"]
                                                    cachePolicy:NSURLRequestUseProtocolCachePolicytimeoutInterval:10.0];

[request setHTTPMethod:@"POST"];
[request setAllHTTPHeaderFields:headers];
[request setHTTPBody:postData];

NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
                                 completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
                                    if (error) {
                                       NSLog(@"%@", error);
                                    } else {
                                       NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
                                       NSLog(@"%@", httpResponse);
                                    }
                                }];
[dataTask resume];

RESPONSE

{
   "trackingId":"2c1379bb-f296-43a4-bfb0-6c8b20a97425",
   "status":"Pending",
   "updatedAt":"2016-01-01T10:00:00.000Z"
}

An SMS is sent to mobile +306932XXXXXX, with body "Your pin is @@pin".
"@@pin" is replaced by a randomly generated numeric code with 4 digits, eg "1234".

Within the next 10 minutes, your user has to enter the code "1234" at your application to get authenticated.

When your user enters a code, a request should be made by your application, to verify the answer.
You use the trackingId parameter of the previous response as path parameter in the new request:

Your Header should contain authorization and content type:

KEYVALUE
Authorization:Bearer {access_token}
Content-Type:application/x-www-form-urlencoded

The example request is shown below:

curl --request POST \
  --url https://connect.routee.net/2step/2c1379bb-f296-43a4-bfb0-6c8b20a97425 \
  --header 'authorization: Bearer 12dc9fe4-7df4-4786-8d7a-a46d307687f4' \
  --header 'content-type: application/x-www-form-urlencoded' \
  --data answer=1234
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
RequestBody body = RequestBody.create(mediaType, "answer=1234");
Request request = new Request.Builder()
  .url("https://connect.routee.net/2step/2c1379bb-f296-43a4-bfb0-6c8b20a97425")
  .post(body)
  .addHeader("authorization", "Bearer 12dc9fe4-7df4-4786-8d7a-a46d307687f4")
  .addHeader("content-type", "application/x-www-form-urlencoded")
  .build();

Response response = client.newCall(request).execute();
var client = new RestClient("https://connect.routee.net/2step/2c1379bb-f296-43a4-bfb0-6c8b20a97425");
var request = new RestRequest(Method.POST);

request.AddHeader("content-type", "application/x-www-form-urlencoded");
request.AddHeader("authorization", "Bearer 12dc9fe4-7df4-4786-8d7a-a46d307687f4");
request.AddParameter("application/x-www-form-urlencoded", "answer=1234", ParameterType.RequestBody);

IRestResponse response = client.Execute(request);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://connect.routee.net/2step/2c1379bb-f296-43a4-bfb0-6c8b20a97425",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "answer=1234",
  CURLOPT_HTTPHEADER => array(
    "authorization: Bearer 12dc9fe4-7df4-4786-8d7a-a46d307687f4",
    "content-type: application/x-www-form-urlencoded"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("connect.routee.net")

payload = "answer=1234"

headers = {
    'authorization': "Bearer 12dc9fe4-7df4-4786-8d7a-a46d307687f4",
    'content-type': "application/x-www-form-urlencoded"
    }

conn.request("POST", "/2step/2c1379bb-f296-43a4-bfb0-6c8b20a97425", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
require 'uri'
require 'net/http'

url = URI("https://connect.routee.net/2step/2c1379bb-f296-43a4-bfb0-6c8b20a97425")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Post.new(url)
request["authorization"] = 'Bearer 12dc9fe4-7df4-4786-8d7a-a46d307687f4'
request["content-type"] = 'application/x-www-form-urlencoded'
request.body = "answer=1234"

response = http.request(request)
puts response.read_body
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://connect.routee.net/2step/2c1379bb-f296-43a4-bfb0-6c8b20a97425",
  "method": "POST",
  "headers": {
    "authorization": "Bearer 12dc9fe4-7df4-4786-8d7a-a46d307687f4",
    "content-type": "application/x-www-form-urlencoded"
  },
  "data": {
    "answer": "1234"
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
#import <Foundation/Foundation.h>

NSDictionary *headers = @{ @"authorization": @"Bearer 12dc9fe4-7df4-4786-8d7a-a46d307687f4",
                           @"content-type": @"application/x-www-form-urlencoded" };

NSMutableData *postData = [[NSMutableData alloc] initWithData:[@"answer=1234" dataUsingEncoding:NSUTF8StringEncoding]];

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://connect.routee.net/2step/2c1379bb-f296-43a4-bfb0-6c8b20a97425"]
                                                       cachePolicy:NSURLRequestUseProtocolCachePolicy
                                                   timeoutInterval:10.0];
[request setHTTPMethod:@"POST"];
[request setAllHTTPHeaderFields:headers];
[request setHTTPBody:postData];

NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
                                            completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
                                                if (error) {
                                                    NSLog(@"%@", error);
                                                } else {
                                                    NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
                                                    NSLog(@"%@", httpResponse);
                                                }
                                            }];
[dataTask resume];

RESPONSE
Since the answer is correct, the response will be:

{
   "trackingId":"2c1379bb-f296-43a4-bfb0-6c8b20a97425",
   "status":"Verified",
   "updatedAt":"2016-01-01T10:02:00.000Z"
}