# Create monitors

## Create a monitor with AI

The AI flow probes a URL from several regions and proposes the settings and metrics for it. It runs in the background, so it is three calls.

1. Start the analysis:

   ```
   POST /monitors/analyze
   {"url": "https://example.com/health"}
   ```

   The answer is 202 with `data.run_id` and `data.status` (`queued`). A 409 means another analysis is already running for the team; wait for it to finish.

2. Poll the run every 2.5 seconds, for up to about 150 seconds:

   ```
   GET /monitors/analyze/{run_id}
   ```

   `data.status` moves through `queued` and `analyzing` to `completed` or `failed`. On `failed`, `data.reason` says why. A 404 means the run expired or is unknown: start a new analysis rather than polling on.

3. Create the monitor from the result. On `completed`, `data.result.data` holds the proposal: `name`, `url`, a `suggestion` object with the monitor settings, and `suggested_metrics`. Send `name`, `url`, `"type": "http"` and every key of `suggestion`, plus the suggested metrics you want to keep as `metrics`:

   ```
   POST /monitors
   Idempotency-Key: 2f1d6c3e-create-example-health
   {"name": "...", "url": "...", "type": "http", "method": "get", "check_interval_sec": 300, "timeout_sec": 10, "regions": ["eu-central"], "metrics": []}
   ```

   The answer is 201 with the monitor, and its first check is queued. The `Idempotency-Key` header is explained in [Idempotency](https://uptizm.com/docs/idempotency.md).

Without AI, skip steps 1 and 2 and send `POST /monitors` with the fields listed on its page. Analyses count against the plan's AI setup allowance.

## Update a monitor

`PUT /monitors/{monitor}` changes only the fields you send. A key never receives the probe's secrets: `request_headers` and `request_body` are left out of every monitor it reads, the `url` comes back without any `user:password@` part, and `auth_config` shows only its `type`. So when you read a monitor and send it back, drop `auth_config` (and any field you did not change): the stored credentials stay as they are. Send `auth_config` with the secret again only to replace it; a body that carries `"auth_config": {"type": "bearer"}` without its `token` answers 422. Sending back the `url` exactly as you read it keeps the stored credentials too.
