// docs

The emiit SDK

Everything you need to send the templates you design in emiit from your own app, in a few minutes.

Design an email once in the builder, then send it from your app whenever you need to: a welcome note, a receipt, a password reset. Your app only references a template ID, so you can change the design anytime without touching code. The Node SDK works today, and a plain HTTP API for other languages is on the way.

Quickstart#

From zero to a sent email in three steps.

01
Create an API key

In your workspace, open Settings → API keys and create a key. Store it as an environment variable.

02
Install the SDK and a provider

emiit delivers through an email service. Here we use Resend, but any of the supported providers works.

terminal
npm install @emiit/sdk resend
03
Send your first email

Grab a template ID from the dashboard and send. The full client setup is in the next section.

javascript
await emiit.send({
  templateId: "tmpl_welcome",
  from: "Emiit <[email protected]>",
  to: "[email protected]",
  subject: "Welcome to Emiit",
  data: { name: "Jane" },
});

Get your API key#

Open Settings → API keys in your workspace and create a key. It's the only thing you need to start sending, so keep it private and store it as an environment variable.

terminal
export EMIIT_API_KEY="emiit_sk_live_..."

Send an email#

Pick a template, say who it's for, and emiit builds and sends the email. The Node SDK is ready now; the other languages call the HTTP API that's coming soon.

import { Emiit } from "@emiit/sdk";
import { resend } from "@emiit/sdk/providers";
import { Resend } from "resend";

const emiit = new Emiit({
  apiKey: process.env.EMIIT_API_KEY,
  provider: resend(new Resend(process.env.RESEND_API_KEY)),
});

await emiit.send({
  templateId: "tmpl_welcome",
  from: "Emiit <[email protected]>",
  to: "[email protected]",
  subject: "Welcome to Emiit",
  data: { name: "Jane", plan: "Pro" },
});

You can send to one person or a whole list, add people on copy, set a reply-to address, or write the preview line. See sending options for everything you can include.

The Node client#

The SDK gives you typed options, readable errors, and no hand-written requests. Add it to your project:

terminal
npm install @emiit/sdk

These are the settings you give the client once, when you create it:

FieldTypeWhat it does
apiKeyrequiredstringYour emiit API key, from Settings → API keys.
providerrequiredProviderThe email service that actually sends the mail.
fromoptionalstringA default sender, used when you don't pass one to send().

Set a default from on the client and you can leave it out of every send() call.

Delivery#

emiit renders your template; an email service delivers it. Plug in the one you already use with your own account and keys, so nothing about your sending reputation changes. These are the supported services:

Resendresend
npm i resend
Nodemailernodemailer
npm i nodemailer
SendGrid@sendgrid/mail
npm i @sendgrid/mail
Postmarkpostmark
npm i postmark
AWS SES@aws-sdk/client-ses
npm i @aws-sdk/client-ses

You set the service up with your own account details, then hand it to emiit. Here it is with Nodemailer over plain SMTP:

javascript
import { Emiit } from "@emiit/sdk";
import { nodemailer } from "@emiit/sdk/providers";
import nm from "nodemailer";

const transport = nm.createTransport({
  host: "smtp.emiit.dev",
  port: 587,
  auth: { user: process.env.SMTP_USER, pass: process.env.SMTP_PASS },
});

const emiit = new Emiit({
  apiKey: process.env.EMIIT_API_KEY,
  provider: nodemailer(transport),
});
soonPrefer not to bring a provider? Direct delivery with emiit is on the way: connect your domain, verify DNS, and send from your own address with no provider account at all.

Sending options#

Everything you can include when you send an email, whether over the API or the SDK:

FieldTypeWhat it does
templateIdrequiredstringThe ID of the template you built, shown on its page in the dashboard.
torequiredstring | string[]One recipient, or a list of them.
subjectrequiredstringThe subject line. It can use variables too, like "Welcome, {{ name }}".
fromrequiredstringWho the email comes from, like "Emiit <[email protected]>". Optional if you set a default from on the client.
previewoptionalstringThe short line shown next to the subject in the inbox. Optional.
dataoptionalobjectThe values that fill in the blanks in your design.
ccoptionalstring | string[]People to copy on the email.
bccoptionalstring | string[]People to copy without others seeing them.
replyTooptionalstring | string[]Where replies should go, if not the sender.
attachmentsoptionalAttachment[]Files to send along, such as a PDF receipt.
tagsoptionalobjectLabels you add to track and filter sends in the dashboard.

Filling in data#

Most emails have parts that change for each person, like a name, an order total, or a list of items. Whatever you pass as data fills in those blanks in your design, matched by name. The subject line can use variables too.

javascript
{
  "templateId": "tmpl_welcome",
  "to": "[email protected]",
  "subject": "Welcome, {{ name }}",
  "data": {
    "name": "Jane",
    "plan": "Pro",
    "items": [
      { "label": "Unlimited templates" },
      { "label": "Team workspaces" }
    ]
  }
}

If a required variable is missing or has the wrong type, the send fails with an invalid_data error that lists exactly which fields to fix, so a broken email never goes out.

Opens & clicks#

Tracking is on by default and needs no setup. Every send is logged per template, links are rewritten to count clicks, and opens are measured automatically. See it all under Analytics in your workspace.

Add tags to a send to label it, so you can tell campaigns apart in the dashboard:

javascript
await emiit.send({
  templateId: "tmpl_receipt",
  to: "[email protected]",
  subject: "Your receipt",
  tags: { campaign: "q3-launch" },
});

Errors#

When an email can't be sent, the SDK throws an EmiitError with a stable code, the HTTP status, and a readable message, so you can show a friendly message or retry.

javascript
import { Emiit, EmiitError } from "@emiit/sdk";

try {
  await emiit.send({
    templateId: "tmpl_welcome",
    to: "[email protected]",
    subject: "Welcome",
  });
} catch (err) {
  if (err instanceof EmiitError) {
    // e.g. "invalid_data" 422 "Missing or invalid variables: name (string)."
    console.error(err.code, err.status, err.message);
  }
  throw err;
}

The codes you might see:

CodeStatusWhat it means
missing_api_key401No API key was sent. Pass it when creating the client, or in the x-api-key header on the HTTP API.
invalid_api_key401The key doesn't match any workspace. Check for a typo or a revoked key.
template_not_found404No template with that ID exists in your workspace.
invalid_body400The request body isn't valid JSON.
invalid_data422Required template variables are missing or the wrong type. The fields array lists each one.
missing_from400Thrown by the SDK before any request: no from on send() and no default on the client.
missing_recipient400Thrown by the SDK before any request: to is empty.