# Create a monitor

`POST /programs/{program_uuid}/monitors`

- Base: `POST https://portal.watcheye.com.au/api/v1/programs/{program_uuid}/monitors`

Create a new monitor in the given program. The `monitor_check_type` is fixed at
creation - to change a monitor's operation type, delete it and create a new one.

## Configuration

The `config` object is per-operation. Its shape is whatever the chosen
`monitor_check_type` expects. The full list of configuration keys, allowed values and
defaults for every operation type is documented in the
[Monitor Configuration](/docs/guides/watcheye_api/monitor-configuration) section
of the API guide. Any required config keys missing from your request will produce a
`400` with the relevant validation errors.

## Idempotency

This endpoint accepts the `Idempotency-Key` header so that retries on network failure
are safe. See the [Idempotency](/docs/guides/watcheye_api/idempotency) section of
the API guide for the full contract.

## Parameters

| Name | In | Type | Description |
|------|----|------|-------------|
| `program_uuid` | path | string (uuid) | **Required.** The program UUID |
| `Idempotency-Key` | header | string [max 255 characters] | Optional client-generated key (typically a UUID) that lets you safely retry a write request without risk of duplicate work or duplicate billing. A retry with the same key and body returns the original response verbatim, with the `Idempotent-Replay: true` response header. Honoured on `POST` requests only. See the [Idempotency](/docs/guides/watcheye_api/idempotency) section of the API guide for the full contract. Example: `8c4d3a18-2f63-4f9a-9f3a-9b1f5a7c2d4f` |

## Request body

The monitor details

| Field | Type | Description |
|-------|------|-------------|
| `monitor_name` | string [3..255 characters] | **Required.** Example: `Weekly PEP Sweep` |
| `monitor_check_type` | string | **Required.** The screening operation to run. Must be one of the operation types enabled on the calling account. Example: `pep_sanction_check` |
| `status` | string | **Required.** Enum: `active`, `paused` Example: `active` |
| `schedule` | string | **Required.** Enum: `manual`, `every_day`, `weekdays`, `weekends`, `monday`, `tuesday`, `wednesday`, `thursday`, `friday`, `saturday`, `sunday`, `monthly_1`, `monthly_15`, `monthly_1_15`, `quarterly` Example: `weekdays` |
| `config` | object (dynamic) | Per-operation configuration; see the Configuration section above. |

**Sample request**

```json
{
    "monitor_name": "Weekly PEP Sweep",
    "monitor_check_type": "pep_sanction_check",
    "status": "active",
    "schedule": "weekdays",
    "config": {
        "search_type": "pep_and_sanction",
        "similarity_threshold": 90
    }
}
```

## Responses

### 201 Monitor created

Content type: `application/json`

| Field | Type | Description |
|-------|------|-------------|
| `data` | object | A monitor is a scheduled (or manual) screening job that runs a single screening operation (PEP/sanction, ASIC, address verification, etc.) against the entities in its parent program. The operation type is fixed at creation; only configuration, name, status and schedule can be changed after that. |
| `data.uuid` | string (uuid) | The monitor's UUID Example: `5d6c8f93-91d4-4d6a-bb5e-2c64e9a3b1f0` |
| `data.monitor_number` | string | A short obfuscated public identifier for the monitor (e.g. "M-12-34-56") Example: `M-12-34-56` |
| `data.monitor_name` | string | The display name of the monitor Example: `Weekly PEP Sweep` |
| `data.monitor_check_type` | string | The screening operation this monitor runs. Cannot be changed after creation - create a new monitor instead. The list of allowed values depends on the products enabled on the calling account. Example: `pep_sanction_check` |
| `data.monitor_check_type_name` | string | Human-readable name for `monitor_check_type` (e.g. "PEP & Sanction Check") Example: `PEP & Sanction Check` |
| `data.status` | string | Lifecycle status: * `active` - the monitor runs on its schedule and can be triggered manually * `paused` - the monitor does not run on its schedule and cannot be triggered manually Enum: `active`, `paused` Example: `active` |
| `data.process_status` | string or null | In-flight run state, or `null` when the monitor is idle: * `pending` - queued * `processing` - currently running * `failed` - the most recent run failed (cleared on next successful run) * `paused` - the run was paused mid-flight (e.g. due to insufficient credit) Callers polling after `POST /monitors/{uuid}/run` should wait for this field to transition out of `pending`/`processing` before reading results. Enum: `pending`, `processing`, `failed`, `paused` |
| `data.process_status_comment` | string or null | Optional human-readable detail accompanying `process_status` (e.g. failure message) |
| `data.schedule` | string | How often the monitor runs unattended. `manual` means it never runs on its own and must be triggered via the run endpoint. Enum: `manual`, `every_day`, `weekdays`, `weekends`, `monday`, `tuesday`, `wednesday`, `thursday`, `friday`, `saturday`, `sunday`, `monthly_1`, `monthly_15`, `monthly_1_15`, `quarterly` Example: `weekdays` |
| `data.schedule_name` | string or null | Human-readable description of the schedule (e.g. "Every Day (Mon-Sun)") Example: `Weekdays (Mon-Fri)` |
| `data.config` | object (dynamic) | Per-operation configuration. The shape depends on `monitor_check_type`; see the [Monitor Configuration](/docs/guides/watcheye_api/monitor-configuration) section of the API guide for the schema of each operation. The portal's monitor create/edit screens render the same fields you'd send here. |
| `data.last_run_at` | string (date-time) or null | ISO 8601 timestamp of the most recent run, or `null` if the monitor has never run Example: `2025-01-15T03:00:00Z` |
| `data.has_run_before` | boolean | `true` if the monitor has processed at least one entity. Used by the "new" run mode to know whether there is a cursor to resume from. Example: `true` |
| `data.program_uuid` | string (uuid) | UUID of the program this monitor belongs to Example: `9c3e0a8e-2b9f-4f0e-8d1a-1e2b3c4d5e6f` |
| `data.created_at` | string (date-time) | ISO 8601 timestamp at which the monitor was created Example: `2025-01-01T00:00:00Z` |
| `data.updated_at` | string (date-time) | ISO 8601 timestamp at which the monitor was last updated Example: `2025-01-01T00:00:00Z` |
| `api_reference` | string (uuid) |  |

**Sample response**

```json
{
    "data": {
        "uuid": "5d6c8f93-91d4-4d6a-bb5e-2c64e9a3b1f0",
        "monitor_number": "M-12-34-56",
        "monitor_name": "Weekly PEP Sweep",
        "monitor_check_type": "pep_sanction_check",
        "monitor_check_type_name": "PEP & Sanction Check",
        "status": "active",
        "process_status": null,
        "process_status_comment": null,
        "schedule": "weekdays",
        "schedule_name": "Weekdays (Mon-Fri)",
        "config": {
            "search_type": "pep_and_sanction",
            "similarity_threshold": 90
        },
        "last_run_at": "2025-01-15T03:00:00Z",
        "has_run_before": true,
        "program_uuid": "9c3e0a8e-2b9f-4f0e-8d1a-1e2b3c4d5e6f",
        "created_at": "2025-01-01T00:00:00Z",
        "updated_at": "2025-01-01T00:00:00Z"
    },
    "api_reference": "00000000-0000-0000-0000-000000000000"
}
```

### 409 Conflict - a request with this Idempotency-Key is currently being processed

Content type: `application/json`

| Field | Type | Description |
|-------|------|-------------|
| `message` | string | Example: `A request with this Idempotency-Key is already being processed.` |

**Sample response**

```json
{
    "message": "A request with this Idempotency-Key is already being processed."
}
```

### 422 Idempotency-Key was reused with a different request body

Content type: `application/json`

| Field | Type | Description |
|-------|------|-------------|
| `message` | string | Example: `Idempotency-Key was reused with a different request body.` |

**Sample response**

```json
{
    "message": "Idempotency-Key was reused with a different request body."
}
```

Standard error responses: 400, 401, 402, 403, 404, 429, 5XX (see [Common error responses](/docs/reference/general/common-error-responses.md))

