notify

Send a notification

Changed on

Fan out one notification to up to 500 recipients. Requires a Notify subscription: without one the call is refused with 403 NOTIFY_SUBSCRIPTION_REQUIRED, but for a replay of a send already accepted (its send_id), which is answered with the stored send when it repeats that request. Supply send_id to make retries safe — the call is idempotent on it within the account. An ingot send publishes a stored vault file, so, like the vault's own sharing routes, it requires proof the caller holds a key to that vault: a read-write VAT from POST /vaults/{id}/unseal (with the VMK or a read-write DVAK) in X-Vault-Access-Token. The send speaks in your organization's name, so the organization needs a name of its own. A send that would email someone (its channels name email and a recipient has an email address) goes out from your organization's own sender (GET /products/notify/email-sender), so it needs the organization's handle, and it is admitted against your hourly share of the platform's sending capacity: the last checks before anything is sealed, charged or stored. A replay of an accepted send is answered from that send without meeting any of them again.

post/products/notify/send

Request

Headers

X-Vault-Access-Tokenstring

A read-write VAT for ingot.vault_id. Required on an ingot send and ignored on a content send. Missing, unknown, or minted by a since-revoked DVAK: 401 AUTHENTICATION_ERROR. Expired: 403 with details.reason VAT_EXPIRED (unseal again and retry). Read-only: 403 with details.reason VAT_READ_ONLY. Bound to another vault or account: 403 FORBIDDEN.

Request body

send_idstring

Idempotency key, unique within the account. Server-generated (ntsnd_…) when omitted. Replaying one returns the original send with idempotent: true and fans out nothing further, even once the account's Notify tier has ended. A replay is the same send when it repeats what the recipient meets, sealed or plaintext alike: the delivery mode, title, category, instructions, policy, channels, escalation.delays, every recipient with each handle it names, and the content (its payload, content_type, filename and ttl_minutes, as written) or the ingot. A replay that differs in any of them is refused 400 VALIDATION_ERROR, and the stored send stands. type and history_ttl_days are not compared: a replay that differs only there is answered idempotent, and the stored send keeps its own.

delivery'sealed' | 'plaintext'

Sealed hands the recipient a pointer to encrypted content behind the policy. Plaintext puts the body inline: no ceremony, no ingot, and at most 50 recipients.

channelsstring[]

Overrides the account config channel resolution; order is the escalation order, and duplicates collapse to their first position. in_app is delivered by the notification's row in your Notify inbox, which your app reads through the inbox API: the inbox lists a recipient's row when their in_app step runs, at once when in_app leads the ladder and only when that step comes due when it follows email (a stop that ends the ladder first, such as an unsubscribe on a non-critical send or a recall, leaves it unlisted). So a send naming email alone lists nothing there, and neither does one to a recipient who switched In-app off for your site on auth.sv (any send but a security one, which crosses that switch); email goes out from your organization's own sender (GET /products/notify/email-sender). A name that is no Notify channel at all is rejected with 400 VALIDATION_ERROR quoting the bad value and the valid set: naming channels states an intent, so a typo has to be heard about rather than dropped into a ladder you never asked for. A channel Notify does not deliver (sms, voice, whatsapp, rcs), or one only SparkVault's own notifications use (push, web_push, webhook, slack, teams), is refused with 403 NOTIFY_CHANNEL_NOT_AVAILABLE naming it. A value that is not an array (a single string such as "email") is the same 400; only an omitted, null or empty list means the account config ladder. Channels resolved from the account CONFIG are narrowed silently to the ones above instead — they are validated on write, and a standing default must never break a live send.

titlestring

Channel-agnostic display title, folded to one line (control characters, and the noncharacters U+FFFE and U+FFFF no delivery channel can carry, become spaces). At most 200 characters are kept: a longer title is cut to 199 and an ellipsis, never rejected, so the bound is stated here rather than as a schema bound a validating client would refuse it by. A title that reads as SparkVault, or holds a text-direction control character (U+202A–U+202E, U+2066–U+2069), is refused 400 (details.field title, details.reason reserved_name): your notification goes out in your organization's name.

categorystring required

Required. One of the account configured categories, or a preset: alert, secure, conversation, approval, signature. It decides whether the recipient may mute the send, whether it is on the compliance floor, whether it must seal, which channel ladder resolves, and whether its email may offer a one-click unsubscribe. Omitting it returns 400 naming the categories this account accepts.

typestring

Display classifier, stored on every recipient's inbox row and returned as a string by the inbox and status reads. Folded to one line like title; a non-string, or a longer value, is a 400 rather than cut short.

instructionsstring

Non-secret text shown alongside a sealed send. Never the sealed content itself, and free of U+FFFE and U+FFFF, which no delivery channel can carry.

history_ttl_daysinteger

Inbox-row retention in days. Omitted (or null), it is the account history config, then 30; any other value outside the range is a 400, never replaced. Plaintext rows are capped at 7 days.

Response

Send accepted and queued for fan-out.

Changes

    • info

      the response property / became required for the status

    • info

      the response property / became required for the status

    • info

      the response property / became required for the status

    • info

      the response property / became required for the status

    • info

      the response property / became required for the status

    • info

      the response property / became required for the status

    • info

      the response property / became required for the status

    • info

      the response property / became required for the status

    • info

      the response property became required for the status

    • info

      the response property became required for the status

    • info

      the response property became required for the status

    • info

      the response property became required for the status

    • info

      the response property became required for the status

    • info

      the response property became required for the status

    • info

      the response property became required for the status

    • info

      the response property became required for the status

    • info

      the response property / became required for the status

    • info

      the response property / became required for the status

    • info

      the response property / became required for the status

    • info

      the response property / became required for the status

    • info

      the response property / became required for the status

    • info

      the response property / became required for the status

    • info

      the response property / became required for the status

    • info

      the response property / became required for the status

    • info

      added the required property / to the response with the status

    • info

      added the required property / to the response with the status

    • info

      added the required property / to the response with the status

    • info

      added the required property / to the response with the status

    • info

      added the required property / to the response with the status

    • info

      added the required property / to the response with the status

    • info

      added the required property / to the response with the status

    • info

      added the required property / to the response with the status

    • breaking

      removed the enum value push of the request property /

    • breaking

      removed the enum value rcs of the request property /

    • breaking

      removed the enum value slack of the request property /

    • breaking

      removed the enum value sms of the request property /

    • breaking

      removed the enum value teams of the request property /

    • breaking

      removed the enum value voice of the request property /

    • breaking

      removed the enum value web_push of the request property /

    • breaking

      removed the enum value webhook of the request property /

    • breaking

      removed the enum value whatsapp of the request property /

    • breaking

      the response property / became nullable for the status

    • breaking

      the response property / became nullable for the status

    • breaking

      the response property / became nullable for the status

    • breaking

      the response property / became nullable for the status

    • breaking

      the response property / became nullable for the status

    • breaking

      the response property / became nullable for the status

    • warning

      the /// request property's maxLength was set to 256

    • warning

      the request property's maxLength was set to 64

    • warning

      the request property's max was set to 3650.00

    • info

      added the non-success response with the status

    • info

      added the non-success response with the status