Core concepts
Errors
Consistent error shapes and the full code catalog.
Errors use standard HTTP status codes and a consistent JSON body:
error.json
{
"error": {
"type": "feature_locked",
"message": "Sequences are on the Marketing Growth plan.",
"details": { "required_plan": "mk_growth", "upgrade_url": "…" }
}
}The SDK throws a single RootMailError with .status, .type, and .details so you can branch on the machine-readable type rather than parsing messages.
handle-error.ts
import { RootMailError } from "@rootmail/node";
try {
await mail.sequences.create({ /* … */ });
} catch (e) {
if (e instanceof RootMailError && e.type === "feature_locked") {
// send them to e.details.upgrade_url
}
}Status codes
400bad_request | Invalid or missing parameters. The message says which. |
401unauthorized | Missing, malformed, or revoked API key. |
402feature_locked | The feature needs a higher plan or an add-on. details carries the upgrade path. |
403forbidden | Authenticated, but your role or scope isn't allowed. |
404not_found | No such resource in this workspace. |
409conflict | A uniqueness or state conflict — e.g. a duplicate slug. |
429rate_limited | Too many requests. Back off and retry — see Rate limits. |
noteValidation is strict and fails closed: a paid feature is never silently granted, and a bad write never partially applies.