KoltrixDocs

Integrations

Koltrix speaks plain HTTP, SMTP and webhooks, so it fits anything that does. These are the patterns that come up most.

  • Something happens elsewhere, and you want to send an email: receive that system's webhook, then call POST /api/v2/emails.
  • Something happens to your email, and you want another system to know: add a Koltrix webhook and act on the event.

Stripe receipts

Send a receipt when a Checkout payment succeeds. Using the Stripe event id as the Idempotency-Key means Stripe's own retries never send a second receipt.

Next.js route handler
import Stripe from "stripe";
 
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!);
 
export async function POST(req: Request) {
  const raw = await req.text();
  const event = stripe.webhooks.constructEvent(
    raw,
    req.headers.get("stripe-signature")!,
    process.env.STRIPE_WEBHOOK_SECRET!,
  );
 
  if (event.type === "checkout.session.completed") {
    const session = event.data.object as Stripe.Checkout.Session;
    const amount = ((session.amount_total ?? 0) / 100).toFixed(2);
    const res = await fetch("https://api.koltrix.com/api/v2/emails", {
      method: "POST",
      headers: {
        Authorization: `Bearer ${process.env.KOLTRIX_KEY}`,
        "Content-Type": "application/json",
        "Idempotency-Key": event.id,
      },
      body: JSON.stringify({
        from: "Acme Billing <[email protected]>",
        to: [session.customer_details!.email!],
        subject: "Your Acme receipt",
        body_html: `<p>Thanks for your order of ${amount} ${session.currency?.toUpperCase()}.</p>`,
      }),
    });
    // Let Stripe retry if Koltrix couldn't take it; the key prevents duplicates.
    if (!res.ok && res.status >= 500) return new Response("retry", { status: 500 });
  }
  return new Response("ok");
}

GitHub notifications

Email a code owner when a pull request is opened against main:

Next.js route handler
export async function POST(req: Request) {
  // Verify X-Hub-Signature-256 here before trusting the payload.
  const { action, pull_request, repository } = await req.json();
  if (action !== "opened" || pull_request.base.ref !== "main") {
    return new Response("ignored");
  }
 
  await fetch("https://api.koltrix.com/api/v2/emails", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.KOLTRIX_KEY}`,
      "Content-Type": "application/json",
      "Idempotency-Key": `pr-${repository.id}-${pull_request.number}-opened`,
    },
    body: JSON.stringify({
      from: "[email protected]",
      to: ["[email protected]"],
      subject: `[${repository.full_name}] ${pull_request.title}`,
      body_html: `<p><a href="${pull_request.html_url}">Review #${pull_request.number}</a></p>`,
    }),
  });
  return new Response("ok");
}

Slack alerts on bounces

Forward message.bounced events to a Slack incoming webhook:

Next.js route handler
import crypto from "node:crypto";
 
export async function POST(req: Request) {
  const raw = await req.text();
  const expected =
    "sha256=" +
    crypto.createHmac("sha256", process.env.KOLTRIX_WEBHOOK_SECRET!).update(raw).digest("hex");
  const given = req.headers.get("x-koltrix-signature") ?? "";
  if (
    given.length !== expected.length ||
    !crypto.timingSafeEqual(Buffer.from(given), Buffer.from(expected))
  ) {
    return new Response("bad signature", { status: 401 });
  }
 
  const event = JSON.parse(raw);
  if (event.event === "message.bounced") {
    await fetch(process.env.SLACK_WEBHOOK_URL!, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        text: `:warning: "${event.subject}" bounced (${event.message_id}): ${event.error}`,
      }),
    });
  }
  return new Response("ok");
}

One endpoint can fan out to several places: branch on event.event. The payload of each event is in Webhooks.

Zapier, Make and n8n

There is no Koltrix app in these marketplaces yet, but their generic HTTP steps work well:

  • Send an email from a workflow: add an HTTP request step (Zapier: Webhooks by Zapier → Custom Request) that POSTs JSON to https://api.koltrix.com/api/v2/emails with the header Authorization: Bearer kx_…. Remember that to is an array.
  • Start a workflow from a Koltrix event: add the workflow's webhook URL as a Koltrix webhook. Its events arrive as JSON.

Use a key with only the send scope for these tools.

AI assistants

To work with your inbox from Claude, ChatGPT, Cursor or another AI assistant, connect Koltrix's MCP server. See AI assistants (MCP).

Incoming mail

Mail to your domain arrives in your Koltrix team inbox. There is no webhook for incoming mail and no API to read it yet. To pass a mailbox's mail on to another system, set up Settings → Forwarding, or let an AI assistant read it through the MCP connection.

Languages

There are no official SDKs. The API is a handful of JSON endpoints, and each language's standard HTTP client is enough.

LanguageREST APISMTP relay
Node.jsfetch (Node 18+)nodemailer
Pythonrequests or httpxsmtplib
Gonet/httpnet/smtp (see the relay page for authentication)
PHPcURL or GuzzlePHPMailer
RubyNet::HTTPthe mail gem

Code for each is in Sending email and SMTP relay.