Organization Settings
Organization settings let admins configure infrastructure-level options. Navigate to Organization > Settings in the sidebar.
Custom SMTP (Email)
Configure custom SMTP servers for outgoing email notifications.

Pulse sends notification emails automatically using its built-in email service. Add a custom SMTP server to send emails from your own domain instead. When multiple custom servers are configured, Pulse tries them in the order shown, using the first one that succeeds.
Click Add Server to configure a new SMTP server:
| Field | Description |
|---|---|
| Host | SMTP server hostname |
| Port | SMTP server port (e.g., 587 for TLS) |
| Username | Authentication username |
| Password | Authentication password |
| From Address | Email address used as the sender |
| From Name | Display name used as the sender |
| Use TLS | Enable TLS encryption for the connection |
TIP
To validate SMTP settings you are able to send test e-mails
INFO
SMTP servers are used for notification emails only. User-related emails like registration are not affected.
Licenses
Licenses have their own page. See Licenses to add a license key, review your plan limits and usage, and learn about the license status banner.
License usage
The license usage panel shows how your organization's current consumption compares to the limits in your active license, measured over the license term.

The panel has two groups:
Plan limits — dimensions with a quota cap, shown as progress bars:
| Dimension | Description |
|---|---|
| Endpoint monitors | Active endpoint monitors against the plan limit |
| Node monitors | Active node monitors against the plan limit |
| On-call schedules | Active on-call schedules against the plan limit |
| Emails | Emails sent during the license term |
| SMS | SMS messages sent during the license term |
| Voice calls | Voice calls made during the license term |
Bar colors indicate capacity status:
- Gray — within limits (below 80 %)
- Amber / near limit — approaching the cap (80 – 99 %)
- Amber / limit reached — usage exactly at the cap (100 %)
- Red / +N over — quota exceeded
Dimensions not included in your plan show a "not in your plan" badge. If usage is recorded despite not being in the plan, the badge turns red.
Tracked usage — dimensions with no quota cap, shown as bare counts for the license term:
| Dimension | Description |
|---|---|
| Notifications | In-app notifications sent |
| Push notifications | Mobile push notifications sent |
| Webhooks | Webhook deliveries made |
Features — licensed capabilities shown as enabled (✓) or not included (—):
| Feature | Description |
|---|---|
| MCP (Model Context Protocol) | Whether MCP token creation and API access is enabled |
| CVE monitoring | Whether CVE monitors can be created and will scan |
If no active license is attached to the organization, the panel shows an informational message instead. Contact your administrator to add a license key.
Webhooks
Webhooks let Pulse send real-time HTTP(S) or TCP notifications to external systems when events occur.
Navigate to Organization > Settings > Webhooks to manage webhooks.

Click Add Webhook to create a new webhook:
| Field | Description |
|---|---|
| Display Name | A label to identify this webhook |
| Endpoint URL | Target URL — supports https://, http://, or tcp:// schemes |
| Active | Toggle to enable or disable delivery |
| Event Types | Select which events trigger this webhook |
WARNING
Pulse shows an "Unencrypted transport" warning when you enter a tcp:// or http:// URL. Plain TCP and plain HTTP do not encrypt payloads in transit — use them only for legacy systems that cannot use HTTPS.
INFO
TCP payloads are padded with spaces so the total message length (JSON + padding + newline) is always a multiple of 64 bytes. This supports fixed-size stream buffers on SPS controllers that read in 64-byte blocks.
How delivery works
Each event triggers a delivery to every matching webhook. Deliveries to the same endpoint are processed in order, one at a time, so a slow endpoint never causes events to arrive out of sequence.
If a delivery fails — connection error, non-2xx HTTP response, or timeout — Pulse retries up to 3 attempts total with exponential backoff between attempts. After the third failed attempt the event is dropped for that endpoint. For durability beyond this, point the webhook at a queue or reverse proxy you control.
HTTP(S) transport
HTTP(S) endpoints receive a POST with these headers:
| Header | Value |
|---|---|
Content-Type | application/json |
User-Agent | Pulse-Webhook/1.0 |
X-Pulse-Signature | sha256=<hex> — only present if signing is on |
The request body is the JSON event payload — verbatim, with no trailing newline.
TCP transport
TCP endpoints receive each frame in the order JSON payload → ASCII-space padding (0x20) → a single newline (\n) — that is, the spaces sit between the payload and the closing newline, which is always the final byte. The padding is sized so the total frame length (payload + spaces + newline) is a multiple of 64 bytes. Pulse opens a fresh TCP connection per delivery, sends the padded frame, then shuts down the write half of the socket and closes the connection.
NOTE
This is raw TCP, not WebSockets. There is no HTTP upgrade handshake, no opcode framing, and no persistent session — every event is its own short-lived connection. The 64-byte padding exists so PLCs and similar controllers can read in fixed-size blocks. The trailing newline and spaces are insignificant whitespace per the JSON specification (RFC 8259, where JSON-text = ws value ws and ws includes space 0x20 and newline 0x0A), so any conformant JSON parser accepts the padded frame as-is — no trimming required. If your parser is stricter than the spec, read until end-of-stream and trim the trailing whitespace before parsing.
Verifying signatures
When you configure one or more signing secrets on a webhook, every HTTP(S) delivery carries an X-Pulse-Signature header containing an HMAC-SHA256 of the request body.
The header value is a comma-separated list of sha256=<hex> entries — one per signing secret, in the order the secrets are stored on the webhook. Multiple entries let you rotate secrets without dropping deliveries: add the new secret, deploy the new verifier (which accepts either secret), then remove the old secret.
To verify a delivery:
- Read the raw request body as bytes — do not parse and re-serialize the JSON. Even insignificant whitespace differences will change the hash.
- Compute
HMAC-SHA256(secret, body)and format it as lowercase hexadecimal. - Compare your computed value
sha256=<hex>to any one of the entries inX-Pulse-Signature. Use a constant-time comparison to avoid timing leaks. - If at least one entry matches, the delivery is authentic. If none match, reject the request.
Node.js example:
import crypto from "node:crypto";
// `body` must be the raw request body bytes, not a parsed object.
function verifyPulseWebhook(body, header, secrets) {
const expected = secrets.map((secret) => {
const hex = crypto.createHmac("sha256", secret).update(body).digest("hex");
return `sha256=${hex}`;
});
const received = header.split(",").map((s) => s.trim());
return received.some((r) =>
expected.some(
(e) =>
e.length === r.length &&
crypto.timingSafeEqual(Buffer.from(e), Buffer.from(r)),
),
);
}Python example:
import hmac
import hashlib
def verify_pulse_webhook(body: bytes, header: str, secrets: list[str]) -> bool:
expected = [
f"sha256={hmac.new(s.encode(), body, hashlib.sha256).hexdigest()}"
for s in secrets
]
received = [s.strip() for s in header.split(",")]
return any(hmac.compare_digest(e, r) for e in expected for r in received)WARNING
Always use a constant-time comparison (crypto.timingSafeEqual, hmac.compare_digest, or equivalent). A normal string == comparison can leak the expected signature one byte at a time via timing differences.
Event types
Each event type is identified by its event.type key in the webhook payload:
event.type | Description |
|---|---|
incident.created | Incident created |
incident.acknowledged | Incident acknowledged |
incident.resolved | Incident resolved |
oncall.rotation | On-call responders or operating hours changed |
notification.email_scheduled | Email notification scheduled |
notification.sms_scheduled | SMS notification scheduled |
notification.push_scheduled | Push notification scheduled |
notification.call_scheduled | Voice call scheduled |
Webhook payload envelope
Every webhook delivery is a JSON object. Pulse injects the event_type field at the top level alongside the event-specific fields:
{
"event_type": "incident.created",
...event-specific fields
}Incident event payloads
The incident.created, incident.acknowledged, and incident.resolved events share the same payload shape:
| Field | Type | Description |
|---|---|---|
event_type | string | One of incident.created, incident.acknowledged, incident.resolved |
incident_id | integer | ID of the incident |
title | string | Incident title |
status | string | Incident status — "created", "acknowledged", or "resolved" |
Notification event payloads
The notification.email_scheduled, notification.sms_scheduled, notification.push_scheduled, and notification.call_scheduled events share the same payload shape:
| Field | Type | Description |
|---|---|---|
event_type | string | One of notification.email_scheduled, notification.sms_scheduled, notification.push_scheduled, notification.call_scheduled |
incident_id | integer | ID of the incident that triggered the notification |
channel | string | Notification channel — "email", "sms", "push", or "call" |
recipients | array | List of notification recipients |
Each entry in recipients has:
| Field | Type | Description |
|---|---|---|
display_name | string | Display name of the recipient |
email | string|null | Email address, if available |
phone_number | string|null | Phone number, if available |
oncall.rotation payload
The oncall.rotation event fires whenever the set of active on-call responders changes or the operating-hours or override status of a schedule changes:
| Field | Type | Description |
|---|---|---|
event_type | string | Always "oncall.rotation" |
schedule_id | integer | ID of the on-call schedule |
schedule_name | string | Name of the on-call schedule |
previous_responders | array | Responders active before this change |
current_responders | array | Responders active after this change |
in_operating_hours | boolean | Whether the schedule is currently within operating hours |
is_override | boolean | Whether an override is currently active |
Each entry in previous_responders and current_responders has:
| Field | Type | Description |
|---|---|---|
id | integer | Login ID |
name | string | Display name or email |
email | string | Email address |
phone | string|null | Mobile number, if set |
MCP Tokens
MCP access tokens let external tools authenticate with your organization via the Model Context Protocol. Use them to connect AI assistants or automation tools that support MCP.
INFO
MCP access requires an active license that includes MCP. If your license does not include MCP, the tab shows an informational message and token creation is disabled. Contact your administrator to upgrade your license.
Navigate to Organization > Settings > MCP Tokens to manage tokens.

Click New Token to create a token:
| Field | Description |
|---|---|
| Name | A descriptive label so you can identify the token later (e.g., "CI/CD Pipeline") |
After creation, Pulse displays the token once. Copy it immediately — it cannot be retrieved again. Store it securely (for example, in a secrets manager or environment variable).
Using tokens
Pass the token in the Authorization header as a Bearer token when connecting to the MCP endpoint:
Authorization: Bearer pulse_mcp_...The MCP endpoint is available at /mcp on your Pulse instance.
Claude Code
export PULSE_MCP_TOKEN="pulse_mcp_..."
claude mcp add pulse "https://your-pulse-instance/mcp" \
-t http -s user \
-H "Authorization: Bearer ${PULSE_MCP_TOKEN}"Generic MCP client
{
"mcpServers": {
"pulse": {
"type": "http",
"url": "https://your-pulse-instance/mcp",
"headers": {
"Authorization": "Bearer ${PULSE_MCP_TOKEN}"
}
}
}
}Managing tokens
Each token row shows its name, creation date, and when it was last used. To revoke a token, click the delete icon and confirm. Revocation is immediate — any integration using that token stops working at once.
WARNING
Treat MCP tokens like passwords. Anyone with a token can access your organization's data through the MCP API. Revoke tokens you no longer need.
Available MCP tools
The Pulse MCP server exposes these tools to connected clients. Parameters are self-describing — your AI assistant will discover them automatically via the MCP schema.
list_monitors— List and filter monitors in your organization.query_data— Query time-series data with aggregations, displayed as an ASCII graph or table.
Related
- Members & Roles -- Manage organization members
- Preferences -- Personal notification settings