API Documentation - Twizo

API Documentation

Introduction

Twizo’s API is a RESTful API and you can use any HTTP client in any programming language to communicate with our API. Request and response data are JSON formatted using UTF-8 encoding and URL encoded values. The only requirement to use our API is to create an account on our portal (https://register.twizo.com/ ).

API URL

We have located our servers at different locations around the globe. Which one for you is the best to use, depends on the location of your server. Each location has its own host. We have the following locations.
Location Host Callback host
Singapore * api-asia-01.twizo.com api-asia-01-out.twizo.com
Germany * api-eu-01.twizo.com api-eu-01-out.twizo.com
* = proposed based on your location

To ensure data privacy our API is only accessible via HTTPS so the traffic is encrypted. When our API performs a callback to deliver message results to you, it will come from the callback host listed above. Please make sure that you have white listed the callback hosts to ensure we can deliver the results to you.

Authentication

With each API call you will need to authenticate yourself via HTTP Basic Authentication. You can do this by setting the request headers. In the request headers you can set the username and password for the authentication. The user name and password must be base64 encoded. For the username you have to fill in ‘twizo’. If you use one of our libraries or SDK’s the username will be done for you, you just have to create an instance and set your API key and node you want to connect to. The base64 encoding of the username and password will be done by cURL and our libraries and SDK’s automatically.

The API key you can retrieve from our portal (https://portal.twizo.com/applications ).

curl -X POST https://api-asia-01.twizo.com/v1/verification/submit \
    -H "Accept: application/json" \
    -H "Content-Type: application/json; charset=utf8" \
    -u "twizo:<API_KEY>"
$twizo = Twizo\Api\Twizo::getInstance('<API_KEY>', 'api-asia-01.twizo.com');

Versioning

Currently we have 1 version of our API but in the future we might have other versions as well. We try to keep updates of the API backwards compatible but sometimes this is not possible. When this is the case a new version will be available. In the URL of the API you can specify the version you want to use. If you do not specify the version you will use the latest version. All examples on this documentation page and in the tutorials use the latest version of our API.

Example without version:
https://api-eu-01.twizo.com/verification/submit

Example with a version set:
https://api-eu-01.twizo.com/v1/verification/submit

Currently we have the following versions:
Version Release date Available until
1 February 1, 2017 December 31, 2017

Errors

The Twizo API uses standard HTTP status codes to indicate success or failure of your API calls. API calls, which are successful, have a HTTP status code in the range of 2xx. API calls, which have a failure, have a HTTP status code in the range of 4xx. The Twizo API can at least return HTTP status codes as shown in the table below. For some status codes an errorCode is added as well. Example response:
{
    "errorCode": 103,
    "type": "http:\/\/www.w3.org\/Protocols\/rfc2616\/rfc2616-sec10.html",
    "title": "Unprocessable Entity",
    "status": 422,
    "detail": "Invalid token."
}
 
HTTP status code Error code Description
200 OK The HTTP call is successful.
201 Created The Verification, SMS or Number Lookup is successfully created.
204 No content The SMS delivery reports and number lookup results are successfully confirmed or the backup codes are successfully deleted.
400 Bad Request The data you have submitted could not be properly JSON decoded.
401 Unauthorized You have provided an invalid API key. Get the correct API key from our portal (https://portal.twizo.com/applications ).
402 Payment Required 303 Your wallet is out of credit. Please topup your wallet to ensure you can use our service again.
403 Forbidden 301 Your account is disabled. Please contact our support team to help you further on this.
403 Forbidden 302 Your account is not enabled for the service. You can enable the service in our portal (https://portal.twizo.com/accounts ).
404 Not Found The Verification, SMS or Number Lookup with the specified messageId was not found.
406 Not Acceptable Cannot honor Accept type specified, only Accept header ‘application/json’ is supported. See Authentication example how to set it.
409 Conflict You have requested to create backup codes via a HTTP POST but the used identifier already exists. If you want to overwrite the existing entity use HTTP PUT instead.
415 Unsupported Media Type Invalid content-type specified, only Content-type header ‘application/json’ is supported. See Authentication example how to set it.
422 Unprocessable Entity 103 Invalid token. The token entered by the user does not match with the token sent by our API to the user.
423 Locked 101 The token you tried to verify was already verified, you are only allowed to check a certain token once.
102 The token you tried to verify is expired. The token was not entered by the user within the required time (validity).
104 The token you tried to verify is failed. The reason why it is failed is for example because the Verification service of the account is disabled. In that case no token is sent and the user entered a random token.
429 Too Many Requests You are sending too fast and your calls are throttled.
5xx An internal system error occurred. When this happens you can retry submitting the message.
For a full overview of HTTP status codes check the following HTTP Status Codes overview .

Credit balance

You can retrieve the credit balance of your wallet with a HTTP GET to the URL:
https://api-asia-01.twizo.com/wallet/getbalance

Example how to retrieve the credit balance of your wallet:

                    curl https://api-asia-01.twizo.com/v1/wallet/getbalance \
                        -H "Accept: application/json" \
                        -H "Content-Type: application/json; charset=utf8" \
                        -u "twizo:<API_KEY>"
                    
                    $balance = $twizo->getBalance();
                    

The API will return the HTTP status 200 OK with a response in JSON format like this:

{
    "credit": 13.37,
    "currencyCode": "usd",
    "freeVerifications": 42,
    "wallet": "Default wallet"
}
                

The below table explains the fields you will find in the response:

Field Description
credit Float, not null. The current credit balance of your wallet. Can be negative in certain situations.
currencyCode String, not null. This is a 3-digit ISO 4217 code of the currency of your wallet.
freeVerifications Integer, not null. The number of free verifications you have left for this month.
wallet String, not null. The name of your wallet.

Verification

With our verification service you can easily integrate Two Factor Authentication (2FA) into your application. We will describe in a few simple steps how to do it.

First you start with submitting a verification by doing a HTTP POST to our API with URL:
https://api-asia-01.twizo.com/verification/submit

You will need to specify in JSON format the recipient you want the token to receive and the type, SMS or call (Text-to-speech). An example on how to do it:

curl -X POST https://api-asia-01.twizo.com/v1/verification/submit \
    -H "Accept: application/json" \
    -H "Content-Type: application/json; charset=utf8" \
    -u "twizo:<API_KEY>" \
    -d '{
        "recipient" : "1234567890"
    }'
$verification = $twizo->createVerification('1234567890');
$verification->send();
When you have posted the verification successfully, the API will return the HTTP status 200 OK with a response in JSON format like this:
{
    "applicationTag": "Default application",
    "tokenLength": null,
    "tokenType": null,
    "createdDateTime": "2016-11-29T11:11:17+00:00",
    "dcs": null,
    "language": null,
    "messageId": "asia-01-1.17172.ver583d6255ae66f2.27354409",
    "reasonCode": null,
    "recipient": "1234567890",
    "salesPrice": null,
    "salesPriceCurrencyCode": null,
    "sender": null,
    "senderNpi": null,
    "senderTon": null,
    "sessionId": "3f2d893f-a663-4919-9472-e8b7f4b61fa7",
    "status": "no status",
    "statusCode": 0,
    "tag": null,
    "bodyTemplate": null,
    "type": "sms",
    "validity": null,
    "validUntilDateTime": null,
    "_links": {
        "self": {
            "href": "https:\/\/api-asia-01.twizo.com\/v1\/verification\/submit\/asia-01-1.17172.ver583d6255ae66f2.27354409"
        }
    }
}
The returned JSON response will contain a messageId field. This messageId must be used when you want to verify the token sent to the phone. See Verification status for more information about the other fields returned in the response.

Verification parameters

When you request a verification you can specify several parameters. Below you can find an overview of all parameters.

Parameter Description
recipient This is a mandatory string parameter. The recipient is a single phone number in international format. The phone number can be a mobile number or a fixed phone number.
type This is an optional string parameter. The type defines how the token will be send to the phone. Possible values are: ‘sms’ or ‘call’. The default value is ‘sms’.
tokenLength This is an optional integer parameter. The tokenLength defines the length of the token. The minimum value is 4 and the maximum value 10. The default value is 6. When you set the tokenLength, you have to set the tokenType as well.
tokenType This is an optional string parameter. Possible values are ‘numeric’ and ‘alphanumeric’. Numeric token will only contain the digits 0-9. For alphanumeric the token contains the digits 0-9 and characters a-z (lowercase). The default value of the tokenType is ‘numeric’. When you set the tokenType, you have to set the tokenLength as well.
tag This is an optional string parameter. The tag is a free text parameter you can use for your own reference. The maximum length of the tag is 30 characters. The tag parameter is returned in the result and you can use it for reporting purposes on your side.
sessionId This is an optional string parameter. If it is not set the API will automatically generate the value. See ‘Verification session’ for more information. The maximum length of the sessionId is 54 characters.
validity This is an optional integer parameter. The validity specifies how long the token is valid. The validity is in seconds. If the token is not verified within this time, the token is expired. The minimum value of the validity is 5 seconds and the maximum value is 3600 seconds (= 1 hour). The default value is 60 seconds.
The Type parameter specifies if an SMS will be send or a call will be made. For SMS there are some additional parameters, which can be set.
bodyTemplate This is an optional string parameter. The body template in case an SMS needs to be send. The body template must contain the tag ‘%token%’ which will be used by the system to replace it with the actual token to be send to the end user. The maximum length on the body template is for GSM-7 alphabet 160 characters and for Unicode maximum 70 characters. This is including the token which will be inserted by the system. So if you set a tokenLength of 8, the max length of the bodyTemplate is 160-8=152 characters excluding the text ‘%token%’. If you do not set the tokenLength, the API will need to consider the maximum length of the token (10) for the maximum bodyTemplate length, so in that case the bodyTemplate can have a maximum length of 150 characters for GSM-7 and 60 for Unicode. Concatenated messages are not possible for these SMS messages. See our tutorial ‘Unicode’ for more information on the maximum length of the body. Default value for the bodyTemplate is: Your verification token is: %token%
sender This is an optional string parameter. The sender is what the receiver of the SMS see as the submitter of the SMS. See our tutorial ‘Sender’ for more information. The default value for the sender is ‘Twizo’.
senderTon This is an optional integer parameter. If it is not set the API will automatically detect the value. See our tutorial ‘Sender’ for more information.
senderNpi This is an optional integer parameter. If it is not set the API will automatically detect the value. See our tutorial ‘Sender’ for more information.
dcs This is an optional integer parameter. With the DCS parameter you can specify the character set of the bodyTemplate. For GSM-7 the value should be 0 and for Unicode the value should be 8. The default value is 0. See our tutorial ‘Unicode’ for more information.

Verify token

When the user received the token and entered it in your website, the API will verify the token with the token we have sent. You will have to do a GET to the URL:
https://api-asia-01.twizo.com/verification/submit/<messageId>?token=<token>

You will have to put the following parameters in the URL:

<messageId> The messageId returned with the verification submit.
<token> The token entered by the user and you want to verify with the token we sent to the user.

Please note: you can verify the token for a session ID only once! This is to prevent users will try to guess a token.

Example code to verify a token:
curl https://api-asia-01.twizo.com/v1/verification/submit/<MESSAGE_ID>?token=<TOKEN> \
    -H "Accept: application/json" \
    -H "Content-Type: application/json; charset=utf8" \
    -u "twizo:<API_KEY>"
try {
    $result = $twizo->getTokenResult($verification->getMessageId(), '12345');

    print 'Success' . PHP_EOL;
} catch (Verification\Exception $e) {
    print 'Failed: ' . $e->getMessage() . PHP_EOL;
} catch (Twizo\Api\Exception $e) {
    print 'Exception: ' . $e->getMessage() . PHP_EOL;
}

When the verification is successful you get a HTTP status 200 OK and a response where the ‘statusCode’ field has the value 1 and the ‘status’ field has the value ‘success’ like below example in JSON format:

{
    "applicationTag": "Default application",
    "tokenLength": 6,
    "tokenType": "numeric",
    "createdDateTime": "2016-11-30T13:17:44+00:00",
    "dcs": 0,
    "language": null,
    "messageId": "asia-01-1.25569.ver583ed178a52521.24988267",
    "reasonCode": null,
    "recipient": "1234567890",
    "salesPrice": 0,
    "salesPriceCurrencyCode": "eur",
    "sender": "Twizo",
    "senderNpi": 0,
    "senderTon": 5,
    "sessionId": "3f2d893f-a663-4919-9472-e8b7f4b61fa7",
    "status": "success",
    "statusCode": 1,
    "tag": null,
    "bodyTemplate": "Your verification token is: %token%",
    "type": "sms",
    "validity": 30,
    "validUntilDateTime": "2016-11-30T13:18:14+00:00",
    "_links": {
        "self": {
            "href": "https:\/\/api-asia-01.twizo.com\/v1\/verification\/submit\/asia-01-1.25569.ver583ed178a52521.24988267"
        }
    }
}

Verification status

You can check the status of a verification with a simple GET and specifying the ‘messageId’ returned in the submit of the verification:
curl https://api-asia-01.twizo.com/v1/verification/submit/<MESSAGE_ID> \
    -H "Accept: application/json" \
    -H "Content-Type: application/json; charset=utf8" \
    -u "twizo:<API_KEY>"
$result = $twizo->getVerification($verification->getMessageId());
This will return in JSON format the following:
{
    "applicationTag": "Default application",
    "tokenLength": 6,
    "tokenType": "numeric",
    "createdDateTime": "2016-11-29T11:16:03+00:00",
    "dcs": 0,
    "language": null,
    "messageId": "asia-01-1.18667.ver583d637356cd58.88711156",
    "reasonCode": null,
    "recipient": "1234567890",
    "salesPrice": 0.024,
    "salesPriceCurrencyCode": "eur",
    "sender": "Twizo",
    "senderNpi": 0,
    "senderTon": 5,
    "sessionId": "3f2d893f-a663-4919-9472-e8b7f4b61fa7",
    "status": "success",
    "statusCode": 1,
    "tag": null,
    "bodyTemplate": "Your verification token is: %token%",
    "type": "sms",
    "validity": 30,
    "validUntilDateTime": "2016-11-29T11:16:33+00:00",
    "_links": {
        "self": {
            "href": "https:\/\/api-asia-01.twizo.com\/v1\/verification\/submit\/asia-01-1.18667.ver583d637356cd58.88711156"
        }
    }
}
The below table explains the fields you will find in the response:
Field Description
applicationTag String, not null. The application used for sending the verification.
tokenLength Integer, can be null. The length of the token as specified when sending the verification or the default value (6).
tokenType String, can be null. The type of the token as specified when sending the verification or the default value (numeric).
createdDateTime String, not null. The datetime the verification was received by the API. The datetime is in ISO-8601 format.
dcs Integer, can be null. The DCS value as specified when sending the verification.
language String, can be null. Currently not used yet.
messageId String, not null. The unique identifier, generated by the API, of the verification.
reasonCode Integer, can be null. When the verification is rejected or failed a reasonCode can be given explaining the cause of the rejection. See further down below for an overview of possible reasonCodes
recipient String, not null. The phone number as specified when sending the verification, the token must be send to.
salesPrice Float, can be null. The sales price of the verification. When the verification was a free monthly verification the sales price is 0.
salesPriceCurrencyCode String, can be null. The currency code of the salesPrice field. The value can be ‘eur’, ‘usd’ or ‘sgd’. The currency code is defined by the currency of your wallet.
sender String, can be null. The sender of the token in case of an SMS as specified when sending the verification or the default value (Twizo).
senderNpi Integer, can be null. The senderNpi of the token in case of an SMS as specified when sending the verification or the automatically detected value by the API. See our tutorial ‘Sender’ for more information.
senderTon Integer, can be null. The senderTon of the token in case of an SMS as specified when sending the verification or the automatically detected value by the API. See our tutorial ‘Sender’ for more information.
sessionId String, not null. The sessionId generated by the API when it was left out with the verification request or the sessionId you specified at the verification request. See ‘Verification session‘ for more information.
status String, not null. The status of the verification. The status and statusCode fields are bound together and can have the following values:
0 no status The token is generated and sent to the phone.
1 success The token is successfully verified. The entered token matches with the token sent to the phone.
2 rejected The verification is rejected by the system and no token is sent to the phone. The reasonCode field indicates the reason why it is rejected. See further down below for an overview of possible reasonCodes.
3 expired The verification is expired as the token was not verified within the specified validity time.
4 failed The verification is failed as the entered token didn’t match with the token sent to the phone. The reasonCode field indicates the reason why it is rejected. See further down below for an overview of possible reasonCodes.
statusCode Integer, not null. See ‘status’ field for more information.
tag String, can be null. The tag as specified when sending the verification.
bodyTemplate String, can be null. The tag value as specified when sending the verification or the default value (Your verification token is: %token%)
type String, not null. The type as specified when sending the verification or the default value (sms)
validity Integer, not null. The validity in seconds as specified when sending the verification or the default value (60)
validUntilDateTime String, not null. The datetime until when the verification is valid. This is calculated by the API based on the validity field.
_links HATEOAS (Hypermedia as the Engine of Application State) is a constraint of the REST application architecture. A hypermedia-driven site provides information to navigate the site’s REST interfaces dynamically by including hypermedia links with the responses. See HATEOAS for more information.
The status of a verification can be checked up to 24 hours after the validity. After that the verification is removed from the API and you will receive a HTTP status code 404 Not Found. You can however still check the verification in the portal via Message details .

Verification session

When a user logs in to your website you request a verification and the API will send a token to the user. If for some reason the user does not receive the token or enters the token incorrect, you have to do a new verification request. This will continue until the user entered the correct token. All these verifications for this user login are part of the same session.

When you submit the first verification request and leave the sessionId parameter of the request empty, the API generates a unique sessionId which is returned in the result. If you set this sessionId in the next verification request for the user login, we store that sessionId with both verifications. That way we keep track of the sessions and you can do analysis of how often a verification fails in a session. This way you can improve the success rate of your verifications.

Reason codes

When a verification has status ‘2 – rejected’ or ‘4 – failed’ a reasonCode can be returned. The following reason codes can be returned:
Reason code Description
1 Insufficient credits
2 Verification service not enabled for account
3 Unsupported destination country or operator
4 Account not allowed to send verifications
5 Verification failed due to system error
6 Verification expired
7 Token not delivered to phone as phone is busy, hang up, did not answer, could not receive message, etc.
8 Token not delivered to phone due to network problems
10 Content of the bodyTemplate is not allowed by the network

Verification widget

With the verification widget you can easily integrate our verification service without the need of implementing forms to handle the verification. For more information how to integrate the widget, checkout our widget guide. When you create a widget verification session and start the widget, the widget will create one or more verifications. Those verifications will have as as sessionId the session token of the widget verification session.

You start a widget verification session by doing a HTTP POST to our API with URL:
https://api-asia-01.twizo.com/widget/session

You will need to specify in JSON format the recipient you want the token to be send to. An example on how to do it:

curl -X POST https://api-asia-01.twizo.com/v1/widget/session \
    -H "Accept: application/json" \
    -H "Content-Type: application/json; charset=utf8" \
    -u "twizo:<API_KEY>" \
    -d '{
        "recipient" : "601234500000"
    }'
$widgetSession = $twizo->createWidgetSession(array('sms','call'));
$widgetSession->setRecipient('601234500000');
$widgetSession->create();
When you have posted the widget verification session successfully, the API will return the HTTP status 200 OK with a response in JSON format like this:
{
    "sessionToken": "asia-01_1161130_wid59003566562fe8.59122114e17b",
    "applicationTag": "Default application",
    "bodyTemplate": "Your verification token is %token%",
    "createdDateTime": "2017-04-26T05:51:34+00:00",
    "dcs": null,
    "language": null,
    "recipient": "601234500000",
    "sender": "Twizo",
    "senderNpi": null,
    "senderTon": null,
    "tag": null,
    "tokenLength": 6,
    "tokenType": "numeric",
    "requestedTypes": [
        "sms",
        "call"
    ],
    "allowedTypes": [
        "sms",
        "call"
    ],
    "validity": null,
    "status": "no status",
    "statusCode": 0,
    "backupCodeIdentifier": null,
    "verificationIds": [],
    "verification": null,
    "_links": {
        "self": {
            "href": "https:\/\/api-asia-01.twizo.com\/v1\/widget\/verification\/session\/asia-01_1161130_wid59003566562fe8.59122114e17b"
        }
    }
}
The returned JSON response will contain a sessionToken field. This sessionToken you will need to open the widget. See the widget guide for more information. See status for more information about the other fields returned in the response.

Verification widget parameters

When you request a widget verification session you can specify several parameters. Below you can find an overview of all parameters.

Parameter Description
allowedTypes This is a mandatory array parameter. The allowedTypes defines which verification types can be used with the widget. Possible values are: ‘sms’, ‘call’ or ‘backupcode’. The default value is [‘sms’, ‘call’]. The first type you set as allowed type will be the first verification the widget will perform. The API will filter out certain types when that option is not available for the user. For example when you set ‘backupcode’ but for the backupCodeIdentifier you specified the API cannot find backup codes, the type will be removed. See ‘requestedTypes’ and ‘allowedTypes’ in the status result for more information.
recipient This is a mandatory string parameter when for the allowedTypes ‘sms’ or ‘call’ is included. The recipient is a single phone number in international format. The phone number can be a mobile number or a fixed phone number.
backupCodeIdentifier This is a mandatory string parameter when for the allowedTypes ‘backupcode’ is included. The backupCodeIdentifier is the identifier you used for creating the backup codes for the user.
tokenLength This is an optional integer parameter. The tokenLength defines the length of the token. The minimum value is 4 and the maximum value 10. The default value is 6. When you set the tokenLength, you have to set the tokenType as well.
tokenType This is an optional string parameter. Possible values are ‘numeric’ and ‘alphanumeric’. Numeric token will only contain the digits 0-9. For alphanumeric the token contains the digits 0-9 and characters a-z (lowercase). The default value of the tokenType is ‘numeric’. When you set the tokenType, you have to set the tokenLength as well.
tag This is an optional string parameter. The tag is a free text parameter you can use for your own reference. The maximum length of the tag is 30 characters. The tag parameter is returned in the result and you can use it for reporting purposes on your side.
The Type parameter specifies if an SMS will be send or a call will be made. For SMS there are some additional parameters, which can be set.
bodyTemplate This is an optional string parameter. The body template in case an SMS needs to be send. The body template must contain the tag ‘%token%’ which will be used by the system to replace it with the actual token to be send to the end user. The maximum length on the body template is for GSM-7 alphabet 160 characters and for Unicode maximum 70 characters. This is including the token which will be inserted by the system. So if you set a tokenLength of 8, the max length of the bodyTemplate is 160-8=152 characters excluding the text ‘%token%’. Concatenated messages are not possible for these SMS messages. See our tutorial ‘Unicode’ for more information on the maximum length of the body. Default value for the bodyTemplate is: Your verification token is: %token%
sender This is an optional string parameter. The sender is what the receiver of the SMS see as the submitter of the SMS. See our tutorial ‘Sender’ for more information. The default value for the sender is ‘Twizo’.
senderTon This is an optional integer parameter. If it is not set the API will automatically detect the value. See our tutorial ‘Sender’ for more information.
senderNpi This is an optional integer parameter. If it is not set the API will automatically detect the value. See our tutorial ‘Sender’ for more information.
dcs This is an optional integer parameter. With the DCS parameter you can specify the character set of the bodyTemplate. For GSM-7 the value should be 0 and for Unicode the value should be 8. The default value is 0. See our tutorial ‘Unicode’ for more information.

Verification widget status

You can check the status of a widget verification session with a simple GET and specifying the sessionToken and recipient and/or backupCodeIdentifier. If you have to set recipient, backupCodeIdentifier or both depends on how the verification session is created. The values you have set when the verification session was created is also needed when you check the status. Check the status of a verification session:
curl https://api-asia-01.twizo.com/v1/widget/session/<SESSION_TOKEN>?recipient=<RECIPIENT>&backupCodeIdentifier=<IDENTIFIER> \
    -H "Accept: application/json" \
    -H "Content-Type: application/json; charset=utf8" \
    -u "twizo:<API_KEY>"
$result = $twizo->getWidgetSession($widgetSession->getSessionToken(), $widgetSession->getRecipient(), $widgetSession->getBackupCodeIdentifier());
This will return in JSON format the following:
{
    "sessionToken": "asia-01_1161130_wid59003566562fe8.59122114e17b",
    "applicationTag": "Default application",
    "bodyTemplate": "Your verification token is %token%",
    "createdDateTime": "2017-04-26T05:51:34+00:00",
    "dcs": null,
    "language": null,
    "recipient": "601234500000",
    "sender": "Twizo",
    "senderNpi": null,
    "senderTon": null,
    "tag": null,
    "tokenLength": 6,
    "tokenType": "numeric",
    "requestedTypes": [
        "sms",
        "call"
    ],
    "allowedTypes": {
        "1": "sms",
        "2": "call"
    },
    "validity": null,
    "status": "success",
    "statusCode": 1,
    "backupCodeIdentifier": null,
    "verificationIds": [
        "asia-01-1.17172.ver583d6255ae66f2.27354409",
        "asia-01-1.18352.ver529c5e45ae72a2.83645283"
    ],
    "verification": {
            "applicationTag": "Default application",
            "bodyTemplate": null,
            "createdDateTime": "2017-04-26T05:51:34+00:00",
            "dcs": null,
            "language": null,
            "messageId": "asia-01-1.18352.ver529c5e45ae72a2.83645283",
            "reasonCode": null,
            "recipient": "601234500000",
            "salesPrice": 0.07,
            "salesPriceCurrencyCode": "eur",
            "sender": null,
            "senderNpi": null,
            "senderTon": null,
            "sessionId": "asia-01_1161130_wid59003566562fe8.59122114e17b",
            "status": "success",
            "statusCode": 1,
            "tag": null,
            "tokenLength": null,
            "tokenType": null,
            "type": "sms",
            "validity": null,
            "validUntilDateTime": null,
            "webHook": null,
            "_links": {
                "self": {
                    "href": "https:\/\/api-asia-01.twizo.com\/v1\/verification\/submit\/asia-01-1.18352.ver529c5e45ae72a2.83645283"
                }
            },
    "_links": {
        "self": {
            "href": "https:\/\/api-asia-01.twizo.com\/v1\/widget\/verification\/session\/asia-01_1161130_wid59003566562fe8.59122114e17b"
        }
    }
}
The below table explains the fields you will find in the response:
Field Description
sessionToken String, not null. The unique id identifying this widget verification session.
applicationTag String, not null. The application used for sending the verification.
tokenLength Integer, can be null. The length of the token as specified when sending the verification or the default value (6).
tokenType String, can be null. The type of the token as specified when sending the verification or the default value (numeric).
createdDateTime String, not null. The datetime the verification was received by the API. The datetime is in ISO-8601 format.
dcs Integer, can be null. The DCS value as specified when sending the verification.
language String, can be null. Currently not used yet.
recipient String, not null. The phone number as specified when sending the verification, the token must be send to.
sender String, can be null. The sender of the token in case of an SMS as specified when sending the verification or the default value (Twizo).
senderNpi Integer, can be null. The senderNpi of the token in case of an SMS as specified when sending the verification or the automatically detected value by the API. See our tutorial ‘Sender’ for more information.
senderTon Integer, can be null. The senderTon of the token in case of an SMS as specified when sending the verification or the automatically detected value by the API. See our tutorial ‘Sender’ for more information.
status String, not null. The status of the widget verification session. The status and statusCode fields are bound together and can have the following values:
0 no status The widget verification session is created and waiting for the widget to get started and performing verifications.
1 success The widget verification session is successfully verified. The entered token matches with the token sent to the phone.
2 expired The widget verification session is expired as the token was not verified within the specified validity time of the widget verification session.
3 max_attempts The verification is failed the maximum number of attempts of sending verification has reached.
statusCode Integer, not null. See ‘status’ field for more information.
tag String, can be null. The tag as specified when sending the verification.
bodyTemplate String, can be null. The tag value as specified when sending the verification or the default value (Your verification token is: %token%)
requestedTypes Array, not null. The allowed types as specified when creating the widget verification session.
allowedTypes Array, not null. The allowed types as specified when creating the widget verification session minus types not available for the user. For example when you set ‘backupcode’ but for the backupCodeIdentifier you specified the API cannot find backup codes, the type will be removed.
validity Integer, not null. The validity in seconds as specified when sending the verification or the default value (60).
backupCodeIdentifier String, can be null. The backupCodeIdentifier if set when creating the session.
verificationIds Array, not null. An array with verification ID’s performed during the session.
verification Verification object, can be null. When the session is successfull, this parameter contains the successful verification object.
_links HATEOAS (Hypermedia as the Engine of Application State) is a constraint of the REST application architecture. A hypermedia-driven site provides information to navigate the site’s REST interfaces dynamically by including hypermedia links with the responses. See HATEOAS for more information.
The status of a widget verification session can be checked up to 24 hours after the validity. After that the widget verification session is removed from the API and you will receive a HTTP status code 404 Not Found. The verifications performed by the widget, you can find in the portal via Message details by filling in the session token in the session Id field in the search form.

Backup codes

If you lose your phone(s) or otherwise can’t receive codes via SMS, voice call, or Google Authenticator, you can use backup codes to sign in. With our backup code feature you can generate 10 backup codes for a user. When the user loses his phone or can’t receive the verification token via SMS or a voice all, he can use a backup code to verify.

To start you first need to create backup codes for a user. When the backup codes are generated by the API you can show them to the user and the user can store them in a safe location. We advise you not to store the backup codes on your server, only the user should store them. Once the backup codes are generated the user can use them when needed. The backup codes will be stored on our servers. Each time the user uses a backup code, the number of remaining backup codes left will be returned by the API. Inform the user in time when he is almost out of backup codes, as when he is out of backup codes he can’t verify anymore. To generate new backup codes the user doesn’t have to wait until he used the last one, he can generate new backup codes at any time. When generating new backup codes the old ones will be removed and cannot be used anymore.

Backup codes you have generated for a user will be available on all our API nodes. So when you generated backup codes on one of our Asia nodes, you can verify a backup code also on one of our Europe nodes.

Create backup codes

You can create backup codes by doing a HTTP POST to the API with URL:
https://api-asia-01.twizo.com/backupcode

You will need to specify in JSON format the identifier you want the backup codes to be updated. An example on how to do it:

curl -X POST https://api-asia-01.twizo.com/v1/backupcode \
    -H "Accept: application/json" \
    -H "Content-Type: application/json; charset=utf8" \
    -u "twizo:<API_KEY>" \
    -d '{
        "identifier" : "<IDENTIFIER>"
    }'
$backupCode = $twizo->createBackupCode('<IDENTIFIER>');
$backupCode->create();

When the backup codes are generated successfully a HTTP status 201 is returned. The response will contain the generated backup codes like below example in JSON format:

{
    "identifier": "1234567890",
    "amountOfCodesLeft": 10,
    "codes": [
        "73502977",
        "64553227",
        "61260614",
        "91387132",
        "74052942",
        "29371709",
        "22740780",
        "43369151",
        "51168501",
        "19402795"
    ],
    "createdDateTime": "2017-05-19T08:51:01+00:00",
    "_links": {
        "self": {
            "href": "https:\/\/api-asia-01.twizo.com\/v1\/backupcode\/1234567890"
        }
    }
}

When you want to generate new backup codes for a user, please check Update backup codes.

Verify backup code

When the user uses a backup code and entered it in your website, the API will verify the backup code with the backup codes generated for the user. You will have to do a GET to the URL:
https://api-asia-01.twizo.com/backupcode/<identifier>?token=<backupCode>

You will have to put the following parameters in the URL:

<identifier> The identifier you used to generate the backup codes for the user.
<backupCode> The backup code entered by the user and you want to verify with the generated backup codes for the user.

Please note: you can successfully verify a backup code only once!

Example code to verify a backup code:
curl https://api-asia-01.twizo.com/v1/backupcode/<IDENTIFIER>?token=<BACKUP_CODE> \
    -H "Accept: application/json" \
    -H "Content-Type: application/json; charset=utf8" \
    -u "twizo:<API_KEY>"
$backupCode = $twizo->createBackupCode('<IDENTIFIER>');
$backupCode->verify('<BACKUP_CODE>');

When the backup code is successfully verified you get a HTTP status 200 OK and a response with the number of remaining backup codes left for the user. Below an example response in JSON format:

{
    "identifier": "1",
    "amountOfCodesLeft": 9,
    "codes": [],
    "createdDateTime": "2017-05-19T13:06:40+00:00",
    "_embedded": {
        "verification": {
            "applicationTag": "Default application",
            "bodyTemplate": null,
            "createdDateTime": "2017-05-19T13:06:40+00:00",
            "dcs": null,
            "language": null,
            "messageId": "asia-01-1.7926.ver5955ec8f6e9640.25672922",
            "reasonCode": null,
            "recipient": "",
            "salesPrice": null,
            "salesPriceCurrencyCode": null,
            "sender": null,
            "senderNpi": null,
            "senderTon": null,
            "sessionId": "",
            "status": "success",
            "statusCode": 1,
            "tag": null,
            "tokenLength": null,
            "tokenType": null,
            "type": "backupcode",
            "validity": null,
            "validUntilDateTime": null,
            "webHook": null,
            "_links": {
                "self": {
                    "href": "https:\/\/api-asia.twizo.com\/v1\/verification\/submit\/asia-01-1.7926.ver5955ec8f6e9640.25672922"
                }
            }
        }
    },
    "_links": {
        "self": {
            "href": "https:\/\/api-asia-01.twizo.com\/v1\/backupcode\/1234567890"
        }
    }
}

Check remaining backup codes

To check how many backup code a user has left you will have to do a GET to the URL:
https://api-asia-01.twizo.com/backupcode/<identifier>

You will have to put the following parameters in the URL:

<identifier> The identifier you used for generating the backup codes for the user.

Example code to get the number of remaining backup codes left:

curl https://api-asia-01.twizo.com/v1/backupcode/<identifier> \
    -H "Accept: application/json" \
    -H "Content-Type: application/json; charset=utf8" \
    -u "twizo:<API_KEY>"
$backupCode = $twizo->getBackupCode('<IDENTIFIER>');

You will get a response like the below example in JSON format:

{
    "identifier": "1234567890",
    "amountOfCodesLeft": 9,
    "codes": [],
    "createdDateTime": "2017-05-19T13:06:40+00:00",
    "_links": {
        "self": {
            "href": "https:\/\/api-asia-01.twizo.com\/v1\/backupcode\/1234567890"
        }
    }
}

Update backup codes

When you have generated backup codes for a user before, you can update the backup codes. When you update the backup codes of a user, new backup codes will be generated and the old remaining backup codes will be invalid. You can update backup codes by doing a HTTP PUT to the API with URL:
https://api-asia-01.twizo.com/backupcode/<IDENTIFIER>

You will have to put the following parameters in the URL:

<IDENTIFIER> The unique identifier for your user. The identifier parameter is a string with a maximum length of 64 characters.

Also you will need to specify in JSON format the identifier you want the backup codes to be updated. An example on how to do it:

curl -X PUT https://api-asia-01.twizo.com/v1/backupcode/<IDENTIFIER> \
    -H "Accept: application/json" \
    -H "Content-Type: application/json; charset=utf8" \
    -u "twizo:<API_KEY>"
    -d '{
        "identifier" : "<IDENTIFIER>"
    }'
$backupCode = $twizo->createBackupCode('<IDENTIFIER>');
$backupCode->update();

When the backup codes are generated successfully a HTTP status 200 is returned. The response will contain the generated backup codes like below example in JSON format:

{
    "identifier": "1234567890",
    "amountOfCodesLeft": 10,
    "codes": [
        "73502977",
        "64553227",
        "61260614",
        "91387132",
        "74052942",
        "29371709",
        "22740780",
        "43369151",
        "51168501",
        "19402795"
    ],
    "createdDateTime": "2017-05-19T08:51:01+00:00",
    "_links": {
        "self": {
            "href": "https:\/\/api-asia-01.twizo.com\/v1\/backupcode\/1234567890"
        }
    }
}

Delete backup codes

You can delete the backup codes of a user. The user will then not be able to use any of backup codes generated before. To delete the backup codes of a user you have to do a DELETE to our API with the ‘identifier’. When the API has deleted the backup code you will get a HTTP status 204 ‘No content’ returned from the API.
curl -X DELETE https://api-asia-01.twizo.com/v1/backupcode/<identifier> \
    -H "Accept: application/json" \
    -H "Content-Type: application/json; charset=utf8" \
    -u "twizo:<API_KEY>"
$backupCode = $twizo->createBackupCode('<IDENTIFIER>');
$backupCode->delete();

You will get a response like the below example in JSON format:

{
    "identifier": "1234567890",
    "amountOfCodesLeft": 9,
    "codes": [],
    "createdDateTime": "2017-05-19T13:06:40+00:00",
    "_links": {
        "self": {
            "href": "https:\/\/api-asia-01.twizo.com\/v1\/backupcode\/1234567890"
        }
    }
}

SMS

With our SMS API you can easily send SMS messages to any operator in the world.

You can send an SMS by doing a HTTP POST to API with URL:
https://api-asia-01.twizo.com/sms/submitsimple

You will need to specify in JSON format the recipients and body of the SMS. An example how to do it:

curl -X POST https://api-asia-01.twizo.com/v1/sms/submitsimple \
    -H "Accept: application/json" \
    -H "Content-Type: application/json; charset=utf8" \
    -u "twizo:<API_KEY>" \
    -d '{
        "recipients" : ["1234567890"],
        "body" : "Body of the sms",
        "sender" : "Hello world"
    }'
$sms = $twizo->createSms('Body of the sms', '1234567890', 'Hello world');
$sms->sendSimple();
An example of the result of this call in JSON format is:
{
    "_links": {
        "self": {
            "href": "https:\/\/api-asia-01.twizo.com\/v1\/sms\/submit"
        }
    },
    "_embedded": {
        "items": [
            {
                "applicationTag": "test",
                "body": "Body of the SMS",
                "callbackUrl": null,
                "createdDateTime": "2016-11-29T11:20:22+00:00",
                "dcs": null,
                "messageId": "asia-01-1.18667.sms583d64765f6b28.36322430",
                "networkCode": null,
                "pid": null,
                "reasonCode": null,
                "recipient": "1234567890",
                "resultType": 0,
                "salesPrice": null,
                "salesPriceCurrencyCode": null,
                "scheduledDelivery": null,
                "sender": "Hello world",
                "senderNpi": 0,
                "senderTon": 5,
                "status": "no status",
                "statusCode": 0,
                "tag": null,
                "resultTimestamp": null,
                "udh": null,
                "validity": 259200,
                "validUntilDateTime": "2016-12-02T11:20:22+00:00",
                "_links": {
                    "self": {
                        "href": "https:\/\/api-asia-01.twizo.com\/v1\/sms\/submit\/asia-01-1.18667.sms583d64765f6b28.36322430"
                    }
                }
            }
        ]
    },
    "total_items": 1
}

Most important field in the response is the messageId. See SMS status for more information about the other fields returned in the response. You will need this to check the status of the SMS or to get the delivery report. How to get the status or delivery reports is described further below.

The above example is using our simple SMS function. With this function can send long SMS and the API will automatically split up the messages into parts as an SMS has a maximum length. Check our tutorial ‘Concatenated/long SMS’ for more information on concatenated SMS.

Apart from the simple SMS function we also have an advanced SMS function where you have full control on the properties of an SMS. The parameters of both functions are described in the next paragraphs.

Simple SMS parameters

To submit a simple SMS you have to do a POST with the data in JSON format to our API with URL:
https://api-asia-01.twizo.com/sms/submitsimple

Parameters you can set when submitting SMS are:

Parameter Description
recipients This is a mandatory array with strings parameter. It should be an array of numbers (in string format), in international format, for the SMS. At least 1 number must be set and maximum 1000.
body This is a mandatory string parameter. The body of the SMS. The API will automatically determine if the body is Unicode or not and when the body is too long for a single SMS the API will automatically split up the body into multiple parts. The maximum number of concatenated parts is 9. See our tutorials ‘Unicode’ and ‘Concatenated/long SMS’ for more information.
sender This is a mandatory string parameter. The sender is what the receiver of the SMS see as the submitter of the SMS. See our tutorial ‘Sender’ for more information. When it is numeric the maximum length is 17 digits, when it is alphanumeric the maximum length is 11.
senderTon This is an optional integer parameter. If it is not set the API will automatically detect the value. See our tutorial ‘Sender’ for more information.
senderNpi This is an optional integer parameter. If it is not set the API will automatically detect the value. See our tutorial ‘Sender’ for more information.
pid This is an optional integer parameter. Can be used to send hidden SMS. Allowed values: 0-255. See also GSM specification .
scheduledDelivery This is an optional string parameter. Datetime of scheduled delivery. Must be in ISO-8601 format, example: 2016-10-31T12:34:56Z
tag This is an optional string parameter. The tag is a free text parameter you can use for your own reference. The maximum length of the tag is 30 characters. The tag parameter is returned in the result and you can use it for reporting purposes on your side
validity This is an optional integer parameter. The validity specifies how long the message is valid. The validity is in seconds. If the message could not be delivered within this time, the message will expire and no more attempts will be made to deliver it. The minimum value of the validity is 5 seconds and the maximum value is 259200 seconds (= 72 hours). The default value is 259200 seconds.
resultType This is an optional integer parameter. If you want to receive or poll for final results of your verifications, you can set the resultType. You can use the results for your own reporting purposes. Possible values of the resultType are:
0 No results (default)
1 Callback (you have to specify the callbackUrl)
2 Polling
3 Callback & polling (you have to specify the callbackUrl)
callbackUrl This string parameter is only mandatory when resultType is set to 1 or 3. When the callbackUrl is set, this URL will be used by our system to submit status updates to you. This parameter is only allowed when the resultType parameter is set to 1 or 3.

Advanced SMS parameters

To submit an advanced SMS you have to do a POST with the data in JSON format to our API with URL:
https://api-asia-01.twizo.com/sms/submit

For the advanced SMS you can set the same parameters as for the simple SMS except that the body parameter is different and there are 2 additional possible parameters:

body This is a mandatory string parameter. The body of the SMS. The body shall be send in GSM-7 alphabet and the maximum length is 160 characters. When you want to send characters not in the GSM-7 alphabet you have to send it as Unicode. In that case you have to set the DCS to 8. The maximum length is in that case 70 characters. When you send a concatenated message, you have to set a UDH as well and the maximum length for GSM-7 is then 153 characters and for Unicode 67 characters. See our tutorials ‘Unicode‘ and ‘Concatenated/long SMS‘ for more information.
dcs Optional integer parameter for advanced, can be used to mark body as Unicode (8). Allowed values: 0-255. See also GSM specification .
udh Optional string parameter for advanced; sets concat message. Can only consist of hexadecimal characters. Length in this parameter divided by 2 is subtracted from the maximum body length. See also GSM specification .

SMS status

You can check the status of an SMS with a simple GET and specifying the ‘messageId’ returned in the submit of the SMS:
curl https://api-asia-01.twizo.com/v1/sms/submit/<MESSAGE_ID> \
    -H "Accept: application/json" \
    -H "Content-Type: application/json; charset=utf8" \
    -u "twizo:<API_KEY>"
$result = $twizo->getSms($sms->getMessageId());
This will return in JSON format the following:
{
    "applicationTag": "test",
    "body": "Body of the SMS",
    "callbackUrl": null,
    "createdDateTime": "2016-11-29T11:20:22+00:00",
    "dcs": null,
    "messageId": "asia-01-1.18667.sms583d64765f6b28.36322430",
    "networkCode": 12345,
    "pid": null,
    "reasonCode": 0,
    "recipient": "1234567890",
    "resultType": 0,
    "salesPrice": 0.001,
    "salesPriceCurrencyCode": "eur",
    "scheduledDelivery": null,
    "sender": "Hello world",
    "senderNpi": 0,
    "senderTon": 5,
    "status": "delivered",
    "statusCode": 1,
    "tag": null,
    "resultTimestamp": "2016-11-29T11:20:24+00:00",
    "udh": null,
    "validity": 259200,
    "validUntilDateTime": "2016-12-02T11:20:22+00:00",
    "_links": {
        "self": {
            "href": "https:\/\/api-asia-01.twizo.com\/v1\/sms\/submit\/asia-01-1.18667.sms583d64765f6b28.36322430"
        }
    }
}
The below table explains the fields you will find in the response:
Field Description
applicationTag String, not null. The application used for sending the SMS.
body String, not null. The body as specified when sending the SMS.
callbackUrl String, can be null. The callback URL specified when sending the SMS. Our system will call this URL to return the delivery report of the SMS.
createdDateTime String, not null. The datetime the SMS was received by the API. The datetime is in ISO-8601 format.
dcs Integer, can be null. The DCS value as specified when sending the SMS.
messageId String, not null. The unique identifier, generated by the API, of the SMS.
networkCode String, can be null. The network code of the operator the mobile number is subscribed to. The network code is the MCC (Mobile Country Code) and MNC (Mobile Network Code) concatenated.
pid Integer, can be null. The PID value as specified when sending the SMS.
reasonCode Integer, can be null. When the SMS is rejected or could not be delivered a reasonCode is given explaining the cause of the rejection. See further down below for an overview of possible reasonCodes
recipient String, not null. The phone number as specified when sending the SMS.
resultType Integer, not null. The result type specified when sending the SMS. Possible values are:
0 No results (default)
1 Callback (you have to specify the callbackUrl)
2 Polling
3 Callback & polling (you have to specify the callbackUrl)
salesPrice Float, can be null. The sales price of the SMS.
salesPriceCurrencyCode String, can be null. The currency code of the salesPrice field. The value can be ‘eur’, ‘usd’ or ‘sgd’. The currency code is defined by the currency of your wallet.
scheduledDelivery String, can be null. The scheduled delivery time as specified when sending the SMS.
sender String, not null. The sender of the SMS as specified when sending the SMS.
senderNpi Integer, can be null. The senderNpi of the SMS as specified when sending the SMS or the automatically detected value by the API. See our tutorial ‘Sender’ for more information.
senderTon Integer, can be null. The senderTon of the SMS as specified when sending the SMS or the automatically detected value by the API. See our tutorial ‘Sender’ for more information.
status String, not null. The status of the SMS. The status and statusCode fields are bound together and can have the following values:
0 no status The SMS is received by our system. This is a temporary status, a final status will follow later.
1 delivered The SMS is successfully delivered to the mobile phone.
2 rejected The SMS is rejected by the system and is not sent to the phone. The reasonCode field indicates the reason why it is rejected. See further down below for an overview of possible reasonCodes.
3 expired The SMS is expired as it could not be delivered within the specified validity time.
4 enroute The SMS is on it’s way in the mobile network and will be tried to deliver at a later moment. This is a temporary status, a final status will follow later.
5 buffered The SMS is buffered in a queue in the mobile network and will be tried to deliver at a later moment. This is a temporary status, a final status will follow later.
6 accepted The SMS is accepted by the mobile network and will be tried to deliver at a later moment. This is a temporary status, a final status will follow later.
7 undelivered The SMS could not be delivered.
8 deleted The SMS is deleted and will not be delivered.
9 unknown The SMS could not be delivered due to an unknown reason.
statusCode Integer, not null. See ‘status’ field for more information.
tag String, can be null. The tag as specified when sending the SMS.
resultTimestamp String, can be null. The timestamp when the message is delivered to the mobile phone.
udh String, can be null. The UDH as specified when sending the SMS.
validity Integer, not null. The validity in seconds as specified when sending the SMS or the default value (60)
validUntilDateTime String, can be null. The datetime until when the SMS is valid. This is calculated by the API based on the validity field.
_links HATEOAS (Hypermedia as the Engine of Application State) is a constraint of the REST application architecture. A hypermedia-driven site provides information to navigate the site’s REST interfaces dynamically by including hypermedia links with the responses. See HATEOAS for more information.
The status of an SMS can be checked 24 hours after the validity. After that the SMS is removed from the API and you will receive a HTTP status code 404 Not Found. You can however still check the SMS in the portal via Message details .

SMS delivery reports

Apart from checking the status of an SMS, you can also retrieve delivery reports. Each time you check for delivery reports you will receive up to maximum 10 delivery reports at a time. When you received the delivery reports you will need to confirm them so that our system knows you received them correctly. If you do not confirm them, after a timeout of 5 minutes, the same delivery reports will be available again. If you do not retrieve/confirm delivery reports, they will automatically be removed after 24 hours. When you are using one of our libraries or SDK’s you do not have to confirm the delivery reports, it will be done for you, so you don’t have to confirm.

To get the results do a GET call to our API:
curl https://api-asia-01.twizo.com/v1/sms/poll \
    -H "Accept: application/json" \
    -H "Content-Type: application/json; charset=utf8" \
    -u "twizo:<API_KEY>"
$results = $twizo->getSmsResults();
It will return an output in JSON format like this:
{
	"batchId": "12467857ea2d2f8867d3.73020448",
	"count": 1,
	"_embedded": {
    	"messages": [
        	{
                "applicationTag": "test",
                "body": "Body of the SMS",
                "callbackUrl": null,
                "createdDateTime": "2016-11-29T11:20:22+00:00",
                "dcs": null,
                "messageId": "asia-01-1.18667.sms583d64765f6b28.36322430",
                "networkCode": 12345,
                "pid": null,
                "reasonCode": 0,
                "recipient": "1234567890",
                "resultType": 0,
                "salesPrice": 0.001,
                "salesPriceCurrencyCode": "eur",
                "scheduledDelivery": null,
                "sender": "Hello world",
                "senderNpi": 0,
                "senderTon": 5,
                "status": "delivered",
                "statusCode": 1,
                "tag": null,
                "resultTimestamp": "2016-11-29T11:20:24+00:00",
                "udh": null,
                "validity": 259200,
                "validUntilDateTime": "2016-12-02T11:20:22+00:00",
                "_links": {
                    "self": {
                        "href": "https:\/\/api-asia-01.twizo.com\/v1\/sms\/submit\/asia-01-1.18667.sms583d64765f6b28.36322430"
                    }
                }
        	}
    	]
	},
	"_links": {
    	"self": {
        	"href": "https:\/\/api-asia-01.twizo.com\/v1\/sms\/poll\/12467857ea2d2f8867d3.73020448"
    	}
	}
}
You can confirm the delivery reports by doing a DELETE to our API with the ‘batchId’ returned from the GET call. When you are using one of our libraries or SDK’s you do not have to confirm the delivery reports, it will be done for you, so you don’t have to confirm.
curl -X DELETE https://api-asia-01.twizo.com/v1/sms/poll/<BATCH_ID> \
    -H "Accept: application/json" \
    -H "Content-Type: application/json; charset=utf8" \
    -u "twizo:<API_KEY>"

Callback URL

When you have specified a callback URL, our system will HTTP POST that URL with the delivery report. The result will be sent in JSON format, similar like when you check the status of an SMS. You will have to respond to the call with HTTP status code 200 OK. If you respond with another HTTP status code we will try to call the URL again after some time. We will try to call the URL maximum 10 times with an increasing time interval where the last attempt is 72 hours after the first attempt.

Reason codes

When our API accepted an SMS but for example the number could not be found, a reason code is returned. The following reason codes can be returned:
Reason code Description
201 Insufficient credit
202 Recipient temporary not available (phone switched off, roaming, handset memory full, etc.)
203 Recipient permanent not available (invalid number, handset doesn’t support SMS, blacklisted, etc.)
204 Permanent network error
205 Temporary network error
206 Incorrect message parameter
207 Rejected due to account issue
208 Rejected due to spam or illegal content
209 Validity expired
299 Unknown

Incoming SMS

Incoming SMS, or sometimes called Mobile Originated SMS (MO), are SMS messages sent by a phone to our platform. Those messages are sent to so called Virtual Mobile Numbers (VMN) and handled by our platform. You can use this Incoming SMS service for e.g. 2-way SMS. In order to use this service you need to register a VMN, you can do this by contacting us at support@twizo.com.

When you register a VMN, you will receive all incoming messages on that number. You can also register keywords for the VMN and per keyword you can set a different callback URL. A keyword is the first word of the incoming message.

When you register a VMN you will be asked to provide us a URL which our platform can call to deliver the incoming SMS to you. The URL will do a HTTP POST from one of our callback hosts to your URL. The incoming SMS will be sent to you in JSON format. You will have to respond to the call with HTTP status code 200 OK. If you respond with another HTTP status code we will try to call the URL again after some time. We will try to call the URL maximum 10 times with an increasing time interval where the last attempt is 72 hours after the first attempt.

An example of the JSON data you will receive from us:

{
    "body":"Hello world",
    "createdDateTime":"2017-07-21T13:54:28+00:00",
    "keyword":null,
    "networkCode":null,
    "recipient":"1234567890",
    "sender":"Twizo",
    "udh":null
}

The below table explains the fields:

Field Description
body String, not null. The body of the incoming SMS.
createdDateTime String, not null. The datetime the incoming SMS was received by our platform. The datetime is in ISO-8601 format.
keyword String, can be null. If you have configured keyword for your VMN and the message begins with the keyword, the keyword will be set in this field.
networkCode String, can be null. The network code of the operator of the mobile number who sent the SMS. The network code is the MCC (Mobile Country Code) and MNC (Mobile Network Code) concatenated.
recipient String, not null. The recipient is the mobile number when the MO is sent to, so the VMN configured for you.
sender String, not null. The mobile number who sent the SMS.
udh Strong, can be null. When the mobile number who sent the SMS sent a long SMS, it will be split up by the network into parts. Each part will have a UDH which you can use to combine it to one text again. See our tutorial on Concatenated/long SMS for more details.

Number Lookup

With Number Lookup you can get information specific to a mobile phone number. You can get the following information:

  • If the mobile number is still active or not (the number might be out of use because the subscription has ended).
  • If the mobile number is ported to another operator (the current operator is different then the operator who issues the number).
  • If the mobile number is roaming (connected to a network other then his home network, e.g. in another country).

You can perform a Number Lookup by doing a HTTP POST to API with URL:
https://api-asia-01.twizo.com/numberlookup/submit

You will need to specify in JSON format the numbers you want to perform the Number Lookup for. An example how to do it:

curl -X POST https://api-asia-01.twizo.com/v1/numberlookup/submit \
    -H "Accept: application/json" \
    -H "Content-Type: application/json; charset=utf8" \
    -u "twizo:<API_KEY>" \
    -d '{
        "numbers" : ["1234567890"]
    }'
$numberLookup = $twizo->createNumberLookup('1234567890');
$numberLookup->send();
An example of the result of this call in JSON format is:
{
    "_links": {
        "self": {
            "href": "https:\/\/api-asia-01.twizo.com\/v1\/numberlookup\/submit"
        }
    },
    "_embedded": {
        "items": [
            {
                "applicationTag": "Default application",
                "callbackUrl": null,
                "countryCode": null,
                "createdDateTime": "2016-11-29T11:26:46+00:00",
                "imsi": null,
                "messageId": "asia-01-1.19910.nrl583d65f60cdc75.96102916",
                "msc": null,
                "networkCode": null,
                "number": "1234567890",
                "operator": null,
                "reason": null,
                "resultType": 0,
                "salesPrice": null,
                "salesPriceCurrencyCode": null,
                "status": "no status",
                "statusCode": 0,
                "tag": null,
                "resultTimestamp": null,
                "validity": 60,
                "validUntilDateTime": "2016-11-29T11:27:46+00:00",
                "_links": {
                    "self": {
                        "href": "https:\/\/api-asia-01.twizo.com\/v1\/numberlookup\/submit\/asia-01-1.19910.nrl583d65f60cdc75.96102916"
                    }
                }
            }
        ]
    },
    "total_items": 1
}
Most important field in the response is the messageId. See Number Lookup status for more information about the other fields returned in the response. You will need this to check the status of the Number Lookup or to get the result. How to get the status or results is described further below.

Number Lookup parameters

When you perform a Number Lookup you can specify several parameters. Below you can find an overview of all parameters.
Parameter Description
numbers This is a mandatory array with string parameter. It should be an array of numbers (in string format), in international format, for the number lookup. At least 1 number must be set and maximum 1000 numbers can be set.
tag This is an optional string parameter. The tag is a free text parameter you can use for your own reference. The maximum length of the tag is 30 characters. The tag parameter is returned in the result and you can use it for reporting purposes on your side.
validity This is an optional integer parameter. The validity specifies how long the Number Lookup is valid. The validity is in seconds. If the Number Lookup could not be performed within this time, the Number Lookup is expired. The minimum value of the validity is 5 seconds and the maximum value is 259200 seconds (= 72 hours). The default value is 259200 seconds.
resultType This is an optional integer parameter. If you want to receive or poll for final results of your verifications, you can set the resultType. You can use the results for your own reporting purposes. Possible values of the resultType are:
0 No results (default)
1 Callback (you have to specify the callbackUrl)
2 Polling
3 Callback & polling (you have to specify the callbackUrl)
callbackUrl This string parameter is only mandatory when resultType is set to 1 or 3. When the callbackUrl is set, this URL will be used by our system to submit status updates to you. This parameter is only allowed when the resultType parameter is set to 1 or 3.

Number Lookup status

You can check the status of a Number Lookup with a simple GET and specifying the ‘messageId’ returned in the submit of the Number Lookup:
curl https://api-asia-01.twizo.com/v1/numberlookup/submit/<MESSAGE_ID> \
    -H "Accept: application/json" \
    -H "Content-Type: application/json; charset=utf8" \
    -u "twizo:<API_KEY>"
$result = $twizo->getNumberLookup($numberLookup->getMessageId());
This will return in JSON format the following:
{
    "applicationTag": "Default application",
    "callbackUrl": null,
    "countryCode": "es",
    "createdDateTime": "2016-11-29T11:26:46+00:00",
    "imsi": "214031500000000",
    "messageId": "asia-01-1.19910.nrl583d65f60cdc75.96102916",
    "msc": null,
    "networkCode": 12345,
    "number": "1234567890",
    "operator": "(SPAIN)ORANGE",
    "reasonCode": 0,
    "resultType": 0,
    "salesPrice": 0.00011,
    "salesPriceCurrencyCode": "eur",
    "status": "delivered",
    "statusCode": 1,
    "tag": null,
    "resultTimestamp": "2016-11-29T11:26:48+00:00",
    "validity": 60,
    "validUntilDateTime": "2016-11-29T11:27:46+00:00",
    "_links": {
        "self": {
            "href": "https:\/\/api-asia-01.twizo.com\/v1\/numberlookup\/submit\/asia-01-1.19910.nrl583d65f60cdc75.96102916"
        }
    }
}
The below table explains the fields you will find in the response:
Field Description
applicationTag String, not null. The application used for sending the Number Lookup.
callbackUrl String, can be null. The callback URL specified when sending the Number Lookup. Our system will call this URL to return the result of the Number Lookup.
countryCode String, can be null. A two digit ISO 3166-1 alpha-2 code of the country of the operator the mobile number is subscribed to.
createdDateTime String, not null. The datetime the Number Lookup was received by the API. The datetime is in ISO-8601 format.
imsi String, can be null. The IMSI (International Mobile Subscriber Identity) of the SIM card the mobile number is linked to.
messageId String, not null. The unique identifier, generated by the API, of the Number Lookup.
msc String, can be null. The MSC (Mobile Switching Center) of the operator the mobile phone is currently registered to. This can be used to identify if a mobile phone is currently roaming or not.
networkCode Integer, can be null. The network code of the operator the mobile number is subscribed to. The network code is the MCC (Mobile Country Code) and MNC (Mobile Network Code) concatenated.
number String, not null. The phone number as specified when sending the Number Lookup.
operator String, can be null. The name of the operator the mobile number is subscribed to.
reasonCode Integer, can be null. When the Number Lookup is rejected or could not be performed a reasonCode is given explaining the cause of the rejection. See further down below for an overview of possible reasonCodes
resultType The result type specified when sending the Number Lookup. Possible values are:
0 No results (default)
1 Callback (you have to specify the callbackUrl)
2 Polling
3 Callback & polling (you have to specify the callbackUrl)
salesPrice Float, can be null. The sales price of the Number Lookup.
salesPriceCurrencyCode String, can be null. The currency code of the salesPrice field. The value can be ‘eur’, ‘usd’ or ‘sgd’. The currency code is defined by the currency of your wallet.
status String, not null. The status of the Number Lookup. The status and statusCode fields are bound together and can have the following values:
0 no status The Number Lookup is received by our system. This is a temporary status, a final status will follow later.
1 delivered The Number Lookup is successfully performed.
2 rejected The Number Lookup is rejected by the system and is not performed. The reasonCode field indicates the reason why it is rejected. See further down below for an overview of possible reasonCodes.
3 expired The Number Lookup is expired as it could not be performed within the specified validity time.
4 enroute The Number Lookup is on it’s way in the mobile network and will be tried to perform at a later moment. This is a temporary status, a final status will follow later.
5 buffered The Number Lookup is buffered in a queue in the mobile network and will be tried to perform at a later moment. This is a temporary status, a final status will follow later.
6 accepted The Number Lookup is accepted by the mobile network and will be tried to perform at a later moment. This is a temporary status, a final status will follow later.
7 undelivered The Number Lookup could not be performed.
8 deleted The Number Lookup is deleted and will not be performed.
9 unknown The Number Lookup could not be performed due to an unknown reason.
statusCode Integer, not null. See ‘status’ field for more information.
tag String, can be null. The tag as specified when sending the Number Lookup.
resultTimestamp String, can be null. The timestamp when the Number Lookup was performed.
validity Integer, not null. The validity in seconds as specified when sending the Number Lookup or the default value (60)
validUntilDateTime String, can be null. The datetime until when the Number Lookup is valid. This is calculated by the API based on the validity field.
_links HATEOAS (Hypermedia as the Engine of Application State) is a constraint of the REST application architecture. A hypermedia-driven site provides information to navigate the site’s REST interfaces dynamically by including hypermedia links with the responses. See HATEOAS for more information.
The status of a Number Lookup can be checked 24 hours after the validity. After that the Number Lookup is removed from the API and you will receive a HTTP status code 404 Not Found. You can however still check the Number Lookup in the portal via Message details .

Number Lookup results

Apart from checking the status of a Number Lookup, you can also retrieve the results. Each time you check for results you will receive up to maximum 10 results at a time. When you received the results you will need to confirm them so that our system knows you receive them correctly. If you do not confirm them, after a timeout of 5 minutes, the same results will be available again. If you do not retrieve/confirm results, they will automatically be removed after 24 hours. When you are using one of our libraries or SDK’s you do not have to confirm the delivery reports, it will be done for you, so you don’t have to confirm.

To get the results do a GET call to our API:
curl https://api-asia-01.twizo.com/v1/numberlookup/poll \
    -H "Accept: application/json" \
    -H "Content-Type: application/json; charset=utf8" \
    -u "twizo:<API_KEY>"
$results = $twizo->getNumberLookupResults();
It will return an output in JSON format like this:
{
	"batchId": "12467857ea2d2f8867d3.73020448",
	"count": 1,
	"_embedded": {
    	"messages": [
        	{
                "applicationTag": "Default application",
                "callbackUrl": null,
                "countryCode": "es",
                "createdDateTime": "2016-11-29T11:26:46+00:00",
                "imsi": "214031500000000",
                "messageId": "asia-01-1.19910.nrl583d65f60cdc75.96102916",
                "msc": null,
                "networkCode": 12345,
                "number": "1234567890",
                "operator": "(SPAIN)ORANGE",
                "reason": 0,
                "resultType": 0,
                "salesPrice": 0.00011,
                "salesPriceCurrencyCode": "eur",
                "status": "delivered",
                "statusCode": 1,
                "tag": null,
                "resultTimestamp": "2016-11-29T11:26:48+00:00",
                "validity": 60,
                "validUntilDateTime": "2016-11-29T11:27:46+00:00",
                "_links": {
                    "self": {
                        "href": "https:\/\/api-asia-01.twizo.com\/v1\/numberlookup\/submit\/asia-01-1.19910.nrl583d65f60cdc75.96102916"
                    }
                }
        	}
    	]
	},
	"_links": {
    	"self": {
        	"href": "https:\/\/api-asia-01.twizo.com\/v1\/numberlookup\/poll\/12467857ea2d2f8867d3.73020448"
    	}
	}
}
You can confirm the delivery reports by doing a DELETE to our API with the ‘batchId’ returned from the GET call. When you are using one of our libraries or SDK’s you do not have to confirm the delivery reports, it will be done for you, so you don’t have to confirm.
curl -X DELETE https://api-asia-01.twizo.com/v1/numberlookup/poll/<MESSAGE_ID> \
    -H "Accept: application/json" \
    -H "Content-Type: application/json; charset=utf8" \
    -u "twizo:<API_KEY>"

Callback URL

When you have specified a callback URL, our system will HTTP POST that URL with the result. The result will be sent in JSON format, similar like when you check the status of a Number Lookup. You will have to respond to the call with HTTP status code 200 OK. If you respond with another HTTP status code we will try to call the URL again after some time. We will try to call the URL maximum 10 times with an increasing time interval where the last attempt is 72 hours after the first attempt.

Reason codes

When our API accepted a Number lookup but for example the number could not be found, a reason code is returned. The following reason codes can be returned:
Reason code Description
1 Absent subscriber (phone is switched off, phone out of coverage, roaming, etc.)
9 Unknown subscriber (number not known in network)
13 Operator barred the number
30 Operator cannot be determined based on the number therefor no number lookup can be performed
53 Rejected as you are not allowed to perform number lookups for this operator/country
61 Unknown
75 Number lookup aborted due to network issues
Sign up and Get Started for Free

sign up for free
Monthly 100 free verification credits
and no credit card required at sign up!