API DocumentationSafedelivr provides you a robust way to deliver mail with fallbacks to one or another mail provider
Basic

You will need your personal API_KEY and USER_ID in order to make calls to the safedelivr's API server. Both can be found on the settings page.

Sending a Hello

Let us start with sending a Hello World to your friends, you can easily try this with command line curl utility.

curl -X POST \
-H Content-Type: application/x-www-form-urlencoded --data \
'from=me@me.com&\
to=you@you.com&\
subject=Holla&\
body=Adios&\
user_id=user_id&\
api_key=api_key' https://safedelivr.com/api/batch/

The above request will return a unique batch_id which can be used later to access logs and status.

{"status": "success", "batch_id": "8020fcbf-7a31-11e7-9cb0-a45e60d46cc1"}
Fetching Batch Status

You can retrieve a Batch Status by simply calling a GET request on the /api/batch/:batch_id endpoint

curl https://safedelivr.com/api/batch/8020fcbf-7a31-11e7-9cb0-a45e60d46cc1?user_id=YOUR_USER_ID&api_key=API_KEY

The API response will be in the format as shown below

{
  "code": "",
  "created_at": "2017-08-07T12:01:59.985Z",
  "description": "",
  "options": {
    "content": "\u003cp\u003eHi\u003c/p\u003e \u003cp\u003eWelcome to SafeDelivr, please go to the dashboard to access stuff\u003c/p\u003e",
    "from": "no-reply@safedelivr.com",
    "isBulk": "true",
    "name": "Dron Rathore",
    "subject": "Welcome to SafeDelivr",
    "to": "dron.rathore@gmail.com,dron.rathore@housing.com"
},
  "reason": "",
  "status": "queued",
  "subject": "Welcome to SafeDelivr",
  "user_id": "8020fcbf-7a31-11e7-9cb0-a45e60d46cc1"
}

The above will return the a JSON struct with the details of the batch and its status, it contains the original message too under the options key.

Logs

Safedelivr has a concept of Logs which are basically email logs, each log is associated to a batch_id and the fail safe mechanism works with this associativity.

A single batch can have multiple log entries which correspondes to the individual receivers in the batch's to field

Accessing Logs

To access logs of a batch_id you can hit the below endpoint

/api/batch/batch-id/logs?user_id=user_id&api_key=api_key

Above request will return a response similar to this

[{"
  "batch_id": "37ba28f3-7b68-11e7-a84f-a45e60d46cc1",
  "created_at": "2017-08-07T13:29:17.933Z",
  "email": "alice@example.com",
  "last_update": "2017-08-07T13:29:18.439Z",
  "log_id": "69c9952e-7b74-11e7-8ac6-a45e60d46cc1",
  "state": "dispatched",
  "status": {
    "mailgun": true,
    "sendgrid": true
  },
  "user_id": "8020fcbf-7a31-11e7-9cb0-a45e60d46cc1"
}, {
  "batch_id": "37ba28f3-7b68-11e7-a84f-a45e60d46cc1",
  "created_at": "2017-08-07T13:25:20.291Z",
  "email": "dron.rathore@sendgrid.com",
  "last_update": "2017-08-07T13:25:21.73Z",
  "log_id": "dc2469d5-7b73-11e7-9ba6-a45e60d46cc1",
  "state": "dispatched",
  "status": {
    "mailgun": true,
    "sendgrid": false
  },
  "user_id": "8020fcbf-7a31-11e7-9cb0-a45e60d46cc1"
}]
Webhooks

Future plans are well in place to support user webhooks. Currently not availaible. 😔

Architecture

Safedelivr makes use of RabbitMq queues to transmit emails, whenever you make a request to the API server in most cases it will be accepted and than pushed to the queue.

The fail-safe mechanism is incorporated within the consumer, whenever a Mail Provider crashes consumer will retry the same request with next availaible mail provider, and if that too fails than the same cycle is repeated till MAX_RETRY_COUNT, after that the request is marked failed.

Safedelivr also retries to send a mail if it recieves a failed status from one of the providers webhook for a address. Safedelivr will push that request into the next availaible provider's queue and will wait for that provider's webhook response(to say), if all the providers are exhausted, the request is marked failed.

Safedelivr will not try to resend an email if it recieves a HARD BOUNCE status from the mail provider

System Specs
Email Providers

Currently safedelivr supports Sendgrid and MailGun, platform can be extended to any number of providers.

Adding an Email Provider

To add an email provider within the existing ecosystem you would be required to add few of the integrations to help it be more cohesive in the system.

You will require to add the following:

rabbitmq consumer

You will have to create a separate Queue for the new email provider so that in case of fail safe recovery it can be directly called.

The consumer executor was written keeping in mind the extensibility features of it, you would require to create these functions to help integrate it with the existing one

func Listener(packet amqp.Delivery)
func GetEmailVars(batchOptions map[string]string, customArgs map[string]string) (body string, err error)
func SendRequest(body *string) (statusCode int, err error)

To get a gist of what a consumer will look like look at this sendgrid integration.

webhook

You will have to create a webhook consumer too, in a webhook controller you can take carious decisions of whether to put back the email in the queue for re-processing or to save the status and exit.

© Created with ❤ by Dron Rathore 🕺🏻 MIT LICENSED