Connect Mailcheer to your application
The REST API replaces a transactional sending service. The fields and response match Resend: a migration is just the base URL and the key.
Create an API key
In your Mailcheer workspace: Settings → API → New key. Name it, tick the permissions, save. The key is shown ONCE — copy it immediately. It starts with mch_live_ followed by thirty-two characters.
Set the key in the service environment
Like any secret: in environment variables, never in the repository.
MAILCHEER_API_KEY=mch_live_…If you're coming from Resend: copy the minimal client
One file, no dependency, the same signature as the SDK you're leaving. The rest of your sending code is unchanged: it still reads { data, error } and data.id.
curl -O https://mailcheer.com/mailcheer-client.ts // then, in your code: - const resend = new Resend(process.env.RESEND_API_KEY); + const mailcheer = new Mailcheer(process.env.MAILCHEER_API_KEY); const { data, error } = await mailcheer.emails.send({ from, to, subject, html }); if (error) throw new Error(`Email delivery failed: ${error.message}`);Or send without copying anything
No library is needed: a plain HTTP call is enough. The response is a 202 with the message ID — the email is accepted, not yet delivered.
const res = await fetch("https://mailcheer.com/api/v1/emails", { method: "POST", headers: { Authorization: `Bearer ${process.env.MAILCHEER_API_KEY}`, "Content-Type": "application/json", // A unique value per send: a retry will not create a duplicate. "Idempotency-Key": invoiceId, }, body: JSON.stringify({ from: "Your brand <hello@yourdomain.com>", to: customer.email, subject: "Your invoice", html: "<p>Here it is.</p>", }), }); if (!res.ok) { // Always the same shape: { error: { code, message, details } }. // Write your code against "code", never against "message". const { error } = await res.json(); throw new Error(`${error.code} — ${error.message}`); } const { id } = await res.json();Check whether the message was delivered
The status evolves after sending: sent, then delivered, bounced or complained. A bouncing address is automatically added to the suppression list — your application does not need to handle it.
curl https://mailcheer.com/api/v1/emails/ID \ -H "Authorization: Bearer $MAILCHEER_API_KEY"Check that it's connected
Ask for the account status. This is read-only: nothing is modified, nothing is sent. The response names your workspace and lists your verified sending domains — those are the addresses you can send from.
curl -s https://mailcheer.com/api/v1/me \ -H "Authorization: Bearer $MAILCHEER_API_KEY"
Troubleshooting
Every API error carries a readable code. Here are the ones you encounter when connecting.
| 422 suppressed_recipient on a transactional email | The recipient's address bounced, they complained, or you removed it by hand: those three reasons refuse individual sends too. A plain unsubscribe only refuses sends that carry unsubscribe_url. |
|---|---|
| 401 invalid_api_key | The key is incomplete (a newline crept in during copy-paste) or has been replaced. Create a new one. |
| 401 revoked_api_key | The key was cut under Settings → API. Create another one. |
| 403 insufficient_scope | The key does not have the required permission. Permissions are chosen at creation and cannot be changed: create a key with the right scope. |
| 422 unverified_from_domain | The sending address is not on a verified domain in the workspace. The error message lists the ones that are. To add one: Domains → Add a domain, then set the DNS records. |
| 429 rate_limit_exceeded | More than 600 requests per minute for this key. The Retry-After header says how many seconds to wait. |