Start here
Move in from another status page
Bring components, incident history, maintenance and eligible email subscribers into Lamp, with a reviewed dry run and public-link cutover checks.
On this page
Lamp can bring components, incident history, scheduled maintenance and eligible email subscribers into your page. Synthetic-only validation: provider fixtures follow published API documentation; no real account export has been supplied.
Common workflow
- Sign in and open Settings → Move in (
/app/move-in). Choose the matching source in the Source menu; its source-specific instructions are below. - Enter the source page ID and API key or token, or upload saved provider JSON.
Credential reads use fixed provider origins and
GETrequests only. Keys are used for that read, are not stored, and are not forwarded through redirects. - Choose Run dry run. Nothing has been written. Review the read, imported, changed, skipped and refused counts and the reason for every non-imported row. You can download the exact responses read and use those saved files later.
- Check the review box and choose Import. Large imports may pause in batches; choose Continue until the job is complete. This does not send mail.
- Open Settings → Cutover (
/app/cutover). Before import it shows proposed destinations; after import it shows surviving records. Review the first 25 old public addresses, the total address count, unavailable links, reader gaps and eligible invitation count. - Choose Send invitations in Cutover. This is the only move-in action that sends mail. It sends one invitation to each eligible pending email subscriber; repeat for any remaining batch before the confirmation deadline.
- Point a hostname you control to Lamp using the custom-domain guide, or keep the deployment's default public address. Select that public origin in Cutover. Selecting it records your choice; it does not check DNS.
- After switching, use Check opens for the listed links. These checks run in your browser without cookies or credentials, follow redirects and confirm a successful HTML page at the exact Lamp destination. A network, CORS or browser access error does not prove that a link works or that it is broken.
- Keep the old page available through the pending subscribers' confirmation deadlines. Update old links, feeds, widgets and API readers before retiring it.
Cutover lists the first 25 public addresses. A live check covers only the rows shown there; it does not validate the rest of the total automatically. A hostname switch affects the address you control. It does not transfer or control a provider-owned shortlink host, so keep its redirect active or update links that still use that host.
What carries over
Subject to the selected source's documented fields and the dry-run report:
| Source data | Lamp result |
|---|---|
| Component groups and components | Native groups and components; supported names, descriptions, ordering and relationships are retained. |
| Incidents and supplied updates | Native incident history at the source times the reader supports; notifications are not replayed. |
| Scheduled maintenance | Native maintenance windows and source-specific history where supported; a window already over is imported as completed. |
| Eligible email subscribers | Pending Lamp subscriptions. Each person must confirm an invitation before the deadline. |
The sources do not expose identical fields. Each source section and the dry run name omitted, changed, skipped or refused records; relevant source-specific defaults are described below.
Dry runs, import, Continue, job reads, re-running an import, undo and Cutover checks send no mail or trigger customer notices for imported history. Imported history appears on the public page. Only Send invitations sends mail. Eligible email rows stay pending until they confirm. Unconfirmed or unsubscribed source rows are skipped where the source provides those states; the reader differences are described below. Lamp permits at most one invitation per imported subscriber and claims it before the mail transport call. A claimed or uncertain send is not automatically retried. A transport acceptance or local outbox capture does not prove inbox delivery.
The confirmation deadline is 72 hours from the import review time, even if you have not sent the invitation yet. Sending later leaves only the time remaining. Expired pending subscriptions cannot be invited; the expiry job deletes their unconfirmed addresses. Cutover shows eligible, already-claimed and expired counts.
Lamp serves its native public JSON at /api/public/status. It does not provide a
provider-shaped JSON compatibility API by default. Cutover lists the selected
source's unsupported API and feed paths. Replace old feed subscriptions with
Lamp's /feed.atom; replace source widgets with /widget.js and configure the
allowed widget origins in Settings. A source widget keeps calling its old host or
stops working when that host is removed.
Repeat, undo and full-install restore
Repeating an identical import while its prior job is present is an idempotent no-op. After a successful undo, the source can be imported again. Undo under Your imports is conditional: it removes rows created by that import only when their expected values are still present. Rows changed since import and confirmed subscribers stay, with their reason shown. Aliases stay for surviving imported incidents or maintenance and are removed when the imported target is removed. Undo sends no mail.
Undo applies to one move-in job; it is not a full installation restore. To restore a complete Lamp installation from an archive, follow Portable backups and restore. Full restore has its own archive and empty-destination requirements.
Statuspage
Choose Statuspage. In that account, open the avatar menu and choose API
info; enter the displayed page ID and API key. Lamp makes bounded GET
requests to https://api.statuspage.io and uses the key only in those requests.
The API calls read components, component groups, incidents, scheduled incidents
and subscribers. The key is not saved. See the official API reference.
For saved responses, upload the unchanged JSON arrays named:
component-groups.json, components.json, incidents.json,
incidents-scheduled.json and subscribers.json. Include later pages as
<resource>-2.json, <resource>-3.json and so on. The incidents and scheduled
incidents collections may both contain a maintenance; duplicates are carried
once. Statuspage maintenance windows carry over, but their update messages do
not enter Lamp's maintenance history; the unchanged responses remain in raw
source provenance. API reads use pages of 100 and stop after 50 pages per
resource. In saved-file mode, components.json is required, but the reader
cannot establish that the files cover every source page or form a complete page
sequence. Include the unchanged pages from one export set. The reader checks
response shapes and its input limits of 8 MiB total, 5,000 records, 512 KiB per
record and 200 files. It cannot prove that no further source pages exist past
its configured page limit. The other resource files may be omitted.
The subscriber API defaults to state=active; Lamp does not request
state=all, the unconfirmed state or the separate
/subscribers/ endpoint. For a saved-file import, provide the
default active collection. The saved-row reader cannot reliably reclassify a
hand-picked all-state export, so do not upload one. Non-email and quarantined
rows are skipped. Eligible email rows become pending and need the Lamp
invitation and confirmation described above.
The import does not read the source page's visibility settings. Check that the
page is intended to become publicly readable before moving it; Lamp's public
page does not preserve member-login or IP restrictions. The import also omits
post-mortem text, templates and unsupported subscriber channels. Components
marked only_show_if_degraded are shown normally in Lamp; the dry run names
that change. The source's showcase flag does not set a Lamp visibility rule.
This reader maps the source /incidents/<id> path for each imported incident or
maintenance, along with any supplied shortlink path. If a source shortlink is
absent, that separate shortlink is unavailable; Lamp does not guess it. A full
shortlink such as https://stspg.io/abc remains on
that source-owned host; Lamp can serve /abc on your moved hostname only when
that path was supplied and accepted. Keep the original redirect or update the
consumer's link.
The source's /history.atom path reaches Lamp's Atom feed. /history.rss
returns 404; change RSS readers to /feed.atom. Readers using the source JSON
API under /api/v2/ receive 404 and must use Lamp's native
/api/public/status format. The source's provider widget is not served by
Lamp; replace it with /widget.js and allow its origin in Settings.
Better Stack
Choose Better Stack. Enter the status page ID and API token, or upload
saved original JSON response envelopes. Lamp reads from
https://incidents. using Bearer authentication and GET
only; the token is not saved, redirects are refused, and requests stay within
the selected page and report. See the official status-page API reference.
Every section, resource, report and subscriber page must be present. Each
report needs its complete update timeline, supplied through update pages or a
matching report detail response. The reader refuses collections over 8 MiB,
5,000 records, 200 files or 50 pages per list rather than importing a truncated
source.
Use these unchanged saved envelopes: status-page.json, sections.json,
resources.json, status-reports.json, subscribers.json and
status-updates-REPORTID.json. Number later list pages for each list as
sections-2.json, resources-2.json, status-reports-2.json,
subscribers-2.json and status-updates-REPORTID-2.json. An unchanged
status-report-REPORTID.json detail response may supply the complete included
update relationship instead; duplicate included and list updates are carried
once. An optional original webhook-ID.json payload may supply its exact
documented incident or maintenance shortlink. REST reports alone have no
documented public address, so those old report links are unavailable and Lamp
does not invent /incident/<REST-id>.
The page response must explicitly include published, password_enabled and
ip_allowlist. Lamp refuses unpublished, password-protected, IP-restricted or
declared audience pages. Confirm that the page is public and unrestricted,
including that it has no visitor SSO. The REST contract does not document an SSO
read flag, so Lamp cannot detect visitor SSO. Missing visibility fields are
refused.
Sections become groups. Displayed resource IDs identify components; underlying
monitor IDs do not. Known operational, degraded, downtime and maintenance
states map to Lamp; paused not_monitored or unknown states are refused.
Current non-operational resource states become standing claims at review time.
Historical daily availability aggregates, monitor integrations and widgets
remain source provenance, not invented incidents. Reports retain their
messages, publication times and affected resource states. Because the source
REST report has no investigation lifecycle, Lamp projects Investigating for
affected updates and Resolved for all-resolved updates or the final update of an
ended report. That projection is not a claim about the source lifecycle.
Maintenance windows need a valid end; supplied history appears on the owner
record and public maintenance page without native lifecycle notices, feed
notices or notification jobs.
Only email rows with a valid source confirmation time become pending subscriptions. Unconfirmed, missing or invalid confirmation, declared unsubscribed and unsupported channel rows are skipped with reasons. Missing preferences or unresolved selected resource IDs are never broadened to all components; an empty explicit selection means all. Existing subscriptions and suppressions are preserved. The endpoint does not export a complete unsubscribe ledger, so the dry run cannot account for rows absent from that API response.
The source hostname stays with its owner. Cutover shows only exact supplied
links, the /feed.atom feed and the unsupported /feed.rss and /index.json
readers. Update feed and API readers to Lamp's Atom feed and native
/api/public/status endpoint. Source widgets need the same replacement described
above.
Better Stack uses its own source namespace with the same dry run, journal, revision checks, batching and conditional undo. The additive maintenance-history migration is included in a full installation backup and restore; a complete undo removes its unchanged historical messages with the imported maintenance record.
Instatus
Choose Instatus. Enter the page ID for saved files or an API read. For an API
read, also enter the API key. Lamp uses fixed-origin GET requests to
https://api.instatus.com; it does not save the key or forward it through a
redirect. It selects the requested page from /v2/pages, then reads components,
incidents with embedded updates, maintenance lists and each maintenance's
detail, subscribers and audience groups. Saved files require the selected page
ID but no API key. The reader refuses incomplete
collections and input over 8 MiB, 5,000 records, 512 KiB per record, 200 files
or 50 pages per list; it never silently truncates a collection. See
Instatus API help.
For saved responses, request per_page=100 and save each consecutive page until
the final short or empty page. Use these unchanged JSON filenames:
instatus-pages.json,instatus-components.json,instatus-incidents.jsoninstatus-maintenances.json, plusinstatus-maintenance-ID.jsonfor each detailinstatus-subscribers.json,instatus-audience-groups.json- Later list pages add
-2,-3and so on before.json.
Empty component, incident, maintenance, subscriber and audience-group resources
still need their empty [] response; the pages response must contain the
selected page. Maintenance detail is required because the list does not
establish affected components. The optional
instatus-summary.json can preserve exact public links supplied for a record;
it is not a complete history export. The API help uses v2 component and
maintenance lists while the official OpenAPI attaches their schemas to v1
reads; deployed account parity has not been verified. Fixture families remain
synthetic-only.
The saved pages response cannot establish public access or the absence of audience rules. Lamp asks you to confirm that the page and supplied history are published and unrestricted; this is your acknowledgement, not provider evidence. Known private, allow-listed, audience-scoped or secure-link pages are refused, and known unpublished records are not made public. Audience groups are access controls, not display groups. Visual parent components and their children retain their documented grouping; conflicts, cycles and missing group references are refused.
During Instatus normalization, a missing component or visual-group createdAt
uses the selected page's createdAt, or 1970-01-01T00:00:00.000Z if that is
also absent. A missing component or group order defaults to 0. This
timestamp is a source-normalization default; Lamp timestamps native groups at
import time.
Incident update chronology uses started, preserving supplied creation
metadata separately. Maintenance uses its explicit end, or an end derived from
documented duration minutes when completed or configured to end automatically.
Missing or contradictory required ends are refused. Every maintenance update
is retained as history without lifecycle notices or replayed notifications.
Only confirmed, approved, email-only subscribers become pending. Unconfirmed, unapproved, unsubscribed or deleted rows and unsupported phone, webhook or chat subscriptions are skipped with reasons. Component preferences must resolve and are never widened. Capability fields such as tokens, component automation addresses and webhook credentials are omitted from retained source records.
The optional summary file preserves exact supplied public URLs from
activeIncidents, activeMaintenances and recentlyResolvedIncidents, matched
to management records by source ID. A summary is not complete history. Old URLs
missing from it are unavailable; Lamp never guesses a path or host. Supplied
incident and maintenance paths redirect to surviving Lamp records. The source's
/history.atom path reaches Lamp's Atom feed; /history.rss, /summary.json,
/v3/summary.json and /v3/components.json are unsupported. Update readers to
/feed.atom or Lamp's native /api/public/status format. The source hostname
remains outside Lamp's control.
This page is drawn from docs/moving-in.md in the repository. Edit it on GitHub.