Quickstart
Send your first email with the API
Verify a domain, create an API key and send your first email with cURL or an official SDK for Node.js, Python, PHP, Ruby, Go, Java, .NET or Rust.
This quickstart takes you from a new account to a delivered email in about five minutes, plus the time your DNS provider needs to publish records. You’ll verify a domain, create an API key, send an email and find it in the dashboard.
Before you begin
- An Emailit account. Sign up at dash.emailit.com.
- A domain you can add DNS records to, such as
acme.com. You can also use a subdomain, such asmail.acme.com.
Add and verify your domain
Emailit only sends from domains you’ve verified, so recipients’ mail servers can check that the email really comes from you.
-
Add the domain. Go to Email APIDomains, select Add domain, enter
acme.comand select Create. -
Publish the DNS records. The domain page lists the records to add at your DNS provider. Copy the exact values from that page. The three required records look like this:
Type Name Value TXT emailit._domainkey.acme.comv=DKIM1; t=s; h=sha256; p=…(your key)TXT emailit.acme.comv=spf1 include:_spf.emailit.com ~allMX emailit.acme.com, priority 10feedback-smtp.ffdc-1.emailit.comIf your DNS is on Cloudflare, you can publish the records in one click instead. See Cloudflare.
-
Check DNS. Select Check DNS. When SPF, DKIM and Return Path show OK, the domain is Verified. Most providers publish records within minutes, but it can take up to 48 hours.
On Pay as you go, a domain registered less than 30 days ago shows Pending verification until the Emailit team reviews it. See Add a domain for the details and optional records for DMARC, tracking and inbound email.
Create an API key
-
Open API Keys. Go to Email APIAPI Keys and select Add API key.
-
Name the key and choose a scope. Enter a name such as
Quickstart. Sending Only can only send email. Full Access can also call the rest of the API. Either works for this quickstart. -
Copy the key. Select Create and copy the key. It starts with
secret_and is shown only once. -
Store it in an environment variable so it stays out of your code:
export EMAILIT_API_KEY="secret_••••"
Send an email
Install the SDK for your language, or use cURL:
# cURL is preinstalled on macOS, Linux and Windows 10 or later
curl --versionnpm install @emailit/nodepip install emailitcomposer require emailit/emailit-phpcomposer require emailit/emailit-laravel
# Then add EMAILIT_API_KEY=secret_•••• to your .env filegem install emailitgo get github.com/emailit/emailit-go/v2<dependency>
<groupId>com.emailit</groupId>
<artifactId>emailit-java</artifactId>
<version><!-- latest version from Maven Central --></version>
</dependency>dotnet add package Emailitcargo add emailit
cargo add tokio --features fullThen send an email. Use a From address on the domain you verified, and send it to the email address you signed up with:
curl https://api.emailit.com/v2/emails \
-H "Authorization: Bearer $EMAILIT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"from": "Acme <hello@acme.com>",
"to": "ada@example.com",
"subject": "Hello from Emailit",
"html": "<p>This is my first email sent with Emailit.</p>"
}'import { Emailit } from '@emailit/node';
const emailit = new Emailit(process.env.EMAILIT_API_KEY);
const email = await emailit.emails.send({
from: 'Acme <hello@acme.com>',
to: 'ada@example.com',
subject: 'Hello from Emailit',
html: '<p>This is my first email sent with Emailit.</p>',
});
console.log(email.id, email.status);import os
from emailit import EmailitClient
client = EmailitClient(os.environ["EMAILIT_API_KEY"])
email = client.emails.send({
"from": "Acme <hello@acme.com>",
"to": "ada@example.com",
"subject": "Hello from Emailit",
"html": "<p>This is my first email sent with Emailit.</p>",
})
print(email.id, email.status)<?php
require 'vendor/autoload.php';
$emailit = Emailit::client(getenv('EMAILIT_API_KEY'));
$email = $emailit->emails()->send([
'from' => 'Acme <hello@acme.com>',
'to' => 'ada@example.com',
'subject' => 'Hello from Emailit',
'html' => '<p>This is my first email sent with Emailit.</p>',
]);
echo $email->id . ' ' . $email->status;use Emailit\Laravel\Facades\Emailit;
$email = Emailit::emails()->send([
'from' => 'Acme <hello@acme.com>',
'to' => 'ada@example.com',
'subject' => 'Hello from Emailit',
'html' => '<p>This is my first email sent with Emailit.</p>',
]);
logger()->info('Sent email', ['id' => $email->id]);require "emailit"
client = Emailit::EmailitClient.new(ENV["EMAILIT_API_KEY"])
email = client.emails.send(
from: "Acme <hello@acme.com>",
to: "ada@example.com",
subject: "Hello from Emailit",
html: "<p>This is my first email sent with Emailit.</p>"
)
puts email.id, email.statuspackage main
import (
"fmt"
"os"
"github.com/emailit/emailit-go/v2"
)
func main() {
client := emailit.NewClient(os.Getenv("EMAILIT_API_KEY"))
email, err := client.Emails.Send(&emailit.SendEmailRequest{
From: "Acme <hello@acme.com>",
To: []string{"ada@example.com"},
Subject: "Hello from Emailit",
Html: "<p>This is my first email sent with Emailit.</p>",
})
if err != nil {
panic(err)
}
fmt.Println(email.Id)
}import com.emailit.*;
import com.emailit.params.*;
import java.util.List;
public class SendEmail {
public static void main(String[] args) throws Exception {
EmailitClient emailit = new EmailitClient(System.getenv("EMAILIT_API_KEY"));
EmailitObject email = emailit.emails().send(
EmailSendParams.builder()
.setFrom("Acme <hello@acme.com>")
.setTo(List.of("ada@example.com"))
.setSubject("Hello from Emailit")
.setHtml("<p>This is my first email sent with Emailit.</p>")
.build()
);
System.out.println(email.getString("id"));
}
}using Emailit;
using Emailit.Options;
using Emailit.Resources;
var emailit = new EmailitClient(Environment.GetEnvironmentVariable("EMAILIT_API_KEY"));
Email email = emailit.Emails.Send(new EmailSendOptions
{
From = "Acme <hello@acme.com>",
To = new[] { "ada@example.com" },
Subject = "Hello from Emailit",
Html = "<p>This is my first email sent with Emailit.</p>",
});
Console.WriteLine($"{email.Id} {email.Status}");use emailit::types::CreateEmailBaseOptions;
use emailit::{Emailit, Result};
#[tokio::main]
async fn main() -> Result<()> {
let api_key = std::env::var("EMAILIT_API_KEY").expect("EMAILIT_API_KEY is not set");
let emailit = Emailit::new(&api_key);
let email = CreateEmailBaseOptions::new(
"Acme <hello@acme.com>",
["ada@example.com"],
"Hello from Emailit",
)
.with_html("<p>This is my first email sent with Emailit.</p>");
let result = emailit.emails.send(email).await?;
println!("{:?}", result.id);
Ok(())
}Read the response
A successful request returns 200 with the new email:
{
"object": "email",
"id": "em_2pX7cN4kQ9vLm3RtB8yWd1Zs",
"token": "2pX7cN4m8FqT1vKz6RbL3HwYd",
"message_id": "<2pX7cN4m8FqT1vKz6RbL3HwYd@acme.com>",
"from": "Acme <hello@acme.com>",
"to": ["ada@example.com"],
"subject": "Hello from Emailit",
"status": "accepted",
"scheduled_at": null,
"created_at": "2026-10-01T09:30:12.418Z",
"tracking": { "loads": false, "clicks": false }
}| Field | Meaning |
|---|---|
id |
The email’s ID. Use it to look the email up, cancel or retry it, and to match webhook events. |
status |
accepted means Emailit has queued the email for delivery. It’s scheduled if you set scheduled_at. |
message_id |
The Message-ID header of the email. |
ids |
Only present with several recipients. Maps each recipient address to its own email ID. |
tracking |
Whether opens (loads) and clicks are tracked for this email. Tracking needs a verified tracking subdomain. |
accepted doesn’t mean delivered yet. Delivery happens in the background, and the status changes as it progresses.
Check it in the dashboard
Go to Email APIEmails. Your email is at the top of the Outgoing tab. Within a few seconds its status usually changes from accepted to delivered. Open it to see the headers, the content, every delivery attempt with the receiving server’s response, and the spam check results.
The request itself appears in Email APILogs, with the status code and the request and response bodies.
Troubleshooting
| Response | Cause | Fix |
|---|---|---|
401 API key required or Invalid API key |
The Authorization header is missing or the key is wrong |
Send Authorization: Bearer secret_… with a current key |
403 unverified_workspace_recipient |
The workspace is in sandbox mode | Send to a workspace member’s account email, or request production access |
422 From/Sender domain is not valid or not verified |
The From domain isn’t verified in this workspace | Verify the domain, or use an address on a verified domain |
403 Domain not authorized |
The Sending Only key is restricted to a different domain | Use a key for this domain, or an unrestricted key |
402 Insufficient credits |
The workspace doesn’t have enough credits | Add credits |
429 Rate limit exceeded |
Too many emails this second or today | Wait for the time in retry-after. See Rate limits. |