API Documentation

Introduction

Welcome to the Sift Documentation!

Sift identifies certain types of emails and parses email content so you can deliver a richer experience to your users. Sift can parse emails from a variety of domains. A comprehensive list of supported domains is available here.

There are 2 ways to interact with Sift: via API and via email connection.

To use Sift via API, follow the instructions on your account home page to forward an email to the specified address or run the sample code. You’ll receive an email with the parsed results. Using Sift via API gives you control over when and which emails of your choosing are parsed.

To use Sift via email connection, follow the instructions below. Using Sift via email connection ensures that all emails are parsed in real-time. For new connected email, we will process back all emails in last 3 months

SDKs are available for Python, Java, Ruby and Node.js developers. Additionally, code samples are provided for PHP and the various SDKs below.

OAuth Setup

Sift supports 5 kinds of email connections:

  • Gmail OAuth2

  • Yahoo OAuth2

  • Hotmail / Microsoft Live OAuth2

  • IMAP

  • Exchange (EWS)

All of the above are optional and you can choose to ignore the ones you won’t be using. For instance, if you only wish to allow your users to connect a Gmail account then you only need to follow the setup for Gmail OAuth2.

OAuth 2.0 is a commonly used open standard to authorize email access to third-party applications. Using OAuth provides Sift with the access tokens necessary to access user email accounts and parse emails in real-time.

Sift supports getting OAuth2 connections for Gmail, Yahoo and Hotmail / Microsoft Live. Instructions on how to set up for each provider can be found below.

Gmail

  1. Register for a Google Developer Account and create a new Project, if not done already.

  2. Enable Google+ API and Gmail API for your project.

  3. Create a new Client ID with the following settings:

    • Application type: Web Application

    • Authorized JavaScript origins: blank

    • Redirect URIs: https://api.easilydo.com/v1/connect_email/gmail_callback

  4. Copy the generated Client ID and the Client Secret.

  5. Login to Sift Developer Dashboard and go to the OAuth Settings page.

  6. Paste the Client ID from Step 3 under the Google OAuth section and press Enter.

  7. Paste the Client Secret from Step 3 under the Google OAuth section and press Enter.

Google OAuth reference: https://developers.google.com/identity/protocols/OAuth2

Required scope: email https://mail.google.com/

Yahoo

  1. Register for a Yahoo Developer Account, if not done already.

  2. Create a new App with the following settings:

    • Access Scopes: This app requires access to private user data.

    • Callback Domain: https://api.easilydo.com

    • Select APIs for private user data access: Mail Web Service - Read/Write (Full Access)

  3. Copy the generated Client ID and the Client Secret.

  4. Login to Sift Developer Dashboard and go to the OAuth Settings page.

  5. Paste the Client ID from Step 3 under the Yahoo OAuth section and press Enter.

  6. Paste the Client Secret from Step 3 under the Yahoo OAuth section and press Enter.

Yahoo OAuth reference: https://developer.yahoo.com/oauth2/guide/

Required scope: mail-x

Hotmail / Microsoft Live

  1. Register for a Live Developer Account, if not done already.

  2. Create a new App with the following settings:

    • Redirect URLs: https://api.easilydo.com/v1/connect_email/live_callback

  3. Copy the generated Client ID and the Client Secret.

  4. Login to Sift Developer Dashboard and go to the OAuth Settings page.

  5. Paste the Client ID from Step 3 under the Microsoft Live OAuth section and press Enter.

  6. Paste the Client Secret from Step 3 under the Microsoft Live OAuth section and press Enter.

Live OAuth reference: https://msdn.microsoft.com/en-us/library/hh243647.aspx

Required scope: wl.emails, wl.imap, wl.offline_access

Sift SDKs

Sift support 5 kinds of SDKs:

  • Python SDK

  • Java SDK

  • Ruby SDK

  • Node.js SDK

  • PHP SDK

Python SDK

The Python SDK currently supports Python 2.7.11 and 3.5.1, and the requests package is required.

Installation

We recommend using pip to install the SDK.

pip install siftapi

Java SDK

A Java library acting as a convenient interface to the Sift API. Java 7 and above supported. Sample code for the various apis can be seen below.

Installation

We recommend using Apache Maven to install the SDK. If using Apache Ant, add the following to your build.xml:

<dependency groupId="com.easilydo" artifactId="sift-sdk" version="1.0.0"/>

The SDK uses Simple Logging Facade for logging. It is necessary to include the appropriate jar for your logging framework as a dependency, if you want to enable logging for the sdk. For example:

<dependency groupId="org.slf4j" artifactId="slf4j-simple" version="1.7.13"/>

Ruby SDK

The Ruby SDK requires Ruby 2.0.0 or greater.

Installation

We recommend using RubyGems to install the SDK.

gem install sift_email_api

Node.js SDK

The npm package requires Node 5.0.0 and NPM v3.3.10

Installation

We recommend using NPM to install the SDK.

npm install siftapi

Documentation and source code can be found in the GitHub repository here. Report any issues with GitHub.

PHP SDK

The PHP SDK requires PHP 5.4 or greater, or PHP 7.0 or greater.

Installation

We recommend using composer to install the SDK.

php composer.phar require easilydo/sift-php-sdk

Documentation and source code can be found in the GitHub repository here. Report any issues with GitHub.

Endpoints

All API access is over HTTPS, and accessed with the https://api.easilydo.com domain.

A comprehensive list of supported endpoints is documented below:

Common Request Parameters

This section outlines the common parameters that all Sift API endpoints require. (unless otherwise specified)

Parameter

Description

api_key

The API Key provided by Sift. This can be found at the Sift Dashboard, under Account Info.

timestamp

The current timestamp, in epoch seconds (seconds since January 1st, 1970)

signature

A cryptographic signature that is generated for every request. Detailed instructions on how to generate this signature can be found here.

Signature Generation

This section describes the process of generating the signature that is required as a parameter in many Sift APIs.

Generating the signature requires the API Secret, which can be retrieved from the Sift Dashboard, under the Account Info section.

Once the API Secret is acquired, the signature can be generated using the following steps:

  • Start with an empty string as the base string

  • Append the uppercase HTTP method of the API Endpoint to the base string.
    Example: "GET"

  • Append a single "&" character to the base string.
    Example: "GET&"

  • Append the path of the API Endpoint without the host or any parameters.
    Example: "GET&/v1/users"

  • Sort all request parameters (both url parameters and body parameters) lexicographically on the parameter name, except the signature.

  • For every parameter, append the following string to the base string:
    "&parameter-name=parameter-value"

  • Generate an HMAC-SHA1 signature using the API secret as the key and the base string as the data.

  • Get the hexadecimal representation or the hexdigest of the generated signature. This is the value that should be used as the signature parameter for Sift APIs.

Discovery

POST /v1/discovery

Performs discovery on the input eml file

This API can be used to send individual emails to Sift for parsing. This is acheived by sending individual eml files as part of the request. This is a synchronous API and returns the result (if any) as the reponse for the API request.

Sample Code


import siftapi

sift = siftapi.Sift(api_key='', '')
parsed_eml = sift.discovery('/path/to/file')

<?php

use Easilydo\SiftApi;

$sift = new SiftApi('api_key', 'api_secret');

$email = file_get_contents('test_file.eml');
$email = trim($email);

try {
  $response = $sift->discovery($email);
} catch (Easilydo\Exceptions\SiftRequestException $e) {
  echo $e->getMessage();
  exit;
}

$result = $response['result'];

import com.easilydo.sift.api.ApiManager;
import com.easilydo.sift.model.*;

public class Discovery {
    private static final String API_KEY = "your_api_key_here";
    private static final String API_SECRET = "your_secret_key_here";
    private static final String EML_FILE = "path/to/eml/file";

    public static void main(String [] args) {
		ApiManager apiMan = new ApiManager(API_KEY, API_SECRET);
		List sifts = apiMan.discovery(new java.io.File(EML_FILE));    
   }
}

require 'sift_email_api'

API_KEY = 'your_api_key'
API_SECRET = 'your_secret_key'

manager = SiftEmailApi.new(API_KEY, API_SECRET)

eml_data = File.new(ARGV[0]).read
puts manager.discovery(eml_data)


// ES5
var siftapi = require('siftapi');
var fs = require('fs');
var sift = new siftapi.SiftAPI('', '');

var data;
fs.readFile('', function(err, eml) {
  if(err) {
    return console.log(err);
  }

  sift.discovery('', eml)
    .then(function(body) {
      data = body;
    })
    .catch(function(err) {
      return console.log(err);
    });
});

// ES6/7
import { SiftAPI } from 'siftapi';
import fs from 'fs';
let sift = new SiftAPI('', '');

let data;
fs.readFile('', (err, eml) => {
  if(err) {
    return console.log(err);
  }

  sift.discovery('', eml)
    .then(body => {
      data = body;
    })
    .catch(err => {
      return console.log(err);
    });
});

Response Schema

This API can return a variety of objects, depending on the domain of the discovered information, if any. The following section contains a complete list of all the possible data objects that this API can return.

Response schemas will follow Schema.org, unless otherwise indicated. We consistently update our responses with any new email data that can be extracted, so check back for updates.

Following is a sample response for a Hotel Reservation:


{
    "message": "OK",
    "code": 200,
    "id": "bcbb50ba-97b3-11e4-9480-0a32a945b5b0",
    "result": {
        "hotel": {
            "@context": "http://schema.org",
            "@type": "LodgingReservation",
            "reservationId": "12345678",
            "reservationStatus": "http://schema.org/ReservationConfirmed",
            "reservationFor": {
                "@type": "LodgingBusiness",
                "address": "200 International Drive, 21202 Baltimore, Maryland, U.S.A.",
                "telephone": "1 (410) 576-5800",
                "name": "Four Seasons Hotel Baltimore",
                "x-days": "1"
            },
            "checkinTime": "2015-05-06T15:00:00",
            "checkoutTime": "2015-05-07T15:00:00",
            "broker": {
                "@type": "Organization",
                "name": "Four Seasons Hotels and Resorts"
            }
        }
    }
}

The value in the response above can be different depending on the key. The key can take one of the following values:

  • flight - Flights

  • hotel - Hotels

  • rentalcar - Car Rentals

  • train - Train Tickets

  • boardingpass - Boarding Passes

  • shipment - Package Shipments

  • contact - Contacts

  • purchase - Purchases

  • restaurant - Restaurant Reservations

  • event - Event Confirmations

  • deal - Deals

  • bill - Bills

  • cruise - Cruises

The corresponding "data" objects are:

Users

Delete User

DELETE /v1/users/<username>

Deletes the user with the given username

This API deletes the user with the given username. The user's email connections along with all the associated data is deleted as well.

Sample Code


import siftapi

sift = siftapi.Sift(api_key='', '')
response = sift.remove_user('username')

<?php

use Easilydo\SiftApi;

$sift = new SiftApi('api_key', 'api_secret');
try {
  $response = $sift->deleteUser('testuser');
} catch (Easilydo\Exceptions\SiftRequestException $e) {
  echo $e->getMessage();
  exit;
}

$result = $response['result'];

import com.easilydo.sift.api.ApiManager;
import com.easilydo.sift.model.*;

public class DeleteUser {
    private static final String API_KEY = "your_api_key_here";
    private static final String API_SECRET = "your_secret_key_here";

    public static void main(String [] args) {
		ApiManager apiMan = new ApiManager(API_KEY, API_SECRET);
		apiMan.deleteUser("username");
   }
}

require 'sift_email_api'

API_KEY = 'your_api_key'
API_SECRET = 'your_secret_key'

manager = SiftEmailApi.new(API_KEY, API_SECRET)

puts manager.delete_user('username')


// ES5
var siftapi = require('siftapi');
var sift = new siftapi.SiftAPI('', '');

var result;
sift.deleteUser('test')
  .then(function(body) {
    result = body.result;
  })
  .catch(function(err) {
    return console.log(err);
  });

// ES6/7
import { SiftAPI } from 'siftapi';
let sift = new SiftAPI('', '');

let result;
sift.deleteUser('test')
  .then(body => {
    result = body.result;
  })
  .catch(err => {
    return console.log(err);
  });

Response Schema


{
    "message": "success",
    "code": 200,
    "id": "<uuid>",
    "result": "deleted"
}

Add User

POST /v1/users

Add an user with the given username

This API adds the user with the given username.

Fields(Post form)

  • locale: The Locale info of the Sift user (e.g. en_US)

Sample Code


import siftapi

sift = siftapi.Sift(api_key='', '')
response = sift.add_user('username', 'en_US')

<?php

use Easilydo\SiftApi;

$sift = new SiftApi('api_key', 'api_secret');
try {
  $response = $sift->addUser('en_US', 'testuser');
} catch (Easilydo\Exceptions\SiftRequestException $e) {
  echo $e->getMessage();
  exit;
}

$result = $response['result'];

import com.easilydo.sift.api.ApiManager;
import com.easilydo.sift.model.*;

public class AddUser {
    private static final String API_KEY = "your_api_key_here";
    private static final String API_SECRET = "your_secret_key_here";

    public static void main(String [] args) {
		ApiManager apiMan = new ApiManager(API_KEY, API_SECRET);
		long userId = apiMan.addUser("username", "en_US");
   }
}

require 'sift_email_api'

API_KEY = 'your_api_key'
API_SECRET = 'your_secret_key'

manager = SiftEmailApi.new(API_KEY, API_SECRET)

puts manager.add_user('username', 'en_US')


// ES5
var siftapi = require('siftapi');
var sift = new siftapi.SiftAPI('', '');

var newUser;
sift.addUser('test')
  .then(function(body) {
    newUser = body.result;
  })
  .catch(function(err) {
    return console.log(err);
  });

// ES6/7
import { SiftAPI } from 'siftapi';
let sift = new SiftAPI('', '');

let newUser;
sift.addUser('test')
  .then(body => {
    newUser = body.result;
  })
  .catch(err => {
    return console.log(err);
  });

Response Schema


{
    "message": "success",
    "code": 200,
    "id": "<uuid>",
    "result": {
        "user_id": "<newly created user id>",
        "username": "<given user name>"
    }
}

Email Connections

Users can connect multiple emails of varying types to Sift.

For instance, a single user may connect a Gmail account, Yahoo account and two Exchange accounts. This API can be used to add email connections, delete email connections and show how many and which type of emails a user has already connected.

List Email Connections

GET /v1/users/<username>/email_connections

Returns the list of all the email connections for the given username

Query filter

  • limit: The maximum number of results to return. Developer can set any value between 0 to 100 and max is 100. Default value is 100

  • offset: Start the list at this offset (zero-based).

Sample Code


import siftapi

sift = siftapi.Sift(api_key='', '')
response = sift.get_email_connections('username')

<?php

use Easilydo\SiftApi;

$sift = new SiftApi('api_key', 'api_secret');
try {
  $response = $sift->getEmailConnections('testuser');
} catch (Easilydo\Exceptions\SiftRequestException $e) {
  echo $e->getMessage();
  exit;
}

$result = $response['result'];

import com.easilydo.sift.api.ApiManager;
import com.easilydo.sift.model.*;

public class ListEmailConnections {
    private static final String API_KEY = "your_api_key_here";
    private static final String API_SECRET = "your_secret_key_here";

    public static void main(String [] args) {
		ApiManager apiMan = new ApiManager(API_KEY, API_SECRET);
		java.util.List conns = apiMan.listConnections("username");
    }
}

require 'sift_email_api'

API_KEY = 'your_api_key'
API_SECRET = 'your_secret_key'

manager = SiftEmailApi.new(API_KEY, API_SECRET)

puts manager.list_connections('username')


// ES5
var siftapi = require('siftapi');
var sift = new siftapi.SiftAPI('', '');

var emailConnections;
sift.getEmailConnections('username')
  .then(function(body) {
    emailConnections = body.result;
  })
  .catch(function(err) {
    return console.log(err);
  });

// ES6/7
import { SiftAPI } from 'siftapi';
let sift = new SiftAPI('', '');

let emailConnections;
sift.getEmailConnections('username')
  .then(body => {
    emailConnections = body.result;
  })
  .catch(err => {
    return console.log(err);
  });

Response Schema


{
    "message": "success",
    "code": 200,
    "id": "<uuid>",
    "result": [{
        "email": "johndoe@gmail.com",
        "state": "<valid or invalid>",
        "id": 2,
        "email_type": "google"
    }, {
        "email": "john.doe@icloud.com",
        "state": "<valid or invalid>",
        "id": 3,
        "email_type": "imap"
    }]
}

Add Email Connection

POST /v1/users/<username>/email_connections

Add an email connection for the given username

If you connect to your users’ emails outside of Sift (either on your own or through a 3rd-party), you will need to share certain information in order for Sift to access those email accounts. See below to view how to do so for each type of email connection.

Request Schema

Other than the common parameters, this endpoint requires additional parameters that depend on the type of email connection that is being added.

Parameter

Description

account_type

One of the following 5 supported values - “google”, “yahoo”, “live”, “imap”, “exchange”

The rest of the parameters depend on the this value.

Sample Code (for IMAP)


import siftapi

sift = siftapi.Sift(api_key='', '')
data = {
  "account_type": "google",
  "account": ,
  "refresh_token": 
}
response = sift.add_email_connection('username', params)

<?php

use Easilydo\SiftApi;

$sift = new SiftApi('api_key', 'api_secret');

$google = new \Easilydo\EmailConnections\GoogleConnection('123@abc.com', 'abc');
try {
  $response = $sift->addEmailConnection('testuser', $google);
} catch (Easilydo\Exceptions\SiftRequestException $e) {
  echo $e->getMessage();
  exit;
}

$result = $response['result'];

import com.easilydo.sift.api.ApiManager;
import com.easilydo.sift.model.*;

public class AddEmailConnection {
    private static final String API_KEY = "your_api_key_here";
    private static final String API_SECRET = "your_secret_key_here";

    public static void main(String [] args) {
		ApiManager apiMan = new ApiManager(API_KEY, API_SECRET);
		long connectionId = apiMan.addGmailConnection("username", "sift-tester@gmail.com", "refresh_token");
    }
}

require 'sift_email_api'

API_KEY = 'your_api_key'
API_SECRET = 'your_secret_key'

manager = SiftEmailApi.new(API_KEY, API_SECRET)

puts manager.add_imap_connection('username', 'email_address@somewhere.com', 'password', 'host')


// ES5
var siftapi = require('siftapi');
var sift = new siftapi.SiftAPI('', '');

var params = {
  account: "username@gmail.com",
  refresh_token: "token"
};

var newEmailConnectionId;
sift.addEmailConnection('username', 'google', params)
  .then(function(body) {
    newEmailConnectionId = body.result.id;
  })
  .catch(function(err) {
    return console.log(err);
  });

// ES6/7
import { SiftAPI } from 'siftapi';
let sift = new SiftAPI('', '');

let params = {
  account: "username@gmail.com",
  refresh_token: "token"
};

let newEmailConnectionId;
sift.addEmailConnection('username', 'google', params)
  .then(body => {
    newEmailConnectionId = body.result.id;
  })
  .catch(err => {
    return console.log(err);
  });

Response Schema


{
    "message": "success",
    "code": 200,
    "id": "<uuid>",
    "result": {
        "id": "<newly created connection_id>"
    }
}

Delete Email Connection

DELETE /v1/users/<username>/email_connections/<connection_id>

Deletes the email connection with the given connection_id for the given username

Sample Code


  import siftapi

  sift = siftapi.Sift(api_key='', '')
  sift.delete_email_connection('username')

<?php

use Easilydo\SiftApi;

try {
  $response = $sift->deleteEmailConnection('testuser', '123');
} catch (Easilydo\Exceptions\SiftRequestException $e) {
  echo $e->getMessage();
  exit;
}

$result = $response['result'];

import com.easilydo.sift.api.ApiManager;
import com.easilydo.sift.model.*;

public class DeleteEmailConnection {
    private static final String API_KEY = "your_api_key_here";
    private static final String API_SECRET = "your_secret_key_here";

    public static void main(String [] args) {
		ApiManager apiMan = new ApiManager(API_KEY, API_SECRET);
		apiMan.deleteConnection("username", 1234L);
    }
}

require 'sift_email_api'

API_KEY = 'your_api_key'
API_SECRET = 'your_secret_key'

manager = SiftEmailApi.new(API_KEY, API_SECRET)

puts manager.delete_connection('username', 345)


// ES5
var siftapi = require('siftapi');
var sift = new siftapi.SiftAPI('', '');

sift.deleteEmailConnection('username', 'connection_id')
  .then(function(body) {
    var result = body.result;
  })
  .catch(function(err) {
    return console.log(err);
  });

// ES6/7
import { SiftAPI } from 'siftapi';
let sift = new SiftAPI('', '');

sift.deleteEmailConnection('username', 'connection_id')
  .then(body => {
    result = body.result;
  })
  .catch(err => {
    return console.log(err);
  });

Response Schema


{
    "message": "success",
    "code": 200,
    "id": "<uuid>",
    "result": "deleted"
}

Sifts

List Sifts

GET /v1/users/<username>/sifts

Returns the list of sifts for the specified user

This endpont returns the list of sifts without the raw email from the user's inbox. If you need the raw email, you can retrieve it by using the Get Sift endpoint.

Query filter

  • limit: The maximum number of results to return. Developer can set any value between 0 to 100 and max is 100. Default value is 100

  • offset: Start the list at this offset (zero-based).

  • last_update_time: Epoch timestamp. Returns results with last update time greater than (that is, more recent than) the specified time.

  • domains: A list of domains separated by comma. The domain should be one of the following string: flight, hotel, rentalcar, train, boardingpass, shipment, contact, purchase, reservation, event, deal, bill. If omited, this api will return the sifts with all domains.

Sample Code


import siftapi

sift = siftapi.Sift(api_key='', '')
response = sift.get_sifts('username')

<?php

use Easilydo\SiftApi;

$sift = new SiftApi('api_key', 'api_secret');
try {
  $response = $sift->getSifts('testuser', 10, 0, 0, ['flight']);
} catch (Easilydo\Exceptions\SiftRequestException $e) {
  echo $e->getMessage();
  exit;
}

$result = $response['result'];

import com.easilydo.sift.api.ApiManager;
import com.easilydo.sift.model.*;

public class GetSift {
    private static final String API_KEY = "your_api_key_here";
    private static final String API_SECRET = "your_secret_key_here";

    public static void main(String [] args) {
		ApiManager apiMan = new ApiManager(API_KEY, API_SECRET);
		java.util.List sifts = apiMan.listSifts("username");    
   }
}

require 'sift_email_api'

API_KEY = 'your_api_key'
API_SECRET = 'your_secret_key'

manager = SiftEmailApi.new(API_KEY, API_SECRET)

puts manager.list_sifts('username')


// ES5
var siftapi = require('siftapi');
var sift = new siftapi.SiftAPI('', '');

var sifts;
sift.getSifts('username', {})
  .then(function(body) {
    sifts = body.result;
  })
  .catch(function(err) {
    return console.log(err);
  });

// ES6/7
import { SiftAPI } from 'siftapi';
let sift = new SiftAPI('', '');

let sifts;
sift.getSifts('username', {})
  .then(body => {
    sifts = body.result;
  })
  .catch(err => {
    return console.log(err);
  });

Response Schema


{
    "message": "success",
    "code": 200,
    "id": "<uuid>",
    "result": [
        {
            "domain": <domain name>,
            "payload": <schema object for sift payload>,
            "sift_id": <sift id>,
            "mime_id": <id of raw email message>,
            "email_time": <timestamp of email>,
            "fid": <id of folder in the email server>,
            "mid": <id of message in the email server>,
            "gmid": <id of message for gmail>,
            "account_id": <id of email account>,
            "username": <name of user>
        }, ...
    ]
}

Get Sift

GET /v1/users/<username>/sifts/<sift_id>

Returns the sift with the specified id for the specified user

If "include_eml" is provided in the query string, then a "mime" field that containes the raw message is also returned.

Sample Code


import siftapi

sift = siftapi.Sift(api_key='', '')
response = sift.get_sift('username', 123)

<?php

use Easilydo\SiftApi;

$sift = new SiftApi('api_key', 'api_secret');
try {
  $response = $sift->getSift('testuser', 101);
} catch (Easilydo\Exceptions\SiftRequestException $e) {
  echo $e->getMessage();
  exit;
}

$result = $response['result'];

import com.easilydo.sift.api.ApiManager;
import com.easilydo.sift.model.*;

public class GetSift {
    private static final String API_KEY = "your_api_key_here";
    private static final String API_SECRET = "your_secret_key_here";

    public static void main(String [] args) {
		ApiManager apiMan = new ApiManager(API_KEY, API_SECRET);
		Sift sift = apiMan.getSift("username", 12345L);    
   }
}

require 'sift_email_api'

API_KEY = 'your_api_key'
API_SECRET = 'your_secret_key'

manager = SiftEmailApi.new(API_KEY, API_SECRET)

puts manager.get_sift('username', 12345)


// ES5
var siftapi = require('siftapi');
var sift = new siftapi.SiftAPI('', '');

var result;
sift.getSift('username', '', { include_eml: 1 })
  .then(function(body) {
    result = body.result;
  })
  .catch(function(err) {
    return console.log(err);
  });

// ES6/7
import { SiftAPI } from 'siftapi';
let sift = new SiftAPI('', '');

let result;
sift.getSift('username', '', { include_eml: 1 })
  .then(body => {
    result = body.result;
  })
  .catch(err => {
    return console.log(err);
  });

Response Schema


{
    "message": "success",
    "code": 200,
    "id": "<uuid>",
    "result": [
        {
            "domain": <domain name>,
            "payload": <schema object for sift payload>,
            "sift_id": <sift id>,
            "mime_id": <id of raw email message>,
            "mail_time": <timestamp of email>,
            "mime": <mime content of email>,
            "fid": <id of folder in the email server>,
            "mid": <id of message in the email server>,
            "gmid": <id of message for gmail>,
            "account_id": <id of email account>,
            "username": <name of user>
        }
    ]
}

Connect Tokens

POST /v1/connect_token

Returns a new connect token for the given username

If you wish to connect to your users’ email via Sift, you will first need to generate a connect token for email connections using OAuth. After getting the connect token using this API, the Connect Email needs to be called with the generated token.

Request Schema

This endpoint requires one other parameter in addition to the common parameters. The extra parameters for this endpoint is:

Parameter

Description

username

The username of the user for whom the connect token should be generated

Sample Code


import siftapi

sift = siftapi.Sift(api_key='', '')
response = sift.get_token('username')

<?php

use Easilydo\SiftApi;

$sift = new SiftApi('api_key', 'api_secret');
try {
  $response = $sift->getConnectToken('testuser');
} catch (Easilydo\Exceptions\SiftRequestException $e) {
  echo $e->getMessage();
  exit;
}

$connectToken = $response['result']['connect_token'];

import java.util.*;
import java.security.SignatureException;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

import com.mashape.unirest.http.*;
import com.mashape.unirest.http.exceptions.UnirestException;

public class ConnectTokens
{
    private static final String HMAC_SHA1_ALGORITHM = "HmacSHA1";
    private static final char[] hexArray = "0123456789ABCDEF".toCharArray();
    private static final String username = "dummy_username";
    private static final String resource = "/v1/connect_token";
    private static final String url = "https://api.easilydo.com" + resource;
    private static final String apiKey = "dummy_api_key";
    private static final String apiSecret = "dummy_api_secret";

    public static void main(String [] args) throws UnirestException
    {
        HashMap<String, Object> params = new HashMap<String, Object>();
        params.put("api_key", apiKey);
        params.put("timestamp", System.currentTimeMillis() / 1000L);
        params.put("username", username);

        String signature = generateSignature("POST", resource, params);
        params.put("signature", signature);

        HttpResponse<JsonNode> response = Unirest.post(url)
                                          .header("content-type", "x-www-form-urlencoded")
                                          .queryString(params)
                                          .asJson();
        System.out.println(response.getBody());
    }

    public static String bytesToHex(byte[] bytes)
    {
        char[] hexChars = new char[bytes.length * 2];

        for (int j = 0; j < bytes.length; j++)
        {
            int v = bytes[j] & 0xFF;
            hexChars[j * 2]     = hexArray[v >>> 4];
            hexChars[j * 2 + 1] = hexArray[v & 0x0F];
        }

        return new String(hexChars).toLowerCase();
    }

    public static String signData(String data, String key)
    throws java.security.SignatureException
    {
        String result;
        try {
            SecretKeySpec signingKey = new SecretKeySpec(key.getBytes(), HMAC_SHA1_ALGORITHM);
            Mac mac = Mac.getInstance(HMAC_SHA1_ALGORITHM);
            mac.init(signingKey);
            byte[] rawHmac = mac.doFinal(data.getBytes());
            result = bytesToHex(rawHmac);
        } catch (Exception e) {
            throw new SignatureException("Failed to generate HMAC : " + e.getMessage());
        }
        return result;
    }

    public static String generateSignature(String httpMethod, String resource, HashMap<String, Object> params)
    {
        String baseString = "";
        baseString += httpMethod.toUpperCase();
        baseString += "&" + resource;

        ArrayList<String> list = new ArrayList<String>();
        Iterator<String> it = params.keySet().iterator();
        while (it.hasNext()) {
            list.add(it.next());
        }

        Collections.sort(list);
        it = list.iterator();
        while(it.hasNext()) {
            String key = it.next();
            baseString += "&" + key + "=" + params.get(key);
        }

        try {
            String signature = signData(baseString, apiSecret);
            return signature;
        } catch (Exception e) {
            System.out.println(e.getMessage());
            return "";
        }
    }
}

// ES5
var siftapi = require('siftapi');
var sift = new siftapi.SiftAPI('', '');

var connectToken;
sift.getConnectToken('username')
  .then(function(body) {
    connectToken = body.result.connect_token;
  })
  .catch(function(err) {
    return console.log(err);
  });

// ES6/7
import { SiftAPI } from 'siftapi';
let sift = new SiftAPI('', '');

let connectToken;
sift.getConnectToken('username')
  .then(body => {
    connectToken = body.result.connect_token;
  })
  .catch(err => {
    return console.log(err);
  });

Response Schema


{
    "message": "success",
    "code": 200,
    "id": "<uuid>",
    "result": {
        "connect_token": "<newly created connect_token>"
    }
}

Connect Emails

GET /v1/connect_email

Launches the Email Connection webpage that allows a user to connect an email account to Sift

This endpoint is a user facing endpoint. It requires the user specific connect token that can be generated using the Connect Token endpoint.

This connection page will not show any Sift/EasilyDo branding and only show the email connection types that you have set up.

You should redirect your users to this endpoint when they want to connect an email to Sift.

Request Schema

This endpoint does not require the common parameters. The parameters for this endpoint are outlined below.

Parameter

Description

api_key

The Sift API Key

username

The username of the user for which the connect token was generated

token

The connect token that should be generated by calling the Connect Tokens endpoint.

redirect_url

The URL that you want to redirect the person logging in back to.

Sample URL

https://api.easilydo.com/v1/connect_email?
    api_key=<dummy_api_key>&
    username=<dummy_username>&
    token=<dummy_connect_token>

Feedback

POST /v1/feedback

Notify us of emails that sift did not parse correctly

If sift processed an email and you believe it failed to extract relevant information, you can send it to us for review and we will review our templates.

Request Schema

This endpoint requires one other parameter in addition to the common parameters. The extra parameters for this endpoint is:

Parameter

Description

email

The contents of the eml file, the same as is sent to the discovery api

locale

The locale of the email, e.g. en_US

timezone

The timezone of the email, e.g. America/Los_Angeles

Response Schema


{
    "message": "OK",
    "code": 200,
    "id": "<uuid>",
    "result": {
        "bill": {"extracted": true, "classified": true}
    }
}

Webhooks

Sift Callback

Sift will automatically send callbacks when certain events occur (e.g a new sift is discovered, an connected emails credentials are no onger invalid). In these cases, Sift will send an HTTP POST to your Callback URL, which is set in the dashboard settings. The POST body will contain the id and type of the changed resource. Additional details can be fetched using the type's corresponding GET api documented above. The possibles types and the events they represent are:

  • "sift": a new sift was discovered

  • "shipment": a shipment related to a sift has been delivered

  • "connection": an email connection's credentials are no longer valid

Request body

The body of this request is a JSON object which includes the id and type of the updated object.


{
    "username": <name of user>,
    "resource_id": <id of resource>,
    "resource_type": "sift"
}