---
title: "Create a monitor"
method: POST
path: "/monitors"
tags: ["Monitors"]
---

# Create a monitor

`POST /monitors`

## Request

- Base URL: `https://api.spectate.net/v1`
- URL: `https://api.spectate.net/v1/monitors`
- Auth: HTTP bearer

The monitor starts checking at once unless `enabled` is `false`. Without `project_id` it
joins the team's default project. Monitors and hosts together are limited by the plan
(`403` `PLAN_LIMIT_REACHED`), and so is the shortest `interval` (`422`). Targets on private
or reserved addresses are refused (`422`).

## Request body

- CreateMonitor: A new monitor. Only `label`, `protocol`, `uri` and `interval` are required; everything else has a sensible default. A `heartbeat` monitor needs `label`, `protocol` and `ping_period` instead.
  - `label` string, required: Name shown in the dashboard, alerts and status pages
  - `protocol` 'https' | 'http' | 'icmp' | 'tcp' | 'dns' | 'nameserver' | 'smtp' | 'imap' | 'pop3' | 'heartbeat', required: What a monitor checks, and so the format of its `uri`. | | |---| | `https` <br/> An HTTPS request to the URL in `uri`, with a certificate check. | | `http` <br/> An HTTP request to the URL in `uri`. | | `icmp` <br/> A ping (ICMP echo) to the host in `uri`. | | `tcp` <br/> A TCP connect to `host:port`, optionally with a TLS handshake and a banner keyword. | | `dns` <br/> A DNS query for a record of the name in `uri`, optionally compared with expected values. | | `nameserver` <br/> One authoritative nameserver at `host:port` (port optional, default 53), asked for the SOA record of each zone in `advanced_settings.nameserver_zones`. | | `smtp` <br/> An SMTP greeting from `host:port` (port optional), with STARTTLS by default. | | `imap` <br/> An IMAP greeting from `host:port` (port optional), over TLS by default. | | `pop3` <br/> A POP3 greeting from `host:port` (port optional), over TLS by default. | | `heartbeat` <br/> A job calls the monitor's secret ping URL each time it runs. No check goes out, and `uri` is empty. |
  - `uri` string: The target: a URL for `http` and `https`, a host for `icmp`, `host:port` for `tcp`, `host` or `host:port` for mail, a DNS name for `dns`, `host` or `host:port` for `nameserver` (default port 53). Private and reserved addresses are refused. For `http` and `https` the scheme is optional: `example.com/health` and `https://example.com/health` give the same monitor, stored without the scheme. A scheme that differs from `protocol` (`http://` for an `https` monitor) is refused with `422`
  - `interval` 30 | 60 | 120 | 180 | 300 | 600 | 900 | 1800 | 3600: Seconds between checks. Plans set the shortest interval a team may use.
  - `enabled` boolean: Whether the monitor starts running at once. Default `true`
  - `primary_location` 'eu' | 'us' | 'as' | 'oc': A region checks run from. A monitor's primary region decides its uptime and alerts (a failed check is repeated from the same region about 5 seconds later before it is marked down); on the Team plan and up the other regions can also measure its response time. | | |---| | `eu` <br/> Europe. | | `us` <br/> North America. | | `as` <br/> Asia. | | `oc` <br/> Oceania. |
  - `timeout` integer: Seconds before a check times out, 1 to 60. Default 30
  - `max_redirects` integer, nullable: HTTP: redirects to follow, 0 to 10; `null` follows up to 10
  - `headers` MonitorHeader[]: HTTP: up to 25 headers to send
    - `key` string, required: Header name
    - `value` string, required: Header value
  - `advanced_settings` MonitorAdvancedSettingsInput: Protocol-specific settings to set. On update, settings you leave out keep their value; send `null` to reset one to its default.
    - `connection_timeout` integer, nullable: Seconds to wait for the connection, 1 to 60; `null` uses the monitor's `timeout`
    - `auth_method` 'basic' | 'bearer' | 'digest': How an HTTP monitor authenticates its request. | | |---| | `basic` <br/> HTTP Basic: `auth_user` and `auth_password`. | | `bearer` <br/> `Authorization: Bearer <auth_password>`. | | `digest` <br/> HTTP Digest: `auth_user` and `auth_password`. |
    - `auth_user` string, nullable: HTTP: user name for `basic` and `digest`
    - `auth_password` string, nullable: HTTP: password, or the token for `bearer`. Write-only: never returned. Leave out or send an empty string to keep the stored one
    - `keyword` string, nullable: HTTP: text the response body must contain (or must not, with `keyword_inverted`). TCP: the same for the server's banner
    - `keyword_inverted` boolean, nullable: Fail the check when `keyword` is found, instead of when it's missing
    - `useragent` string, nullable: HTTP: the `User-Agent` header; `null` sends Spectate's
    - `method` 'HEAD' | 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE': The HTTP method an HTTP monitor sends.
    - `tls_mode` 'none' | 'tls' | 'starttls': How TCP and mail monitors use TLS: not at all, from the first byte (implicit TLS, e.g. 465/993/995), or by upgrading a plaintext session with STARTTLS (SMTP), STARTTLS (IMAP) or STLS (POP3). | | |---| | `none` <br/> Plain TCP, no TLS. | | `tls` <br/> TLS from the first byte (implicit TLS), as on ports 465, 993 and 995. | | `starttls` <br/> Upgrade a plaintext session: STARTTLS (SMTP, IMAP) or STLS (POP3). Mail monitors only. |
    - `dns_record_type` 'A' | 'AAAA' | 'CNAME' | 'MX' | 'NS' | 'TXT' | 'CAA' | 'SOA': The DNS record type a DNS monitor queries.
    - `dns_resolver` string, nullable: DNS: the resolver to query, as a public `ip` or `ip:port`. Without `dns_authoritative`, this turns it off. `null` uses the checker's resolver when `dns_authoritative` is off
    - `dns_authoritative` boolean, nullable: DNS: ask the zone's authoritative nameservers directly. New monitors do, unless you set `dns_resolver` or send `false`
    - `dns_expected_values` string[], nullable: DNS: up to 20 values the answer must contain or equal (see `dns_match`)
    - `dns_match` 'contains' | 'exact': How a DNS monitor compares the answer with `dns_expected_values`. | | |---| | `contains` <br/> Every expected value is in the answer; the answer may have more. | | `exact` <br/> The answer is exactly the expected values, in any order. |
    - `dns_alert_on_change` boolean, nullable: DNS: raise an alert when the answer changes
    - `dns_check_all_nameservers` boolean, nullable: DNS: ask every authoritative nameserver of the zone. One failed nameserver keeps the monitor up with a separate alert. Implies `dns_authoritative`
    - `dns_expected_nameservers` string[], nullable: DNS: up to 20 host names the zone should list, compared when `dns_check_all_nameservers` is on
    - `nameserver_zones` string[], nullable: Nameserver: the 1 to 20 zones the server must answer for, as domain names. Required when you create a `nameserver` monitor or switch a monitor to that protocol
  - `allow_insecure_requests` boolean: HTTPS: accept invalid certificates for the check itself. Default `false`
  - `expected_http_status_code` string, nullable: HTTP: status codes that count as up, comma-separated, `*` as a wildcard digit; `null` accepts 2xx and 3xx
  - `certificate_check_enabled` boolean: Check the TLS certificate for validity and expiry (HTTPS, and TCP or mail with TLS). Default `false`
  - `certificate_expiry_threshold_days` integer: Days before the certificate expires that the "expires soon" alert fires, 1 to 90. Default 14
  - `performance_check_enabled` boolean: Raise alerts for slow responses. Default `false`
  - `performance_hard_threshold` integer, nullable: Milliseconds, 1 to 30000: a response slower than this raises an alert
  - `performance_deviation_percentage` integer, nullable: Percent, 1 to 500: alert when recent response times are this much above the earlier ones (see the two timeframes)
  - `performance_deviation_timeframe` integer, nullable: Minutes of recent checks to compare: 15, 30, 45, 60, 75, 90, 105 or 120. Must be shorter than `performance_deviation_before_timeframe`
  - `performance_deviation_before_timeframe` integer, nullable: Minutes before those to compare with, a whole number of hours from 60 to 1440
  - `regional_performance_enabled` boolean: Also measure response time from the regions other than `primary_location`, every minute (or at the interval, when longer). Shown with the monitor's performance; not used for uptime or alerts. Team plan and up. Default `false`
  - `project_id` string, uuid, nullable: Project to add the monitor to; default the team's default project, `null` for none
  - `escalation_path_ids` string[]: Escalation paths for the monitor's alerts. Leave out or send `[]` to follow the project's paths, else the team's default path
  - `ping_period` integer: `heartbeat` monitors: seconds between the job's runs, 30 to 31622400 (366 days). Required when creating one
  - `ping_grace` integer: `heartbeat` monitors: seconds a ping may be late before it counts as missed, up to 30 days. Default 300
  - `ping_timezone` string: `heartbeat` monitors: time zone of the clock the job runs on, so a change of clocks doesn't look like a missed run. Default: the team's
  - `ping_alert_after` integer: `heartbeat` monitors: missed runs in a row before the monitor goes down and alerts, 1 to 20. Default 1
  - `ping_severity` 'critical' | 'high' | 'medium' | 'low': How urgent an alert or incident is. Escalation paths can branch on it. | | |---| | `critical` <br/> Customers are affected right now. | | `high` <br/> Serious, needs attention soon. | | `medium` <br/> Should be looked at. | | `low` <br/> Informational. |

## Response `201`

The new monitor.

- Monitor: A monitor: a check of a URL, host or DNS name from Spectate's regions, with its settings and latest results.
  - `id` string, uuid, required: Monitor ID
  - `label` string, required: Name shown in the dashboard, alerts and status pages
  - `protocol` 'https' | 'http' | 'icmp' | 'tcp' | 'dns' | 'nameserver' | 'smtp' | 'imap' | 'pop3' | 'heartbeat', required: What a monitor checks, and so the format of its `uri`. | | |---| | `https` <br/> An HTTPS request to the URL in `uri`, with a certificate check. | | `http` <br/> An HTTP request to the URL in `uri`. | | `icmp` <br/> A ping (ICMP echo) to the host in `uri`. | | `tcp` <br/> A TCP connect to `host:port`, optionally with a TLS handshake and a banner keyword. | | `dns` <br/> A DNS query for a record of the name in `uri`, optionally compared with expected values. | | `nameserver` <br/> One authoritative nameserver at `host:port` (port optional, default 53), asked for the SOA record of each zone in `advanced_settings.nameserver_zones`. | | `smtp` <br/> An SMTP greeting from `host:port` (port optional), with STARTTLS by default. | | `imap` <br/> An IMAP greeting from `host:port` (port optional), over TLS by default. | | `pop3` <br/> A POP3 greeting from `host:port` (port optional), over TLS by default. | | `heartbeat` <br/> A job calls the monitor's secret ping URL each time it runs. No check goes out, and `uri` is empty. |
  - `uri` string, required: The target as stored: a URL without the scheme for `http` and `https` (the protocol is the scheme), a host for `icmp`, `host:port` for `tcp` and mail, a DNS name for `dns`. `url` has the full URL
  - `url` string, required: The target as the dashboard shows it, for example `smtp://mail.example.com:587` for SMTP
  - `interval` 30 | 60 | 120 | 180 | 300 | 600 | 900 | 1800 | 3600, required: Seconds between checks. Plans set the shortest interval a team may use.
  - `primary_location` 'eu' | 'us' | 'as' | 'oc', required: A region checks run from. A monitor's primary region decides its uptime and alerts (a failed check is repeated from the same region about 5 seconds later before it is marked down); on the Team plan and up the other regions can also measure its response time. | | |---| | `eu` <br/> Europe. | | `us` <br/> North America. | | `as` <br/> Asia. | | `oc` <br/> Oceania. |
  - `timeout` integer, required: Seconds before a check times out
  - `max_redirects` integer, nullable, required: HTTP: redirects followed before the check fails; `null` follows up to 10
  - `headers` MonitorHeader[], required: HTTP: headers sent with every check
    - `key` string, required: Header name
    - `value` string, required: Header value
  - `advanced_settings` MonitorAdvancedSettings, required: Protocol-specific settings of a monitor. Settings that don't apply to its protocol are `null`. The password is never returned; `has_auth_password` says whether one is set.
    - `connection_timeout` integer, nullable, required: Seconds to wait for the connection; `null` uses the monitor's `timeout`
    - `auth_method` 'basic' | 'bearer' | 'digest', required: How an HTTP monitor authenticates its request. | | |---| | `basic` <br/> HTTP Basic: `auth_user` and `auth_password`. | | `bearer` <br/> `Authorization: Bearer <auth_password>`. | | `digest` <br/> HTTP Digest: `auth_user` and `auth_password`. |
    - `auth_user` string, nullable, required: HTTP: user name for `basic` and `digest`
    - `has_auth_password` boolean, required: HTTP: whether a password or bearer token is stored
    - `keyword` string, nullable, required: HTTP: text the response body must contain (or must not, with `keyword_inverted`). TCP: the same for the server's banner
    - `keyword_inverted` boolean, nullable, required: Whether the check fails when `keyword` is found, instead of when it's missing
    - `useragent` string, nullable, required: HTTP: the `User-Agent` header; `null` sends Spectate's
    - `method` 'HEAD' | 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE', required: The HTTP method an HTTP monitor sends.
    - `tls_mode` 'none' | 'tls' | 'starttls', required: How TCP and mail monitors use TLS: not at all, from the first byte (implicit TLS, e.g. 465/993/995), or by upgrading a plaintext session with STARTTLS (SMTP), STARTTLS (IMAP) or STLS (POP3). | | |---| | `none` <br/> Plain TCP, no TLS. | | `tls` <br/> TLS from the first byte (implicit TLS), as on ports 465, 993 and 995. | | `starttls` <br/> Upgrade a plaintext session: STARTTLS (SMTP, IMAP) or STLS (POP3). Mail monitors only. |
    - `dns_record_type` 'A' | 'AAAA' | 'CNAME' | 'MX' | 'NS' | 'TXT' | 'CAA' | 'SOA', required: The DNS record type a DNS monitor queries.
    - `dns_resolver` string, nullable, required: DNS: the resolver to query when `dns_authoritative` is off, as `ip` or `ip:port`; `null` uses the checker's resolver
    - `dns_authoritative` boolean, nullable, required: DNS: whether to ask the zone's authoritative nameservers directly, not a resolver that may answer from its cache
    - `dns_expected_values` string[], nullable, required: DNS: values the answer must contain or equal (see `dns_match`); `null` or empty accepts any answer
    - `dns_match` 'contains' | 'exact', required: How a DNS monitor compares the answer with `dns_expected_values`. | | |---| | `contains` <br/> Every expected value is in the answer; the answer may have more. | | `exact` <br/> The answer is exactly the expected values, in any order. |
    - `dns_alert_on_change` boolean, nullable, required: DNS: whether a changed answer raises an alert
    - `dns_check_all_nameservers` boolean, nullable, required: DNS: whether to ask every authoritative nameserver of the zone
    - `dns_expected_nameservers` string[], nullable, required: DNS: the host names the zone should list, compared when `dns_check_all_nameservers` is on
    - `nameserver_zones` string[], nullable, required: Nameserver: the zones the server must answer for
  - `enabled` boolean, required: Whether the monitor runs. `false` when paused by a member or by the system (see `paused_reason`)
  - `paused_reason` 'plan_limit' | 'team_paused', required: Why the system (not the user) paused a monitor, host, domain or status page. | | |---| | `plan_limit` <br/> Over the plan limit (trial expired, downgrade); the oldest resources stay active. | | `team_paused` <br/> The whole team's monitoring is paused (no paid plan, staff action or scheduled deletion). |
  - `allow_insecure_requests` boolean, required: HTTPS: whether invalid certificates are accepted for the check itself (the certificate check still reports them)
  - `expected_http_status_code` string, nullable, required: HTTP: status codes that count as up, comma-separated, `*` as a wildcard digit (`2**,301`); `null` accepts 2xx and 3xx
  - `certificate_check_enabled` boolean, required: Whether the TLS certificate is checked for validity and expiry
  - `certificate_expiry_threshold_days` integer, required: Days before the certificate expires that the "expires soon" alert fires
  - `uses_tls` boolean, required: Whether a check reports a certificate: HTTPS, and TCP or mail with TLS
  - `certificate_status` 'pending' | 'valid' | 'invalid' | 'expires_soon' | 'expired', required: The state of a monitor's TLS certificate, from its latest certificate check. | | |---| | `pending` <br/> Not checked yet. | | `valid` <br/> Valid and not about to expire. | | `invalid` <br/> Not trusted, for example self-signed, for another host or with a broken chain. | | `expires_soon` <br/> Valid, but expires within the monitor's `certificate_expiry_threshold_days`. | | `expired` <br/> Past its expiry date. |
  - `certificate_expires_at` string, date-time, nullable, required: When the certificate expires
  - `certificate_valid_from` string, date-time, nullable, required: When the certificate became valid
  - `certificate_issuer` string, nullable, required: Who issued the certificate
  - `certificate_error` string, nullable, required: Why the certificate isn't valid, with `certificate_status` `invalid` or `expired`
  - `certificate_checked_at` string, date-time, nullable, required: When the certificate was last checked
  - `performance_check_enabled` boolean, required: Whether slow responses raise alerts (`performance_hard_threshold`, `performance_deviation_percentage`)
  - `performance_hard_threshold` integer, nullable, required: Milliseconds: a response slower than this raises an alert
  - `performance_deviation_percentage` integer, nullable, required: Percent: an alert fires when the average response time of the last `performance_deviation_timeframe` minutes is this much above the average of the `performance_deviation_before_timeframe` minutes before
  - `performance_deviation_timeframe` integer, nullable, required: Minutes of recent checks compared (15 to 120, in steps of 15)
  - `performance_deviation_before_timeframe` integer, nullable, required: Minutes before those that they're compared with (60 to 1440, in whole hours)
  - `regional_performance_enabled` boolean, required: Also measure response time from the regions other than `primary_location`, every minute (or at the interval, when longer). Shown with the monitor's performance; not used for uptime or alerts. Team plan and up
  - `uptime_status` 'pending' | 'up' | 'down', required: Whether a monitor's target answers, from its latest checks. | | |---| | `pending` <br/> Not checked yet. | | `up` <br/> The latest check succeeded. | | `down` <br/> Checks fail: a failed check, repeated from the same region about 5 seconds later, failed again. |
  - `uptime_status_changed_at` string, date-time, nullable, required: When `uptime_status` last changed
  - `last_checked_at` string, date-time, nullable, required: When the monitor was last checked
  - `response_time` integer, nullable, required: Milliseconds the latest check took
  - `check_details` MonitorCheckDetails, required: Protocol details of the latest check, as the checker reported them. Fields that don't apply to the protocol are `null`.
    - `banner` string, nullable, required: TCP and mail: the first line of the server's greeting or banner
    - `reply_code` integer, nullable, required: SMTP: the greeting's reply code
    - `starttls` boolean, nullable, required: Mail: whether the session was upgraded with STARTTLS (or STLS)
    - `tls_version` string, nullable, required: The negotiated TLS version
    - `cipher_suite` string, nullable, required: The negotiated cipher suite
    - `dns_answers` string[], nullable, required: DNS: the answer's values of the queried record type, sorted
    - `dns_server` string, nullable, required: DNS: the server that answered, as `ip:port`
    - `dns_rcode` string, nullable, required: DNS: the response code
    - `dns_zone` string, nullable, required: DNS, with `dns_check_all_nameservers`: the zone of the record
    - `dns_nameservers` MonitorDnsNameserver[], nullable, required: DNS, with `dns_check_all_nameservers`: what each nameserver of the zone answered
      - `host` string, required: The host name of the nameserver
      - `address` string, nullable, required: The address the query went to; `null` when the name has none
      - `authoritative` boolean, required: Whether the answer has `NOERROR`, the AA flag and the zone's SOA record
      - `rcode` string, nullable, required: The response code of the SOA query; `null` without a response
      - `serial` integer, nullable, required: The serial of the SOA record
      - `answers` string[], nullable, required: The server's values of the monitored record, sorted
      - `response_time` integer, nullable, required: Milliseconds the SOA query took
      - `tcp` boolean, nullable, required: Whether a query over TCP worked; `null` when it wasn't tried
      - `error` string, nullable, required: Why the answer isn't authoritative; `null` when it is
    - `nameserver_zones` MonitorNameserverZone[], nullable, required: Nameserver: what the server answered for each zone
      - `zone` string, required: The zone
      - `authoritative` boolean, required: Whether the answer has `NOERROR`, the AA flag and the zone's SOA record
      - `rcode` string, nullable, required: The response code; `null` without a response
      - `serial` integer, nullable, required: The serial of the SOA record
      - `response_time` integer, nullable, required: Milliseconds the SOA query took
      - `error` string, nullable, required: Why the answer isn't authoritative; `null` when it is
    - `nameserver_recursion` boolean, nullable, required: Nameserver: whether the server's responses have the recursion available flag
    - `nameserver_issues` MonitorNameserverIssue[], nullable, required: Nameserver, and DNS with `dns_check_all_nameservers`: problems the check found that leave the monitor up
      - `type` 'tcp_failed' | 'unreachable' | 'lame' | 'answers_differ' | 'serial_drift' | 'delegation_mismatch' | 'nameservers_unexpected' | 'rrsig_expiring' | 'rrsig_expired', required: A problem with a nameserver that leaves the monitor up. Each type and server has its own alert, which resolves when a successful check no longer reports it. | | |---| | `tcp_failed` <br/> The nameserver answers over UDP, but not over TCP. | | `unreachable` <br/> One nameserver of the zone doesn't respond, has no address, or has a private address. | | `lame` <br/> One nameserver of the zone responds, but not with an authoritative answer. | | `answers_differ` <br/> The nameservers of the zone give different answers for the monitored record. | | `serial_drift` <br/> The nameservers of the zone have had different SOA serials for 30 minutes. | | `delegation_mismatch` <br/> The parent zone lists other nameservers than the zone itself. | | `nameservers_unexpected` <br/> The zone lists other nameservers than the expected list. | | `rrsig_expiring` <br/> The RRSIG on the zone's SOA record expires within 3 days. | | `rrsig_expired` <br/> The RRSIG on the zone's SOA record has expired. |
      - `server` string, nullable, required: The nameserver with the problem
      - `message` string, nullable, required: What the check saw
  - `uptime` MonitorUptime, required: Share of successful checks, in percent, over rolling windows; `null` until there is data.
    - `twenty_four_hours` number, nullable, required: Last 24 hours
    - `seven_days` number, nullable, required: Last 7 days
    - `thirty_days` number, nullable, required: Last 30 days
    - `ninety_days` number, nullable, required: Last 90 days
  - `project_id` string, uuid, nullable, required: The project the monitor belongs to; `null` for none
  - `escalation_paths` EscalationPathReference[], required: Escalation paths the monitor's alerts follow. Empty: the project's paths, else the team's default path
    - `id` string, uuid, required: Escalation path ID
    - `name` string, required: Escalation path name
  - `ping_url` string, nullable, required: `heartbeat` monitors: the secret URL the job calls. Add `/fail` or the exit code to report a failure. Anyone with the URL can report for the job; rotate it if it leaks
  - `ping_period` integer, nullable, required: `heartbeat` monitors: seconds between the job's runs
  - `ping_grace` integer, nullable, required: `heartbeat` monitors: seconds a ping may be late before it counts as missed
  - `ping_timezone` string, nullable, required: `heartbeat` monitors: the time zone of the clock the job runs on
  - `ping_alert_after` integer, nullable, required: `heartbeat` monitors: missed runs in a row before the monitor goes down and alerts
  - `ping_severity` 'critical' | 'high' | 'medium' | 'low', required: How urgent an alert or incident is. Escalation paths can branch on it. | | |---| | `critical` <br/> Customers are affected right now. | | `high` <br/> Serious, needs attention soon. | | `medium` <br/> Should be looked at. | | `low` <br/> Informational. |
  - `ping_due_at` string, date-time, nullable, required: `heartbeat` monitors: when the next ping must have arrived; `null` until the first ping
  - `created_at` string, date-time, required: When the monitor was created
  - `updated_at` string, date-time, required: When the monitor's settings last changed

## Other responses

- `401`: `UNAUTHENTICATED`: no token was sent. `INVALID_TOKEN`: the token is unknown or revoked. `TOKEN_EXPIRED`: the token has expired.
- `403`: `PLAN_LIMIT_REACHED`: the plan doesn't allow another one; `details.feature` names the limit. `FORBIDDEN`: the token lacks an ability this endpoint requires (listed in `details.required_abilities`). `TEAM_PENDING_DELETION`: the team is scheduled for deletion. `TEAM_SUSPENDED`: Spectate suspended the team.
- `422`: `VALIDATION_FAILED`: the request is invalid; `details.errors` lists the fields.
- `429`: `RATE_LIMITED`: too many requests for this token. Wait for the number of seconds in `Retry-After`.

---

[API](https://skmtc.dev/spectate/apis/spectate-api.md) - [All operations](https://skmtc.dev/spectate/apis/spectate-api/llms.txt) - [OpenAPI document](https://skmtc.dev/spectate/apis/spectate-api/revisions/9b1a233997de?raw)
