DEV Community

Cover image for Introducing 'sparkpost' a Rust Crate for email API
Harry Gill
Harry Gill

Posted on • Updated on

Introducing 'sparkpost' a Rust Crate for email API

Rust is an enjoyable language, and I have been experimenting with it for a some time. I started with creating a few web servers using different crates including rocket and actix. I needed to use an email api to send messages from the backend to either myself or the user.

I have used Sparkpost as an email service for such purpose in some of my nodejs apps. Having not found any rust API lib for it I decided to create one for myself. It is available on

Current implementation includes transmission api only. That allows you to send emails with metadata, templates and other features.

Here is a complete example of how to use the lib
serde_derive = "1.0"
serde = "1.0"
chrono = { version = "0.4", features = ["serde"] }
dotenv = "0.13"

extern crate serde_derive;
extern crate chrono; // for setting dateTime option to an email
extern crate dotenv; // optional- to read api key from .env file
extern crate serde;
extern crate sparkpost;

use chrono::prelude::*;
use sparkpost::transmission::{
  Attachment, EmailAddress, Message, Options, Recipient, Transmission, TransmissionResponse,

// this could be any Type to replace vlaues in sparkpost template
// only requirement is that it implements Serialize from serde
#[derive(Debug, Serialize)]
struct Data {
  name: String,

fn get_api_key() -> String {
  use dotenv::dotenv;
  use std::env;
  env::var("SPARKPOST_API_KEY").expect("SPARKPOST_API_KEY must be set")

fn main() {
  // for eu servers use 
  // let tm = Transmission::new_eu(get_api_key());
  let tm = Transmission::new(get_api_key());

  // new email message with sender name and email
  let mut email = Message::new(EmailAddress::new(
    "Example Company",

  let options = Options {
    open_tracking: true,
    click_tracking: true,
    transactional: false,
    sandbox: false,
    inline_css: false,
    start_time: Some(Utc.ymd(2019, 1, 1).and_hms(0, 0, 0)),

  // recipient with substitute data for the template
  let recipient = Recipient::with_substitution(
    EmailAddress::new("", "Bob"),
    Data { name: "Bob".into() },

  let attachment = Attachment {
       file_type: "image/png".into(),
       name: "AnImage.png".into(),
       // data is base64 encoded string

  // complete the email message with details
    .subject("My Awesome email 😎")
    .html("<h1>hello {name}</h1>")
    .text("hello {name}");

  let result = tm.send(&email);

  match result {
    Ok(res) => {
      match res {
        TransmissionResponse::ApiResponse(api_res) => {
          println!("API Response: \n {:#?}", api_res);
            assert_eq!(1, api_res.total_accepted_recipients);
            assert_eq!(0, api_res.total_rejected_recipients);
        TransmissionResponse::ApiError(errors) => {
          println!("Response Errors: \n {:#?}", &errors);
    Err(error) => {
      println!("error \n {:#?}", error);

As I mentioned above that there are many features that are lacking i.e. saving and retrieving templates and recipient list etc. Reason is that I don't use those features for now. If anyone is interested I will be more than happy to help.


Originally published on

Top comments (0)