Manage OneUptime monitoring resources
Project description
Pulumi OneUptime Provider
A native Pulumi provider for managing OneUptime monitoring resources.
Installation
Go
go get github.com/ottercoders/pulumi-oneuptime/sdk/go/oneuptime
Node.js
npm install @ottercoders/pulumi-oneuptime
Python
pip install pulumi-oneuptime
Configuration
The provider requires an API key and optionally a base URL and default project ID.
| Property | Environment Variable | Required | Default | Description |
|---|---|---|---|---|
apiKey |
ONEUPTIME_API_KEY |
Yes | API key for authentication | |
baseUrl |
ONEUPTIME_BASE_URL |
No | https://oneuptime.com |
Base URL of the OneUptime instance |
projectId |
ONEUPTIME_PROJECT_ID |
No | Default project ID for all resources |
Using Pulumi Config
pulumi config set oneuptime:apiKey --secret <your-api-key>
pulumi config set oneuptime:projectId <your-project-id>
# For self-hosted instances
pulumi config set oneuptime:baseUrl https://your-instance.example.com
Using Environment Variables
export ONEUPTIME_API_KEY="your-api-key"
export ONEUPTIME_PROJECT_ID="your-project-id"
Resources
All resources (except Project) accept an optional projectId property. When omitted, the provider-level projectId config is used. Every resource exposes resourceId, slug, createdAt, and updatedAt as outputs.
| Resource | Description |
|---|---|
Team |
Manages teams within a project |
Monitor |
Manages monitors (API, website, etc.) |
StatusPage |
Manages public/private status pages |
Incident |
Manages incidents |
OnCallDutyPolicy |
Manages on-call duty escalation policies |
Label |
Manages labels for categorizing resources |
MonitorGroup |
Manages logical groupings of monitors |
IncidentState |
Manages incident workflow states (e.g. Created, Acknowledged, Resolved) |
IncidentSeverity |
Manages incident severity levels (e.g. Critical, Major, Minor) |
AlertState |
Manages alert workflow states |
AlertSeverity |
Manages alert severity levels |
Project |
Manages OneUptime projects |
StatusPageGroup |
Groups monitors on a status page |
StatusPageResource |
Links a monitor or monitor group to a status page |
OnCallDutyPolicyEscalationRule |
Escalation timing/order within an on-call policy |
OnCallDutyPolicySchedule |
Rotation schedule within an on-call policy |
OnCallDutyPolicyEscalationRuleSchedule |
Assigns an on-call schedule as a paging target on an escalation rule |
OnCallDutyPolicyEscalationRuleUser |
Assigns a specific user as a paging target on an escalation rule |
OnCallDutyPolicyEscalationRuleTeam |
Assigns a whole team as a paging target on an escalation rule |
ProjectSSO |
OIDC/SAML SSO configuration |
Domain |
Verified email domain for SSO user matching |
ProjectSsoTeam |
Auto-assigns SSO users to a team on first login |
ApiKey |
API key lifecycle (the apiKey output is a secret) |
ApiKeyPermission |
Fine-grained permissions on an API key |
TeamMember |
Adds an existing user to a team |
TeamPermission |
Assigns permissions to a team |
MonitorTeamOwner |
Team owns a monitor |
MonitorUserOwner |
User owns a monitor |
MonitorGroupResource |
Adds a monitor to a monitor group |
Probe |
Monitoring probe registration (the key output is a secret) |
StatusPageAnnouncement |
Announcement banner on status pages |
StatusPageDomain |
Binds a custom domain to a status page |
StatusPageHeaderLink |
Link in the status page header |
StatusPageFooterLink |
Link in the status page footer |
StatusPageSubscriber |
Email/SMS/webhook subscriber |
StatusPageTeamOwner |
Team owns a status page |
StatusPageUserOwner |
User owns a status page |
IncidentTemplate |
Standardized template for incident creation |
IncidentNoteTemplate |
Reusable incident note template |
ScheduledMaintenanceEvent |
Planned maintenance window |
ScheduledMaintenanceState |
Workflow state for maintenance events |
ScheduledMaintenanceTemplate |
Template for maintenance events |
Workflow |
Automation workflow |
Bootstrap flow
The provider cannot create the very first OneUptime user or the master API key; both must be set up via the OneUptime UI:
- Install OneUptime and register an admin user via the UI
- Create a project in the UI
- Mint the master API key in Project Settings → API Keys
- Set
oneuptime:apiKeyin your Pulumi config (or exportONEUPTIME_API_KEY) - Everything else — additional API keys, team membership, permissions, monitors, etc. — is declarative from here on
On-call: wiring paging targets
An OnCallDutyPolicyEscalationRule by itself doesn't page anyone — it's just a timing/order slot. Attach at least one of the three "target" resources to it:
import * as oneuptime from "@ottercoders/pulumi-oneuptime";
const policy = new oneuptime.OnCallDutyPolicy("primary", { name: "Primary paging" });
const firstRule = new oneuptime.OnCallDutyPolicyEscalationRule("first", {
onCallDutyPolicyId: policy.resourceId,
order: 1,
escalateAfterInMinutes: 0,
});
// Choose one or more target resources — all three can coexist on the same rule.
new oneuptime.OnCallDutyPolicyEscalationRuleUser("oncall-user", {
onCallDutyPolicyId: policy.resourceId,
onCallDutyPolicyEscalationRuleId: firstRule.resourceId,
userId: primaryOncallUserId,
});
new oneuptime.OnCallDutyPolicyEscalationRuleTeam("oncall-team", {
onCallDutyPolicyId: policy.resourceId,
onCallDutyPolicyEscalationRuleId: firstRule.resourceId,
teamId: sreTeamId,
});
new oneuptime.OnCallDutyPolicyEscalationRuleSchedule("oncall-sched", {
onCallDutyPolicyId: policy.resourceId,
onCallDutyPolicyEscalationRuleId: firstRule.resourceId,
onCallDutyPolicyScheduleId: rotationScheduleId,
});
On-call schedule layers with typed rotation
OnCallScheduleLayer.rotation and .restrictionTimes are typed — you don't need to hand-build the OneUptime envelope JSON:
new oneuptime.OnCallScheduleLayer("weekly-primary", {
onCallDutyPolicyScheduleId: scheduleId,
name: "Weekly primary",
order: 1,
startsAt: "2026-01-06T00:00:00Z",
handOffTime: "2026-01-13T00:00:00Z",
rotation: { intervalType: "Week", intervalCount: 1 },
restrictionTimes: {
restrictionType: "Weekly",
weeklyRestrictionTimes: [{
startDay: "Monday", endDay: "Friday",
startTime: "09:00", endTime: "17:00",
}],
},
});
Workflows
Workflow.graph is a free-form JSON object — OneUptime intentionally doesn't expose a typed schema for it (see the comment in Common/Models/DatabaseModels/Workflow.ts: "Ideally, create this via UI and not via API"). The recommended flow is:
- Build and test the workflow in the OneUptime UI.
- Export its graph JSON (from the UI or by reading the record via the API).
- Paste that JSON into the
graphfield of a PulumiWorkflowresource.
This keeps the declarative boundary aligned with OneUptime's own guidance and avoids a schema that would drift on every upstream release.
Default resources — look up, don't create
OneUptime auto-creates a default set of rows in every project and does not allow them to be deleted. Trying to create a resource with one of these names returns HTTP 400 "already exists":
MonitorStatus: Operational, Degraded, OfflineIncidentState: Created, Acknowledged, ResolvedIncidentSeverity: Critical, Major, Minor (varies by OneUptime version)AlertState/AlertSeverity: similar defaults
Reference these from your program using the corresponding data source instead of declaring a resource:
import * as oneuptime from "@ottercoders/pulumi-oneuptime";
const operational = oneuptime.getMonitorStatusOutput({ name: "Operational" });
const resolved = oneuptime.getIncidentStateOutput({ name: "Resolved" });
const critical = oneuptime.getIncidentSeverityOutput({ name: "Critical" });
new oneuptime.Monitor("web", {
name: "Website",
monitorType: "Website",
currentMonitorStatusId: operational.resourceId,
});
Only declare MonitorStatus / IncidentState / IncidentSeverity resources for custom statuses/states your workflow adds on top of the defaults.
Resource Properties
Team
| Property | Type | Required | Description |
|---|---|---|---|
name |
string | Yes | Team name |
description |
string | No | Team description |
Monitor
| Property | Type | Required | Description |
|---|---|---|---|
name |
string | Yes | Monitor name |
monitorType |
string | Yes | One of the 23 MonitorType values — e.g. "Website", "API", "Ping", "Port", "Incoming Request", "Server" |
currentMonitorStatusId |
string | Yes | ID of the current monitor status (from a MonitorStatus resource or getMonitorStatus data source) |
description |
string | No | Monitor description |
disableActiveMonitoring |
bool | No | Disable active monitoring |
monitoringInterval |
string | No | Check interval (e.g. "1m", "5m") |
monitorSteps |
MonitorStep[] |
No (Yes for non-Manual) | Probe steps with destinations, request config, and decision criteria. See Monitor steps below |
defaultMonitorStatusId |
string | No | Fallback status when no criteria match |
labels |
string[] |
No | Label resource IDs to attach (ManyToMany) |
customFields |
map | No | Free-form values keyed by MonitorCustomField name |
postUpdatesToWorkspaceChannels |
WorkspaceChannelRef[] |
No | Slack/Teams channels to notify on status changes |
Output-only: resourceId, slug, createdAt, updatedAt, incomingRequestSecretKey (secret), serverMonitorSecretKey (secret), incomingEmailSecretKey (secret), incomingMonitorRequest, incomingEmailMonitorRequest, serverMonitorResponse.
Monitor steps
Each MonitorStep configures one probe and its decision logic. Populate only the sub-monitor field (logMonitor, snmpMonitor, dnsMonitor, etc.) that matches the parent monitor's monitorType; omit the rest. A minimal Website step looks like:
import * as oneuptime from "@ottercoders/pulumi-oneuptime";
const offline = oneuptime.getMonitorStatusOutput({ name: "Offline" });
const operational = oneuptime.getMonitorStatusOutput({ name: "Operational" });
new oneuptime.Monitor("web", {
name: "Marketing site",
monitorType: "Website",
currentMonitorStatusId: operational.resourceId,
monitorSteps: [{
id: "step-root",
monitorDestination: "https://example.com",
requestType: "GET",
monitorCriteria: {
criteriaInstances: [{
id: "down-on-5xx",
name: "Down if 5xx",
description: "Server-side failure",
filterCondition: "Any",
filters: [{
checkOn: "Response Status Code",
filterType: "Greater Than",
value: "499",
}],
monitorStatusId: offline.resourceId,
changeMonitorStatus: true,
}],
},
}],
});
For an API monitor add requestHeaders/requestBody on the step. For SNMP/DNS/Kubernetes/Docker/Synthetic monitors populate the matching snmpMonitor / dnsMonitor / kubernetesMonitor / dockerMonitor / customCode fields and set filters[].checkOn to the appropriate value ("SNMP OID Value", "DNS Response Time (in ms)", "CPU Usage (in %)", etc.). filters[].checkOn and filters[].filterType use OneUptime's full display strings verbatim.
Server-generated secret keys
IncomingRequest, Server, and IncomingEmail monitor types expose auto-generated secret keys the server wires at create time. Read them from the outputs to construct webhook/agent URLs:
const server = new oneuptime.Monitor("db", {
name: "Database host",
monitorType: "Server",
currentMonitorStatusId: operational.resourceId,
});
export const agentUrl = pulumi.interpolate`https://oneuptime.example.com/api/server-monitor/response/ingest/${server.serverMonitorSecretKey}`;
Pulumi encrypts these in state (AlwaysSecret) and redacts them from pulumi stack output unless --show-secrets is passed.
StatusPage
| Property | Type | Required | Description |
|---|---|---|---|
name |
string | Yes | Status page name |
description |
string | No | Status page description |
pageTitle |
string | No | HTML page title |
pageDescription |
string | No | Page description text |
isPublicStatusPage |
bool | No | Whether the page is public |
showIncidentHistoryInDays |
int | No | Days of incident history to show |
showAnnouncementHistoryInDays |
int | No | Days of announcement history |
showScheduledEventHistoryInDays |
int | No | Days of scheduled event history |
Incident
| Property | Type | Required | Description |
|---|---|---|---|
title |
string | Yes | Incident title |
currentIncidentStateId |
string | Yes | ID of the current state |
incidentSeverityId |
string | Yes | ID of the severity level |
description |
string | No | Incident description |
declaredAt |
string | No | When the incident was declared |
OnCallDutyPolicy
| Property | Type | Required | Description |
|---|---|---|---|
name |
string | Yes | Policy name |
description |
string | No | Policy description |
repeatPolicyIfNoOneAcknowledges |
bool | No | Repeat if no acknowledgement |
repeatPolicyIfNoOneAcknowledgesNoOfTimes |
int | No | Number of times to repeat |
Label
| Property | Type | Required | Description |
|---|---|---|---|
name |
string | Yes | Label name |
color |
string | Yes | Hex color code (e.g. #e74c3c) |
description |
string | No | Label description |
MonitorGroup
| Property | Type | Required | Description |
|---|---|---|---|
name |
string | Yes | Group name |
description |
string | No | Group description |
IncidentState
| Property | Type | Required | Description |
|---|---|---|---|
name |
string | Yes | State name |
color |
string | Yes | Hex color code |
description |
string | No | State description |
isCreatedState |
bool | No | Mark as the initial created state |
isAcknowledgedState |
bool | No | Mark as the acknowledged state |
isResolvedState |
bool | No | Mark as the resolved state |
order |
int | No | Display order |
IncidentSeverity
| Property | Type | Required | Description |
|---|---|---|---|
name |
string | Yes | Severity name |
color |
string | Yes | Hex color code |
description |
string | No | Severity description |
order |
int | No | Display order (1 = most severe) |
AlertState
| Property | Type | Required | Description |
|---|---|---|---|
name |
string | Yes | State name |
color |
string | Yes | Hex color code |
description |
string | No | State description |
isCreatedState |
bool | No | Mark as the initial created state |
isAcknowledgedState |
bool | No | Mark as the acknowledged state |
isResolvedState |
bool | No | Mark as the resolved state |
order |
int | No | Display order |
AlertSeverity
| Property | Type | Required | Description |
|---|---|---|---|
name |
string | Yes | Severity name |
color |
string | Yes | Hex color code |
description |
string | No | Severity description |
order |
int | No | Display order (1 = most severe) |
Project
| Property | Type | Required | Description |
|---|---|---|---|
name |
string | Yes | Project name |
description |
string | No | Project description |
Note: The
Projectresource does not accept aprojectIdproperty since it represents the project itself.
Example
YAML
name: oneuptime-example
runtime: yaml
resources:
engineering-team:
type: oneuptime:resources:Team
properties:
name: Engineering
description: Engineering team managed by Pulumi
api-monitor:
type: oneuptime:resources:Monitor
properties:
name: API Health Check
monitorType: API
currentMonitorStatusId: ${monitorStatusId}
status-page:
type: oneuptime:resources:StatusPage
properties:
name: Public Status
pageTitle: Service Status
isPublicStatusPage: true
showIncidentHistoryInDays: 14
env-label:
type: oneuptime:resources:Label
properties:
name: production
color: "#e74c3c"
description: Production environment
api-monitors:
type: oneuptime:resources:MonitorGroup
properties:
name: API Monitors
description: All API health check monitors
critical-severity:
type: oneuptime:resources:IncidentSeverity
properties:
name: Critical
color: "#e74c3c"
description: Service is completely down
order: 1
TypeScript
import * as oneuptime from "@ottercoders/pulumi-oneuptime";
const team = new oneuptime.resources.Team("engineering", {
name: "Engineering",
description: "Engineering team",
});
const label = new oneuptime.resources.Label("production", {
name: "production",
color: "#e74c3c",
description: "Production environment",
});
const severity = new oneuptime.resources.IncidentSeverity("critical", {
name: "Critical",
color: "#e74c3c",
description: "Service is completely down",
order: 1,
});
Python
from pulumi_oneuptime import resources
team = resources.Team("engineering",
name="Engineering",
description="Engineering team",
)
label = resources.Label("production",
name="production",
color="#e74c3c",
description="Production environment",
)
severity = resources.IncidentSeverity("critical",
name="Critical",
color="#e74c3c",
description="Service is completely down",
order=1,
)
Development
Prerequisites
- Go 1.25+
- Pulumi CLI
Build
make provider # Build the provider binary
make install # Install to $GOPATH/bin
make schema # Generate schema.json
make sdk # Generate SDKs (Go, Node.js, Python, .NET)
make test # Run unit tests
make lint # Run linter
make clean # Remove build artifacts
Testing
Unit tests use mocked HTTP servers and require no credentials:
make test
Acceptance tests run against a real OneUptime instance:
export ONEUPTIME_API_KEY="your-key"
export ONEUPTIME_PROJECT_ID="your-project-id"
make test-acceptance
Adding a New Resource
- Create a new file in
provider/resources/(e.g.,workflow.go) - Define
Args,State, and resource structs withpulumi:"..."andjson:"..."tags - Implement
Create,Read,Update,Deletemethods following the pattern in existing resources - Register the resource in
provider/provider.go
License
Apache 2.0 - See LICENSE for details.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pulumi_oneuptime-0.7.0.tar.gz.
File metadata
- Download URL: pulumi_oneuptime-0.7.0.tar.gz
- Upload date:
- Size: 73.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9f2a0b63084f4e815a5fea87f1358142225444aa870780d7b46debb8b892b524
|
|
| MD5 |
11e99c12888cc239bbf51d35687c80a2
|
|
| BLAKE2b-256 |
d4423ab7b55362f06ad36808d4c194507cde4b08e936cd4fe83550450a0aec46
|
Provenance
The following attestation bundles were made for pulumi_oneuptime-0.7.0.tar.gz:
Publisher:
release-please.yml on ottercoders/pulumi-oneuptime
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pulumi_oneuptime-0.7.0.tar.gz -
Subject digest:
9f2a0b63084f4e815a5fea87f1358142225444aa870780d7b46debb8b892b524 - Sigstore transparency entry: 1407043419
- Sigstore integration time:
-
Permalink:
ottercoders/pulumi-oneuptime@c19f9e2cdcd2a529cb9804c8ee63568d75fe8439 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/ottercoders
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-please.yml@c19f9e2cdcd2a529cb9804c8ee63568d75fe8439 -
Trigger Event:
push
-
Statement type:
File details
Details for the file pulumi_oneuptime-0.7.0-py3-none-any.whl.
File metadata
- Download URL: pulumi_oneuptime-0.7.0-py3-none-any.whl
- Upload date:
- Size: 164.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f97902c83ca8df0fbd90e5e104f290986f662b22b37ea835f099e0abc300cf8a
|
|
| MD5 |
b1e0ea46aae6b202f8f104f6c60d7d98
|
|
| BLAKE2b-256 |
5541b64f98d180a50b4066ed9fbb0e1d842a2fb2c44b62c6575ac50041e2a269
|
Provenance
The following attestation bundles were made for pulumi_oneuptime-0.7.0-py3-none-any.whl:
Publisher:
release-please.yml on ottercoders/pulumi-oneuptime
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pulumi_oneuptime-0.7.0-py3-none-any.whl -
Subject digest:
f97902c83ca8df0fbd90e5e104f290986f662b22b37ea835f099e0abc300cf8a - Sigstore transparency entry: 1407043470
- Sigstore integration time:
-
Permalink:
ottercoders/pulumi-oneuptime@c19f9e2cdcd2a529cb9804c8ee63568d75fe8439 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/ottercoders
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-please.yml@c19f9e2cdcd2a529cb9804c8ee63568d75fe8439 -
Trigger Event:
push
-
Statement type: