Provenance
Notifications

Subscriptions

Subscribe to events and get notified when interactions happen.

Subscriptions connect events to notification adapters. When an interaction matches a subscription's resource type + action combination, a notification is automatically queued.

Creating a subscription

POST /api/subscriptions
{
  "actionId": "uuid",
  "resourceTypeId": "uuid",
  "subscriberId": "uuid",
  "originId": "uuid",
  "config": {
    "adapter": "adapter:email",
    "personalizations": [{
      "to": [{
        "email": "{{interaction.email}}",
        "name": "{{interaction.name}}"
      }],
      "dynamic_template_data": {
        "userName": "{{interaction.name}}"
      }
    }],
    "from": { "email": "noreply@example.com" },
    "template_id": "d-template-id"
  }
}

Fields

FieldRequiredDescription
actionIdYesAction UUID to match
resourceTypeIdYesResource type UUID to match
subscriberIdYesSubscriber to notify
originIdNoFilter by origin — null matches all origins
configNoAdapter-specific configuration with template variables
labelsNoArray of label strings for organizing subscriptions (max 10, each max 50 chars)
delivery_scheduleNoTime-window configuration controlling when notifications are delivered (see Delivery Schedule)

How it works

  1. An interaction is created via POST /api/interactions
  2. A database trigger finds all matching subscriptions (by resource type + action)
  3. For each match, a notification is added to the queue
  4. The queue processor picks it up and calls the configured adapter
  5. The adapter delivers the notification (email, Slack, webhook, etc.)
  6. The result is logged in the audit trail

Template variables

Use {{interaction.fieldName}} in your subscription config to inject values from the interaction's metadata:

{
  "to": "{{interaction.email}}",
  "subject": "Order {{interaction.orderId}} confirmed",
  "body": "Hi {{interaction.name}}, your order is ready."
}

Beyond interaction fields, you can reference global config, adapter settings, secrets, and built-in functions. See the full Template Engine reference for all available namespaces and functions.

Labels

Labels are user-defined text tags for organizing and categorizing subscriptions. Assign labels like "Production Alerts", "Billing", or "Security" to group related subscriptions together.

Label format

RuleConstraint
Allowed charactersAlphanumeric, spaces, hyphens, underscores
Max label length50 characters
Max labels per subscription10
Regex pattern/^[a-zA-Z0-9 _-]{1,50}$/

Creating a subscription with labels

POST /api/subscriptions
{
  "actionId": "uuid",
  "resourceTypeId": "uuid",
  "subscriberId": "uuid",
  "labels": ["Production", "Billing Alerts", "high-priority"],
  "config": { ... }
}

Updating labels

Labels are replaced on update — provide the full array each time:

PUT /api/subscriptions/:id
{
  "labels": ["Production", "Security"]
}

Filtering by label

Use the label query parameter to find subscriptions containing a specific label:

GET /api/subscriptions?label=Production

Use the labels query parameter with a comma-separated list to find subscriptions containing at least one of the specified labels:

GET /api/subscriptions?labels=Production,Security,Billing

When no label filter is provided, all subscriptions are returned regardless of their labels.

Delivery Schedule

Delivery schedules control when notifications are eligible for delivery. Configure time windows so notifications are only sent during business hours, on-call shifts, or other specific periods.

When a subscription has a delivery schedule and a notification is queued outside all configured windows, the queue processor defers the notification — setting its nextAttempt to the start of the next eligible window. The notification is delivered once the window opens.

Schedule structure

{
  "timezone": "America/New_York",
  "windows": [
    {
      "days": [1, 2, 3, 4, 5],
      "startTime": "09:00",
      "endTime": "17:00"
    },
    {
      "days": [6],
      "startTime": "10:00",
      "endTime": "14:00"
    }
  ]
}
FieldTypeDescription
timezonestringIANA timezone identifier (e.g., "America/New_York", "Europe/London")
windowsarrayOne or more delivery windows
windows[].daysnumber[]Days of the week: 0 = Sunday, 1 = Monday, ..., 6 = Saturday
windows[].startTimestringWindow start in HH:MM 24-hour format
windows[].endTimestringWindow end in HH:MM 24-hour format

Timezone handling

The timezone field must be a valid IANA timezone identifier. The queue processor converts the current time to the schedule's timezone before checking windows. If the timezone is invalid at processing time, the notification is delivered immediately (fail-open).

Default behavior

When no delivery schedule is configured (delivery_schedule is null), the subscription is treated as "Always active" — notifications are delivered immediately with no time restrictions.

Creating a subscription with a delivery schedule

POST /api/subscriptions
{
  "actionId": "uuid",
  "resourceTypeId": "uuid",
  "subscriberId": "uuid",
  "delivery_schedule": {
    "timezone": "America/New_York",
    "windows": [
      {
        "days": [1, 2, 3, 4, 5],
        "startTime": "09:00",
        "endTime": "17:00"
      }
    ]
  },
  "config": { ... }
}

Updating a delivery schedule

PUT /api/subscriptions/:id
{
  "delivery_schedule": {
    "timezone": "Europe/London",
    "windows": [
      {
        "days": [1, 2, 3, 4, 5],
        "startTime": "08:00",
        "endTime": "18:00"
      },
      {
        "days": [6],
        "startTime": "10:00",
        "endTime": "14:00"
      }
    ]
  }
}

To remove a delivery schedule and return to "Always active", set it to null:

PUT /api/subscriptions/:id
{
  "delivery_schedule": null
}

API reference

MethodEndpointDescription
GET/api/subscriptionsList all
GET/api/subscriptions/:idGet by ID
POST/api/subscriptionsCreate
PUT/api/subscriptions/:idUpdate
DELETE/api/subscriptions/:idDelete
POST/api/subscriptions/:id/pausePause
POST/api/subscriptions/:id/resumeResume

Query parameters

ParameterTypeDescription
labelstringFilter subscriptions containing this label
labelsstringComma-separated list — returns subscriptions containing at least one