@mxplane/bobtailmail
v0.1.0
Published
Official Node/TypeScript SDK for the BobtailMail API
Maintainers
Readme
@mxplane/bobtailmail
Official Node/TypeScript SDK for the BobtailMail API — a transactional email API where agents are first-class senders. This package is a thin, typed client over the same REST contract documented at bobtailmail.com/docs and published as openapi.json; it adds nothing the API itself doesn't do.
Install
npm install @mxplane/bobtailmailUsage
import { BobtailMail } from "@mxplane/bobtailmail";
const bobtail = new BobtailMail({ apiKey: process.env.BOBTAILMAIL_API_KEY! });
const message = await bobtail.messages.send({
from: "[email protected]",
to: "[email protected]",
subject: "Your receipt",
text: "Thanks!",
});
console.log(message.id, message.status);to/cc/bcc/replyTo accept a single address or an array. At least one of text/html is
required. Pass an idempotency key as the second argument to send to make retries safe:
await bobtail.messages.send(input, "order-42-confirmation");Domains
A message can only send from an address at a domain you've registered and verified:
const domain = await bobtail.domains.create({ name: "notify.yourdomain.com" });
console.log(domain.dnsRecords); // the exact records to set
// after setting DNS — verification can take several minutes to reflect propagation
const status = await bobtail.domains.verify(domain.id);Webhooks
import { verifyWebhookSignature } from "@mxplane/bobtailmail";
const valid = verifyWebhookSignature({
secret: endpointSecret, // whsec_... from webhookEndpoints.create()
rawBody, // the exact, unparsed request body your server received
signature: req.headers["x-bobtailmail-signature"],
timestamp: req.headers["x-bobtailmail-timestamp"],
});Verify against the raw request body — signing covers the exact bytes sent, not a re-serialized
object. Rejects anything older than 5 minutes by default (toleranceSeconds to override).
Errors
Every non-2xx response throws BobtailMailError, carrying the API's own typed envelope:
import { BobtailMailError } from "@mxplane/bobtailmail";
try {
await bobtail.messages.send(input);
} catch (err) {
if (err instanceof BobtailMailError) {
console.log(err.type, err.status, err.details);
// e.g. "send_rejected", 422, { rejection: { kind: "unverified_domain", ... } }
}
}Full error type reference: bobtailmail.com/docs#errors.
License
MIT
