• This blog post was originally published on 06/10/2016 and was updated on 7/15/2019

Sending email through SparkPost to your subscribers and/or customers can be done two different ways: using our API, or sending via SMTP. The deciding factor will usually be some combination of convenience for your use case, availability/cost of coding/hardware resources, and the relative priority for your business of things like sending speed and ease of migration.

There are pros and cons to both approaches. Naturally, we think our API is pretty great, and that it has advantages over SMTP, otherwise, we wouldn’t have it. Offering SMTP in addition to our API lets us support a wider range of use cases. Let’s take a look at the pros and cons for both SMTP and our API, as well as examples of each approach.

Sending via SMTP with SparkPost

Sometimes SMTP is the only choice that makes sense, given your constraints. Maybe your legacy system uses SMTP, and nobody is available to write the code to send via API instead. SMTP lowers the friction for this migration path. Common steps such as modifying existing messages by adding a custom header to set the campaign for different message streams, or enabling open/click tracking tend to be significantly less effort than starting to use a new API.

Which is a nice segue to show a pro/con list for sending with SMTP:


  1. Platform-agnostic – SMTP is accepted everywhere
    • If you want to migrate again, it’ll be easier
  2. You have full control over your “mail merge” process
    • Can generate messages however you like
    • Continue to use existing tools
  3. SMTP failures are in-band and always include context
    • Failed command and error code tell you what failed and why


  1. SMTP is not accepted FROM everywhere
    • Some environments’ firewalls block ports commonly used for SMTP
  2. You have to build your own “mail merge” messages
    • MIME and the various email RFCs can be tricky
    • This has a resource (hardware & bandwidth) cost, especially for bulk sends
  3. SMTP is a chatty protocol
    • Each message requires several round trips to our servers
    • This adds up to longer bulk send times

Here’s an example of injecting some test content into SparkPost with SMTP, using swaks. The API key you substitute below will need the Send via SMTP permission, or authentication will fail with 535 5.7.8 Sorry. .

$ swaks --server smtp.sparkpostmail.com:587 \
	--auth-user SMTP_Injection --auth-password $SPARKPOST_API_KEY \
	--to you@test.com.sink.sparkpostmail.com --from you@sp.test.com \
	--h-Subject 'smtp via sparkpost'
=== Trying smtp.sparkpostmail.com:587...
=== Connected to smtp.sparkpostmail.com.
<-  220 2.0.0 smtp.sparkpostmail.com ESMTP ecelerity r(Core: Wed, 08 Jun 2016 15:55:19 +0000
	-> EHLO test
<-  250-momentum1.platform1.us-west-2.aws.cl.messagesystems.com says EHLO to
<-  250-STARTTLS
<-  250-8BITMIME
<-  334 VXNlcm5hbWU6
	-> U01UUF9JbmplY3Rpb24=
<-  334 UGFzc3dvcmQ6
<-  235 2.0.0 Authed. Go on.
	-> MAIL FROM:<you@sp.test.com>
<-  250 2.0.0 MAIL FROM accepted
	-> RCPT TO:<you@test.com.sink.sparkpostmail.com>
<-  250 2.0.0 RCPT TO accepted
	-> DATA
<-  354 3.0.0 continue.  finished with "\r\n.\r\n"
	-> Date: Wed, 08 Jun 2016 09:55:20 -0600
	-> To: you@test.com.sink.sparkpostmail.com
	-> From: you@sp.test.com
	-> Subject: smtp via sparkpost
	-> X-Mailer: swaks v20130209.0 jetmore.org/john/code/swaks/
	-> This is a test mailing
	-> .
<-  250 2.0.0 OK 7D/49-16644-7EF38575
	-> QUIT
<-  221 2.3.0 momentum1.platform1.us-west-2.aws.cl.messagesystems.com closing connection

Sending with the SparkPost API

We like our API, and we hope you like it too. We think you should use it, as there are quite a few advantages over SMTP for many use cases, for example, triggering mail directly from your app’s server-side code. Besides, with a paid account you’re really not getting as much as you could for your money without offloading everything from your systems onto SparkPost that you can, which the API allows you to do.


  1. HTTP is allowed by all but the most restrictive firewalls
  2. Generation AKA “mail merge” is handled by SparkPost
    • Removes load from your servers
    • Can mean generation hardware/horsepower is no longer needed
  3. One connection round trip per API call
    • No per-message latency
  4. Async sending and concurrency is handled by SparkPost
    • Up to 10k message batches for best performance
    • Reduces complexity (AKA things to break) in your app


  1. Using our HTTP API means writing code
  2. Replacing in-house generation may require refactoring
    • Things like pre-processing data to format dates differently
  3. Stats are generally out-of-band
    • Some sending errors are in-band (invalid email, for example)
    • Others require processing event data one of two ways:
  4. For larger sends (10k+ recipients) batching or concurrency is recommended
    • This is a performance sweet spot, not a hard limit

Here’s an example with the same test content as above, using cURL. The API key you substitute below will need the Transmissions: Read/Write permission, or the API call will fail with HTTP/1.1 403 Forbidden, and {“errors”: [ {“message”: “Forbidden.”} ]}  in the body.

$ curl -v -X POST -H "Authorization: $SPARKPOST_API_KEY" \
	--data '{
	"recipients": [
		"address": {
		"email": "you@test.com.sink.sparkpostmail.com"
	"content": {
	"text": "This is a test mailing",
	"subject": "api via sparkpost",
	"from": "you@sp.test.com"
}' https://api.sparkpost.com/api/v1/transmissions
**   Trying
** Connected to api.sparkpost.com ( port 443 (#0)
** TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
** Server certificate: *.sparkpost.com
** Server certificate: RapidSSL SHA256 CA - G3
** Server certificate: GeoTrust Global CA
> POST /api/v1/transmissions HTTP/1.1
> Host: api.sparkpost.com
> User-Agent: curl/7.43.0
> Accept: */*
> Authorization: YSBmYWtlIGFwaSBrZXksIG1hZGUgeW91IGxvb2sh
> Content-Length: 312
> Content-Type: application/x-www-form-urlencoded
** upload completely sent off: 312 out of 312 bytes
< HTTP/1.1 200 OK
< Cache-Control: no-cache, no-store
< Content-Type: application/json
< Date: Wed, 08 Jun 2016 17:53:12 GMT
< Server: msys-http
< Vary: Accept
< Content-Length: 109
< Connection: keep-alive
** Connection #0 to host api.sparkpost.com left intact
{ "results": { "total_rejected_recipients": 0, "total_accepted_recipients": 1, "id": "102364612952283792" } }

So there you have it! As with most things in life, the answer to which will work best for you is (spoiler alert) “It depends.”. We recommend using our API unless there are reasons that won’t work for you, such as lack of development resources to make the switch. SMTP is there as a safety net to help support those cases.

Whichever way you choose, make sure you set up DKIM! Authenticating the source and content of your email is very important, and can have a huge impact on the deliverability of your email. Instructions for setting up DKIM are here.

What were the deciding factors for your choice between SMTP and our API? Let us know on Twitter at @SparkPost or in our Community Slack channel!

~ Dave

Dev Survival Guide Blog Footer