Skip to main content

Overview

The template approval workflow lets you require external review before publishing template changes. When enabled, templates enter a read-only state after submission and can only be published after checks are resolved via API.

How It Works

When a template is submitted for review, Courier emits a notification:submitted webhook. Your external system receives the event, runs its review process, and calls the Courier API to publish or reject the template.
Approval workflow diagram showing submission, webhook, review, and publish steps

Enable Checks for a Template

Enable checks on each template that requires an approval workflow:
  1. Open the notification template
  2. Click the Settings gear
  3. Navigate to the Checks tab
  4. Enable custom checks
Checks tab in template settings with custom checks toggle
The template’s publish button is replaced with a Send for Review option.
Template showing Send for Review button
After submission, the template enters a read-only state. No changes can be made to the latest draft until the submission is resolved or canceled.
Template in read-only state with cancel submission option

Webhooks

Configure a webhook in Settings > Webhooks to receive submission events. The webhook fires when a notification is submitted, canceled, or published. Courier sends all event types to the same webhook endpoint, so filter on the type field.
Webhook configuration in Courier settings
Edit webhook dialog with URL and event configuration

Event Types

{
  "data": {
    "id": "<NOTIFICATION_ID>",
    "submission_id": "<SUBMISSION_ID>"
  },
  "type": "notification:submitted"
}
For other notification event types, see the webhook documentation. Once you receive a notification:submitted event, trigger your external approval workflow. When the review is complete, publish the template.

Fetching Content (Optional)

After receiving the notification:submitted event, you can retrieve the template content for use in your review process:
GET /notifications/:notification_id/draft/content
Sample notification template in the designer

Sample Response

{
  "blocks": [
    {
      "alias": "Greetings",
      "context": "This is where we greet a new user",
      "id": "block_43c114d9-9cfd-4340-808f-17e2fc7a4c87",
      "type": "text",
      "checksum": "fb60f2098fa407a4ff8d48e3e908d889",
      "content": "Hello <variable id=\"3\">{name}</variable>, Welcome to <highlight id=\"6\">Courier</highlight>!"
    },
    {
      "id": "block_f19dd58f-d32c-41b8-911c-239053d34803",
      "type": "markdown",
      "content": "Ready, <variable id=\"3\">{name}</variable>? Get started [here](http://daringfireball.net/projects/markdown/).",
      "checksum": "d06665ec3f663789db81474bc1a82fc5"
    }
  ],
  "channels": [
    {
      "id": "channel_f2e7b2e9-187f-40d9-9725-636d6c59833a",
      "type": "email",
      "content": {
        "subject": "New Subject"
      },
      "checksum": "96bcf212afa5cae1c7918280743aec71"
    }
  ],
  "checksum": "22d224a20345f1e3d3cf4c231243a747"
}

Checksums

Each block, channel, and notification includes an MD5 checksum. Use these to track content changes across submissions and manage translation workflows.

Publishing the Template

Once all checks are resolved, call the API to publish the template:
PUT /notifications/:notification_id/:submission_id/checks
{
  "checks": [
    {
      "status": "RESOLVED"
    }
  ]
}
To reject a submission, see Cancel a submission. You can also set the check status to FAILED or PENDING for more complex state management in your approval workflow.

Fetching Checks

GET /notifications/:notification_id/:submission_id/checks
Example: GET /notifications/SFTYJKSF0241SVH2TWY97TTFFTQG/1630424150210/checks
{
  "checks": [
    {
      "id": "B5BYH93H4D4XRPJBMZJGB43TJEZ3",
      "status": "PENDING",
      "type": "custom",
      "updated": 1630424150210
    }
  ]
}

Cancel a Submission

Cancel a submission by deleting it. This moves the template back to a draft state and sets all checks to FAILED. Once canceled, setting a check to RESOLVED will not publish that submission.
DELETE /notifications/:notification_id/:submission_id/checks

Submitted Keys

Submitted keys let you send notifications using draft content that has been submitted for review but not yet published. This is useful for testing changes before they go live.
Template StateWhat Submitted Key Uses
PublishedPublished notification content
Submitted for reviewLatest draft content
Manage submitted keys in Settings > API Keys.
Submitted keys section in API Keys settings