LogoZonai
zonai.dev

Email

Sending transactional emails from the Dart client.

The email property on ZonaiClient wraps the server's email endpoints. The server handles template rendering and SMTP delivery — the client only needs to supply the body.

Every method here calls POST /email, which requires an admin token. Anyone else gets a 403, and the endpoint is throttled to 10 requests per minute per IP. It is meant for admin tooling, not for sending mail from an end-user app. To email users when something happens, send from an extension on the server instead.

See Email for server-side SMTP configuration and Built-in Templates for available template variables.

Send a Generic Email#

await client.email.send(body: Email(
  to: EmailAddress(address: 'user@example.com'),
  subject: 'Welcome',
  template: 'welcome',
  variables: {'name': 'Alice'},
));

Send an OTP Code#

await client.email.sendOtp(email: SendOtpEmail(
  to: EmailAddress(address: 'user@example.com'),
  table: 'users',
  code: '123456',
  expiresIn: const Duration(minutes: 10),
));
await client.email.sendMagicLink(email: SendMagicLinkEmail(
  to: EmailAddress(address: 'user@example.com'),
  table: 'users',
  magicLinkUrl: 'https://myapp.com/verify?token=abc',
  expiresIn: const Duration(minutes: 15),
));

Send a Verification Email#

await client.email.sendVerifyEmail(email: SendVerifyEmailEmail(
  to: EmailAddress(address: 'user@example.com'),
  table: 'users',
  verificationUrl: 'https://myapp.com/verify-email?token=abc',
  expiresIn: const Duration(hours: 24),
));

Send a Password Reset#

await client.email.sendPasswordReset(email: SendResetPasswordEmail(
  to: EmailAddress(address: 'user@example.com'),
  table: 'users',
  passwordResetUrl: 'https://myapp.com/reset-password?token=abc',
  expiresIn: const Duration(hours: 1),
));

The email endpoints require the caller to be authenticated, except when the server is configured to allow unauthenticated email sends via rules. Ensure a valid token is stored before calling these methods.