On this pagetap to expand
Documentation

ServicePulse Docs

Monitor third-party vendors, build a public status page, and get alerted when your dependencies go down.

Looking for the full reference docs?

In-app guides below cover product behavior end-to-end. The API Reference section lists public HTTP surfaces (personal API under /api/v1, posting keys, widgets, ingest, audit export). Official open-source clients, CI, and orchestrator examples live on GitHub (see Open source & pipelines). For a Swagger-style explorer (try requests, schemas, authorize), use API Explorer.

Getting Started

Everything you need to know in your first 5 minutes.

What is ServicePulse?

ServicePulse monitors your third-party vendor dependencies — Stripe, AWS, Snowflake, GitHub, and 100+ others. When they go down, you know before your customers tell you.

It also lets you build a public status page so your customers can see your service health, and monitors your own HTTP endpoints and databases via heartbeat.

Adding your first vendor

Go to Vendors in the sidebar. Search for the service you depend on and click Track. ServicePulse polls their status page every 2–10 minutes (depending on your plan) and updates your dashboard automatically.

Your dashboard

The Dashboard shows a live overview of everything you track.
  • Green — operational, no issues
  • Yellow — degraded performance or partial outage
  • Red — major outage or active incident
Click any vendor to see its current incidents, component status, and recent history.

Vendor Monitoring

Track third-party services and get alerted when they have incidents.

Vendor catalog

Browse 100+ pre-configured vendors organized by category: cloud, payments, auth, data, communication, and more. Each vendor is pre-wired to poll the correct status API — you just click Track.

Filtering regions (e.g. Snowflake, AWS)

Some vendors have 50+ regions or components. When you click Track on a vendor like Snowflake, you'll be taken to the vendor page where you can select only the regions you actually use. Unselected regions are ignored for your dashboard and alerts — no noise from outages that don't affect you.

Custom vendors

Your vendor isn't in the catalog? Go to Vendors → Add custom vendor. Paste any Atlassian Statuspage or status.io URL and ServicePulse will poll it automatically. Custom vendors work exactly like catalog vendors — same polling, same incident tracking, same alerts.

Polling frequency

ServicePulse polls every tracked vendor's status page every minute. Status snapshots are stored globally — when you add a vendor to your stack, you immediately have access to historical data from the moment it was added to the ServicePulse catalog, not just from when you started tracking it.

Trust Portal & Subprocessors

On any vendor detail page, click Add to Trust Portal to mark that vendor as a subprocessor. Your trust portal is published at yourslug.servicepulse.dev/trust.

Share this URL with customers and security reviewers to demonstrate GDPR-minded vendor transparency. The trust portal lists all your marked subprocessors with their current status.
Start with the vendors that would cause a customer-facing incident if they went down — your payment processor, auth provider, database host, and primary cloud provider are usually the most important. Use the Repo Analyzer to discover them automatically from your codebase.

Incidents

Track and understand active and historical vendor incidents.

Incident timeline

Click any vendor in your stack to see a real-time timeline of all updates for active incidents. Updates are polled directly from the vendor's status page.

AI summaries

Pro plan and above. Summaries appear on vendor pages and in email notifications.

ServicePulse uses Claude to read long incident threads and produce a single plain-English sentence:

"Stripe is experiencing elevated error rates on charge creation in the US-East region, affecting ~15% of API calls. Engineers are investigating."

Incident history

The vendor detail page shows the last 5 resolved incidents. Your plan determines how far back you can look: Free (7 days), Pro (90 days), Team (1 year).

Scheduled maintenance

Planned downtime on your public status page — not the same as third-party vendor incidents above.

What it is

Vendor incidents (the Incidents section) are outages at Stripe, AWS, etc. that ServicePulse tracks for you.

Scheduled maintenance is your planned work — database failovers, deploy freezes, region migrations — that you announce on your status page so customers know what to expect.

In the app

Configure windows under Status Page → Maintenance (or equivalent). You can target specific services, set public vs internal visibility, and optional email reminders before start/end.

Automation & API

Schedule or list windows from CI/CD using the maintenance windows API (same posting key as user-posted incidents, but separate from vendor monitoring). Full request shapes live in API Reference → Maintenance windows.

Notifications

Get alerted when vendors go down — before your customers notice.

Setting up notifications

Available channels depend on your plan — see Notification channels by plan below.

Go to Settings → Notifications. Enter your email, Slack incoming webhook URL (channel alerts only), Microsoft Teams webhook URL, PagerDuty integration key, or other listed channels. You can configure which events trigger alerts: new incident, incident updated, incident resolved.

For the Slack workspace app with slash commands (/servicepulse …), use Account → Integrations — documented under Integrations.

Notification channels by plan

ChannelPlan required
EmailPro+
Microsoft TeamsPro+
DiscordPro+
Slack incoming webhookTeam+
Slack app (OAuth, slash commands)Team+
PagerDutyTeam+
Outbound WebhookTeam+
Google ChatTeam+
ZapierTeam+
Jira AutomationTeam+

All channels apply to both vendor incidents and your own ping monitor alerts.

Outbound webhooks

Team plan and above. Configure under Settings → Notifications → Outbound Webhook.

ServicePulse will POST a signed JSON payload to your URL every time a vendor status changes or an incident fires.

The request includes a signature header for verification:POST <your-webhook-url> X-ServicePulse-Signature: sha256=<hmac-sha256-hex> Content-Type: application/json { "vendor_name": "Stripe", "status": "major_outage", "incident_title": "Elevated API error rates", "incident_description": "...", "timestamp": "2026-03-17T14:32:00.000Z" }

Verify the signature using HMAC-SHA256 with your webhook secret as the key. Use this to trigger runbooks, Slack bots, or incident management workflows.

Notification history

Settings → Notification History shows every alert that was attempted — sent, failed, or suppressed. Each entry shows the channel, trigger event, timestamp, and delivery status.

Use this to debug why an alert didn't arrive: a misconfigured Slack URL, an expired PagerDuty key, or a suppressed duplicate will all appear here with the reason.

Account & Integrations

Profile and billing live under Account; OAuth tools (Slack, metrics, files) live under Account → Integrations.

Account (profile & billing)

In the app sidebar, open Account for your profile, security, and preferences. Plan upgrades, invoices, and the customer billing portal are linked from there. This is separate from Account → Integrations, which only lists third-party connections (Slack workspace, Datadog, document imports, etc.).

Integrations hub

Each integration has its own plan rules (e.g. Slack app is Team+; Datadog sources are Pro+ with tier limits). See Plans & Billing and the sections below.

Open Account → Integrations (signed in) to manage OAuth and long-lived connections: Slack workspaces, external metric sources (e.g. Datadog), and contract/document imports (Google Drive, Dropbox, Common Paper) where your plan supports them.

This is separate from Settings → Notifications, which is where you enable alert channels (email, webhooks, PagerDuty, etc.) and routing rules. Use both together: connect a tool here, then choose how you want to be notified when something breaks.

Slack workspace app

Team plan and above. Install under Account → Integrations → Slack.

Click Connect Slack Workspace to install the ServicePulse app with OAuth. After install, anyone in the workspace can use slash commands in channels:
  • /servicepulse status — rollup of tracked vendors
  • /servicepulse status <vendor> — filter by name
  • /servicepulse incidents — active vendor incidents
  • /servicepulse ping — your ping monitors
  • /servicepulse help — all commands

Self-hosted deployments must set SLACK_CLIENT_ID, SLACK_CLIENT_SECRET, and SLACK_SIGNING_SECRET in the environment.

Slack incoming webhook vs Slack app

Incoming webhook (under Notifications): ServicePulse POSTs formatted incident messages to a channel URL. No slash commands — alerts only.

Slack app (this section): interactive workspace install; use slash commands to query status on demand. You can use both if you want push alerts and in-channel lookups.

Uptime & Endpoint Monitoring

Monitor your own services, jobs, and databases.

HTTP monitors

Enter a URL (e.g. https://api.yourapp.com/health) and ServicePulse pings it at regular intervals. If it returns an unexpected status code or times out, you get an alert. Supports GET, HEAD, and POST (with optional headers and body).

HTTP monitors are for endpoints you can reach over the public internet with a stable success signal. They do not replace warehouse drivers: Snowflake, Databricks, and similar need a script-based check (see Database monitoring) or your own health proxy.

Heartbeat monitors

For background jobs, cron tasks, and queue workers that aren't HTTP-accessible.

You get a unique URL. Your job calls it at the end of each run. If ServicePulse doesn't hear from it within 2× the expected interval, the monitor turns red and you get alerted.

Example: a nightly backup job that runs at 2am. If it doesn't check in by 2:10am, you know something went wrong.

Database monitoring

ServicePulse can't reach your private database or cloud warehouse directly — it's behind a firewall, VPC, or vendor auth. Instead, run a small script on your infrastructure (cron, CI, a VM, Kubernetes, etc.) that:
  1. Connects with your existing drivers or CLI
  2. Runs a health query (e.g. SELECT 1)
  3. Pings the ServicePulse heartbeat URL if successful

When you create a Private DB monitor, ServicePulse generates scripts for PostgreSQL, MySQL, Snowflake, Databricks, SQL Server, Oracle, SQLAlchemy (many engines), shell, Python, and Node. That answers "can we still query from our network?" — not "is Snowflake's status page red?"; for vendor-wide incidents, track Snowflake (and others) under Vendors.

You can customize the query — for example, check that a table has been updated in the last 10 minutes.

Alert thresholds

By default, a monitor alerts after the first failure. You can change this under Monitor → Alert Settings.

Setting "alert after 2 consecutive failures" means a single blip won't wake anyone up — only a sustained outage will. Recovery alerts (when the monitor comes back up) can also be toggled independently.

Monitor detail page

Click any monitor in Ping Monitors to open its detail page:
  • 24h and 90-day uptime percentages
  • Average and p95 response time
  • Response time chart (90 days)
  • Day-by-day uptime calendar with 7/30/90d toggle
  • Full incident log with duration and cause
A self-hosted monitoring agent (for running SQL health checks inside your VPC without a cron script) is on the roadmap for Q3 2026.

Status Pages

Give your customers a public place to check your service health.

Your public status page

Go to Status Page in the sidebar. Your page is published at yourslug.servicepulse.dev. You can also configure a custom domain (e.g. status.yourcompany.com).

Services and dependencies

Define your services (e.g. "API", "Payments", "Mobile App"). Link each service to the vendors it depends on. Your status page shows the computed worst-case status for each service based on live vendor health.

Example: "Payments" depends on Stripe. If Stripe has a partial outage, your Payments service shows degraded automatically.

Embeddable widget & badge

From Status Page in the app, open the embed section to copy snippets. Typical patterns (replace YOUR_APP_URL with your deployment, e.g. https://servicepulse.dev, and slug with your public page slug):

Iframe — compact or badge<iframe src="YOUR_APP_URL/s/slug/embed?style=badge&theme=light" width="280" height="42" frameborder="0" title="Status"></iframe>
JavaScript badge (injects a pill with live text)<script src="YOUR_APP_URL/api/widget/slug" data-style="badge" data-theme="light"></script>
JSON API for custom UIs: GET YOUR_APP_URL/api/widget/slug/status

Linking a ping monitor to a service

Under Status Page → Services, expand a service and select a ping monitor from the dropdown. If that monitor goes down, the service automatically shows as Major Outage on your public page — no manual update needed.

Incidents API

Pro plan and above. Generate a Status Page Posting Key under Developers.

Post your own status-page incidents programmatically from Datadog, PagerDuty, or any tool that can send an HTTP request. Then POST to:
POST /api/status-page/[slug]/incidents
Include your Bearer token and a JSON body with title, body, and status. Full examples: API Reference → Incidents.

Scheduled maintenance (planned downtime)

Planned windows for your services are documented in the dedicated Scheduled maintenance section (separate from vendor incidents). HTTP reference and curl: API Reference → Maintenance windows.

Custom CSS for Status Pages

Business plan only. Available under Status Page → Settings.

Use the Custom CSS textarea to override the look of your public and secure status pages.
Your CSS is applied inside the status page component; use the documented hooks below for predictable styling.

ServicePulse sets these CSS variables on the page:
  • --bg — the status page background
  • --fg — the status page text color
  • --accent — the status page accent color

Documented CSS hooks (stable):
  • .sp-status-page — top-level status page container
  • .header — the page header area
  • .service-item — each service card row
  • .sp-overall-banner — overall status banner
  • .sp-overall-banner-dot — status dot inside the overall banner
  • .sp-overall-banner-label — banner label text
  • .sp-maintenance-banner — maintenance banner (and children like ...-title, ...-item)
  • .sp-maintenance-banner-title — maintenance banner title
  • .sp-maintenance-banner-list — list container
  • .sp-maintenance-banner-item — each maintenance entry
  • .sp-maintenance-banner-link — “View all maintenance…” link
  • .sp-incident-card — each incident details card (active + historical)
  • .sp-incident-card--historical — historical incident card styling (Recent Updates)
  • .sp-incident-summary — incident summary row (title + status badge + timestamp)
  • .sp-incident-body — incident body shown when expanded
  • .sp-incident-created-at — timestamp on the incident summary row
  • .sp-incident-resolved-at — resolved timestamp (historical incidents)
  • .sp-incident-status — incident status badge
  • .sp-service-history — the 30-day history region inside each service card
  • .sp-service-history-item — the service card wrapper when history is enabled
  • .sp-service-history-summary — the summary row inside the service card
  • .sp-service-name — service name text
  • .sp-service-history-toggle — “30-day history” toggle text
  • .sp-service-history-header — “Last 30 days” header row
  • .sp-service-history-day — each 30-day day cell in the history strip
  • .sp-service-history-days — strip/container for the day cells
  • .sp-embed-snippet-toggle — “Embed this status page” summary
  • .sp-embed-snippet-body — embed snippet body
  • .sp-embed-snippet — the “Embed this status page” widget

You can override variables and/or target any elements inside the page. Example:.sp-status-page { background: var(--bg); color: var(--fg); } .sp-status-page .header { border-bottom: 0; } .sp-status-page .service-item { padding: 20px; } .sp-overall-banner { border-width: 0; } .sp-overall-banner-dot { border-radius: 9999px; } .sp-maintenance-banner-title { text-transform: uppercase; } .sp-incident-card { border-color: rgba(37, 99, 235, 0.25) !important; } /* You can also override variables like: */ /* .sp-status-page { --accent: #22c55e; } */

Custom numeric metrics on public status pages

Pro plan and above. Post with your Status Page Posting Key (same as the Incidents API).

ServicePulse supports user-defined numeric metrics (time series) that you post via API. These charts are shown on your public status page under Status Page → Metrics.
POST /api/status-page/<slug>/metrics Authorization: Bearer <your-posting-key> Content-Type: application/json { "metric": "web_traffic", // stable key you pick "value": 120, // number "timestamp": "2026-03-17T14:22:00Z", // optional ISO string (defaults to now) "unit": "req/s", // optional (stored and shown in charts) "label": "Web traffic" // optional (stored as display name) }
Notes:
  • First ingest will upsert the metric and create the public chart configuration if needed.
  • You can remove metrics from Status Page → Metrics; ingesting again may re-add them.

Trust Portal / Subprocessors

On the vendor detail page, click Add to Trust Portal to mark a vendor as a subprocessor. Your trust portal is published at yourslug.servicepulse.dev/trust. Share this URL with customers and prospects to demonstrate GDPR compliance.

Metrics

Uptime history, response time charts, and custom numeric metrics — for vendors, monitors, and your own data.

Vendor metrics

Every time ServicePulse polls a vendor, it records the response time and up/down status. Open any vendor page to see:
  • A response time chart (avg and p95) with a 7/30/90-day toggle
  • A day-by-day uptime calendar color-coded by worst status
History depth depends on your plan: Free (7 days), Pro (90 days), Team/Business (1 year).

Ping monitor metrics

HTTP ping monitors record latency on every check. The monitor detail page shows:
  • 24h and 90-day uptime percentages
  • Average and p95 response time
  • Response time chart (90 days)
  • Day-by-day uptime calendar with a 7/30/90-day toggle
All calculated from your own check results, independent of any vendor status page.

Custom metrics — pushing your own data

Pro plan and above. Custom metric keys and ingest limits scale with your plan — check Billing.

The Metrics page in the sidebar shows all custom numeric metrics you push via API. Use these for anything you want to track over time: request rates, error counts, queue depth, revenue, deploy frequency.

Push a data point with your status page posting key:POST /api/status-page/<slug>/metrics Authorization: Bearer <your-posting-key> Content-Type: application/json { "metric": "error_rate", // stable key you choose "value": 0.42, // numeric value "unit": "%", // optional — stored and shown in charts "timestamp": "2026-04-01T12:00:00Z" // optional, defaults to now }

The first ingest auto-creates the metric. You can send a single object or an array of objects in one request.

External metric sources (Datadog, New Relic)

Pro plan and above. Connection limits increase on Team and Business — see Billing.

Under Developers → External Metric Sources, connect Datadog or New Relic to pull real time-series metrics directly. ServicePulse fetches data every minute and stores it for trend visualization alongside your vendor sparklines.

Use cases:
  • Surface API latency or error rate next to vendor status
  • Correlate a Datadog monitor spike with a vendor incident
  • Show your own service health metrics on your public status page

The number of external metric sources you can connect depends on your plan. See Billing for limits.

Metrics on your public status page

Pro plan and above to show vendor, monitor, and custom metric charts on your public page; chart limits increase on higher tiers.

In Status Page → Metrics, opt in to show charts publicly. You can add any tracked vendor, ping monitor, or custom metric. For each one, toggle uptime and/or response time visibility independently.

Visitors to your status page see the charts with the same 7/30/90-day toggle.

Uptime & SLA comparison

Pro plan and above for SLA targets, breach tracking, and comparison vs measured uptime on the Uptime & SLA page.

The Uptime page shows all your tracked vendors side-by-side: uptime %, SLA target, and whether they're meeting it. Set a custom SLA target per vendor under its detail page → SLA tab. Vendors with attached contracts show their committed uptime automatically.

Push & Webhooks

Receive incident data from vendors that push rather than publish a status page.

Inbound push webhooks — overview

Pro plan and above. Free plans cannot create push endpoints; limits increase on Team and Business.

Some vendors and internal tools push incident data rather than publishing a status page you can poll. Go to Push in the sidebar, create an endpoint, and paste the generated URL into the vendor's webhook settings. Each endpoint has its own unique token embedded in the URL — no extra auth header required.

Incoming payloads are auto-detected and normalized. Supported formats:
  • Native ServicePulse JSON (events + service status push)
  • Atlassian Statuspage (incident & component_update webhooks)
  • PagerDuty webhook v3
  • Alertmanager (Prometheus)
  • Datadog alert webhooks — fires when a monitor alert triggers or recovers
  • New Relic alert webhooks — fires on policy condition state changes
  • Dagster+ alert webhooks — fires on alert policy triggers
  • Jira Automation (outbound POST to your rule's URL)

Setting up a PagerDuty webhook

  1. Go to Push in the sidebar and click New Endpoint. Copy the generated URL.
  2. In PagerDuty, open Integrations → Webhooks and add a new webhook pointing to that URL.
  3. Select the event types you want forwarded (recommended: incident.triggered, incident.resolved, incident.acknowledged).
  4. Save — ServicePulse will start receiving events immediately.

PagerDuty payloads are auto-detected as v3 format. No extra config required on the ServicePulse side.

Setting up Alertmanager (Prometheus)

Add a webhook_configs receiver in your Alertmanager config pointing to your push URL:receivers: - name: servicepulse webhook_configs: - url: https://servicepulse.dev/api/ingest/<token> send_resolved: true

Set send_resolved: true so ServicePulse can auto-resolve incidents when Alertmanager sends a resolved status.

Setting up Dagster+ alert webhooks

Dagster+ can POST an alert webhook to your ServicePulse push endpoint whenever an alert policy fires. ServicePulse auto-detects the Dagster+ format — no extra config needed on the ServicePulse side.

Steps in Dagster+:
  1. Go to Alerts in your Dagster+ deployment.
  2. Create or edit an alert policy. Under Notification channel, choose Webhook.
  3. Set the webhook URL to your ServicePulse push endpoint:
    https://servicepulse.dev/api/ingest/<your-token>
  4. Save the alert policy. ServicePulse will start receiving events immediately.

Dagster+ sends the following fields in the webhook payload — all are available for alert rules in ServicePulse:
  • alert_summary — short summary of the alert
  • alert_content — full alert body
  • alert_policy_name — name of the policy that fired
  • alert_policy_id — policy ID
  • alert_policy_description — policy description
  • alert_id — unique ID for this alert instance
  • deployment_name — Dagster+ deployment name
  • deployment_url — URL to the deployment
  • notification_type — type of notification
  • is_sampletrue when triggered by a test alert

To also update a service status when a Dagster job fails, add serviceId and status fields to the webhook body (see Pushing service status below).

Pushing service status from pipelines

Orchestrators and CI pipelines can push a health signal directly to a ServicePulse service, independently of vendor dependency polling. This lets your Dagster jobs, Airflow DAGs, or deploy scripts report their own status — which is then factored into the service's displayed health on your status page.

Add serviceId and status to any ingest payload:POST https://servicepulse.dev/api/ingest/<token> Content-Type: application/json { "type": "service_status", "serviceId": "<your-service-id>", "status": "degraded_performance", "title": "ETL pipeline latency elevated", "message": "p95 exceeds SLA threshold in us-east-1" }Valid status values: operational, degraded_performance, partial_outage, major_outage, maintenance, unknown.

The pushed status is combined with vendor dependency status — the worst of the two is shown. Find your service ID on the Status Page → Services settings page.

Native push payload format

If you're sending from your own tooling (CI pipelines, deploy scripts, custom monitoring), use the native JSON format. There are two modes:

1. Log an event (recorded in your push feed, can trigger notifications):POST https://servicepulse.dev/api/ingest/<token> Content-Type: application/json { "type": "deploy.failed", "title": "API latency spike", "message": "p95 latency is elevated in us-east-1", "severity": "minor" // info | minor | major | critical }2. Push a service status — updates the displayed health of a specific service on your status page. Use this when your own pipeline is degraded even though all your upstream vendors are green:POST https://servicepulse.dev/api/ingest/<token> Content-Type: application/json { "type": "service_status", "serviceId": "<your-service-id>", "status": "degraded_performance", "title": "ETL pipeline latency elevated", "message": "p95 exceeds SLA threshold in us-east-1" }Valid status values: operational, degraded_performance, partial_outage, major_outage, maintenance. The pushed status is combined with vendor dependency status — the worst of the two is what your status page shows. Find your service ID on the Status Page → Services settings page.

The token in the URL is your push endpoint token — find it on the Push page. No Authorization header needed.

Alert rules for push events

Push events trigger the same notification channels as polled vendor status changes. Go to Settings → Notificationsand configure your channels (email, Slack, PagerDuty, outbound webhook). You can filter alerts by severity — for example, only notify on-call for major or critical events.
Push endpoints are per-account (or per-org when in an org workspace). Create multiple endpoints to track different tools or teams separately — each shows its own feed on the Push page.

Organizations

Share monitoring with your whole team. Requires Team plan or above.

Creating an organization

Team plan and above. Team includes one organization; Business includes unlimited.

Go to Organization in the sidebar. Click Create Organization, enter a name, and invite teammates by email. Once you switch to the org context, all monitored vendors, services, ping monitors, alerts, and the status page are shared across the team.

Plan limits: Team plan includes 1 organization. Business plan includes unlimited organizations.

Switching between personal and org workspace

Use the organization switcher in the top bar to toggle between your personal account and your organization. Your personal stack and your org stack are completely separate — tracked vendors, services, ping monitors, and the status page are all workspace-scoped.

API tokens are also workspace-scoped. A token created while in your personal workspace cannot read org data, and vice versa. Create a separate personal API token for each workspace you need to automate.

Inviting and managing team members

From the Organization page, use the Clerk-powered member UI to:
  • Invite members by email (they receive a Clerk invite link)
  • Assign roles: Admin or Member
  • Remove members or revoke pending invitations

Admins can access billing, audit log, and org settings. Members can view and manage the shared vendor stack but cannot change billing or see the audit log.

Audit log

Team plan and above. Open Settings → Audit Log.

The audit log records every meaningful action taken in your workspace:
  • Vendor added or removed from tracking
  • Ping monitor created, updated, or deleted
  • Notification channel added or removed
  • Status page settings changed
  • API token created or revoked
  • Push endpoint created or deleted
  • Organization member invited or removed

In a personal workspace, you always see your own history. In an org, only admins (Clerk role org:admin) can access the audit log. Each entry shows the actor's name, email, action, and a timestamp.

Export via the in-app UI (CSV or JSON), or call GET /api/audit-log?format=csv with a browser session. For scripted access, use GET /api/v1/audit-log with a personal API token (personal workspace only — org audit log requires browser session).

Richer role-based access (editor/viewer roles) is on the roadmap. Today, sensitive items like billing and the audit log are admin-only in an org context.

My Services

Internal view of your own products and their vendor dependencies.

What are services?

Services represent your own products — "Checkout API", "Mobile App", "Data Pipeline". Each service can depend on one or more tracked vendors. The service's displayed status is the worst-case status of all its vendor dependencies — if Stripe is degraded and Stripe is a dependency of your Checkout API service, Checkout API shows as degraded too.

Creating a service and adding dependencies

Go to My Services and click New Service. Give it a name and optionally a description. Then add vendor dependencies — search your tracked vendor list and select the ones this service relies on.

You can add as many dependencies as you need. The service card on the dashboard shows an aggregated status badge and the individual status of each dependency below it.

My Services vs. Status Page

My Services is your internal view — full technical detail, component-level status, all dependency chains visible. Only team members logged into ServicePulse can see it.

Status Page is the public-facing view your customers see — simplified, with only the services you choose to expose. You decide which of your services to surface publicly and what to call them. Configure which services appear publicly under Status Page → Settings.
Use My Services to model your internal architecture (microservices, pipelines, mobile apps) and the Status Page to publish a customer-friendly view. The two are independent — changes to one don't auto-update the other.

SLA Contracts

Vendor agreements in the app (Business), SLA targets vs measured uptime (Pro+), breach exports (Team+).

What are SLA contracts?

The Contracts page — upload and manage vendor agreements — requires a Business plan.

SLA contracts record the committed availability targets from your agreements and compare them to measured uptime from each vendor's status page.

Go to Contracts in the sidebar to upload or import agreements (Business). Each contract links to a tracked vendor. The Uptime & SLA page shows targets vs actuals and breach signals for plans that include SLA intelligence (Pro+).

Contract ingestion sources

Business plan only. Configure under Settings → Contract Integrations.

The Contract Integrations page (Settings → Contract Integrations) lets you connect document sources to pull contracts in automatically:
  • CommonPaper — sync signed agreements directly from your CommonPaper account
  • Google Drive — index PDFs in a specified Drive folder
  • Dropbox — pull contracts from a Dropbox folder

After connecting a source, ServicePulse parses SLA clauses (uptime percentage, measurement window, exclusions) and pre-fills the contract record. You review and confirm before it goes live.

SLA breach reports

Team plan and above for CSV/JSON breach exports (in-app and GET /api/sla/report).

With contracts attached to vendors (Business), export SLA breach reports from the Uptime & SLA page: pick a vendor, a measurement window (monthly, quarterly, or annual), and download as CSV or view inline.

Same export via API (signed-in browser session, not a personal API token): GET /api/sla/report.
Contracts (upload + AI ingestion from Google Drive, Dropbox, or CommonPaper) is Business. SLA intelligence on Uptime & SLA starts at Pro; breach exports require Team or above.

Repo Analyzer

Scan your codebase to discover which vendors your application actually depends on.

What does Repo Analyzer do?

Pro plan and above (same entitlement as AI incident summaries). In the app, open Account → Repo Analyzer — the sidebar link is shown for workspace admins.

Repo Analyzer scans your GitHub repositories for third-party SDK imports, API calls, and dependency references — then cross-references them against the ServicePulse vendor catalog. The result is a suggested list of vendors to add to your stack, based on what your code is actually using.

This is especially useful when onboarding: instead of manually searching for every vendor, connect your repo and ServicePulse discovers most of them for you.

Connecting a repository

Go to Account → Repo Analyzer in the sidebar. Authorize ServicePulse to read your GitHub repositories (read-only access — no write permissions requested). Select the repositories you want to analyze and click Analyze.

Analysis typically completes in seconds for smaller repos. Results show matched vendors with confidence scores. Click Track next to any vendor to add it to your stack immediately.

What gets detected?

The analyzer looks for signals across multiple file types:
  • package.json / requirements.txt / go.mod — official SDK package names (e.g. stripe, @sendgrid/mail)
  • Source code imports — SDK imports and API client instantiation patterns
  • Environment variables — API key variable names (e.g. STRIPE_SECRET_KEY, TWILIO_ACCOUNT_SID)
  • Config files — references to vendor hostnames and API base URLs
Re-run the analyzer when you add a new dependency — it only looks at the current state of the default branch.

Plans & Billing

What each plan includes and how limits work.

Plan overview

FeatureFreeProTeamBusiness
Tracked vendors525100Unlimited
Ping monitors32050Unlimited
Uptime history7 days90 days1 year1 year
AI summaries
Email notifications
Slack / PagerDuty
Outbound webhooks
Organizations1Unlimited
SLA breach reports
Contract ingestion
Custom CSS status page

Usage meters

The Billing page shows live usage meters for tracked vendors, ping monitors, push endpoints, and API tokens. When you approach a limit (80%+) a warning banner appears. At the limit, you can't add more of that resource until you upgrade or remove existing items.

Upgrading and managing subscriptions

Click Upgrade on the Billing page to start a Stripe checkout session. Upgrades are prorated — you only pay the difference for the remaining billing period. To cancel, downgrade, or update your payment method, click Manage Billing (opens the Stripe customer portal).
If you're evaluating for a team, start on the Team plan trial. You get all org features for free during the trial period — no credit card required until you decide to keep it.

Migrate from Statuspage.io

Import your components, incident history, and subscribers from Atlassian Statuspage in minutes.

One-click importer

The built-in importer connects to the Statuspage Manage API using your existing API key and brings over everything — no CSV exports, no manual work.

  • Components → Services — each Statuspage component becomes a service on your status page, in the same order.
  • Incident history — historical incidents with original timestamps, status, and update bodies.
  • Email subscribers — imported as unconfirmed; subscribers receive a one-time re-confirmation email (CAN-SPAM required) before going live.

Find the importer under Account → Import from Statuspage in the app sidebar, or go directly to /import/from-statuspage. Most migrations complete in under 2 minutes.

Migrating your automation (CI/CD scripts)

If you have scripts or CI pipelines that post to the Statuspage API, you can point them at ServicePulse with a one-line environment variable change. No code changes needed — ServicePulse accepts the same request shapes.

# Old STATUSPAGE_API_BASE=https://api.statuspage.io STATUSPAGE_API_KEY=<your-statuspage-oauth-key> STATUSPAGE_PAGE_ID=<your-statuspage-page-id> # New — only these three lines change STATUSPAGE_API_BASE=https://servicepulse.dev/api/compat/statuspage STATUSPAGE_API_KEY=<your-servicepulse-posting-key> STATUSPAGE_PAGE_ID=<your-servicepulse-slug> # e.g. "acme"

The compat shim supports Authorization: OAuth <key> (Statuspage format) and Authorization: Bearer <key> (ServicePulse format). Full endpoint list: API Reference → Statuspage compatibility shim.

After importing, go to Status Page → Settings to set your custom domain, point your DNS, and update the status page link in your app or support docs. Then cancel Statuspage.

Open source & pipelines

CI (GitHub, GitLab, Azure), Terraform, GitOps, probe, clients in Python/Node/Go, orchestrators, and recipes — same APIs as the product.

GitHub: servicepulsehq/integrations

The open-source integrations monorepo lives at github.com/servicepulsehq/integrations. It includes:

  • Python servicepulse-client and typed JS/Go clients
  • Orchestrator and CI integrations — Airflow, Dagster, Prefect (see libraries/ and examples/), plus GitHub Actions, GitLab, and Azure templates
  • Terraform stack_health, GitOps samples, probe, webhooks

Use a Personal API token (sp_…) from Developers in the app. Vendors must be tracked in the same workspace the token was created for. Pipelines typically call GET /api/v1/tracked-vendors or GET /api/v1/stack-summary for a rolled-up health signal.

Use the in-page Ask AI assistant for any integration surface in the repo (CI, clients, Terraform, Airflow, Dagster, Prefect, etc.) — it is grounded in this documentation and the paths above.

API Reference

Automate status updates, read dashboard data, embed widgets, and integrate with your existing tooling.

Overview — API families

Pick the surface that matches your integration. Each section below documents request shape, auth, and query parameters.

Authentication

ServicePulse exposes three types of API tokens:
  • Personal API token — account-level Bearer token. Generate one under Developers in the sidebar. Pass as Authorization: Bearer sp_.... Use with the Personal API and the discovery endpoint GET /api/v1.
  • Status page posting key — a Bearer token scoped to a single status page. Generate it under Developers → Status Page Posting Key. Use it for incidents, maintenance windows, and posting custom metrics — not for /api/v1.
  • Push endpoint token — embedded directly in the ingest URL (/api/ingest/<token>). No Authorization header needed. Create one under Push in the sidebar.

Workspace scope: when you create a personal API token, it is bound to the workspace active in the app (personal account vs organization). Use a separate token per workspace if you automate both.

Personal API (Bearer sp_…, /api/v1)

Available on all plans; token limits and some endpoints vary by tier (e.g. /api/v1/audit-log is Team+). Check Billing for your quota.

JSON API for scripts, CI, and integrations (mostly reads; create monitors via POST /api/v1/ping-targets). Auth: Authorization: Bearer sp_... (personal tokens from Developers, or Organization API tokens minted there when a Clerk org is active — same /api/v1 behavior, org-owned so automation survives member churn; org admins only). Discovery: GET /api/v1 returns the endpoint index as JSON.

MethodPathDescription
GET/api/v1Discovery (endpoint index)
GET/api/v1/metokenKind: personal (user id, email) vs organization (no user; organizationName, Clerk org id)
GET/api/v1/ping-targetsList monitors; type: heartbeat includes heartbeatUrl + interval for agents (treat like a secret). hasAuthHeaders only flags — no probe secrets
POST/api/v1/ping-targetsCreate HTTP monitor; optional requestHeaders, requestBody (e.g. JSON POST probes)
GET/api/v1/tracked-vendorsTracked vendors + current status snapshot
GET/api/v1/stack-summaryRolled-up stack health (worstStatus, summary, non-operational list) — useful for CI and orchestrators
GET/api/v1/incidentsVendor incidents for your stack; query limit (1–200, default 50)
GET/api/v1/metricsCustom numeric metrics (id, key, unit)
GET/api/v1/metrics/{id}/seriesTime series; query bucket = raw | 1h | 1d | 1w, agg = sum | avg | min | max | count
GET/api/v1/status-pageYour status page slug, title, public URL for this workspace
GET/api/v1/audit-logAudit entries (Team+). Personal workspace token only — use the app for org audit history. Query from, to, q, actionType, limit (≤500)

The in-app chart calls GET /api/metrics/{id}/series with a browser session. For automation, use GET /api/v1/metrics/{id}/series with a personal or organization API token.

Audit log (same Personal API) — response includes actor (name, email) per entry. Org-scoped tokens cannot use this endpoint; open Settings → Audit log in the app when an organization is active.

Audit log export (browser session)

Team plan and above. Uses your signed-in browser session — not a personal API token.

When you are signed into the app, you can export the same audit log your org admins see (with org rules applied) without a Bearer token:

  • GET /api/audit-log?format=json|csv — optional query params from, to, q, actionType, limit (max 2000), offset. Uses the session cookie; not an sp_... token.

GET /api/v1 lists the current discovery payload (including /api/v1/audit-log when deployed).

Public status & embed widgets (no auth)

These endpoints work for public status pages only (isPublic in settings). No Bearer token.

  • GET /api/status-page/<slug>/status — overall status, services, active incidents (JSON for dashboards and monitors).
  • GET /api/widget/<slug>/status — CORS-enabled JSON for embeds; Cache-Control: public, max-age=60.
  • GET /api/widget/maintenance/<slug>/status — upcoming / active maintenance for widgets; supports audience and leadMinutes query params.

Heartbeat monitors (cron) use GET|POST /api/heartbeat/<token> — the token is in the path, not the posting key. With a personal API token, GET /api/v1/ping-targets returns heartbeatUrl for each heartbeat monitor so on-prem agents (for example the integrations probe) do not need copy-paste from the app.

Status page posting key — what it covers

Pro plan and above for programmatic incidents, maintenance, and custom metrics on your status page (see Incidents API below).

One key (shown under Developers → Status Page Posting Key) authenticates write APIs for a single status page slug. It is not the same as a personal sp_... token.

The sections below follow that order: incidents, maintenance, and metrics are different APIs (different paths) that share the same posting key — maintenance is not a sub-resource of incidents.

Status page — incidents API (posting key)

Pro plan and above. Uses your status page posting key, not a personal sp_... token.

Post, update, and resolve incidents on your public status page. Auth: Authorization: Bearer <posting-key>.

Create incidentPOST /api/status-page/<slug>/incidents Authorization: Bearer <your-posting-key> Content-Type: application/json { "title": "Elevated error rates", "body": "We are investigating reports of elevated error rates.", "status": "investigating", // investigating | identified | monitoring | resolved "severity": "major" // minor | major | critical }Update incidentPATCH /api/status-page/<slug>/incidents/<id> Authorization: Bearer <your-posting-key> Content-Type: application/json { "body": "Fix has been deployed. Monitoring.", "status": "monitoring" }Resolve incidentPATCH /api/status-page/<slug>/incidents/<id> Authorization: Bearer <your-posting-key> Content-Type: application/json { "body": "Fully resolved as of 14:32 UTC.", "status": "resolved" }

Planned downtime is not created here — use the maintenance windows API next.

Status page — services API (posting key)

Pro plan and above. Same posting key as incidents and maintenance.

List and update services (components) on your status page programmatically. Useful for CI/CD pipelines that need to mark a service as degraded without creating a full incident.

List servicesGET /api/status-page/<slug>/services Authorization: Bearer <your-posting-key>Get one serviceGET /api/status-page/<slug>/services/<serviceId> Authorization: Bearer <your-posting-key>Update a servicePATCH /api/status-page/<slug>/services/<serviceId> Authorization: Bearer <your-posting-key> Content-Type: application/json { "name": "Payments", "public_name": "Payment Processing", "description": "Stripe payment flows", "active": false }

All fields in the PATCH body are optional. Set active: false to mark a service as inactive (hidden from the status page). The id of each service is returned in the list — use that as serviceId.

Statuspage.io compatibility shim

Use your existing Statuspage.io scripts without modification. The shim accepts the same request shapes as the Statuspage Manage API.

If you have CI/CD scripts, Terraform configs, or automation that targets the Statuspage.io API, you can point them at ServicePulse with a one-line change. Replace https://api.statuspage.io with https://servicepulse.dev/api/compat/statuspage and use your ServicePulse posting key as the OAuth token.

The page ID used in URL paths can be either your status page slug (e.g. acme) or the numeric-style page ID returned by the GET /v1/pages discovery call.

Supported endpoints
MethodPathDescription
GET/v1/pagesDiscover your page ID
GET/v1/pages/:pageIdPage metadata
GET/v1/pages/:pageId/componentsList all components (services)
GET/v1/pages/:pageId/components/:idGet one component
PATCH/v1/pages/:pageId/components/:idUpdate component status / name
GET/v1/pages/:pageId/incidentsList incidents
POST/v1/pages/:pageId/incidentsCreate incident
GET/v1/pages/:pageId/incidents/:idGet one incident
PATCH/v1/pages/:pageId/incidents/:idUpdate incident status / body
DELETE/v1/pages/:pageId/incidents/:idDelete incident
POST/v1/pages/:pageId/incidents/:id/incident_updatesAppend incident update (status + body)
Quick migration — one environment variable# Before STATUSPAGE_API_KEY=your-statuspage-oauth-key STATUSPAGE_PAGE_ID=your-statuspage-page-id STATUSPAGE_API_BASE=https://api.statuspage.io # After (set these, no code changes needed) STATUSPAGE_API_KEY=your-servicepulse-posting-key STATUSPAGE_PAGE_ID=your-servicepulse-slug-or-page-id STATUSPAGE_API_BASE=https://servicepulse.dev/api/compat/statuspage

Auth: use Authorization: OAuth <posting-key> (Statuspage style) or Authorization: Bearer <posting-key> (ServicePulse style) — both work.

Status page — maintenance windows API (posting key)

Pro plan and above. Same posting key as incidents and custom metrics.

Separate from the incidents API above: different paths (/maintenance vs /incidents). Same posting key Bearer token. List or schedule planned work on your status page.

List maintenance windowsGET /api/status-page/<slug>/maintenance?limit=50 Authorization: Bearer <your-posting-key>

limit is optional (1–100, default 50). Response includes maintenance array with window metadata.

Schedule maintenancePOST /api/status-page/<slug>/maintenance Authorization: Bearer <your-posting-key> Content-Type: application/json { "title": "Database upgrade", "description": "Brief read-only window while we fail over.", "startsAt": "2026-04-01T02:00:00.000Z", "endsAt": "2026-04-01T03:00:00.000Z", "serviceIds": ["clxxxxxxxx"], "audienceMode": "inherit", "notifyOnCreate": true, "notifyMinutesBefore": 60, "notifyOnStart": true, "notifyOnEnd": true }

audienceMode: inherit | public-only | internal-only.serviceIds must be valid service IDs on your page (empty array = no specific services).

Status page — custom metrics ingest (posting key)

Pro plan and above. Same posting key as incidents and maintenance.

POST numeric time-series points for metrics defined on your status page.

POST /api/status-page/<slug>/metrics Authorization: Bearer <your-posting-key> Content-Type: application/json { "metric": "request_rate", "value": 42.5, "timestamp": "2026-04-01T12:00:00.000Z", "unit": "req/s", "label": "Optional label" }

You can send a single object or an array of objects. Each item requires metric (key) and a numeric value.

Push webhook endpoint

Pro plan and above. Create endpoints under Push in the sidebar.

Receive incident data from external tools by creating a push endpoint. Go to Push in the sidebar, create an endpoint, and paste the URL into your external tool's webhook configuration.

POST https://servicepulse.dev/api/ingest/<token>
ServicePulse auto-detects the payload format. Supported formats:
  • Native ServicePulse JSON
  • Atlassian Statuspage (incident / component_update webhooks)
  • PagerDuty webhook v3
  • Alertmanager (Prometheus)
  • Datadog alert webhooks — fires when a monitor alert triggers or recovers
  • New Relic alert webhooks — fires on policy condition state changes
  • Jira Automation (outbound POST to your rule's URL)

Note on Datadog & New Relic: these integrations receive alert/incident events (monitor fired, policy breached), not raw time-series metrics. Full metric ingestion (response times, error rates) from external APM tools is on the roadmap.

Native push payload

If you're sending from your own tooling, use the native format:

POST /api/ingest/<token> Content-Type: application/json { "status": "degraded", // operational | degraded | outage | maintenance "title": "API latency spike", "message": "p95 latency is elevated in us-east-1", "severity": "minor" // info | minor | major | critical }

SLA breach report (browser session)

Team plan and above. Requires a signed-in browser session (cookie), not a personal API token.

GET /api/sla/report — exports SLA breach analysis for a vendor and time window (slaBreachReports).

Query params: vendorId, window (monthly | quarterly | annual), periodStart (ISO date), optional format=csv.

curl examples

Personal API — who am I?curl -s https://servicepulse.dev/api/v1/me \ -H "Authorization: Bearer sp_your_personal_token..."Personal API — list ping monitors:curl -s https://servicepulse.dev/api/v1/ping-targets \ -H "Authorization: Bearer sp_your_personal_token..."Personal API — create authenticated API monitor:curl -X POST https://servicepulse.dev/api/v1/ping-targets \ -H "Authorization: Bearer sp_your_personal_token..." \ -H "Content-Type: application/json" \ -d '{"name":"Payments API","url":"https://api.example.com/v1/health","method":"GET","expectedStatus":200,"requestHeaders":{"Authorization":"Bearer YOUR_TOKEN"}}'Create incident (status page posting key — not sp_):curl -X POST https://servicepulse.dev/api/status-page/acme/incidents \ -H "Authorization: Bearer <your-posting-key>" \ -H "Content-Type: application/json" \ -d '{"title":"Database degraded","status":"investigating","severity":"major"}'Push ingest (account push URL):curl -X POST https://servicepulse.dev/api/ingest/<token> \ -H "Content-Type: application/json" \ -d '{"status":"operational","title":"Deploy complete","severity":"info"}'Schedule maintenance (posting key):curl -X POST https://servicepulse.dev/api/status-page/acme/maintenance \ -H "Authorization: Bearer <your-posting-key>" \ -H "Content-Type: application/json" \ -d '{"title":"Planned DB maintenance","startsAt":"2026-04-01T02:00:00.000Z","endsAt":"2026-04-01T03:00:00.000Z","serviceIds":[]}'

Outbound webhook payload

Team plan and above. Configure under Settings → Notifications → Outbound Webhook.

When you configure an outbound webhook (Settings → Notifications → Outbound Webhook), ServicePulse sends a signed POST request on each trigger:

POST <your-webhook-url> X-ServicePulse-Signature: sha256=<hmac-sha256-hex> Content-Type: application/json { "vendor_name": "Stripe", "status": "major_outage", "incident_title": "Elevated API error rates", "incident_description": "Stripe is reporting elevated error rates...", "timestamp": "2026-03-17T14:32:00.000Z" }
The signature uses HMAC-SHA256 with your webhook secret as the key. Verify it to confirm the payload came from ServicePulse.
All API endpoints require HTTPS. Your Status Page Posting Key is shown once at creation — store it in a secret manager (e.g. GitHub Actions secrets, AWS Secrets Manager).

Something missing or unclear? Contact support or check the roadmap.