Skip to content

Latest commit

 

History

History
244 lines (185 loc) · 8.7 KB

File metadata and controls

244 lines (185 loc) · 8.7 KB

Notification Payload Schema

This document defines the structure, required fields, validation rules, and examples for notification payloads used by the NotifyChain listener service.

Table of Contents

  1. Overview
  2. Request Payload
  3. Notification Types
  4. Field Reference
  5. JSON Examples
  6. Validation Rules
  7. Versioning

Overview

When scheduling a notification via the REST API, the caller provides a CreateScheduledNotificationInput object. The listener stores this, then delivers it at the specified time through the chosen channel (Discord, email, webhook, or SMS).

Endpoint: POST /api/schedule


Request Payload

interface CreateScheduledNotificationInput {
  payload:           Record<string, any>;   // required
  notificationType:  NotificationType;      // required
  targetRecipient:   string;                // required
  executeAt:         Date;                  // required (ISO 8601)
  maxRetries?:       number;                // optional, default 3
  eventId?:          string;                // optional
  contractAddress?:  string;                // optional
  priority?:         number;                // optional, default 0
  metadata?:         Record<string, any>;   // optional
}

Notification Types

enum NotificationType {
  DISCORD = 'discord',
  EMAIL   = 'email',
  WEBHOOK = 'webhook',
  SMS     = 'sms',
}
Value Description targetRecipient format
discord Posts a message to a Discord channel via webhook Discord webhook URL
email Sends an email to a recipient Valid email address
webhook HTTP POST to an arbitrary endpoint Full HTTPS URL
sms Sends an SMS to a phone number E.164 format (e.g. +15551234567)

Field Reference

payload — required

A free-form JSON object containing the notification content. Its shape depends on notificationType:

notificationType Recommended fields in payload
discord content (string), embeds[] (optional Discord embed objects)
email subject (string), body (string), html (string, optional)
webhook Any JSON your receiving endpoint expects
sms message (string, ≤ 160 chars for a single SMS segment)

notificationType — required

One of the four values in the NotificationType enum. Determines both the delivery channel and how payload is interpreted.

targetRecipient — required

The delivery destination. Format varies by notificationType (see table above).
Max length: 512 characters.

executeAt — required

ISO 8601 datetime string indicating when the notification should be delivered.
Must be in the future at the time of scheduling.
Example: "2025-12-31T23:59:00.000Z"

maxRetries — optional

Number of delivery attempts before the notification is marked FAILED.
Default: 3 Range: 0–10

eventId — optional

The on-chain event ID that triggered this notification. Used for deduplication — the listener will not schedule two notifications with the same eventId and notificationType.
Max length: 255 characters.

contractAddress — optional

The Soroban contract address that emitted the triggering event. Used for audit and filtering.
Format: Stellar strkey (56-character C… string).

priority — optional

Integer controlling processing order when multiple notifications are due at the same time.
Higher value = processed first. Default: 0 Range: 0–100

metadata — optional

Arbitrary key-value object stored alongside the notification. Not sent to the recipient; useful for internal tracking, tagging, or debugging.


JSON Examples

Discord notification

{
  "payload": {
    "content": "🔔 New task created on NotifyChain!",
    "embeds": [
      {
        "title": "Task #42 — Write unit tests",
        "description": "Reward: 50 XLM",
        "color": 5814783,
        "timestamp": "2025-12-01T10:00:00.000Z"
      }
    ]
  },
  "notificationType": "discord",
  "targetRecipient": "https://discord.com/api/webhooks/123456789/abcdef",
  "executeAt": "2025-12-01T10:00:00.000Z",
  "maxRetries": 3,
  "eventId": "evt_abc123",
  "contractAddress": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABSC4",
  "priority": 5
}

Email notification

{
  "payload": {
    "subject": "Your task submission was approved",
    "body": "Congratulations! Your submission for Task #42 has been approved. Your reward of 50 XLM has been released.",
    "html": "<p>Congratulations! Your submission for <strong>Task #42</strong> has been approved.</p>"
  },
  "notificationType": "email",
  "targetRecipient": "user@example.com",
  "executeAt": "2025-12-01T10:05:00.000Z",
  "priority": 10,
  "metadata": {
    "userId": "usr_789",
    "taskId": "42"
  }
}

Webhook notification

{
  "payload": {
    "event": "task.approved",
    "taskId": "42",
    "reward": "50",
    "currency": "XLM",
    "approvedAt": "2025-12-01T10:00:00.000Z"
  },
  "notificationType": "webhook",
  "targetRecipient": "https://api.yourapp.com/notifychain-events",
  "executeAt": "2025-12-01T10:00:00.000Z",
  "maxRetries": 5,
  "eventId": "evt_xyz456"
}

SMS notification

{
  "payload": {
    "message": "NotifyChain: Task #42 approved. Reward 50 XLM released to your wallet."
  },
  "notificationType": "sms",
  "targetRecipient": "+15551234567",
  "executeAt": "2025-12-01T10:00:00.000Z"
}

Validation Rules

Field Rule
payload Must be a valid JSON object (not null, not an array)
notificationType Must be one of: discord, email, webhook, sms
targetRecipient Non-empty string, ≤ 512 chars. Format validated per channel.
executeAt Must be a valid ISO 8601 datetime. Must be in the future.
maxRetries Integer between 0 and 10 (inclusive). Defaults to 3.
eventId Optional. If provided, used for deduplication. ≤ 255 chars.
contractAddress Optional. If provided, must be a valid Stellar strkey (56 chars).
priority Integer between 0 and 100 (inclusive). Defaults to 0.
metadata Optional. Must be a valid JSON object if provided. When present, source (non-empty string) is required. Nested objects/arrays are rejected.

Channel-specific validation

DiscordtargetRecipient must start with https://discord.com/api/webhooks/.
EmailtargetRecipient must match standard email format (user@domain.tld).
WebhooktargetRecipient must be a valid HTTPS URL.
SMStargetRecipient must match E.164 format (+ followed by 7–15 digits).

Deduplication

If eventId is provided, the system checks for an existing PENDING or COMPLETED notification with the same eventId and notificationType. If found, the new request is rejected with HTTP 409 Conflict to prevent duplicate deliveries.


Versioning

Every notification payload carries a protocol version field so consumers can gate parsing logic across future schema changes.

Version Date Changes
v1 2026-07-26 Initial versioned payloads (version: 1 stamped by API)
v1.0 2025-12-01 Initial schema — four channel types, priority, metadata

Current version: 1 (CURRENT_NOTIFICATION_VERSION in listener/src/utils/notification-version.ts and CURRENT_NOTIFICATION_VERSION in the Soroban contract).

When scheduling via the REST API, if payload.version is omitted the listener stamps the current version automatically. Explicit future versions are rejected.

Breaking changes to this schema (removing or renaming required fields) will be communicated with a major version bump and a minimum 30-day deprecation notice in the changelog.