# Preview an import — API reference

> Previews a monitor import without applying it.

Source: https://upfour.io/docs/api/monitors/preview-an-import

[Developers](https://upfour.io/docs/api.md)/[Monitors](https://upfour.io/docs/api/monitors.md)

Previews a monitor import without applying it.

POST https://app.upfour.io/v1/monitors/batch/dry-run

scope monitor.write stable [Idempotency-Key supported](https://upfour.io/docs/api/idempotency.md) returns 200

## Body

`application/json` required 8 fields

rowsBatchMonitorRowInput[] (required)

Nested fields 19 fields

| Field | Type | Description |
| --- | --- | --- |
| `allow_duplicate` optional | boolean | |
| `client_id` optional | uuid  · nullable | |
| `confirmation_period` optional | integer | |
| `dns_expected` optional | string | |
| `dns_query` optional | string | |
| `dns_type` optional | string one of`A` `AAAA` `MX` `CNAME` `TXT` `NS` | |
| `expected_status_code` optional | integer  · nullable | |
| `fields` optional | map of any | Per-row overrides of monitor fields by name. Any other key of the row object is read as an entry of fields, too. |
| `interval_seconds` optional | integer | |
| `keyword` optional | string | |
| `line` optional | integer | |
| `monitor_type` optional | string one of`http` `tcp` `ping` `dns` | |
| `name` optional | string | |
| `raw` optional | string | |
| `recovery_period` optional | integer | |
| `regions` optional | string[] one of`eu` `us` `asia` `au` `default` | |
| `tcp_host` optional | string | |
| `tcp_port` optional | integer  · nullable | |
| `url` optional | string | |

All other fields65 fields

create_pausedboolean

default_alert_planboolean · nullable

defaultsCreateMonitorInput

Nested fields 58 fields

| Field | Type | Description |
| --- | --- | --- |
| `alert_channel_names` optional | string[] | |
| `alert_plan_name` optional | string | |
| `alert_type` optional | string one of`""` `status` `keyword` `keyword_absence` `expected_status_code` | |
| `auth_password` optional | string | Basic-auth password. Write-only: responses carry has_auth_password instead. |
| `auth_password_action` optional | string one of`""` `keep` `replace` `clear` | |
| `auth_username` optional | string | |
| `capture_on_incident_open` optional | boolean  · nullable | |
| `client_id` optional | uuid  · nullable | |
| `client_name` optional | string | |
| `confirmation_period` optional | integer | |
| `creation_key` optional | uuid  · nullable | |
| `default_alert_plan` optional | boolean | |
| `degraded_alert_enabled` optional | boolean | |
| `degraded_threshold_ms` optional | integer  · nullable | |
| `dns_expected` optional | string | |
| `dns_query` optional | string | |
| `dns_server` optional | string | |
| `dns_type` optional | string one of`""` `A` `AAAA` `MX` `CNAME` `TXT` `NS` | |
| `domain_expiry_alert_days` optional | integer  · nullable | |
| `escalation_policy_id` optional | uuid  · nullable | |
| `expected_status_code` optional | integer  · nullable | |
| `follow_redirects` optional | boolean  · nullable | |
| `http_method` optional | string | |
| `interval_seconds` optional | integer | |
| `ip_version` optional | string one of`""` `4` `6` | |
| `keep_cookies` optional | boolean | |
| `keyword` optional | string | |
| `keyword_case_insensitive` optional | boolean  · nullable | |
| `maintenance_from` optional | string  · nullable | |
| `maintenance_timezone` optional | string | |
| `maintenance_to` optional | string  · nullable | |
| `maintenance_weekdays` optional | string[] one of`mon` `tue` `wed` `thu` `fri` `sat` `sun` | |
| `metadata` optional | map of string max 100 keys each value max length 4096 | On update, omitted or null leaves the stored metadata unchanged, {} removes all keys and any other object replaces them. |
| `monitor_group_id` optional | uuid  · nullable | |
| `monitor_group_name` optional | string | |
| `monitor_type` optional | string one of`http` `tcp` `ping` `dns` | |
| `name` optional | string | |
| `notification_channel_ids` optional | uuid[] | |
| `notification_mode` optional | string one of`quiet` `immediate` | |
| `notify_recovery` optional | boolean  · nullable | |
| `pronounceable_name` optional | string | |
| `proxy_host` optional | string | |
| `proxy_port` optional | integer  · nullable | |
| `public_name` optional | string  · nullable | |
| `recovery_period` optional | integer | |
| `regions` optional | string[] one of`eu` `us` `asia` `au` `default` | |
| `request_body` optional | string | |
| `request_headers` optional | RequestHeader[] | Custom request headers, at most 20 and 8 KB in total. On update they are kept unless request_headers_action is replace or clear. |
| Each item · 2 fields FieldTypeDescription `name` optional string `value` optional string | | |
| `request_headers_action` optional | string one of`keep` `replace` `clear` | |
| `request_timeout_s` optional | integer | |
| `ssl_expiry_alert_days` optional | integer  · nullable | |
| `ssl_verification` optional | boolean  · nullable | |
| `state` optional | string one of`""` `UP` `DOWN` `PAUSED` | UP, DOWN or PAUSED (any case); empty creates the monitor running. |
| `tcp_host` optional | string | |
| `tcp_port` optional | integer  · nullable | |
| `url` optional | string | |

dry_run_idstring

escalation_policy_iduuid · nullable

notification_channel_idsuuid[]

sourcestring

## Returns

A successful request returns `200` with application/json.

Response fields 1 top-level fields

| Field | Type | Description |
| --- | --- | --- |
| `data` | BatchMonitorResponse | |
| BatchMonitorResponse · 160 fields FieldTypeDescription `dry_run_id` string `rows` BatchMonitorRowResult[]  · nullable Each item · 148 fields FieldTypeDescription `errors` BatchMonitorRowIssue[]  · nullable Each item · 3 fields FieldTypeDescription `code` string `message` string `details` object free-form keys `index` integer `line` integer `normalized_input` ResolvedMonitorInput ResolvedMonitorInput · 58 fields FieldTypeDescription `alert_type` string one of`""` `status` `keyword` `keyword_absence` `expected_status_code` `auth_password` string Basic-auth password. Write-only: responses carry has_auth_password instead. `auth_password_action` string one of`""` `keep` `replace` `clear` `auth_username` string `confirmation_period` integer `degraded_alert_enabled` boolean `degraded_threshold_ms` integer  · nullable `dns_expected` string `dns_query` string `dns_server` string `dns_type` string one of`""` `A` `AAAA` `MX` `CNAME` `TXT` `NS` `domain_expiry_alert_days` integer  · nullable `expected_status_code` integer  · nullable `follow_redirects` boolean  · nullable `http_method` string `interval_seconds` integer `ip_version` string one of`""` `4` `6` `keep_cookies` boolean `keyword` string `keyword_case_insensitive` boolean  · nullable `maintenance_from` string  · nullable `maintenance_timezone` string `maintenance_to` string  · nullable `maintenance_weekdays` string[]  · nullable one of`mon` `tue` `wed` `thu` `fri` `sat` `sun` `monitor_type` string one of`http` `tcp` `ping` `dns` `name` string `pronounceable_name` string `proxy_host` string `proxy_port` integer  · nullable `recovery_period` integer `regions` string[]  · nullable one of`eu` `us` `asia` `au` `default` `request_body` string `request_headers` ResolvedRequestHeader[]  · nullable Custom request headers, at most 20 and 8 KB in total. On update they are kept unless request_headers_action is replace or clear. Each item · 2 fields FieldTypeDescription `name` string `value` string `request_timeout_s` integer `ssl_expiry_alert_days` integer  · nullable `ssl_verification` boolean  · nullable `state` string one of`""` `UP` `DOWN` `PAUSED` UP, DOWN or PAUSED (any case); empty creates the monitor running. `tcp_host` string `tcp_port` integer  · nullable `url` string `alert_channel_names` string[] `alert_plan_name` string `capture_on_incident_open` boolean `client_id` uuid `client_name` string `creation_key` uuid `default_alert_plan` boolean `escalation_policy_id` uuid `metadata` map of string max 100 keys each value max length 4096 On update, omitted or null leaves the stored metadata unchanged, {} removes all keys and any other object replaces them. `monitor_group_id` uuid `monitor_group_name` string `notification_channel_ids` uuid[] `notification_mode` string one of`quiet` `immediate` `notify_recovery` boolean `public_name` string `request_headers_action` string one of`keep` `replace` `clear` `raw` string `status` string one of`ready` `duplicate` `error` `created` `warnings` BatchMonitorRowIssue[]  · nullable Each item · 3 fields FieldTypeDescription `code` string `message` string `details` object free-form keys `created_monitor` Monitor Monitor · 70 fields FieldTypeDescription `alert_type` string one of`status` `keyword` `keyword_absence` `expected_status_code` `auth_username` string `capture_on_incident_open` boolean `confirmation_period` integer `created_at` string (date-time) `degraded_alert_enabled` boolean `degraded_threshold_ms` integer  · nullable `domain_expiry_alert_days` integer  · nullable `escalation_policy_id` uuid  · nullable `expected_status_code` integer  · nullable `feature_pause_reasons` string[]  · nullable `follow_redirects` boolean `has_auth_password` boolean `has_request_headers` boolean `http_method` string `id` uuid `interval_seconds` integer `ip_version` string one of`""` `4` `6` `is_degraded` boolean `is_pending` boolean `keep_cookies` boolean `keyword` string `keyword_case_insensitive` boolean `maintenance_from` string  · nullable `maintenance_timezone` string `maintenance_to` string  · nullable `maintenance_weekdays` string[]  · nullable one of`mon` `tue` `wed` `thu` `fri` `sat` `sun` `monitor_type` string one of`http` `tcp` `ping` `dns` `name` string `next_check_at` string (date-time)  · nullable `notification_mode` string one of`quiet` `immediate` `notify_recovery` boolean `pronounceable_name` string `proxy_host` string `proxy_port` integer  · nullable `public_name` string `recovery_period` integer `regions` string[]  · nullable one of`eu` `us` `asia` `au` `default` `request_body` string `request_headers` any[]  · nullable Always empty: header values are never returned. has_request_headers says whether the monitor sends any. `request_timeout_s` integer `ssl_expiry_alert_days` integer  · nullable `ssl_verification` boolean `state` string one of`UP` `DOWN` `PAUSED` `url` string `user_id` uuid `badge_token` string `client_id` uuid `dns_expected` string `dns_query` string `dns_server` string `dns_type` string one of`A` `AAAA` `MX` `CNAME` `TXT` `NS` `freshness_timeout_seconds` integer `last_checked_at` string (date-time) `last_result_at` string (date-time) `last_state_change_at` string (date-time) `latency_p50_ms` integer `latency_p95_ms` integer `latency_samples_24h` integer `latest_result_successful` boolean `monitor_group_id` uuid `paused_until` string (date-time) `recent_incidents` MonitorRecentIncident[] Each item · 5 fields FieldTypeDescription `id` uuid `resolved_at` string (date-time)  · nullable `started_at` string (date-time) `status` string `resolved_by_type` string `tcp_host` string `tcp_port` integer `duplicate_match` MonitorBatchMatch MonitorBatchMatch · 5 fields FieldTypeDescription `id` uuid `monitor_type` string `name` string `url` string `client_id` uuid `summary` BatchMonitorSummary BatchMonitorSummary · 5 fields FieldTypeDescription `duplicates` integer `errors` integer `ready` integer `total` integer `warnings` integer `capacity` MonitorCapacity MonitorCapacity · 2 fields FieldTypeDescription `current` integer `limit` integer `import_id` uuid | | |

## Errors

Only the errors this operation can return. Every error uses the [same envelope](https://upfour.io/docs/api/responses.md).

| Status | Code | Meaning |
| --- | --- | --- |
| 400 | [bad_request](https://upfour.io/docs/api/errors#code-bad_request) | The request is malformed or fails validation. |
| 400 | [import_invalid](https://upfour.io/docs/api/errors#code-import_invalid) | The import body is not valid. **When:** A batch monitor import whose body cannot be parsed; the message names the problem. **Fix:** Correct the body and send it again. Stable codes next to the English message: `import_invalid` (the body is not a valid import), `import_rows_out_of_range` (`error.details.min_rows` and `max_rows`: 1 to 500 rows per import). Notes on single rows carry a `code` and, where the sentence names something, `details` (`field`, `option` or `line`). |
| 400 | [import_rows_out_of_range](https://upfour.io/docs/api/errors#code-import_rows_out_of_range) | The import has too few or too many rows. **When:** A batch monitor import with fewer than min_rows or more than max_rows rows, both in details. **Fix:** Send between min_rows and max_rows rows per request. |
| 413 | [import_too_large](https://upfour.io/docs/api/errors#code-import_too_large) | The import body is over the size limit. **When:** A batch monitor import larger than details.max_bytes. **Fix:** Split the import into several requests. `import_too_large`: the import body is larger than 2 MiB (`error.details.max_bytes`). Nothing is imported. |
| 403 | [permission_denied](https://upfour.io/docs/api/errors#code-permission_denied) | The credentials do not permit this action. |

Every call can also return `unauthorized` (401), `rate_limit_exceeded` (429) or `internal_error` (500 / 502). See [Responses and errors](https://upfour.io/docs/api/responses.md).

[PreviousImport monitors](https://upfour.io/docs/api/monitors/import-monitors.md) [NextList imports](https://upfour.io/docs/api/monitors/list-imports.md)

## Request

### cURL

```bash
curl -s -X POST "https://app.upfour.io/v1/monitors/batch/dry-run" \
  -H "Authorization: Bearer $UP4_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "rows": [
      {
        "name": "Docs site",
        "url": "https://example.com"
      },
      {
        "name": "Status page",
        "url": "https://example.org"
      }
    ],
    "source": "csv"
  }'
```

### JavaScript

```javascript
const res = await fetch("https://app.upfour.io/v1/monitors/batch/dry-run", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.UP4_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    rows: [
      {
        name: "Docs site",
        url: "https://example.com",
      },
      {
        name: "Status page",
        url: "https://example.org",
      },
    ],
    source: "csv",
  }),
});
console.log(res.status, await res.json());
```

### Python

```python
import os
import requests

res = requests.post(
    "https://app.upfour.io/v1/monitors/batch/dry-run",
    headers={"Authorization": f"Bearer {os.environ['UP4_API_KEY']}"},
    json={
        "rows": [
            {
                "name": "Docs site",
                "url": "https://example.com",
            },
            {
                "name": "Status page",
                "url": "https://example.org",
            },
        ],
        "source": "csv",
    },
)
print(res.status_code, res.json())
```

### Go

```go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
	"strings"
)

func main() {
	payload := strings.NewReader(`{
  "rows": [
    {
      "name": "Docs site",
      "url": "https://example.com"
    },
    {
      "name": "Status page",
      "url": "https://example.org"
    }
  ],
  "source": "csv"
}`)
	req, _ := http.NewRequest("POST", "https://app.upfour.io/v1/monitors/batch/dry-run", payload)
	req.Header.Set("Authorization", "Bearer "+os.Getenv("UP4_API_KEY"))
	req.Header.Set("Content-Type", "application/json")
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	out, _ := io.ReadAll(res.Body)
	fmt.Println(res.StatusCode, string(out))
}
```

### PHP

```php
<?php
$payload = <<<'JSON'
{
  "rows": [
    {
      "name": "Docs site",
      "url": "https://example.com"
    },
    {
      "name": "Status page",
      "url": "https://example.org"
    }
  ],
  "source": "csv"
}
JSON;

$ch = curl_init("https://app.upfour.io/v1/monitors/batch/dry-run");
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => "POST",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        "Authorization: Bearer " . getenv("UP4_API_KEY"),
        "Content-Type: application/json",
    ],
    CURLOPT_POSTFIELDS => $payload,
]);
$response = curl_exec($ch);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), " ", $response, "\n";
curl_close($ch);
```

## Response

### 200

```json
{
  "data": {
    "capacity": {
      "current": 2,
      "limit": 500
    },
    "dry_run_id": "721378bc96ef2ddece4a66b447ba60d6a1266860d9cb23f4e0e6c152f30279cb",
    "rows": [
      {
        "errors": null,
        "index": 0,
        "line": 1,
        "normalized_input": {
          "alert_type": "status",
          "auth_password": "",
          "auth_password_action": "",
          "auth_username": "",
          "capture_on_incident_open": false,
          "confirmation_period": 0,
          "degraded_alert_enabled": false,
          "degraded_threshold_ms": null,
          "dns_expected": "",
          "dns_query": "",
          "dns_server": "",
          "dns_type": "A",
          "domain_expiry_alert_days": null,
          "expected_status_code": null,
          "follow_redirects": true,
          "http_method": "HEAD",
          "interval_seconds": 60,
          "ip_version": "",
          "keep_cookies": false,
          "keyword": "",
          "keyword_case_insensitive": true,
          "maintenance_from": null,
          "maintenance_timezone": "UTC",
          "maintenance_to": null,
          "maintenance_weekdays": [
            "mon",
            "tue",
            "wed",
            "thu",
            "fri",
            "sat",
            "sun"
          ],
          "monitor_type": "http",
          "name": "Docs site",
          "notification_mode": "immediate",
          "notify_recovery": true,
          "pronounceable_name": "",
          "proxy_host": "",
          "proxy_port": null,
          "recovery_period": 0,
          "regions": [
            "eu"
          ],
          "request_body": "",
          "request_headers": [],
          "request_timeout_s": 30,
          "ssl_expiry_alert_days": null,
          "ssl_verification": true,
          "state": "",
          "tcp_host": "",
          "tcp_port": null,
          "url": "https://example.com"
        },
        "raw": "",
        "status": "ready",
        "warnings": null
      },
      {
        "errors": null,
        "index": 1,
        "line": 2,
        "normalized_input": {
          "alert_type": "status",
          "auth_password": "",
          "auth_password_action": "",
          "auth_username": "",
          "capture_on_incident_open": false,
          "confirmation_period": 0,
          "degraded_alert_enabled": false,
          "degraded_threshold_ms": null,
          "dns_expected": "",
          "dns_query": "",
          "dns_server": "",
          "dns_type": "A",
          "domain_expiry_alert_days": null,
          "expected_status_code": null,
          "follow_redirects": true,
          "http_method": "HEAD",
          "interval_seconds": 60,
          "ip_version": "",
          "keep_cookies": false,
          "keyword": "",
          "keyword_case_insensitive": true,
          "maintenance_from": null,
          "maintenance_timezone": "UTC",
          "maintenance_to": null,
          "maintenance_weekdays": [
            "mon",
            "tue",
            "wed",
            "thu",
            "fri",
            "sat",
            "sun"
          ],
          "monitor_type": "http",
          "name": "Status page",
          "notification_mode": "immediate",
          "notify_recovery": true,
          "pronounceable_name": "",
          "proxy_host": "",
          "proxy_port": null,
          "recovery_period": 0,
          "regions": [
            "eu"
          ],
          "request_body": "",
          "request_headers": [],
          "request_timeout_s": 30,
          "ssl_expiry_alert_days": null,
          "ssl_verification": true,
          "state": "",
          "tcp_host": "",
          "tcp_port": null,
          "url": "https://example.org"
        },
        "raw": "",
        "status": "ready",
        "warnings": null
      }
    ],
    "summary": {
      "duplicates": 0,
      "errors": 0,
      "ready": 2,
      "total": 2,
      "warnings": 0
    }
  }
}
```

### 400

```json
{
  "error": {
    "code": "bad_request",
    "message": "The request is malformed or fails validation.",
    "request_id": "req_…"
  }
}
```

### 403

```json
{
  "error": {
    "code": "permission_denied",
    "message": "The credentials do not permit this action.",
    "request_id": "req_…"
  }
}
```

### 413

```json
{
  "error": {
    "code": "import_too_large",
    "message": "The import body is over the size limit.",
    "request_id": "req_…"
  }
}
```
