notifications

Trigger Notification

The tenant front door: record one triggered event per recipient and accept (202). The request does no per-channel work — channel resolution, rendering and delivery happen asynchronously in the fan-out worker, so one channel's (or one recipient's) failure can't roll back another. Each recipient's event_id correlates its accepted event for status.

An archived account can't send: reject up front (403) rather than record events that fan-out would only skip. (A None tenant — a tenant_id that authenticated but has no row — is a data-integrity impossibility, not an archived account, so it's deliberately allowed through rather than 403'd.)

The archived check runs before the idempotency replay deliberately: an archived account gets the same 403 whether or not it happens to be resending a token, rather than one answer for a fresh trigger and another for a retry.

post/v1/notifications

Request

  • Base URL: https://api.elaan.io (the document declares no server; this is the origin it was published from)
  • URL: https://api.elaan.io/v1/notifications
  • Auth: none declared

Headers

Idempotency-Keystring nullable

Optional dedupe token for this request. Send the same token again and the original event ids come back without sending anything a second time — for callers driven by an at-least-once source (a queue, a webhook, a retried job), where a redelivery is routine. Reusing a token for a different payload is a 409. Scoped to your account, at most 255 characters.

authorizationstring nullable

Request body

notification_type_keystring required
external_idsstring[] required
branding_keystring nullable
strictboolean

Refuse the trigger rather than substituting a different brand for the one it named. By default a branding_key that does not exist falls back to the account's default brand and the send goes out, so a typo cannot stop your mail. With strict that same trigger is a 422 and nothing is queued. Covers the branding key only; it is not a general validation mode, and an unknown notification_type_key is still accepted here and reported on the event. Leave it off unless you would rather send nothing than send under the wrong brand.

variablesobject

Values for the template's {{ slot }} markers. Any JSON is accepted: strings, numbers, booleans, nested objects (read with {{ order.customer.name }}) and lists a template repeats over with {% for line in lines %} … {% endfor %} — invoice lines, order items, digest entries. A name you don't send renders empty rather than failing, and a list you don't send repeats zero times.

secret_variablesobject

Values that must reach the recipient but must not be readable back afterwards — a one-time code, a password-reset link, a signed URL. They fill {{ slot }} markers exactly like variables and are sent in full, but the activity log shows them masked: the raw value is hidden, and the message body shown there is a second render in which the secret is replaced. Flat strings only (no repeat-block lists), and a name used here must not also appear in variables.

Example request

{
  "notification_type_key": "order_shipped",
  "external_ids": [
    "crm-12345",
    "crm-67890"
  ],
  "branding_key": "acme",
  "variables": {
    "invoice_number": "INV-1042",
    "lines": [
      {
        "amount": "$40.00",
        "description": "Widget",
        "qty": 2
      },
      {
        "amount": "$80.00",
        "description": "Gadget",
        "qty": 1
      }
    ],
    "total": "$120.00"
  },
  "secret_variables": {
    "code": "550913"
  }
}

Response

Successful Response

Changes

No recorded changes to this operation across all 1 revision of this API.