# Choose between the API and SMTP

> Compare the Emailit REST API with the SMTP relay feature by feature, from templates and scheduling to idempotency and webhooks, and pick the right one.

Emailit accepts transactional email two ways: the REST API and the SMTP relay. This guide compares them so you can pick one, or use both in the same workspace.

## The short answer

- **Use the API** for new code. It does more: templates, scheduling, idempotent retries, metadata, per-email tracking settings and a JSON response with an ID for every recipient.
- **Use SMTP** when the software you run already has SMTP settings, such as a CMS, a framework mailer, a helpdesk, a device or a legacy app. You change four settings and you're done.

Both use the same API keys, verified domains, suppression list, sending limits, logs and webhooks. You can switch later without touching DNS.

## Feature comparison

| Feature | REST API | SMTP relay |
| --- | --- | --- |
| Endpoint | `POST https://api.emailit.com/v2/emails` | `smtp.emailit.com`, ports 587, 465, 2525, 2587 and 25 |
| Authentication | `Authorization: Bearer secret_…` | AUTH PLAIN or LOGIN, username `emailit`, password = API key |
| Content | `html`, `text`, or a stored template | A complete MIME message, sent as is |
| Templates and variables | `template` (ID or alias) plus `variables`, rendered with [Temple](/docs/templates/temple/) | Not available. Render the message before you send it. |
| Scheduling | `scheduled_at` with ISO 8601, a Unix timestamp or plain English such as `tomorrow at 9am` | Not available. Email is queued right away. |
| Attachments | Base64 `content` or a `url` that Emailit downloads (up to 25 MB each). `content_id` makes an image inline. | Standard MIME parts |
| Message size | 40 MB | 40 MB |
| Recipients per message | Up to 50 each in `to`, `cc` and `bcc` | No fixed limit per transaction |
| Idempotency | `Idempotency-Key` header, replayed for 24 hours | Not available. A retried transaction can send twice. |
| Metadata | `meta` object, returned in webhook payloads | Not available |
| Custom headers | `headers` object | Any header in the message |
| Open and click tracking | Per email with `tracking`, or the domain default | The domain default only |
| `email.accepted` and `email.scheduled` webhooks | Yes | No. Later events such as `email.delivered` and `email.bounced` work the same. |
| Email IDs | Response has `id`, and `ids` with one ID per recipient | Final reply `250 2.0.0 OK: queued as em_…` |
| Errors | HTTP status codes with a JSON body | SMTP reply codes, for example `535` or `550` |
| Sending limits | Shared per workspace. `429` with `ratelimit-*` and `retry-after` headers. | Shared per workspace. `452` replies. |
| Credits | 1 per recipient | 1 per recipient |
| Request log | **Email API → Logs**, source API | **Email API → Logs**, source SMTP |

After an email is accepted, both channels behave the same. Every recipient gets an `em_` ID, appears in **Email API → Emails**, and can be canceled, retried or forwarded from the dashboard or the API.

## When to use the API

Choose the API when you write the sending code yourself, especially if you need any of these:

- **Templates.** Designers edit a template in the dashboard and your code sends it by alias with `variables`. See [Templates](/docs/templates/).
- **Safe retries.** Send an `Idempotency-Key` with each request and retry on network errors without sending twice. See [Idempotency](/docs/email-api/idempotency/).
- **Scheduling.** Send a reminder for tomorrow morning without your own job queue, and reschedule or cancel it until 3 minutes before it goes out. See [Scheduling](/docs/email-api/scheduling/).
- **Correlation.** Attach your own IDs in `meta` and match webhook events to your records. See [Headers and metadata](/docs/email-api/headers-and-metadata/).
- **Clear errors.** A `422` for an unverified domain or a `402` for missing credits is easier to handle than an SMTP reply string.

## When to use SMTP

Choose SMTP when you can't or don't want to change code:

- **Off-the-shelf software** such as WordPress, a helpdesk or a monitoring tool with an SMTP settings page.
- **Framework mailers** that already work over SMTP, such as Laravel, Rails, Django or Nodemailer. You can move to the API later.
- **Quick migrations** from another provider. Swap the host, port, username and password, then test.
- **Devices and scripts** that only speak SMTP, such as printers, scanners or cron jobs.

Things to know before you rely on SMTP:

- Emailit doesn't read provider-specific headers over SMTP. Tracking follows the sending domain's **Track loads** and **Track clicks** settings.
- Emailit replaces your `Message-ID` header with its own, and removes the `Reply-To` header when it's the same as `From`.
- Always use TLS. Port 587 with STARTTLS is recommended, and 465 uses TLS from the first byte. See [SMTP settings](/docs/smtp/settings/).

## Use both

Many teams use both: the API for application email and SMTP for a CMS or internal tools. Use a separate API key for each so you can tell them apart in the logs, and regenerate one without breaking the other. A **Sending Only** key restricted to one domain is a good fit for SMTP credentials stored in third-party software. See [API keys](/docs/developers/api-keys/).

## Next steps

  - [API quickstart](/docs/quickstart/api/): Send your first email with cURL or an SDK.
  - [SMTP quickstart](/docs/quickstart/smtp/): Test the relay with swaks, OpenSSL or Python.
  - [Send an email](/docs/email-api/send-email/): Every option of the send endpoint.
  - [SMTP settings](/docs/smtp/settings/): Hosts, ports, TLS and reply codes.

---
Source: https://emailit.com/docs/get-started/api-or-smtp/
