docs Terraform
Terraform
Manage your monitors, notification channels and public status pages as code
with the official Terraform provider,
uptimepage/uptimepage.
The Terraform Registry page is the full reference — every resource, attribute, and data source, regenerated from the provider on each release. This page is a quick start; it links out rather than duplicating that reference.
Quick start
Credentials
- Token — create one at Settings → API tokens (
/settings/api-tokens; requires a verified email). Supply it via thetokenattribute or theUPTIMEPAGE_TOKENenvironment variable. The full token is shown once. Grant the least scope the provider needs:targets:write+channels:writecovers monitors and channels, andstatus_page:writecovers status pages and their components (writeimpliesread, and Terraform only deletes duringterraform destroy). Add the matching:deletescopes only if you rundestroy. Status-page writes are owner-only, so that token has to belong to an org owner; a member's token gets403on page changes. For defence in depth, bind the token to the org you manage so a leak can't reach your other orgs. - Org — API tokens are user-scoped, so every request must name an
organization. Set
org(the org slug) orUPTIMEPAGE_ORG; it is sent as theX-Uptimepage-Orgheader. Without it the API returns400 ORG_REQUIRED. Find your slug fromGET /api/v1/orgsor your dashboard URL. A token bound to an org requiresorgto match it (else403 ORG_HEADER_MISMATCH). - Endpoint — defaults to the hosted API at
https://app.uptimepage.dev. For a self-hosted instance, setendpointto your host (the apex marketing domain does not serve/api/v1).
Resources & data sources
| Name | Kind | Manages |
|---|---|---|
uptimepage_target | resource | Monitors: http, tcp, ping, heartbeat, tls_cert, domain_expiry, dns, flow checks, and manual monitors (provider 0.13.0 and later), whose state is set in the app and never read into config. A dns check can list an exact record set with expected_records (provider 0.15.0 and later). An http, tcp or tls_cert check can be pinned to IPv4 or IPv6 with ip_version (provider 0.17.0 and later). On a self-hosted install, applying a flow needs max_flow_checks raised on the plan first (monitor types) |
uptimepage_notification_channel | resource | Alert destinations — webhook, slack, discord, msteams, google_chat, mattermost, telegram, whatsapp, email, pagerduty, ntfy, gotify, pushover, sms. The one-tap telegram_app, whatsapp_app, slack_app and discord_app kinds are not manageable: their configs are minted by the link, Add to Slack and Add to Discord flows and the API refuses to create them from request bodies (CHANNEL_KIND_MANAGED) |
uptimepage_status_page | resource | Status pages: slug, operator and display names, enabled state, the branding a visitor sees (about text, brand colour, style, website link, whether the powered-by mark shows), and whether search engines index the page. locale (en or de, provider 0.14.0 and later, against a server that has page languages) sets the page language; leave it out to choose the language in the console instead. Removing a locale line keeps the language it set, so set en to switch back. access (provider 0.16.0 and later) decides who can open the page; making a page private needs a plan with private pages, opening one works on any plan. It holds protected, session_days, the rules list of addresses and domains, the email code's enabled, passkeys_enabled and recheck_days, and password (provider 0.18.0 and later), whose value_wo is write-only (Terraform 1.11 and later, never in plan or state) and is sent when value_wo_version changes. Read it from an ephemeral variable or resource; Terraform keeps no copy to show later, so the people who need it must get it from where it came from. Provider 0.18.0 moved session_days out of email to match the server; older providers that set access need 0.18.0. Leave it out to manage access in the console; the provider then neither reads nor changes it, and removing it leaves the page as it is. Viewers and blocks stay in the console. The logo is uploaded in the console; its URL and the status URL are read back, not set |
uptimepage_status_page_component | resource | What a page publishes — one monitor placed on one page, with its public name, description, group and sort order. The public name is separate from the monitor's internal one |
uptimepage_target | data source | Look up an existing target by id |
uptimepage_heartbeat | data source | The ping URL of a heartbeat monitor, for the job that reports in. The API mints it at creation, so it is read back rather than configured. Reading it needs targets:write, since the URL is itself a write capability. Any other check kind reads as not found |
For the full attribute reference and an example per check type, see the provider docs on the Terraform Registry.
Managed-by badge
Resources the provider creates or updates carry a terraform source marker
(the provider identifies itself on every request). The web UI shows a small
terraform chip next to those monitors and channels, plus a banner on the
monitor detail page, so anyone browsing knows the resource is managed as code.
The marker is informational — the UI does not lock the resource. But an edit
made in the UI flips its badge to ui and will be overwritten the next time
you run terraform apply, since your .tf files remain the source of truth.
Change managed resources in Terraform, not the UI.
Source
Provider source and issue tracker: https://github.com/uptimepage/terraform-provider-uptimepage.