# Getting Started

[**Saino First**](htttps://sainofirst.com) **API** (Application Programming Interfaces)  documentation is intuitive and written with developers in mind. It provide instructions on how to quickly integrate Saino First services into various solutions. In order to interact with our API, any HTTP client in any programming language can be used. Saino First infrastructure Engineered for reliability, quality, and 99.9% uptime.

Saino First APIs power its platform for communications. Behind these APIs is a software layer connecting and optimizing communications networks around the world to allow you to Send messages or voice across 190+ countries and over 800+ telecom networks.

## What’s a REST API?

An API is a set of rules that let programs hand-shake with each other, sharing data and functionality across the internet in a consistent format. REST stands for Representational State Transfer. It is an architectural pattern that describes how distributed systems can expose a consistent interface. When we use the term ‘REST API,’ they are generally referring to an API accessed via HTTP protocol at a predefined set of URLs.

You can send alerts, reminders, notifications, marketing messages, verification messages containing one-time passcodes (OTP).

## How to get started?

Create a Saino First account In order to use our API, you will need credentials. These are not used only for API but also for other Saino First services like Customer portal. If you already have a Saino First account you can skip this step. Otherwise, follow this link:&#x20;

[**Create a new account**](https://app.sainofirst.com)

Part of the signup process includes verifying your personal phone numbe&#x72;**,** this is a security measure that is mandatory before you can try Saino.

### Github for SDKs and Plugins <a href="#got-stuck" id="got-stuck"></a>

#### <https://github.com/sainofirst>

### Got stuck?  <a href="#got-stuck" id="got-stuck"></a>

No problem, we are here for you! We have the best support team available you around the clock, so just drop an email at <support@sainofirst.com>


# Security & Authentication

We know Security is one of the most important thing for any application in API integration so we made sure to provide you with a set of tools that will help you create secure applications.

## SSL Encryption

The majority of requests to Saino First’s API require authentication. We strongly advised to use HTTPS protocol for all API requests in order to keep the submitted request secret.

## API key authorization

This is the most secure authorization with the most flexibility for any request. API keys can have a limited access and they can be revoked at any time. This range of possibilities makes API keys well suited for separating the API access rights across multiple applications or use cases. And last, the loss of an API key is easily manageable.\
&#x20;

**API keys can be generated by following the below steps.**

* To generate the API key, login to your Saino First account. Under profile click on API

![](https://524580821-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LgRc7xkZ1-wXXSjFP9k%2F-LgYKUArAqelJWwU6PfX%2F-LgYMlBV6o7ECaoT6Tav%2FAPI.png?alt=media\&token=c9f91c8d-3a89-4403-a7a2-bfc384a50dd0)

* Now, In API Page click Create API

![](https://524580821-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LgRc7xkZ1-wXXSjFP9k%2F-LgYKUArAqelJWwU6PfX%2F-LgYNMUwOUBO8sUfiVi2%2FScreen%20Shot%202019-06-04%20at%2010.14.38%20PM.png?alt=media\&token=35534da4-3cce-45e2-97dd-8656d65c7173)

* Select the list of apps to allow access with API

![](https://524580821-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LgRc7xkZ1-wXXSjFP9k%2F-LgYKUArAqelJWwU6PfX%2F-LgYNiSgiJTnl0Bntr7z%2FScreen%20Shot%202019-06-04%20at%2010.16.08%20PM.png?alt=media\&token=86e8ede4-1d32-4d5b-b5e6-62278f36995f)

Click on save, Your API key will be generated.&#x20;

{% hint style="info" %}
You can generate multiple API\`s based on your requirement or with limited access to apps.&#x20;

Once you delete the API key, your account will be no longer accessible with old API key.&#x20;
{% endhint %}


# Base URL Setting

Before you start using [SainoFirst](https://sainofirst.com) Platform's API, you should consider reading the API documentations thoroughly. Although, we have kept everything simple for the ease of integration of your application with our platform, but still there are some steps need to be followed to have seamless integration.&#x20;

## Base URL for our platform's APIs

| Base URL                            | Description                                                                                                 |
| ----------------------------------- | ----------------------------------------------------------------------------------------------------------- |
| **`https://api.saino.io/api/apis`** | Use this as base path for all the API endpoints available on [SainoFirst](https://sainofirst.com) Platform. |

## Authentication Methods

You can use **any ONE** of the authentication methods from below.

### 1. Passing API Token in Request Header *(Recommended)*

{% hint style="success" %}
Each request is validated by looking for valid API token into the Header of the HTTP request.
{% endhint %}

| Header Name (or Header Key) | Value                |
| --------------------------- | -------------------- |
| **`Authorization`**         | **`YOUR_API_TOKEN`** |

### 2. Passing API Token in Query Parameter ***(Deprecated, will be removed in future)***

| Authentication                     | Description                                                                                                                                               |
| ---------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Query Parameter Name : **`token`** | <p>Every API request URL must add <code>?token=\<YOUR\_API\_TOKEN></code> in the URL path.</p><p></p><p>This is applicable for all HTTP method calls.</p> |

{% hint style="warning" %}

### IMPORTANT:

For each API request, you have to put a query parameter named **`token`** with value as **`<YOUR_API_TOKEN>.`**

**Pattern: `<base_url>/path?token=<YOUR_API_TOKEN>&otherParam=...`**

Example: To get your account information, the complete URL will be...\
&#x20;***GET Method:***   `https://api.saino.io/api/apis/my-account?token=<API_TOKEN>`
{% endhint %}

###


# SDKs & Plugins

We've made a number of open source libraries and plugins available for the API.

#### Github Link - <https://github.com/sainofirst>

#### NPM  - <https://www.npmjs.com/package/sainofirst>

#### Python - <https://pypi.org/project/sainofirst>

Currently SDKs available on below languages and adding more in the near future.&#x20;

* Node Js&#x20;
* Python&#x20;


# Overview

[Saino First](https://sainofirst.com) makes sending and receiving SMS easy. Find the documentation, sample codes and developer tools you need to build exactly what you want, fast & secure. We’ll handle all the complexity of mobile operators and global regulations. Let’s get building.

Our SMS API allows you to send text messages to users around the globe through simple RESTful APIs.

## Quick check before using API

{% hint style="success" %}

#### HTTP Methods : For SMS api&#x20;

* **`GET`** – To send a GET request for sending SMS with data in request's query parameter.
* **`POST`** - To send a POST request for sending SMS with data in body of request.
  {% endhint %}

### **Number Formatting**&#x20;

Numbers are important to understand when working with the API. The following points should be considered before developing the Application.

All phone numbers in the APIs use **E.164** format. It means that numbers:

* Omit both a leading + and the international code such as 00.
* Contain no special characters, such as  `' " / \  ,  ( ) blank space` etc.

{% hint style="info" %}
For example, **Indian numbers** have format like **91***7777084093*. A **UK number** would have the format **44***7700314144*     (where, **91** & **44** are the country code)<br>
{% endhint %}

{% hint style="success" %}
If you are using it for **India**, usin&#x67;**`Transactional`** or **`Promotional`** connectivity then the country code 91 is optional.&#x20;
{% endhint %}

### Routes or Connectivity

Saino First have multiple gateway but majorly below 3 routes are used for sending messages via API.

1. **Global**
2. **Transactional**
3. **Promotional**

**`Global`** gateway can be used to send messages to more than **190+ countries**. The API request **must** contain the numbers with country code, else the message will be failed. &#x20;

**`Promotional`** and **`Transactional`** connectivity is used only for India. If country code is not found, the **91** *(country's default code)* will be appended before all mobile numbers automatically.

{% hint style="info" %}
Multiple country have different price for messages so the price will be deducted accordingly. The current price/message can be seen under **`Apps > SMS > Connectivity`**.&#x20;

Price calculations are done on the basis of **`Number of SMS * cost per SMS`**.&#x20;

Multi countries numbers can be send on one request. [Saino First](https://sainofirst.com) system will auto calculate based on number of messages.
{% endhint %}

### Sender ID

Global gateway have open Sender ID which can be approved based on requirement but in India sender id is mandatory. While sending a message you can use any approved sender IDs for your account.

In case you have not created a sender ID, you can always create one through our customer portal. It can be created under **`SMS App > Manage > Sender ID`**. Once the Sender ID is approved, you can start sending the messages.

### Message Template

Mostly we have open content but many countries have restrictions on content template. Before production, please test your content by sending a test message Otherwise, the *SMS may end up being rejected.*


# Send SMS

To make it simple, We have designed a method which allows you to **send SMS in a single line** of the HTTP **GET** request:

```http
https://api.saino.io/api/apis/bulk-sms?token=enterAPI&senderid=YourApprovedSenderID&route=EnterRoute&number=EnterNumber&message=hello
```

This is all you need to send a message. No codings skills required, to test this, You can even send this message through your web browser address bar, Just copy the URL and change the parameters.  Now, this is something that you could put into your application without writing any code!

### Placeholder

Placeholder names will be provided by the application system from which you want to send messages. What you need to understand is where to put these placeholders. Let’s break down our example request in several lines so we can understand it closely:

```http
https://api.saino.io/api/apis/bulk-sms?
token=EnterAPIkey 
&senderid=YourApprovedSenderID
&route=EnterRouteName ( Transactional, Global, Promotional )
&number=EnterNumber ( Where SMS needs to be send )
&message=hello ( Enter your text message )
```

{% hint style="info" %}
If you want to send sms via user ID and password, That will replace token (API key ) to below parameters :

username=myUsername\&password=myPassword&#x20;

Remaining all parameters will be same
{% endhint %}

### Mandatory Parameters&#x20;

| Type      | Parameter   | Description                                                               |
| --------- | ----------- | ------------------------------------------------------------------------- |
| Token     | token=      | Generate your API key at your Saino First account                         |
| Sender ID | \&senderid= | The registered and approved Sender name                                   |
| Route     | \&route=    | Type of connectivity like Global, Promotional, Transactional              |
| Number    | \&number=   | Number with country prefix. (multiple numbers can be separated by comma.) |
| Message   | \&message=  | Content of message                                                        |

### Optional Parameters

You can add these parameters in the HTTP API only, as per your requirement you can use one of them or all.  &#x20;

| Type             | Parameter            | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| ---------------- | -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| DLT TemplateId   | \&dltTemplateId=     | Only for India, If you want to pass directly template id via API you can do that with this parameter, Update Entity id directly under Saino app profile section. For more info click here - [https://help.saino.io/registration-on-dlt-india#how-to-add-template-on-saino-platform](https://www.google.com/url?q=https://help.saino.io/registration-on-dlt-india%23how-to-add-template-on-saino-platform\&sa=D\&source=hangouts\&ust=1615122091604000\&usg=AFQjCNGF5QcEDit0MZuuvapjGx0l_WtsFw) |
| Unicode          | \&unicode=1          | Message can be send in any language ( Values 1 or 0 )                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| Schedule         | \&time=              | Schedule time (in format i.e,yyyy-mm-dd hh:mm:ss) at which the SMS has to be sent                                                                                                                                                                                                                                                                                                                                                                                                              |
| Flash            | \&flash=1            | Send flash sms via API ( Values 1 or 0 )                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| Confidential SMS | \&is\_confidential=1 | Saino Platform will not store the message. It will simply pass the actual content to the operator. More information click [here](https://apidocs.saino.io/sms-api/confidential-sms)                                                                                                                                                                                                                                                                                                            |

### Got stuck?  <a href="#got-stuck" id="got-stuck"></a>

No problem, we are here for you! We have the best support team available you around the clock, so just drop an email at <support@saino.io>


# Send SMS (POST API)

HTTP Post API to send SMS.

## Send SMS

<mark style="color:green;">`POST`</mark> `<base_url>/bulk-sms`

This endpoint allows you to send SMS.

#### Headers

| Name          | Type   | Description                     |
| ------------- | ------ | ------------------------------- |
| Authorization | string | Your API key in request header. |

#### Request Body

| Name             | Type    | Description                                                                                                                                                                                                                                                                   |
| ---------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| is\_confidential | boolean | <p>0 - Send as Normal SMS<br>1 - Send as Confidential SMS<br><br>Read more on Confidential SMS section (<https://apidocs.saino.io/sms-api/send-sms-post-api>).</p>                                                                                                            |
| dltTemplateId    | number  | Only for India, If you want to pass directly template id via API you can do that with this parameter., update Entity under Saino app profile section. For more info open below link - <https://help.saino.io/registration-on-dlt-india#how-to-add-template-on-saino-platform> |
| reportUrl        | string  | <p>The URL at which the SMS reports will be sent for this campaign. <br><br><em>Read Reports & Deliveries section below for more information.</em></p>                                                                                                                        |
| senderid         | string  | The registered and approved Sender name.                                                                                                                                                                                                                                      |
| route            | string  | Type of connectivity ex Global, Promotional, Transactional, etc.                                                                                                                                                                                                              |
| number           | string  | Number with country prefix. (multiple numbers can be separated by comma.)                                                                                                                                                                                                     |
| message          | string  | SMS text body. The actual message.                                                                                                                                                                                                                                            |
| unicode          | number  | Message can be send in any language ( Values 1 or 0 )                                                                                                                                                                                                                         |
| time             | string  | Schedule time (in format i.e, yyyy-mm-dd hh:mm:ss) at which the SMS has to be sent                                                                                                                                                                                            |
| flash            | number  | Send flash SMS via API ( Values 1 or 0 )                                                                                                                                                                                                                                      |

{% tabs %}
{% tab title="200 SMS sent successfully.

campaignId : This ID is the reference ID of your request. You can store this ID to capture the deliveries specific to this campaign.  For every request, you will get a new and unique campaignId." %}

```javascript
{
    status: true,
    data: {
        campaignId: 12345
      },
    message: "SMS Sent Successfully."
}
```

{% endtab %}

{% tab title="400 Error in request data." %}

```javascript
{
    status: false,
    message: "Error_Message_For_Root_Cause"
}
```

{% endtab %}
{% endtabs %}

### Reports & Deliveries

In order to get delivery reports directly into your system you need to take care of few simple things.

* Please make sure that, the URL passed in the field `reportUrl`, **must accept** **`HTTP POST`** request with **`JSON`** request body.
* If you wish to get any additional data in the report callback, you should user query parameters and values in the URL itself.

{% hint style="info" %}
If you don't pass the `reportUrl` parameter in request body, we will not be able to push the reports to your system. However, messages will still be delivered to the destination.
{% endhint %}

### Sample Request

{% tabs %}
{% tab title="Request Body" %}

```
{
	"senderid": "SAIFST",
	"route": "Transactional",
	"number": 989XXXXXXX,
	"message": "Hello SainoFirst!! My first Post API.",
	
	// The url at which you want to track the delivery report for this campaign
  "reportUrl": "https://app.sainofirst.com/api-delivery-endpoint?customKey1=CustomValue1&customKey2=CustomValue2" 
}
```

{% endtab %}

{% tab title="Response Body" %}

```
{
    "status": true,
    "data": {
        "campaignId": 12345 // this id should be preserved to track the sms reports.
    },
    "message": "SMS sent successfully."
}
```

{% endtab %}
{% endtabs %}


# Confidential SMS

Being the most trusted Communication Service provider by our banking, Stock Market etc. clients, the team at [Saino](https://saino.io/) identified that the SMSes sent by these clients often include Confidential Details of their prestigious customers like OTPs, Transaction Notifications, etc. These details may sometimes be too critical to be stored/persisted into the systems.

So we came up with a solution that we would simply not store these details in our systems once it is sent to the operator for the delivery. However, we cannot promise a similar behavior from the Operators' side as it is not in our hands. This feature lets you make sure that your customers' confidential details are no longer persisted at least in our systems and assures better privacy to their data.&#x20;

{% hint style="info" %}
**T**his feature may sound exciting for some, it has one downside as well. Enabling this feature will not let you see the actual SMS content on Saino portal sections including reports, downloads, or any other place from our portal.
{% endhint %}

### **So how can you use this feature?**

Currently, it's possible to set a flag in the existing SMS API request and it's already documented in our [API documentation](https://apidocs.saino.io/sms-api/send-sms#optional-parameters).&#x20;

You need to pass this parameter in the API request:  **\&is\_confidential=1**

This is an **OPTIONAL** feature. Existing API requests will have no impact and will be working normally. Soon we will be adding this feature to our Web Application Portal too.\
\
Please feel free to reach out to our support team for any further clarifications or details on this.


# Overview

Saino First Voice call or messaging is an automated way to call multiple numbers to deliver a voice message via call that was prerecorded or converted from a text. Also known as Voice SMS or robocalling or Voice broadcast, it delivers voice messages to any fixed or mobile phone in the world.&#x20;

**2-Factor Authentication**

It helps companies to deliver PINs for 2-Factor Authentication and transactional messages in a quicker way and ensures 100% delivery via retry methods. &#x20;

Businesses use Voice messaging to inform their customers of their latest marketing offers. It is especially effective for spreading time-sensitive messages like emergency messages, last-minute updates, to generate an opinion on a certain matter, send political campaigns etc. Voice messaging helps companies to save money because it eliminates the need for call centers to spread messages via Call.

**Voice API**

Saino First's Voice API is a simple REST API. For an originating Voice call, you submit a POST HTTP request with a well-structured body and in response, you get a confirmation from our system.&#x20;

**Testing with Postman - Use below settings**

![](https://524580821-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LgRc7xkZ1-wXXSjFP9k%2F-MC726Hw1Iv4yuWwQ4O3%2F-MC72T5VlBGlKgZAZ32h%2FScreen%20Shot%202020-07-13%20at%205.30.13%20PM.png?alt=media\&token=7f08a589-e6ac-443b-a3c3-896903662171)

![](https://524580821-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LgRc7xkZ1-wXXSjFP9k%2F-MC726Hw1Iv4yuWwQ4O3%2F-MC72Xd8R_XX8EOeV14X%2FScreen%20Shot%202020-07-13%20at%205.29.38%20PM.png?alt=media\&token=e637b78f-6c25-4f14-a4c5-7ee6f1d8d93d)


# Send Voice Call

Sending a Voice call is completely different from Sending Text SMS. A Voice call involves multiple factor to be considered **before** & **after** the Voice Call is sent. But not to worry when you are using [SainoFirst](https://sainofirst.com)'s Voice Platform. We've taken all complexities on us, so that you can have a seamless integration.\
\
To send voice call you have below options:-

1. **Text-To-Speech** based Voice Call
2. **Pre-Recorded Audio File** based voice Call

## Voice Call Send

<mark style="color:green;">`POST`</mark> `<base_url>/bulk-voice`

#### Request Body

| Name             | Type    | Description                                                                                                                                                                                                                                                                                                                                                                       |
| ---------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| reportUrl        | string  | <p>The URL at which Voice Campaign reports will be sent for this campaign. <br><br><em>Read Reports & Deliveries section below for more information</em></p>                                                                                                                                                                                                                      |
| text             | string  | <p>The actual text that would be converted to voice by Text-to-Speech synthesis and will be played over Voice call.<br><br>🚩<strong>Required</strong> if <strong>is\_text</strong> is <strong><code>true</code></strong><br>✔  <strong>Not-Required</strong> if <strong>is\_text</strong> is <strong><code>false</code></strong></p>                                             |
| audio\_file\_url | string  | <p>URL of audio file that will be played on voice call.<br><br>🚩 Make sure the above URL passed, is publicly accessible. If call scheduled for future date, this URL must be accessible till the date call is scheduled at.</p>                                                                                                                                                  |
| config           | object  | See below for more details on `config` object. There is a separate section with detailed explanation.                                                                                                                                                                                                                                                                             |
| timezone         | string  | <p>Timezone. See the timezone table for more help. <br><br> 📌 <strong>Required</strong> if <code>send\_at</code> is passed in the request.</p>                                                                                                                                                                                                                                   |
| send\_at         | integer | <p>Epoch time (time in milliseconds) equivalent to the <strong>Actual Future Time</strong> (at which the call must be sent). <br><br><em>1. Time must be in future. (Min. 5 minutes, Max. 60 Days)</em><br><em>2. All the requests with past date/time will be rejected.</em><br><em>3. All the request with future date more than 60 days, will be rejected.</em></p>            |
| subscription\_id | integer | Pricing and Routes will be based on this ID. The value of this ID can be accessed from the SainoFirst's Application under connectivity. If subscription not assigned please contact your account manager.                                                                                                                                                                         |
| maxLengthOfCall  | number  | <p>Limits the call duration to this much seconds, the call will be disconnected after this much second automatically even if receiver is not cutting the call. <br>(Value In Second)<br><br>📌 This max duration is not applicable for the calls which are forwarded by the receiver.</p>                                                                                         |
| speech\_rate     | number  | <p>minimum 0.5 - maximum 2 (Lower the value, Slower the speed of voice audio converted via text-to-speech synthesis )<br><br>🚩 <strong>Required</strong> if <strong>is\_text</strong> is <strong><code>true</code></strong><br>✔   <strong>Not-Required</strong> if <strong>is\_text</strong> is <strong><code>false</code></strong></p>                                         |
| language\_id     | integer | <p>Language ID of the text to be converted via Text-to-Speech synthesis. Please refer voice call language page.<br><br>🚩 <strong>Required</strong> if <strong>is\_text</strong> is <strong><code>true</code></strong><br>✔   <strong>Not-Required</strong> if <strong>is\_text</strong> is <strong><code>false</code></strong></p>                                               |
| is\_text         | boolean | <p>Set this to <strong><code>true</code></strong> for sending <em><strong>text-to-speech</strong></em> based voice call.<br><br>Set this to <strong><code>false</code></strong> for sending <em><strong>pre-recorded audio</strong></em> based voice call.<br><br>If <strong>false</strong> : <em><strong><code>audio\_file\_url</code></strong></em> parameter is mandatory.</p> |
| numbers          | array   | Array of `String` of numbers.                                                                                                                                                                                                                                                                                                                                                     |

{% tabs %}
{% tab title="200 " %}

```javascript
{    "id":xxx, // permanent ID of current request    "status":true,    "message":"Voice Call Sent/scheduled Successfully."}
```

{% endtab %}

{% tab title="400 " %}

```javascript
{    "status":false,    "message":"Information about why the request is rejected (in string format)"}
```

{% endtab %}

{% tab title="401 " %}

```javascript
{    "status":false,    "message":"Auth-Error root cause will be stated here."}
```

{% endtab %}

{% tab title="403 " %}

```javascript
{    "status":false,    "message":"Forbidded Resource Access."}
```

{% endtab %}

{% tab title="500 " %}

```javascript
{    "status":false,    "message":"Something Went Wrong"}
```

{% endtab %}
{% endtabs %}

### Simple Text-To-Speech Voice Call ( 2 Factor Authentication )

#### Request:

A `HTTP POST` request should contain body like below.

{% tabs %}
{% tab title="Text-to-Speech-Voice-Call-Request.json" %}

```javascript
{
    "numbers": [        
             "xxxxxxxxxx"    
        ], // if same message is to be sent on multiple numbers, just add them into this array    
    "text": "This is text-to-speech service.",    
    "language_id": 4, // Language Id of Text    
    "maxLengthOfCall": 30, // Maximum Length of call, in seconds    
    "subscription_id": 5, // Subscription used (for Price calculation and Routing)    
    "speech_rate": 1, // Speed of voice call (lower the value, slower the speed [0.5 to 2])    
    "is_text": true,
    // The url at which you want to track the delivery report for this campaign
    "reportUrl": "https://app.sainofirst.com/api-delivery-endpoint?customKey1=CustomValue1&customKey2=CustomValue2"
}
```

{% endtab %}
{% endtabs %}

#### Response:

After the request is successfully received at our server, response will be like below with ***`Status Code: 200`***

{% tabs %}
{% tab title="Response.json" %}

```javascript
{    
    "status":true,    
    "message":"Voice Call scheduled Successfully.",
    "id":xyz // request-id for this request, can be used for future references.
}
```

{% endtab %}
{% endtabs %}

### Fully Featured Text-To-Speech Voice Call

#### Request:

A `HTTP POST` request should contain body like below.

{% tabs %}
{% tab title="Text-to-Speech-Voice-Call-Request.json" %}

```javascript
{
    "numbers": [ "xxxxxxxxxx" ], // if same message is to be sent on multiple numbers, just add then in this array like this    
    "text": "This is text-to-speech service.",    
    "language_id": 4, // Language Id of Text    
    "maxLengthOfCall": 30, // Maximum Length of call, in seconds    
    "subscription_id": 5, // Subscription used (for Price calculation and Routing)    
    "speech_rate": 1, // Speed of voice call (lower the value, slower the speed [0.5 to 2])    
    "is_text": true, 
    "config": { // optional        
        "repeat": 1, // If pressed, voice message will be repeated (maxLengthOfCall will be counted)        
        "callTransfer": {            
                "transferKey": 2, // While call is active, pressing this key will forward the call            
                "transferNumber": xxxxxxxxxx // Forward call to this Number         
            }    
        },    
    "send_at": 1569266700, // required if scheduled for later date or time, otherwise optional    
    "timezone": "Asia/Kolkata(GMT +05:30)" // timezone,
    // The url at which you want to track the delivery report for this campaign
    "reportUrl": "https://app.sainofirst.com/api-delivery-endpoint?customKey1=CustomValue1&customKey2=CustomValue2"
}
```

{% endtab %}
{% endtabs %}

#### Response:

After the request is successfully received at our server, response will be like below with ***`Status Code: 200`***

{% tabs %}
{% tab title="Response.json" %}

```javascript
{
    "status":true,    
    "message":"Voice Call scheduled Successfully.",     
    "id":xyz // request-id for this request, can be used for future references.
}
```

{% endtab %}
{% endtabs %}

### Pre-Recorded Audio Voice Call

#### Request:&#x20;

A `HTTP POST` request should contain body like below.

{% tabs %}
{% tab title="Pre-Recorded-Voice-Call-Request.json" %}

```javascript
{    
    "numbers": [        "xxxxxxxxxx"    ], // if same message is to be sent on multiple numbers, just add then in this array like this    
    "maxLengthOfCall": 30, // Maximum Length of call, in seconds    
    "subscription_id": 5, // Subscription used (for Price calculation and Routing)    
    "is_text": false,    
    "audio_file_url": "https://somefancy-audio-file-url", // required, is_text is true    
    "config": { // optional        
        "repeat": 1, // If pressed, voice message will be repeated (maxLengthOfCall will be counted)        
        "callTransfer": {            
            "transferKey": 2, // While call is active, pressing this key will forward the call            
            "transferNumber": xxxxxxxxxx // Forward call to this Number         
        }    
    },    
    "send_at": 1569266700, // required if scheduled for later date or time, otherwise optional    
    "timezone": "Asia/Kolkata(GMT +05:30)", // timezone
    // The url at which you want to track the delivery report for this campaign
      "reportUrl": "https://app.sainofirst.com/api-delivery-endpoint?customKey1=CustomValue1&customKey2=CustomValue2"
}
```

{% endtab %}
{% endtabs %}

#### Response:

After the request is successfully received at our server, response will be like below with ***`Status Code: 200`***

{% tabs %}
{% tab title="Response.json" %}

```javascript
{
    "status":true,
    "message":"Voice Call scheduled Successfully.",     
    "id":xyz // request-id for this request, can be used for future references.
}
```

{% endtab %}
{% endtabs %}

## Advanced Voice Call:   How to ***Configure*** Voice Call ?

*Advanced voice call*  is the voice call where Listener (or Receiver) will be able to interact even with the simple **pre-recorded** or **text-to-speech** voice call.\
\
**Features in Advance voice call:** &#x20;

* Repeat the same voice message again on press of 'Assigned' key.
* Forward the call to some other (predefined) number on press of 'Assigned' key.
* Capture the response of every phone key pressed by the user while the call is going on.

The `config` parameter of the request body is used to make a advanced voice call.

This parameter is a **JSON** Object which has two properties.

1. `repeat` -  Value must be a single digit number. On press of this number key, the call will be repeated.
2. `callTransfer` - Value is an object with two properties: \
   &#x20;                                  `transferKey` -  Value must be a single digit number. On press of this number key, the call will be repeated.

|    Parameter   |      Value Type     |                                                                                                              Description                                                                                                              |
| :------------: | :-----------------: | :-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
|    `repeat`    | Single Digit Number |                     <p></p><p>On press of this number key, the call will be repeated.</p><p></p><p><em>The vice call will be disconnected automatically when the <code>maxLengthOfCall</code> is reached.</em></p>                    |
| `callTransfer` |        Object       | <p> Must contain two properties inside this object. </p><p></p><ol><li><code>transferKey</code> - On press of this key, call will be forwarded.</li><li><code>transferNumber</code> - Number on which call to be forwarded.</li></ol> |

Example:-

{% tabs %}
{% tab title="Advanced-Voice-Config-PART.json" %}

```javascript
"config": { // optional        
    "repeat": 1, // If pressed, voice message will be repeated (maxLengthOfCall will be counted)        
    "callTransfer": {            
    "transferKey": 2, // While call is active, pressing this key will forward the call            
    "transferNumber": xxxxxxxxxx // Forward call to this Number         
    }    
},
```

{% endtab %}
{% endtabs %}

### Reports & Deliveries

In order to get delivery reports directly into your system you need to take care of few simple things.

* Please make sure that, the URL passed in the field `reportUrl`, **must accept** **`HTTP POST`** request with **`JSON`** request body.
* If you wish to get any additional data in the report callback, you should user query parameters and values in the URL itself.&#x20;

{% hint style="info" %}
If you don't pass the `reportUrl` parameter in request body, we will not be able to push the reports to your system. However, messages will still be delivered to the destination.
{% endhint %}


# Scheduled Voice Setting

There are many cases where you might need to change the Scheduled Time of voice call which you had scheduled earlier. To do so, use this API.

## Reschedule (Change) the Schedule Date of Voice Call

<mark style="color:orange;">`PUT`</mark> `<base_url>/bulk-voice/reschedule`

#### Request Body

| Name          | Type    | Description                                                                   |
| ------------- | ------- | ----------------------------------------------------------------------------- |
| voice\_id     | integer | Unique ID which was received in **response** while sending the voice call.    |
| new\_send\_at | integer | Epoch Time (time in milliseconds) as like Voice Call **`send_at`** parameter. |
| timezone      | string  | Timezone. Refer the Timezone Table for more information.                      |

{% tabs %}
{% tab title="200 " %}

```javascript
{    status: true,    message: "Voice call rescheduled successfully."}
```

{% endtab %}

{% tab title="400 " %}

```javascript
{    "status":false,    "message":"Information about why the request is rejected (in string format)"}
```

{% endtab %}

{% tab title="401 " %}

```javascript
{    "status":false,    "message":"Auth-Error root cause will be stated here."}
```

{% endtab %}

{% tab title="403 " %}

```javascript
{    "status":false,    "message":"Forbidded Resource Access."}
```

{% endtab %}

{% tab title="500 " %}

```javascript
{    "status":false,    "message":"Something Went Wrong"}
```

{% endtab %}
{% endtabs %}

### Example: Rescheduling/Changing the scheduled time of voice

A **`HTTP PUT`** request must have body in below format.

#### Request:

{% tabs %}
{% tab title="Rescheduled-Voice-Request.json" %}

```javascript
{    
"voice_id": XXX, // The Unique ID you got in response of Send-Voice call request.    
"new_send_at": 1569266700,    
"timezone": "Asia/Kolkata(GMT +05:30)" // timezone
}
```

{% endtab %}
{% endtabs %}

#### Response:

After the request is successfully received at our server, response will be like below with ***`Status Code: 200`***

{% tabs %}
{% tab title="Rescheduled-Voice-Response.json" %}

```javascript
{    status: true,    message: "Voice call rescheduled successfully."}
```

{% endtab %}
{% endtabs %}

## Cancel Scheduled Voice Call

If you have scheduled a voice call for future date/time, but because of any reason you may want to cancel the call, before it is actually sent to the recipient. To do so, this API comes handy. &#x20;

## Cancel Scheduled Voice Call

<mark style="color:red;">`DELETE`</mark> `<base_url>/bulk-voice/cancelScheduled/{voice_id}`

#### Path Parameters

| Name      | Type   | Description                                                              |
| --------- | ------ | ------------------------------------------------------------------------ |
| voice\_id | number | **Unique ID** which was received in the **response** of Send Voice Call. |

{% tabs %}
{% tab title="200 " %}

```javascript
{    status: true,     message: "Voice call cancelled successfully."}
```

{% endtab %}

{% tab title="400 " %}

```javascript
{    "status":false,    "message":"Information about why the request is rejected (in string format)"}
```

{% endtab %}

{% tab title="401 " %}

```javascript
{    "status":false,    "message":"Auth-Error root cause will be stated here."}
```

{% endtab %}

{% tab title="403 " %}

```javascript
{    "status":false,    "message":"Forbidded Resource Access."}
```

{% endtab %}

{% tab title="500 " %}

```javascript
{    "status":false,    "message":"Something Went Wrong"}
```

{% endtab %}
{% endtabs %}

### Example: Cancel/Delete The scheduled Voice Call

A **`HTTP DELTE`** request must have URL in below format.

#### Request URL:

{% tabs %}
{% tab title="" %}

```java
https://<base_url>/bulk-voice/cancelScheduled/207 
```

{% endtab %}
{% endtabs %}

{% hint style="success" %}
here, ***`207`*** is the Unique ID of Send Voice Call Request.
{% endhint %}

#### Response:

After the request is successfully received at our server, response will be like below with ***`Status Code: 200`***

{% tabs %}
{% tab title="Cancel-Scheduled-Voice-Response.json" %}

```javascript
{    status: true,    message: "Voice call cancelled successfully."}
```

{% endtab %}
{% endtabs %}


# Voice Language

Our voice API for text-to-speech feature supports below listed languages currently. We're working on to add support for more languages. Please get in touch with our team to know more.

| Language               | Code      | language\_id |
| ---------------------- | --------- | ------------ |
| English                | en        | 1            |
| English (British)      | en-gb     | 2            |
| English (Australian)   | en-au     | 3            |
| English (Indian)       | en-in     | 4            |
| English (Welsh)        | en-gb-wls | 5            |
| Spanish                | es        | 6            |
| Catalan                | ca        | 7            |
| Chinese-Simplified     | zh-cn     | 8            |
| Chinese-Traditional    | zh-tw     | 9            |
| Danish                 | da        | 10           |
| Dutch                  | nl        | 11           |
| French                 | fr        | 12           |
| German                 | de        | 13           |
| Italian                | it        | 14           |
| Japanese               | ja        | 15           |
| Korean                 | ko        | 16           |
| Norwegian              | no        | 17           |
| Polish                 | pl        | 18           |
| Portuguese             | pt-pt     | 19           |
| Portuguese - Brazilian | pt-br     | 20           |
| Russian                | ru        | 21           |
| Swedish                | sv        | 22           |
| Finnish                | fi        | 23           |
| Turkish                | tr        | 24           |
| Welsh                  | wls       | 25           |
| Arabic                 | ar        | 26           |
| Indonesian             | id        | 27           |
| Malay                  | ms        | 28           |
| Tamil                  | ta        | 29           |
| Thai                   | th        | 30           |
| Vietnamese             | vi        | 31           |


# Overview

What is an **email API**? An email API (application programming interface) gives applications access to the functionality available in an email platform, such as generating and sending transactional emails, manipulating templates, and enabling access to email metrics.

**Saino First** provides a service named **Email API**. An email API service allows you to send email communications to large lists of multiple recipients by incorporating email into your applications.&#x20;

Our email API allows you to send emails to users around the globe through simple RESTful APIs. You can send one email to many people, or a unique email to each person on your list with an email API service.

You can send marketing messages, newsletters, updates, coupons, and invitations through email API. <br>


# Send Email

## Send Email

<mark style="color:green;">`POST`</mark> `https://api.saino.io/api/apis/email/send`

This endpoint allows you to send an email.

#### Headers

| Name          | Type   | Description                                                                                                                                                                                                                                                                            |
| ------------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Authorization | string | <p>It is a bearer authentication token to validate request coming from a valid user or not. You can get this token from Saino first account from API keys section.<br><br>if you passing  programmtically then follow below approach: <br><br>Authorization: "Bearer " + API\_KEY </p> |

#### Request Body

| Name         | Type    | Description                                                                                                                                                                                                 |
| ------------ | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| to           | array   | This is **to** contain **email ids** where you need to send emails. you can add multiple email ids where you need to send emails                                                                            |
| subject      | string  | This contains email subject                                                                                                                                                                                 |
| from         | string  | <p>This is a from email id. you can assigned only verified email id. you can verify from email id from sainofirst dashboard by below-specified section.<br>dashboard -> bulk email -> settings-> domain</p> |
| fromName     | string  | Display name for from email address                                                                                                                                                                         |
| bodyHtml     | string  | <p>This field used to send html content in email <br><strong>either bodyHtml or bodyText is required</strong></p>                                                                                           |
| bodyText     | string  | <p>This field used to send normal text content in email<br><strong>either bodyHtml or bodyText is required</strong></p>                                                                                     |
| trackClicks  | boolean | Should the click be tracked? If no value has been provided, Account's default setting will be used.                                                                                                         |
| trackOpens   | boolean | Should the opens be tracked? If no value has been provided, Account's default setting will be used                                                                                                          |
| replyToEmail | string  | Email address to reply to                                                                                                                                                                                   |
| replyToName  | string  | Name to replay to name                                                                                                                                                                                      |
| attachments  | array   | <p>An array of ID's of attachments.<br>Note: you can get attachment id from uploading attachment by upload attachment API</p>                                                                               |
| callbackUrl  | string  | Call back where you received notifications related to email.                                                                                                                                                |

{% tabs %}
{% tab title="200 Cake successfully retrieved." %}

```javascript
{ 
    status: true, 
    message: "Success",
    campaignId:"8asd6sx-as6tasvdt-asdg532v"
}
```

{% endtab %}

{% tab title="400 Whenever some fields missings or invalid values present. " %}

```javascript
{ 
    status: false, 
    error: "Some required fields missings" 
}
```

{% endtab %}

{% tab title="401 Whener ver user access with invalid authorasation key." %}

```javascript
{    
    message: "Unauthorised" 
}
```

{% endtab %}
{% endtabs %}

## Callback Url response

below is the notification response received in provided callback url related to each email id.

```javascript
{
    emailId: "test@test.com",  //provided to email id
    status: "sent/opened/clicked/bounce/complaint/unsubscribed", //this is email status
    campaignId: "8asd6sx-as6tasvdt-asdg532v"  //campaign id to identify
}
```

## Examples

{% tabs %}
{% tab title="NodeJs" %}

```javascript
var axios = require('axios');
var data = JSON.stringify(
  {
    "to":["test@gmail.com"],
    "subject":"API test 1",
    "from":"test@domain.com",
    "fromName":"sahil",
    "bodyHtml":"<h1>Test 1</h1>",
    "trackClicks":true,
    "trackOpens":true,
    "replyToEmail":"test2@domain2.com",
    "attachments":[],
    "replyToName":"sam",
    "bodyText":"Just Text Email",
    "callbackUrl":"https://domain.com/webhook"
  }
);

var config = {
  method: 'post',
  url: 'https://api.saino.io/api/apis/email/send',
  headers: { 
    'Authorization': 'Bearer 808ciij4p18351yml==/pitzkg67bizz0qce1599144457846', 
    'Content-Type': 'application/json'
  },
  data : data
};

axios(config).then(function (response) {
  console.log(JSON.stringify(response.data));
})
.catch(function (error) {
  console.log(error);
});

```

{% endtab %}

{% tab title="PHP" %}

```php
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://api.saino.io/api/apis/email/send",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS =>"{\n     \"to\":[\"test@gmail.com\"], \n     \"subject\":\"API test 1\", \n     \"from\":\"test@domain.com\", \n     \"fromName\":\"sainofirst\", \n     \"bodyHtml\":\"<h1>Test 1</h1>\", \n     \"trackClicks\":true, \n     \"trackOpens\":true, \n     \"replyToEmail\":\"test2@sainofirst.com\", \n     \"attachments\":[], \n     \"replyToName\":\"sainofirst2\", \n     \"bodyText\":\"Just Text Email\",\n     \"callbackUrl\":\"https://domain.com/webhook\"\n}",
  CURLOPT_HTTPHEADER => array(
    "Authorization: Bearer 808ciij4p1835zba8ykvkw9p==/pitzkg67bizz0qce1599144457846",
    "Content-Type: application/json"
  ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;

```

{% endtab %}

{% tab title="Python" %}

```
import requests

url = "https://api.saino.io/api/apis/email/send"

payload = "{\n     \"to\":[\"test@gmail.com\"], \n     \"subject\":\"API test 1\", \n     \"from\":\"test@domain.com\", \n     \"fromName\":\"sainofirst\", \n     \"bodyHtml\":\"<h1>Test 1</h1>\", \n     \"trackClicks\":true, \n     \"trackOpens\":true, \n     \"replyToEmail\":\"test2@sainofirst.com\", \n     \"attachments\":[], \n     \"replyToName\":\"sainofirst2\", \n     \"bodyText\":\"Just Text Email\",\n     \"callbackUrl\":\"https://domain.com/webhook\"\n}"
headers = {
  'Authorization': 'Bearer 808ciij4p1835h8gkybgzba8ykvkw9pz0qce1599144457846',
  'Content-Type': 'application/json'
}

response = requests.request("POST", url, headers=headers, data = payload)

print(response.text.encode('utf8'))

```

{% endtab %}

{% tab title="C" %}

```c
CURL *curl;
CURLcode res;
curl = curl_easy_init();
if(curl) {
  curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
  curl_easy_setopt(curl, CURLOPT_URL, "https://api.saino.io/api/apis/email/send");
  curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
  curl_easy_setopt(curl, CURLOPT_DEFAULT_PROTOCOL, "https");
  struct curl_slist *headers = NULL;
  headers = curl_slist_append(headers, "Authorization: Bearer 808ciij4p18351v9rh8gkybgzba8ykvkw9p==/pitzkg67bizz0q99144457846");
  headers = curl_slist_append(headers, "Content-Type: application/json");
  curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
  const char *data = "{\n     \"to\":[\"test@gmail.com\"], \n     \"subject\":\"API test 1\", \n     \"from\":\"test@domain.com\", \n     \"fromName\":\"sainofirst\", \n     \"bodyHtml\":\"<h1>Test 1</h1>\", \n     \"trackClicks\":true, \n     \"trackOpens\":true, \n     \"replyToEmail\":\"test2@sainofirst.com\", \n     \"attachments\":[], \n     \"replyToName\":\"sainofirst2\", \n     \"bodyText\":\"Just Text Email\",\n     \"callbackUrl\":\"https://domain.com/webhook\"\n}";
  curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);
  res = curl_easy_perform(curl);
}
curl_easy_cleanup(curl);

```

{% endtab %}

{% tab title="C#" %}

```csharp
var client = new RestClient("https://api.saino.io/api/apis/email/send");
client.Timeout = -1;
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer 808ciijv9rzg5h8gkybgzba8ykvkw9p==/dsaddadasdda");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n     \"to\":[\"test@gmail.com\"], \n     \"subject\":\"API test 1\", \n     \"from\":\"test@domain.com\", \n     \"fromName\":\"sainofirst\", \n     \"bodyHtml\":\"<h1>Test 1</h1>\", \n     \"trackClicks\":true, \n     \"trackOpens\":true, \n     \"replyToEmail\":\"test2@sainofirst.com\", \n     \"attachments\":[], \n     \"replyToName\":\"sainofirst2\", \n     \"bodyText\":\"Just Text Email\",\n     \"callbackUrl\":\"https://domain.com/webhook\"\n}",  ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
Console.WriteLine(response.Content);
```

{% endtab %}

{% tab title="HTTP" %}

```http
POST /api/apis/email/send HTTP/1.1
Host: api.saino.io
Authorization: Bearer 808ciij4p18351ymliiznhybgzba8ykvkw9p==/qce1599144457846
Content-Type: application/json

{
     "to":["test@gmail.com"], 
     "subject":"API test 1", 
     "from":"test@domain.com", 
     "fromName":"sainofirst", 
     "bodyHtml":"<h1>Test 1</h1>", 
     "trackClicks":true, 
     "trackOpens":true, 
     "replyToEmail":"test2@sainofirst.com", 
     "attachments":[], 
     "replyToName":"sainofirst2", 
     "bodyText":"Just Text Email",
     "callbackUrl":"https://domain.com/webhook"
}
```

{% endtab %}

{% tab title="JAVA" %}

```java
OkHttpClient client = new OkHttpClient().newBuilder()
  .build();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "{\n     \"to\":[\"test@gmail.com\"], \n     \"subject\":\"API test 1\", \n     \"from\":\"test@domain.com\", \n     \"fromName\":\"sainofirst\", \n     \"bodyHtml\":\"<h1>Test 1</h1>\", \n     \"trackClicks\":true, \n     \"trackOpens\":true, \n     \"replyToEmail\":\"test2@sainofirst.com\", \n     \"attachments\":[], \n     \"replyToName\":\"sainofirst2\", \n     \"bodyText\":\"Just Text Email\",\n     \"callbackUrl\":\"https://domain.com/webhook\"\n}");
Request request = new Request.Builder()
  .url("https://api.saino.io/api/apis/email/send")
  .method("POST", body)
  .addHeader("Authorization", "Bearer 808ciij4p183hrkv9rzg5h8gkybgzba8yasdp==/sadsd")
  .addHeader("Content-Type", "application/json")
  .build();
Response response = client.newCall(request).execute();
```

{% endtab %}

{% tab title="SWIFT" %}

```swift
import Foundation

var semaphore = DispatchSemaphore (value: 0)

let parameters = "{\n     \"to\":[\"test@gmail.com\"], \n     \"subject\":\"API test 1\", \n     \"from\":\"test@domain.com\", \n     \"fromName\":\"sainofirst\", \n     \"bodyHtml\":\"<h1>Test 1</h1>\", \n     \"trackClicks\":true, \n     \"trackOpens\":true, \n     \"replyToEmail\":\"test2@sainofirst.com\", \n     \"attachments\":[], \n     \"replyToName\":\"sainofirst2\", \n     \"bodyText\":\"Just Text Email\",\n     \"callbackUrl\":\"https://domain.com/webhook\"\n}"
let postData = parameters.data(using: .utf8)

var request = URLRequest(url: URL(string: "https://api.saino.io/api/apis/email/send")!,timeoutInterval: Double.infinity)
request.addValue("Bearer 808ciij4pzba8ykvkw9p==/pitzkg99144457846", forHTTPHeaderField: "Authorization")
request.addValue("application/json", forHTTPHeaderField: "Content-Type")

request.httpMethod = "POST"
request.httpBody = postData

let task = URLSession.shared.dataTask(with: request) { data, response, error in 
  guard let data = data else {
    print(String(describing: error))
    return
  }
  print(String(data: data, encoding: .utf8)!)
  semaphore.signal()
}

task.resume()
semaphore.wait()
```

{% endtab %}
{% endtabs %}


# Upload Attachment

Below API used to upload attachments in sainofirst platform.\
Purpose of API is whenever the user wants to send an attachment in the email. user need to upload attachment in sainofirst platform first. sainofirst will provide id represents to attachment. and the user can send this id in send email API's attachment field to send attachment along with the email. &#x20;

## Upload Attachment&#x20;

<mark style="color:green;">`POST`</mark> `https://api.saino.io/api/apis/email/upload-attachment`

#### Headers

| Name          | Type   | Description                                                                                                                                                                                                                                                                     |
| ------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| content-type  | string | multipart/form-data with document boundary                                                                                                                                                                                                                                      |
| Authorization | string | <p>It is a bearer Authorization token to validate request coming from a valid user or not. you can get this token from sainofirst account from API keys section. <br><br>If you passing programatically then follow below approch:<br><br>Authorization: "Bearer "+API\_KEY</p> |

#### Request Body

| Name | Type   | Description      |
| ---- | ------ | ---------------- |
| file | object | binary file data |

{% tabs %}
{% tab title="200 " %}

```javascript
{
    status: true, 
    data: { 
        attachment_id: 100,  //id used in send email
        file_size: 100,   //in bytes
        content_type: "<<file_content_type>>", 
        filename: "<<file_name>>" 
    } 
}
```

{% endtab %}

{% tab title="302 Whenever Invalid data comes" %}

```javascript
{ 
    status: false, 
    error: "Not able to process your request" 
}
```

{% endtab %}

{% tab title="401 Whenever user access with invalid authorization key" %}

```javascript
{    
    message: "Unauthorised" 
}
```

{% endtab %}
{% endtabs %}

## Examples

{% tabs %}
{% tab title="NodeJs" %}

```javascript
var axios = require('axios');
var FormData = require('form-data');
var fs = require('fs');
var data = new FormData();
data.append('file', fs.createReadStream('/path-to-file'));

var config = {
  method: 'post',
  url: 'https://api.saino.io/api/apis/email/upload-attachment',
  headers: { 
    'Authorization': 'Bearer 808ciij4p1g5h8gkybgzba8ykvkw9pitzkg67bizz0qce', 
    ...data.getHeaders()
  },
  data : data
};

axios(config)
.then(function (response) {
  console.log(JSON.stringify(response.data));
})
.catch(function (error) {
  console.log(error);
});

```

{% endtab %}

{% tab title="PHP" %}

```php
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://api.saino.io/api/apis/email/upload-attachment",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => array('file'=> new CURLFILE('/path-to-file')),
  CURLOPT_HTTPHEADER => array(
    "Authorization: Bearer rzg5h8gkybgzba8ykvkw9p==/1599144457846"
  ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

url = "https://api.saino.io/api/apis/email/upload-attachment"

payload = {}
files = [
  ('file', open('/path-to-file','rb'))
]
headers = {
  'Authorization': 'Bearer nhrk67bizz0qce1599144457846',
}

response = requests.request("POST", url, headers=headers, data = payload, files = files)

print(response.text.encode('utf8'))

```

{% endtab %}

{% tab title="C" %}

```c
CURL *curl;
CURLcode res;
curl = curl_easy_init();
if(curl) {
  curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
  curl_easy_setopt(curl, CURLOPT_URL, "https://api.saino.io/api/apis/email/upload-attachment");
  curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
  curl_easy_setopt(curl, CURLOPT_DEFAULT_PROTOCOL, "https");
  struct curl_slist *headers = NULL;
  headers = curl_slist_append(headers, "Authorization: Bearer 808ciij4p18351ymliiznhrk599144457846");
  curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
  curl_mime *mime;
  curl_mimepart *part;
  mime = curl_mime_init(curl);
  part = curl_mime_addpart(mime);
  curl_mime_name(part, "file");
  curl_mime_filedata(part, "/path-to-file");
  curl_easy_setopt(curl, CURLOPT_MIMEPOST, mime);
  res = curl_easy_perform(curl);
  curl_mime_free(mime);
}
curl_easy_cleanup(curl);

```

{% endtab %}

{% tab title="C#" %}

```csharp
var client = new RestClient("https://api.saino.io/api/apis/email/upload-attachment");
client.Timeout = -1;
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer ymlipitzkg67bizz0qce1599144457846");
request.AddFile("file", "/path-to-file");
IRestResponse response = client.Execute(request);
Console.WriteLine(response.Content);
```

{% endtab %}

{% tab title="HTTP" %}

```http
POST /api/apis/email/upload-attachment HTTP/1.1
Host: api.saino.io
Authorization: Bearer hrkv9rzg5hpitzkg67bizz0qce1599144457846
Cookie: Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW

----WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="file"; filename="tets.csv"
Content-Type: text/csv

(data)
----WebKitFormBoundary7MA4YWxkTrZu0gW

```

{% endtab %}

{% tab title="JAVA" %}

```java
OkHttpClient client = new OkHttpClient().newBuilder()
  .build();
  
MediaType mediaType = MediaType.parse("text/plain");

RequestBody body = new MultipartBody.Builder().setType(MultipartBody.FORM)
  .addFormDataPart("file","tets.csv",
    RequestBody.create(MediaType.parse("application/octet-stream"),
    new File("/path-to-file")))
  .build();
  
Request request = new Request.Builder()
  .url("https://api.saino.io/api/apis/email/upload-attachment")
  .method("POST", body)
  .addHeader("Authorization", "Bearer iznhrkv9rzg5h8gkybgzba8ykvqce1599144457846")
  .addHeader("Cookie", "__cfduid=df667dc82cf64d09c75ae34d29e9053bb1598528453")
  .build();
  
Response response = client.newCall(request).execute();
```

{% endtab %}

{% tab title="SWIFT" %}

```swift
import Foundation

var semaphore = DispatchSemaphore (value: 0)

let parameters = [
  [
    "key": "file",
    "src": "/path-to-file",
    "type": "file"
  ]] as [[String : Any]]

let boundary = "Boundary-\(UUID().uuidString)"
var body = ""
var error: Error? = nil
for param in parameters {
  if param["disabled"] == nil {
    let paramName = param["key"]!
    body += "--\(boundary)\r\n"
    body += "Content-Disposition:form-data; name=\"\(paramName)\""
    let paramType = param["type"] as! String
    if paramType == "text" {
      let paramValue = param["value"] as! String
      body += "\r\n\r\n\(paramValue)\r\n"
    } else {
      let paramSrc = param["src"] as! String
      let fileData = try NSData(contentsOfFile:paramSrc, options:[]) as Data
      let fileContent = String(data: fileData, encoding: .utf8)!
      body += "; filename=\"\(paramSrc)\"\r\n"
        + "Content-Type: \"content-type header\"\r\n\r\n\(fileContent)\r\n"
    }
  }
}
body += "--\(boundary)--\r\n";
let postData = body.data(using: .utf8)

var request = URLRequest(url: URL(string: "https://api.saino.io/api/apis/email/upload-attachment")!,timeoutInterval: Double.infinity)
request.addValue("Bearer 808ciij4pitzkg67bizz0qce1599144457846", forHTTPHeaderField: "Authorization")
request.addValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")

request.httpMethod = "POST"
request.httpBody = postData

let task = URLSession.shared.dataTask(with: request) { data, response, error in 
  guard let data = data else {
    print(String(describing: error))
    return
  }
  print(String(data: data, encoding: .utf8)!)
  semaphore.signal()
}

task.resume()
semaphore.wait()

```

{% endtab %}
{% endtabs %}


# Overview

Our verification API allows you to create Custom Integrations to add email verification or Email cleaning to any part of your software.&#x20;

We offer solutions for verifying individual emails as well as lists containing thousands of emails.

Saino bulk email cleaning or verification application provide two verification API's. one for single email cleaning and another for bulk email file cleaning.

Bulk file cleaning API used for uploading a file in Saino appilcations. but this process will take time. based on file size and number of emails inside file time will increase. so for that second API added for bulk email progress for checking the status of a file.


# Single Email

## Verify Signle Email

<mark style="color:blue;">`GET`</mark> `https://api.saino.io/api/apis/email-cleaning/verify-single`

This Endpoint you will used for verifying single email id

#### Query Parameters

| Name  | Type   | Description                        |
| ----- | ------ | ---------------------------------- |
| email | string | Email id which you want to verify. |

#### Headers

| Name  | Type   | Description                                 |
| ----- | ------ | ------------------------------------------- |
| token | string | The token provided by the saino application |

{% tabs %}
{% tab title="200 " %}

```
{
   "data":{
      "email":"any@gmail.com",
      "free_email":"true",
      "result":"Safe to Send / Unsafe to Send",
      "status":"Deliverable"
   },
   "status":"success"
}

```

{% endtab %}

{% tab title="400 " %}

```
{
    status: "failed",
    error: "" //error message
}
```

{% endtab %}
{% endtabs %}

#### Examples

{% tabs %}
{% tab title="NodeJs" %}

```
var axios = require('axios');

var config = {
  method: 'get',
  url: 'https://api.saino.io/api/apis/email-cleaning/verify-single?email=user@domain.com',
  headers: { 
    'token': '7yq7x1hlydj8hyxccfjo130m7usey6g6dyrdmc61al5411m==/twidh21609584683074'
  }
};

axios(config)
.then(function (response) {
  console.log(JSON.stringify(response.data));
})
.catch(function (error) {
  console.log(error);
});

```

{% endtab %}

{% tab title="PHP-HTTP" %}

```
<?php
require_once 'HTTP/Request2.php';
$request = new HTTP_Request2();
$request->setUrl('https://testt.gomnp.com/api/apis/email-cleaning/verify-single?email=usr@domain.com');
$request->setMethod(HTTP_Request2::METHOD_GET);
$request->setConfig(array(
  'follow_redirects' => TRUE
));
$request->setHeader(array(
  'token' => '7yq7x1hlydj8hyxccfjo130msey6g6d5411m==/tw084683074'
));
try {
  $response = $request->send();
  if ($response->getStatus() == 200) {
    echo $response->getBody();
  }
  else {
    echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' .
    $response->getReasonPhrase();
  }
}
catch(HTTP_Request2_Exception $e) {
  echo 'Error: ' . $e->getMessage();
}
```

{% endtab %}

{% tab title="JQuery" %}

```
var settings = {
  "url": "https://api.saino.io/api/apis/email-cleaning/verify-single?email=user@doamin.com",
  "method": "GET",
  "timeout": 0,
  "headers": {
    "token": "7yq7x1hlydj8hyxccfjo13rdmc61al5411m==/twi9584683074"
  },
};

$.ajax(settings).done(function (response) {
  console.log(response);
});
```

{% endtab %}

{% tab title="Python" %}

```
import requests

url = "https://api.saino.io/api/apis/email-cleaning/verify-single?email=sahil@sainofirst.com"

payload={}
headers = {
  'token': '7yq7x1hlydj8hyxccfjo130m6e8v121609584683074',
}

response = requests.request("GET", url, headers=headers, data=payload)

print(response.text)

```

{% endtab %}
{% endtabs %}


# Bulk Email

Bulk email cleaning is a process where you can upload any .txt / .csv / .xlsx file for email cleaning. At one time the only one file can be accepted over API.

The file must be less than 15MB in size and includes a maximum of 100,000 emails.

The header of the email column inside file should be "emails" for identification of email list inside the file.

## Bulk Email Clean

<mark style="color:green;">`POST`</mark> `https://api.saino.io/api/apis/email-cleaning/verify-bulk`

This endpoint allows you to upload bulk email file for cleaning

#### Headers

| Name  | Type   | Description                             |
| ----- | ------ | --------------------------------------- |
| token | string | The token provided by Saino application |

#### Request Body

| Name | Type   | Description                                                 |
| ---- | ------ | ----------------------------------------------------------- |
| file | object | your .csv/.txt/.xlsx file in form-data format (blob format) |

{% tabs %}
{% tab title="200 " %}

```
{
     status: "success",
     bulk_id: 1002,
     message: "Successfully added in queue"
}
```

{% endtab %}

{% tab title="400 " %}

```
{
     status: "failed",
     error: '' //errors
}
```

{% endtab %}
{% endtabs %}

#### Examples

{% tabs %}
{% tab title="Nodejs" %}

```
var request = require('request');
var fs = require('fs');
var options = {
  'method': 'POST',
  'url': 'https://api.saino.io/api/apis/email-cleaning/verify-bulk',
  'headers': {
    'token': '7yq7x1hlydj8hyxccfg6dy6rdmc61al5411mtwid609584683074',
  },
  formData: {
    'file': {
      'value': fs.createReadStream('/path-to-file/test1.csv'),
      'options': {
        'filename': 'test1.csv',
        'contentType': null
      }
    }
  }
};
request(options, function (error, response) {
  if (error) throw new Error(error);
  console.log(response.body);
});

```

{% endtab %}

{% tab title="PHP" %}

```
<?php
require_once 'HTTP/Request2.php';
$request = new HTTP_Request2();
$request->setUrl('https://api.saino.io/api/apis/email-cleaning/verify-bulk');
$request->setMethod(HTTP_Request2::METHOD_POST);
$request->setConfig(array(
  'follow_redirects' => TRUE
));
$request->setHeader(array(
  'token' => '7yq7x1hlydj8hyxccfjo13011m==/tw121609584683074',
));
$request->addUpload('file', '/path-to-file/test1.csv', 'test1.csv', '<Content-Type Header>');
try {
  $response = $request->send();
  if ($response->getStatus() == 200) {
    echo $response->getBody();
  }
  else {
    echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' .
    $response->getReasonPhrase();
  }
}
catch(HTTP_Request2_Exception $e) {
  echo 'Error: ' . $e->getMessage();
}
```

{% endtab %}

{% tab title="JQUERY" %}

```
var form = new FormData();
form.append("file", fileInput.files[0], "test1.csv");

var settings = {
  "url": "https://api.saino.io/api/apis/email-cleaning/verify-bulk",
  "method": "POST",
  "timeout": 0,
  "headers": {
    "token": "7yq7x1hlydj8hy6rdmc61al5411609584683074",
  },
  "processData": false,
  "mimeType": "multipart/form-data",
  "contentType": false,
  "data": form
};

$.ajax(settings).done(function (response) {
  console.log(response);
});
```

{% endtab %}

{% tab title="Python" %}

```
import requests

url = "https://api.saino.io/api/apis/email-cleaning/verify-bulk"

payload={}
files=[
  ('file',('test1.csv',open('/path-to-file/test1.csv','rb'),'text/csv'))
]
headers = {
  'token': '7yq7x1hlydj8hyxccfjo1969f46e8v121609584683074',
}

response = requests.request("POST", url, headers=headers, data=payload, files=files)

print(response.text)

```

{% endtab %}
{% endtabs %}


# Bulk Email Progress / Status

## Get Bulk Email Progress Status

<mark style="color:blue;">`GET`</mark> `https://api.saino.io/api/apis/email-cleaning/bulk-progress`

This endpoint allows you to get progress of bulk email cleaning progress.

#### Query Parameters

| Name     | Type    | Description                                                           |
| -------- | ------- | --------------------------------------------------------------------- |
| bulk\_id | integer | Bulk process id which you got from bullk email cleaning api response. |

#### Headers

| Name  | Type   | Description                              |
| ----- | ------ | ---------------------------------------- |
| token | string | The token provided by saino application. |

{% tabs %}
{% tab title="200 " %}

```
{
    "data": {
        "bulk_id": 1002,
        "status": "completed",
        "percentage": 100,
        "download_link": "https://sfeclean.s3.ap-south-1.amazonaws.com/email-cleaner/report/final_verified_8961ea-2017-421a-a919-a1b2183ad86f_test1.csv.csv"
    },
    "status": "success"
}
```

{% endtab %}

{% tab title="400 " %}

```
{
     status: "failed",
     error: '' //errors
}
```

{% endtab %}
{% endtabs %}

#### Examples

{% tabs %}
{% tab title="NodeJs" %}

```
var request = require('request');
var options = {
  'method': 'GET',
  'url': 'https://api.saino.io/api/apis/email-cleaning/bulk-progress?bulk_id=95',
  'headers': {
    'token': '7yq7x1hlydj8hyxccf61al5411m==/twidh969f9584683074',
  }
};
request(options, function (error, response) {
  if (error) throw new Error(error);
  console.log(response.body);
});

```

{% endtab %}

{% tab title="PHP" %}

```
<?php
require_once 'HTTP/Request2.php';
$request = new HTTP_Request2();
$request->setUrl('https://api.saino.io/api/apis/email-cleaning/bulk-progress?bulk_id=95');
$request->setMethod(HTTP_Request2::METHOD_GET);
$request->setConfig(array(
  'follow_redirects' => TRUE
));
$request->setHeader(array(
  'token' => '7yq7x1hlydj8hyxccfjomc61al5411m==/twid21609584683074'
));
try {
  $response = $request->send();
  if ($response->getStatus() == 200) {
    echo $response->getBody();
  }
  else {
    echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' .
    $response->getReasonPhrase();
  }
}
catch(HTTP_Request2_Exception $e) {
  echo 'Error: ' . $e->getMessage();
}
```

{% endtab %}

{% tab title="JQUERY" %}

```
var settings = {
  "url": "https://api.saino.io/api/apis/email-cleaning/bulk-progress?bulk_id=95",
  "method": "GET",
  "timeout": 0,
  "headers": {
    "token": "7yq7x1hlydj8hyxccfjo130mc61al5411m==/twi46e8v584683074",
  },
};

$.ajax(settings).done(function (response) {
  console.log(response);
});
```

{% endtab %}

{% tab title="Python" %}

```
import requests

url = "https://api.saino.io/api/apis/email-cleaning/bulk-progress?bulk_id=95"

payload={}
headers = {
  'token': '7yq7x1hlydj8hyxccfjordmc61al8v121609584683074',
}

response = requests.request("GET", url, headers=headers, data=payload)

print(response.text)

```

{% endtab %}
{% endtabs %}


# Account & Balance Info

## Check your account information balance

<mark style="color:blue;">`GET`</mark> `<base_url>/my-account?token=<YOUR_API_TOKEN>`

Sometimes you may need to check your balance before sending any SMS, Voice Call or using any services provided by the SainoFirst  platform, use this API to do so.

#### Query Parameters

| Name  | Type   | Description                            |
| ----- | ------ | -------------------------------------- |
| token | string | Your API token (always keep it secret) |

{% tabs %}
{% tab title="200 Account info successfully retrieved." %}

```javascript
{
  "status": true,
  "message": "Successfully Retrived Details.",
  "data": {
    "userId": <your_user_id>,
    "userRole": "<USER_ROLE_STRING>",
    "userName": "<USER_NMAE_STRING>",
    "emailId": "<EMAIL_ID_STRING>",
    "mobileNumber": "<MOBILE_NUMBER_STRING>",
    "contactDetails": {
      "clientName": "<CLIENT_NAME_STRING>",
      "companyName": "<COMPANY_NMAE_STRING>",
      "designation": "<DESIGNATION_STRING>",
      "address": "<ADDRESS_STRING>",
      "city": "<CITY_STRING>",
      "country": "<COUNTRY_STRING>",
      "pincode": "<ZIPCODE_STRING>",
      "state": "<STATE_STRING>",
      "website": "<WEBSITE_STRING>",
      "faxNumber": <fax_number>,
      "taxNumber": "<TAX_NUMBER_OR_ID_STRING>"
    },
    "profile": {
      "language": "<USER_LANGUAGE_STRING>",
      "timezone": "<USER_TIMEZONE_STRING>",
      "currency": "USER_CURRENCY_STRING",
      "balance": <balance_decimal>
    },
    /* Apps allowed only for current API token (token passed in request url)
    *  will be shown here
    */
    "appsAvailable": [
      "BULK_SMS",
      "BULK_VOICE",
      "MISSED_CALL",
      "SHORT_CODE",
      "IVR_TOLL",
      "WHATSAPP",
      "SMPP"
    ]
  }
}
```

{% endtab %}

{% tab title="404 Could not find data." %}

```javascript
{
    status: false, 
    message: "No such user found." // Reason or Error Messgae.
}
```

{% endtab %}

{% tab title="500 Something went wrong on our side while processing your request." %}

```javascript
{
    status: false, 
    message: "Unable to fetch account details." // Reason or Error Messgae.
}
```

{% endtab %}
{% endtabs %}


