Skip to content
Docs/Import from other tools

Get started

Import from other tools

Bring monitors, alert contacts, status pages and incident history over from UptimeRobot, Better Stack or Statuspage.io. You see a preview first, and running the same import again only adds what's new.

What gets imported

SourceYou needImported
UptimeRobotRead-only API key (Integrations & API)HTTP, keyword, port and heartbeat monitors; email, webhook, Slack and Discord alert contacts; public status pages, with one component per monitor
Better Stack UptimeUptime API tokenMonitors (status, expected status code, keyword, TCP/SMTP/POP/IMAP, DNS), heartbeats, status pages: sections become groups, resources become components
Statuspage.ioA public page URL, or an API key + page idComponents and groups, past incidents and maintenance with every update, and the component status history behind the 90-day uptime bars

Things UpButler can't run are skipped with a reason, for example ping (ICMP) and UDP monitors, Playwright scenarios, and SMS or voice contacts. Imported heartbeats get new UpButler ping URLs, so update your jobs to use them. Custom domains aren't moved automatically: add the domain in the page settings and switch its DNS when you're ready.

In the dashboard

Open Settings → Import, pick the source, and click Preview import. Untick anything you don't want, then import. You can follow the progress live, and leaving the page doesn't stop the import.

1. Preview (dry run)

POST /api/v1/import/preview (MCP tool import_preview) reads the source account and writes nothing. Every item has an action:

  • create: will be created. detail says how, for example the check interval after plan limits are applied.
  • exists: already imported earlier. targetId is the UpButler id.
  • skip: left out. reason explains why: not supported, excluded, or over a plan limit.
curl -X POST https://upbutler.com/api/v1/import/preview \
  -H "Authorization: Bearer $UPBUTLER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"source": "uptimerobot", "apiKey": "'"$UPTIMEROBOT_READONLY_KEY"'"}'
200 OK
{
  "source": "uptimerobot",
  "account": "UptimeRobot account",
  "counts": {
    "monitor":   { "create": 4, "exists": 0, "skip": 1 },
    "channel":   { "create": 3, "exists": 0, "skip": 1 },
    "page":      { "create": 1, "exists": 0, "skip": 0 },
    "component": { "create": 2, "exists": 0, "skip": 0 }
  },
  "warnings": ["1 monitor checks more often than the Free plan allows; it will run every 300s."],
  "items": [
    { "ref": "monitor:778812", "kind": "monitor", "name": "Website", "action": "create", "detail": "http · every 300s" },
    { "ref": "monitor:778815", "kind": "monitor", "name": "Router ping", "action": "skip",
      "reason": "Ping (ICMP) monitors are not supported — add an HTTP or TCP monitor instead" },
    { "ref": "channel:4410", "kind": "channel", "name": "Ops email", "action": "create", "detail": "email" }
  ]
}

Options

FieldDefaultMeaning
source—uptimerobot | betterstack | statuspage
apiKey—Source API key or token
url—Statuspage.io: any public page URL, no key needed. Public pages expose about the last 50 incidents.
pageId—Statuspage.io page id, used with apiKey to get the full history and private pages
monitors · channels · pages · incidentstrueWhat to bring over
mirrorfalseStatuspage.io: add a manifest monitor that reads their components.json, so the imported components keep following the old page until you switch
targetPageId—Put components (and incidents) on an existing status page instead of creating one
exclude[]Item refs from the preview to leave out

Plan limits

Check intervals faster than your plan allows are raised to the plan minimum, and the preview warns about it. When there are more monitors, status pages or components per page than the plan includes, the extra ones are marked skip. Exclude some, import into an existing page, or upgrade and run the import again.

2. Apply

POST /api/v1/import (MCP import_apply) takes the same body and starts a background job. Poll GET /api/v1/import/jobs/:id (MCP import_status) until status is done or failed. Only one import runs at a time per workspace.

# Same body as the preview, plus anything you want to leave out
curl -X POST https://upbutler.com/api/v1/import \
  -H "Authorization: Bearer $UPBUTLER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"source": "statuspage", "url": "https://status.example.com", "mirror": true,
       "exclude": ["incident:abc123:xyz789"]}'
# → 202 {"id": "imp_…", "status": "running", "progress": {"done": 0, "total": 0, "step": "Reading your Statuspage.io account"}}

curl https://upbutler.com/api/v1/import/jobs/imp_… -H "Authorization: Bearer $UPBUTLER_API_KEY"
GET /import/jobs/:id
{
  "id": "imp_8h2k…",
  "source": "statuspage",
  "account": "Example Status",
  "status": "done",
  "progress": { "done": 61, "total": 61, "step": "Done" },
  "created": { "monitor": 1, "page": 1, "group": 3, "component": 12, "incident": 44 },
  "log": [],
  "createdAt": "2026-10-09T14:02:11.000Z",
  "finishedAt": "2026-10-09T14:02:19.000Z"
}

Items that fail on their own, such as a URL UpButler rejects, appear in log with level error. The rest of the import continues.

Re-running an import

Every object an import creates is remembered under its source id. Running the import again creates only what's new, such as monitors or incidents added since the last run. Anything you deleted in UpButler is created again. A job that was interrupted can safely be started again: it continues where it stopped.

Statuspage.io history

Resolved incidents and completed maintenance are imported with their full timeline, impact and affected components. They're written as history, so subscribers aren't notified. Each component's status history is rebuilt from those incidents, so the uptime bars and percentages on your new page match the old one from day one. Incidents that are still open aren't imported. With mirror on, the page follows the live status of the old one.

Agents

The three operations are MCP tools, so an agent can run the whole migration and show you the preview first:

"Import our status page from https://status.example.com, keep mirroring it,
 and show me the preview before you apply it."