New:Socket for Asana Is Now Available.Learn more
Get Started

@mailbuttons/sdk

Package Overview
Dependencies
Maintainers
1
Versions
1
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@mailbuttons/sdk

Official SDK for mailbuttons — email for AI agents with policy enforcement.

latest
Source
npmnpm
Version
0.1.0
Version published
Maintainers
1
Created
Source

@mailbuttons/sdk

Official SDK for mailbuttons — email for AI agents with policy enforcement.

v0.1.x is pre-stable. Breaking changes will be flagged in the CHANGELOG.

Install

npm install @mailbuttons/sdk

Requires Node.js 20 or later.

Quick start

import { Mailbuttons, verifyWebhook, parseWebhook, type MailPolicy } from "@mailbuttons/sdk";
import { createServer } from "node:http";

const client = new Mailbuttons({ apiKey: process.env.MAILBUTTONS_API_KEY! });

const policy: MailPolicy = {
  defaultAction: "bounce",
  senders: [
    {
      match: { domain: "your-company.com", requireDkim: true },
      capabilities: ["read_calendar", "propose_meeting"],
      rateLimit: { perHour: 30 },
    },
  ],
  contentGuards: [{ reject: "(?i)wire transfer", reason: "phishing" }],
  auditLog: { retentionDays: 30, includeBodyHash: true },
};

await client.setPolicy(MAILBOX_ID, policy);

createServer(async (req, res) => {
  let body = "";
  for await (const chunk of req) body += chunk;

  if (!verifyWebhook(body, req.headers["x-mailbuttons-signature"], process.env.WEBHOOK_SECRET!)) {
    res.statusCode = 401;
    res.end();
    return;
  }

  const event = parseWebhook(body);
  if (event.type === "inbound_message") {
    await client.reply(MAILBOX_ID, event.data, "Got it — replying soon.");
  }
  res.statusCode = 204;
  res.end();
}).listen(3000);

Policy schema

A MailPolicy declares which senders can talk to your mailbox, what they're allowed to do, and how the platform enforces it. See mailbuttons.com/docs/policy for the full reference.

const policy: MailPolicy = {
  defaultAction: "bounce",
  senders: [
    { match: { address: "boss@acme.com" }, capabilities: ["read_calendar", "confirm_meeting"] },
    { match: { domain: "acme.com", requireDkim: true }, capabilities: ["read_calendar"] },
  ],
  contentGuards: [{ reject: "(?i)\\bsecret\\b", reason: "data exfil" }],
  auditLog: { retentionDays: 90, includeBodyHash: true },
};

Webhook handling

verifyWebhook checks the HMAC-SHA-256 signature in X-Mailbuttons-Signature (format sha256=<hex>) against your shared secret. parseWebhook validates the JSON shape and returns a discriminated WebhookEvent.

const ok = verifyWebhook(rawBody, req.headers["x-mailbuttons-signature"], secret);
if (!ok) return reject();
const event = parseWebhook(rawBody);
switch (event.type) {
  case "inbound_message":
    await handle(event.data);
    break;
}

The signature is computed over the raw body bytes; do not parse JSON before verifying.

Errors

Every method throws one of:

  • AuthError (401/403) — missing or revoked API key.
  • NotFoundError (404) — mailbox or message not found.
  • ValidationError (400/422) — request body rejected; .fieldErrors lists the failures.
  • RateLimitError (429) — too many requests; .retryAfterSeconds if the server hinted.
  • ServerError (5xx) — backend or upstream failure.
  • NetworkError — transport-level failure (DNS, TCP, timeout); .cause carries the original error.
  • WebhookSignatureErrorverifyWebhook got malformed input.
  • WebhookPayloadErrorparseWebhook got a body that didn't match the expected schema.

Every error has a stable .code string for programmatic dispatch ("auth", "rate_limited", etc.).

Reference integration

A working agent built on top of this SDK lives at mailbuttons/claude-scheduling-agent-ts. Five end-to-end scenarios; same harness as the Python version.

Status & versioning

Pre-1.0. Breaking changes will be called out in CHANGELOG.md. Once the public surface settles, this package will move to 1.0 and adopt strict semver.

Licence

MIT.

Keywords

mailbuttons

FAQs

Package last updated on 13 May 2026

Related posts