Elixpo Mails

Elixpo Mails Docs

Quickstart

Go from zero to a sent email: sign in, connect a sender, create a product, design a template, attach a webhook, and fire a signed trigger from your service.

1. Sign in

Sign in to your workspace via Elixpo Accounts (SSO). Your workspace is your tenant — senders, products, and templates all live under it.

2. Add a sender

Connect the mailbox mail will be sent from — your Gmail or any SMTP account, using an app password (not your login password). Elixpo Mails never relays through a shared pool; every email goes out as you.

3. Create a product

A product groups your templates and carries one shared signing secret. On creation you receive a client_id and a shared secret shown once.

Save the secret now

The signing secret is shown a single time. Store it as a server-side environment variable — never ship it to the browser. You can roll it later from the product page (the old secret keeps working for a short grace window).

4. Design a template

Build the email in the lixeditor WYSIWYG editor. Drop {{variables}} into the subject and body — e.g. Hi {{name}}, your order {{order_id}} shipped. Elixpo Mails derives the variable list from the template automatically. Set the transactional flag for essential mail like receipts and password resets.

5. Add a webhook to the template

Attach a webhook to the template. You get a signed endpoint identified by an endpoint_key (shown on the webhook), which forms your trigger URL: https://mails.elixpo.com/v1/hooks/<endpoint_key>.

6. Sign & POST a trigger

From your service, HMAC-sign the request with the product secret and POST the trigger. Build the JSON body once, sign over `${t}.${rawBody}`, and send the same bytes.

javascript
import crypto from "node:crypto";

const secret = "YOUR_PRODUCT_SECRET";
const url = "https://mails.elixpo.com/v1/hooks/whe_xxx";

// Build the body ONCE — sign and send the exact same bytes.
const payload = JSON.stringify({ to: "user@example.com", variables: { name: "Ada" } });
const t = Math.floor(Date.now() / 1000);
const v1 = crypto.createHmac("sha256", secret).update(`${t}.${payload}`).digest("hex");

const res = await fetch(url, {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "X-Elixpo-Signature": `t=${t},v1=${v1}`,
  },
  body: payload,
});

const out = await res.json();
// { ok: true, id, status: "sent", to, subject }
  • 200 { ok: true, status: "sent" } — the email was sent.
  • 200 { ok: false, status: "suppressed" } — recipient unsubscribed; a successful no-op.
  • 502 { ok: false, status: "failed", error } — downstream send failure.
Next: Authentication

OverviewAuthentication