Send your first email
Authenticate with an API key, send an email, follow what happens to it, and the conventions every request shares.
You need an account, an API key and a sending domain. Sign in to the console at https://console.minket.com with a code sent to your email address, or with Google; the first sign-in creates your account and your organization. Create the key in the console under Keys (API keys) and verify the domain (Set up a sending domain). A test key needs no domain: it can send from minket.test.
Send
curl https://api.minket.com/v1/emails \
-H "Authorization: Bearer $MINKET_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: welcome-7f3a9c" \
-d '{
"from": "Acme <hello@mail.acme.example>",
"to": ["jane@example.com"],
"subject": "Welcome",
"text": "Thanks for signing up."
}'import { Minket } from "@minket/sdk";
const minket = new Minket({ apiKey: process.env.MINKET_API_KEY ?? "" });
const email = await minket.emails.send(
{
from: "Acme <hello@mail.acme.example>",
to: ["jane@example.com"],
subject: "Welcome",
text: "Thanks for signing up.",
},
{ idempotencyKey: "welcome-7f3a9c" },
);{
"id": "019a2b3c-4d5e-7f60-8a9b-0c1d2e3f4a5b",
"object": "email",
"status": "queued",
"scheduled_at": null,
"idempotent_replay": false
}from must be on a verified domain of the key's project, or be a connected mailbox. The Idempotency-Key makes a retry safe: the same key and body answer with this result instead of sending again (Idempotency).
Try it without sending
A minket_test_… key takes the same request, stores the email and plays its events back, and delivers nothing. Send to delivered@minket.test, bounced@minket.test, complained@minket.test or delayed@minket.test to see each outcome (Test mode).
Follow it
queued means accepted. What happens next arrives as events: by webhook as it happens, from the event feed, or for one email with GET /v1/emails/{id}/events.
Conventions
Authentication
Send the key as a bearer token on every request:
Authorization: Bearer minket_live_…| Problem | Response |
|---|---|
No Authorization header, or not a Bearer token |
401 missing_api_key |
| Malformed, revoked or unknown key | 403 invalid_api_key |
| The key's scope does not cover the route | 401 restricted_api_key |
Requests and responses
Requests and responses are JSON with snake_case fields. Ids are UUIDs (version 7, so they sort by creation time). Timestamps are ISO 8601 with a timezone, such as 2026-10-24T18:00:00.000Z. Every response carries an x-request-id, and every failure has one shape with a retryable flag (Error codes and retries).
Pagination
Every list takes limit (1 to 100, default 20) and a cursor. Pages are newest first: after=<id> continues to older items, before=<id> returns newer ones.
curl "https://api.minket.com/v1/emails?limit=20&after=019a2b3c-4d5e-7f60-8a9b-0c1d2e3f4a5b" \
-H "Authorization: Bearer $MINKET_API_KEY"{ "object": "list", "data": [], "has_more": false }Pass the id of the last item as after while has_more is true. There are no page numbers and no totals.
Environments
Each project has a production and a preview environment with their own keys, emails and webhook endpoints, so a preview deployment's mail stays apart from production's; domains, templates, contacts and suppressions belong to the project and are shared.
Rate limits
Each key has a per-second request limit and each project a daily cap on live mail; Where limits apply has both.