Skip to content

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.

Organization SMTP settings

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:

FieldDescription
HostSMTP server hostname
PortSMTP server port (e.g., 587 for TLS)
UsernameAuthentication username
PasswordAuthentication password
From AddressEmail address used as the sender
From NameDisplay name used as the sender
Use TLSEnable 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.

License usage panel

The panel has two groups:

Plan limits — dimensions with a quota cap, shown as progress bars:

DimensionDescription
Endpoint monitorsActive endpoint monitors against the plan limit
Node monitorsActive node monitors against the plan limit
On-call schedulesActive on-call schedules against the plan limit
EmailsEmails sent during the license term
SMSSMS messages sent during the license term
Voice callsVoice 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:

DimensionDescription
NotificationsIn-app notifications sent
Push notificationsMobile push notifications sent
WebhooksWebhook deliveries made

Features — licensed capabilities shown as enabled (✓) or not included (—):

FeatureDescription
MCP (Model Context Protocol)Whether MCP token creation and API access is enabled
CVE monitoringWhether 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.

Webhook settings

Click Add Webhook to create a new webhook:

FieldDescription
Display NameA label to identify this webhook
Endpoint URLTarget URL — supports https://, http://, or tcp:// schemes
ActiveToggle to enable or disable delivery
Event TypesSelect 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:

HeaderValue
Content-Typeapplication/json
User-AgentPulse-Webhook/1.0
X-Pulse-Signaturesha256=<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:

  1. Read the raw request body as bytes — do not parse and re-serialize the JSON. Even insignificant whitespace differences will change the hash.
  2. Compute HMAC-SHA256(secret, body) and format it as lowercase hexadecimal.
  3. Compare your computed value sha256=<hex> to any one of the entries in X-Pulse-Signature. Use a constant-time comparison to avoid timing leaks.
  4. If at least one entry matches, the delivery is authentic. If none match, reject the request.

Node.js example:

js
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:

python
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.typeDescription
incident.createdIncident created
incident.acknowledgedIncident acknowledged
incident.resolvedIncident resolved
oncall.rotationOn-call responders or operating hours changed
notification.email_scheduledEmail notification scheduled
notification.sms_scheduledSMS notification scheduled
notification.push_scheduledPush notification scheduled
notification.call_scheduledVoice 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:

json
{
  "event_type": "incident.created",
  ...event-specific fields
}

Incident event payloads

The incident.created, incident.acknowledged, and incident.resolved events share the same payload shape:

FieldTypeDescription
event_typestringOne of incident.created, incident.acknowledged, incident.resolved
incident_idintegerID of the incident
titlestringIncident title
statusstringIncident 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:

FieldTypeDescription
event_typestringOne of notification.email_scheduled, notification.sms_scheduled, notification.push_scheduled, notification.call_scheduled
incident_idintegerID of the incident that triggered the notification
channelstringNotification channel — "email", "sms", "push", or "call"
recipientsarrayList of notification recipients

Each entry in recipients has:

FieldTypeDescription
display_namestringDisplay name of the recipient
emailstring|nullEmail address, if available
phone_numberstring|nullPhone 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:

FieldTypeDescription
event_typestringAlways "oncall.rotation"
schedule_idintegerID of the on-call schedule
schedule_namestringName of the on-call schedule
previous_respondersarrayResponders active before this change
current_respondersarrayResponders active after this change
in_operating_hoursbooleanWhether the schedule is currently within operating hours
is_overridebooleanWhether an override is currently active

Each entry in previous_responders and current_responders has:

FieldTypeDescription
idintegerLogin ID
namestringDisplay name or email
emailstringEmail address
phonestring|nullMobile 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.

MCP Tokens settings

Click New Token to create a token:

FieldDescription
NameA 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

bash
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

json
{
  "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.