# Copy an existing monitor

When you need the same check for another site - same type, interval, locations, validation rules and contacts -
copy an existing monitor instead of building it again. One copy request can create up to 100 monitors, one per
address.

## What a copy carries over

| Part | Copied? |
|---|---|
| Type, all type settings (including stored passwords and keys), timeout, validation rules | Yes |
| Interval or cron schedule | Yes |
| Tags, locations (including excluded checkpoints), recheck strategy, fallback | Yes |
| Attached sub-checks, Full Log, Open Stats, SLA target | Yes |
| Alert subscriptions (same contacts, same events) | Yes, unless you switch **Alerts** off (`includeAlerts: false`) |
| Report subscriptions (same contacts, same frequencies) | Yes, unless you switch **Reports** off (`includeReports: false`) |
| Maintenance windows covering the source (with the same suppression) | Yes, unless you switch **Maintenance** off (`includeMaintenance: false`) |
| Name | The name you give each copy, else the source's name |
| Results, incidents, statistics | No - every copy starts with an empty history |

## Settings reference (copy request)

| Setting (app label) | API field (v2) | Type / allowed values | Default | What it does for you |
|---|---|---|---|---|
| **Target URLs** | `urls` | 1-100 entries; each a string or `{ "url": "...", "name": "..." }`. In the app: one per line, `url, name` | - (required) | One new monitor per address. |
| - | `name` | Text | The source's name | Name for every copy that does not set its own. |
| **Alerts** | `includeAlerts` | `true` / `false` | `true` | Copy the alert subscriptions. |
| **Reports** | `includeReports` | `true` / `false` | `true` | Copy the report subscriptions. |
| **Maintenance** | `includeMaintenance` | `true` / `false` | `true` | Add the copies to the source's maintenance windows. |
| - | `overrides` | `interval`, `cronSchedule`, `enabled`, `fullLog`, `openStat`, `tags`, `slaTarget`, `locations`, `recheck`, `settings`, `attached` | None | Changes applied to every copy; `settings` merges onto the source's settings. |
| - | `onOverlimit` | `fail`, `disable` | `fail` | What happens when your plan has no room: refuse the whole request, or create the copies that do not fit disabled. |

## Running or paused?

- **In the app**, a copy of a **paused** monitor is created **paused**, and a copy of a running monitor runs.
- **Through the API and MCP**, copies always start **running**, even from a paused source. Send
  `"overrides": { "enabled": false }` to stage them paused. The MCP `copy_monitor` tool has no overrides, so its
  copies of a paused monitor start running - use `api_request` if you need them paused.

Either way, review the copies' [alert subscriptions](/alerts/subscribe-monitors/) before relying on them: they
alert the same contacts as the source.

## Set it up in the app

1. On **Sites**, open the monitor's row menu and choose **Copy**.
2. HostTracker first tries a one-click duplicate named "... (copy)" at the same address. Normally two monitors of
   the same type cannot watch the same address on one account, so this usually stops with an "already exists"
   message and opens the **Copy Monitor** panel ("The copy could not be created at the same URL. Enter the URL(s) for the new
   monitor(s) below.").
3. In **Target URLs**, enter one address per line; to name a copy, add the name after a comma
   (`https://shop2.example.com, Shop 2`).
4. Under **Include Settings**, switch **Alerts**, **Reports** and **Maintenance** on or off.
5. Click **Copy Monitor**. Lines that cannot be copied are listed under **These URLs were not copied** with the
   reason; **Remove failed URLs** keeps only the valid lines so you can try again.

## Do it with the API or MCP

```bash
# Two copies, checked every 5 minutes, without report subscriptions (scope monitor:write)
curl -X POST "https://api2.host-tracker.com/monitor/$MONITOR_ID/copy" \
  -H "Authorization: Bearer $HT_TOKEN" -H "Content-Type: application/json" \
  -H "Idempotency-Key: copy-shop-1" \
  -d '{
    "urls": [ "https://shop2.example.com/", { "url": "https://shop3.example.com/", "name": "Shop 3" } ],
    "includeReports": false,
    "overrides": { "interval": 300 }
  }'
```

- **Up to 10 addresses** answer `201` with the created monitors (each in the shape `GET /monitor/{id}` returns)
  and what was copied with them.
- **11 to 100 addresses** answer `202` with a job id; poll `GET /job/{id}` (see
  [Bulk operations](/monitors/bulk-operations/)). An `Idempotency-Key` is required above 10 addresses and
  recommended always.
- More than 100 addresses: create them with `POST /monitor/bulk` instead.
- MCP: **`copy_monitor`** (`id`, `urls` comma-separated, `includeAlerts`, `includeReports`, `includeMaintenance`,
  `name`); longer lists return a job id for **`get_job`** / **`wait_for_job`**.

## What happens next

Every address is validated - format, duplicates, locations and your plan's remaining room - **before** the first
copy is written, so a refused request leaves your account unchanged. The copies are picked up by the scheduler
within about a minute and start with empty history.

## Limits and gotchas

- An address that already has a monitor of the same type is refused (`409 duplicate_monitor`, pointing at
  `/urls/{i}`), including the source's own address.
- Copies count against your plan's monitor limit like any new monitor; with `onOverlimit: "disable"` the ones
  that do not fit are created disabled.
- `overrides` cannot change the type, the address or the name (use `urls` and `name`), and cannot carry tag deltas
  or subscriptions.
- Copying the source's credentials means a copy authenticates exactly like the source; change them per copy if
  the new sites use different accounts.

## Related

- [Importing a list of monitors](/monitors/importing/)
- [Bulk operations](/monitors/bulk-operations/)
- [Pause, enable and delete a monitor](/monitors/pause-enable-delete/)
