Notifications#
The Notifications feature allows you to send automated notifications through multiple channels (Email, Microsoft Teams) using customizable templates. You can create notification configurations, define recipients, and trigger notifications with dynamic content using template variables.
Key capabilities:
Multi-Channel Support - Send notifications via Email or Microsoft Teams
Template-Based - Create reusable templates with dynamic content using Handlebars syntax
Dynamic Content - Replace template variables with real-time data when sending
Array Data Support - Handle complex data structures with loops and tables in templates
History Tracking - View complete history of all sent notifications with status and error details
Test Mode - Preview and test notifications before sending to recipients
Multiple Recipients - Configure default destinations or override them when sending
Getting Started#
The Notifications section is divided into two main tabs:
CONFIG Tab - Manage your notification configurations (templates and settings)
FEED Tab - View the history of all sent notifications
Figure 1: Notifications Config Tab - List of all notification configurations
Note
To access the Notifications feature, navigate to Notifications from the main menu sidebar in the OctaiPipe portal.
Creating a Notification Config#
A notification config is a reusable template that defines how and where notifications should be sent.
Step 1: Click “Create Config” Button
From the CONFIG tab, click the orange + Create Config button in the top-right corner.
Step 2: Fill in Basic Information
Field |
Description |
Required |
|---|---|---|
Name |
A unique identifier for your notification config (e.g., “Model Training Complete”, “Daily Report”) |
Yes |
Description |
A brief description of when this notification should be used |
No |
Step 3: Select Notification Type
Choose the channel through which notifications will be sent:
Email - Send notifications via email using Microsoft Graph API
Teams - Send notifications to Microsoft Teams channels via webhooks
Step 4: Select Content Type
Choose the format of your notification template:
HTML - Rich HTML content for emails (supports styling, images, links, tables)
Text - Plain text content for simple notifications
JSON - JSON format for Teams Adaptive Cards
Note
Use HTML for emails to create visually appealing notifications with dynamic tables and lists. Use JSON for Teams to leverage Adaptive Cards functionality.
Step 5: Upload Template File
Upload your notification template file. The template can include variables that will be replaced with actual values when sending.
Example HTML Email Template:
<!-- email-template.html -->
<html>
<body>
<h1>Hello {{userName}}</h1>
<p>Your model <strong>{{modelName}}</strong> has completed training.</p>
<p>Training Accuracy: <strong>{{accuracy}}%</strong></p>
<p>Status: {{status}}</p>
</body>
</html>
You can drag and drop your file or click BROWSE FILES to select it.
Step 6: Add Default Destinations
Specify the default recipients for this notification:
For Email: Enter email addresses (e.g., user@company.com)
For Teams: Enter webhook URLs from your Teams channel
Click ADD after entering each destination. You can add multiple destinations.
Note
Default destinations can be overridden when sending individual notifications.
Step 7: Save Configuration
Click the SAVE button to create your notification config. It will now appear in the CONFIG list.
Understanding Template Variables#
Template variables (also called replacements or placeholders) allow you to create dynamic content in your notifications. Variables use the Handlebars syntax: {{variableName}}
How Template Variables Work#
Define Variables in Template - Add placeholders in your template file using double curly braces
Provide Values When Sending - Supply actual values for these variables when triggering the notification
Automatic Replacement - The system replaces all variables with their corresponding values
Variable Types#
The notification system supports two types of template variables:
1. Simple Variables (Strings)
Simple variables hold single text values and are replaced directly.
<!-- Simple Variables -->
{{userName}} → Replaced with: "John Doe"
{{modelName}} → Replaced with: "ProductionModel_v2"
{{accuracy}} → Replaced with: "95.7"
<!-- Variables in HTML Context -->
<h1>Hello {{userName}}</h1>
<p>Status: {{status}}</p>
<!-- Variables in JSON Context (Teams) -->
{
"title": "Model: {{modelName}}",
"text": "Accuracy: {{accuracy}}%"
}
2. Array Variables (Lists/Tables)
Array variables hold multiple records and use Handlebars {{#each}} loops to iterate through data. This is perfect for creating dynamic tables or lists.
<!-- HTML Template with Array Loop -->
<h2>Training Metrics</h2>
<table border="1">
<tr>
<th>Metric Name</th>
<th>Value</th>
<th>Notes</th>
</tr>
{{#each data.metrics}}
<tr>
<td>{{name}}</td>
<td>{{value}}</td>
<td>{{note}}</td>
</tr>
{{/each}}
</table>
In this example:
data.metricsis an array variable containing multiple recordsEach record has properties:
name,value,noteThe
{{#each}}loop repeats the table row for each record
Note
The system automatically detects array variables by looking for {{#each}} loops in your template. When testing, array variables will show as either a table editor or JSON textarea.
Array Variable Syntax Examples#
Example 1: Simple List
<h3>Completed Steps:</h3>
<ul>
{{#each steps}}
<li>{{this}}</li>
{{/each}}
</ul>
Example 2: Table with Multiple Columns
<table>
<tr>
<th>Device</th>
<th>Status</th>
<th>Last Check</th>
</tr>
{{#each devices}}
<tr>
<td>{{deviceName}}</td>
<td>{{status}}</td>
<td>{{lastChecked}}</td>
</tr>
{{/each}}
</table>
Example 3: Nested Data
{{#each reports}}
<h3>{{title}}</h3>
<p>Generated by: {{author}}</p>
<ul>
{{#each findings}}
<li><strong>{{category}}:</strong> {{description}}</li>
{{/each}}
</ul>
{{/each}}
Warning
Variable names are case-sensitive. {{userName}} is different from {{username}} or {{UserName}}. Make sure to match the exact variable names when providing replacement values.
Best Practices for Template Variables#
Use descriptive variable names (e.g.,
{{deviceName}}instead of{{d}})Keep variable names consistent across templates
Document which variables are expected in your template
Use camelCase or dot notation for nested variables (e.g.,
{{data.metrics}},{{report.title}})Provide default values or empty state messages in templates when possible
For array variables, ensure consistent column names within each
{{#each}}block
Sending Notifications#
Once you have created a notification config, you can send notifications by triggering them with specific data.
Sending a Test Notification via UI#
Step 1: Click the Actions Menu
In the CONFIG list, find your notification config and click the three-dot menu icon (⋮) in the Actions column.
Step 2: Select “Run Test”
Choose Run Test from the dropdown menu. This opens the test notification dialog.
Step 3: Provide Replacement Values
The system automatically detects your template variables and provides the appropriate input method:
For Simple Variables (Strings):
Enter text values directly in the text fields.
Key |
Value |
|---|---|
userName |
Alice Johnson |
modelName |
PredictionModel_v3 |
accuracy |
96.5 |
status |
Completed Successfully |
For Array Variables (Tables):
You have two options to provide array data:
Option A: Table View (Recommended)
If the system successfully downloads your template, it will display a table editor with columns automatically detected from your {{#each}} loop.
Click + ADD ROW to add more data rows
Fill in each column with your data
Click the delete icon (🗑️) to remove a row
Option B: JSON Textarea
If the template cannot be downloaded or columns cannot be detected, you’ll see a JSON textarea instead.
[
{
"name": "Accuracy",
"value": "96.5",
"note": "Excellent performance"
},
{
"name": "Precision",
"value": "94.2",
"note": "Within acceptable range"
},
{
"name": "Recall",
"value": "97.8",
"note": "High detection rate"
}
]
Tip
The JSON must be a valid array of objects. The system validates your JSON in real-time and shows ✓ or ✗ to indicate if it’s valid.
Step 4: Mark as Test (Optional)
Check the Is Test checkbox to mark this as a test notification. This helps identify test notifications in the Feed history.
Step 5: Override Destinations (Optional)
If you want to send to different recipients than the default destinations, you can add email addresses or webhook URLs in the Override Destinations section.
Note
If you don’t specify override destinations, the notification will be sent to the default destinations configured in the notification config.
Step 6: Preview or Send
PREVIEW - Click to see how the notification will look with your replacement values before sending
SEND - Click to send the notification immediately
Sending Notifications via Python#
You can send notifications programmatically using the OctaiPipe Python client:
Simple Variables Example:
from octaipipe_core.client.notification_client import NotificationClient
# Initialize the client
client = NotificationClient()
# Send a notification with simple replacements
response = client.send_notification(
notification_channel_name="Model Training Complete",
replacements={
"userName": "Alice Johnson",
"modelName": "PredictionModel_v3",
"accuracy": "96.5",
"status": "Completed"
},
is_test=False
)
Array Variables Example:
For array variables, provide the value as a JSON string:
import json
# Prepare array data
metrics_data = [
{"name": "Accuracy", "value": "96.5", "note": "Excellent"},
{"name": "Precision", "value": "94.2", "note": "Good"},
{"name": "Recall", "value": "97.8", "note": "Very High"}
]
# Send notification with array data
response = client.send_notification(
notification_channel_name="Training Report with Metrics",
replacements={
"userName": "Data Science Team",
"modelName": "ProductionModel_v3",
"data.metrics": json.dumps(metrics_data) # Convert array to JSON string
},
is_test=False
)
Complex Example with Multiple Arrays:
import json
devices = [
{"deviceName": "Sensor-01", "status": "Online", "lastChecked": "2026-01-29 08:30"},
{"deviceName": "Sensor-02", "status": "Offline", "lastChecked": "2026-01-29 08:25"},
]
alerts = [
{"severity": "High", "message": "Temperature exceeded threshold"},
{"severity": "Low", "message": "Battery level below 20%"}
]
response = client.send_notification(
notification_channel_name="IoT Device Status Report",
replacements={
"report.title": "Daily Device Status",
"report.date": "2026-01-29",
"devices": json.dumps(devices),
"alerts": json.dumps(alerts)
}
)
Important
When providing array data via Python:
Create a list of dictionaries in Python
Convert it to a JSON string using
json.dumps()Pass it as a string value in the
replacementsdictionary
You can also send by channel ID:
response = client.send_notification(
notification_channel_id=1,
replacements={"subject": "Alert", "message": "System check complete"},
override_destinations=["user@example.com"]
)
Listing Available Channels#
To see available notification channels:
from octaipipe_core.client.notification_client import NotificationClient
client = NotificationClient()
# Get all channels
channels = client.get_channels()
# Filter channels by name
email_channels = client.get_channels(filter='name==Default Email')
Viewing Notification History#
The FEED tab displays a complete history of all sent notifications, allowing you to track their status and troubleshoot issues.
Understanding the Feed Tab#
Column |
Description |
|---|---|
Config Name |
The name of the notification config used. A triangle icon indicates a test notification. |
Triggered By |
Email address of the user who triggered the notification |
Time Triggered |
Date and time when the notification was sent |
Status |
Success - Notification sent successfully |
Error Message |
Details about any errors that occurred (only shown for failed notifications) |
Actions |
Options to view details or resend the notification |
Feed Tab Features#
Sorting - Click column headers to sort by Config Name, Time Triggered, or Status
Filtering - Use the FILTERS button to filter by status, config name, date range, or triggered by user
Export - Click EXPORT to download notification history as CSV or Excel
Pagination - Navigate through pages of notification history at the bottom right
View Details - Click the Actions menu (⋮) to view full notification details including replacement values used
Note
Use the FILTERS feature to quickly find specific notifications or troubleshoot issues by filtering for “Failed” status notifications.
Troubleshooting#
Notification Status: Failed#
Possible Causes:
Invalid destination (incorrect email address or webhook URL)
Missing or incorrect template variables
Network connectivity issues
Authentication problems with Microsoft Graph or Teams webhook
Solution:
Check the Error Message column in the Feed tab for specific error details
Verify all destination addresses are valid and correctly formatted
Ensure all required template variables are provided with values
Contact your system administrator if authentication issues persist
Template Variables Not Replaced#
Possible Causes:
Variable name mismatch (case-sensitive)
Missing replacement values when sending
Incorrect variable syntax in template
Solution:
Verify variable names match exactly between template and replacements (case-sensitive)
Ensure all variables in template have corresponding replacement values
Use the PREVIEW button to check how the content will look before sending
Check that variables use correct Handlebars syntax:
{{variableName}}
Array Data Not Rendering#
Possible Causes:
Invalid JSON format in array data
Missing
{{#each}}or{{/each}}tags in templateColumn names in data don’t match template placeholders
JSON string not properly formatted
Solution:
Verify your JSON array is valid (use the built-in validator in the UI)
Ensure template has matching
{{#each arrayName}}and{{/each}}tagsCheck that property names in your JSON objects match the
{{propertyName}}placeholders inside the loopWhen using Python, ensure you use
json.dumps()to convert arrays to stringsUse the table view in the UI for easier data entry and automatic validation
Example of correct array structure:
// Template expects: {{#each data.items}} {{name}} {{value}} {{/each}}
// Correct data structure:
[
{"name": "Item 1", "value": "100"},
{"name": "Item 2", "value": "200"}
]
Teams Notification Not Appearing#
Possible Causes:
Incorrect webhook URL
Invalid JSON format for Adaptive Card
Webhook expired or disabled
Solution:
Verify the webhook URL is correct and active in your Teams channel settings
Ensure your template contains valid JSON (use a JSON validator)
Test with a simple JSON template first before adding complex Adaptive Card features
Regenerate the webhook URL in Teams if it has expired
Email Not Received#
Possible Causes:
Email in spam/junk folder
Incorrect email address
Email server delay
Solution:
Check spam/junk folder and mark OctaiPipe emails as “Not Spam”
Verify the destination email address is correct in the notification config
Wait a few minutes for email delivery (can take 1-5 minutes)
Check notification status in Feed tab - if it shows “Success”, the email was sent
Getting Help#
If you continue to experience issues:
Check the Error Message column in the Feed tab for detailed error information
Review your notification config settings in the CONFIG tab
Use the PREVIEW feature to test before sending
Contact your OctaiPipe administrator or support team
Note
Always use the “Is Test” option and “Preview” feature when testing new notification configs to avoid sending incorrect notifications to actual recipients.
Advanced Template Examples#
HTML Email with Table and Summary#
<!DOCTYPE html>
<html>
<head>
<style>
body { font-family: Arial, sans-serif; }
table { border-collapse: collapse; width: 100%; margin: 20px 0; }
th { background-color: #4CAF50; color: white; padding: 12px; }
td { border: 1px solid #ddd; padding: 8px; }
tr:nth-child(even) { background-color: #f2f2f2; }
</style>
</head>
<body>
<h1>{{report.title}}</h1>
<p>Generated on: {{report.date}}</p>
<p>Prepared by: {{report.author}}</p>
<h2>Training Results</h2>
<table>
<tr>
<th>Metric</th>
<th>Value</th>
<th>Status</th>
</tr>
{{#each metrics}}
<tr>
<td>{{name}}</td>
<td>{{value}}</td>
<td>{{status}}</td>
</tr>
{{/each}}
</table>
<p><strong>Overall Status:</strong> {{overall.status}}</p>
<p><strong>Recommendation:</strong> {{overall.recommendation}}</p>
</body>
</html>
Teams Adaptive Card with Dynamic List#
{
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"type": "AdaptiveCard",
"version": "1.4",
"body": [
{
"type": "TextBlock",
"text": "{{title}}",
"weight": "Bolder",
"size": "Large"
},
{
"type": "TextBlock",
"text": "{{description}}",
"wrap": true
},
{
"type": "FactSet",
"facts": [
{{#each details}}
{
"title": "{{name}}",
"value": "{{value}}"
}{{#unless @last}},{{/unless}}
{{/each}}
]
}
]
}