Core concepts
Notifications
Section titled “Notifications”A notification is one message sent to one recipient on one channel. Sending either supplies the content inline or references a template by key.
Templates
Section titled “Templates”A template is a reusable, per-tenant, runtime-editable message with per-channel bodies (email subject/HTML, SMS text, chat blocks). Templates render with the variables you pass at send time.
Every template has an editable draft plus a series of immutable,
numbered published versions — sends and /render always use the latest
published version, so a saved draft edit only goes live once you publish it
(the dashboard’s Publish/Version-history/rollback controls, or POST /v1/templates/{key}/publish). A template also supports per-locale
channel bodies with a send-time locale (falling back from an exact tag to a
language-only match, then to the template’s default locale).
Channels
Section titled “Channels”Notavia delivers on multiple channels: email, in_app (the in-app
inbox), sms, and chat (slack, teams, discord). A single workflow can fan
out across several channels.
Idempotency
Section titled “Idempotency”Write endpoints accept an idempotency key so a retried request never
double-sends. Repeat a request with the same key within 24 hours and you get the
original response back without re-sending. Pass it per the SDK
(idempotency_key / idempotencyKey) or the Idempotency-Key header on REST.
Errors
Section titled “Errors”Every error response uses one consistent shape:
{ "error": { "type": "usage_error", "code": "usage_limit_exceeded", "message": "Monthly send limit reached for plan 'starter'.", "param": null }}The code is stable and machine-readable; the message is for humans. Match on
code, never on message. type is a broader category and is always present;
param names the offending field on validation errors (otherwise null).
Rate limits
Section titled “Rate limits”Requests are rate-limited per tenant and per key. When you exceed a limit you
get 429 Too Many Requests with a Retry-After header — the SDKs honour it
automatically with backoff.
Versioning
Section titled “Versioning”The API is versioned in the URL (/v1/*) so an embedded integration never
breaks silently. Breaking changes ship under a new version; the changelog
records every change.