{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/replynodes-com/json-schema/replynodes-com-monitor-update-request-schema.json",
  "title": "MonitorUpdateRequest",
  "description": "Update frequency, pause state, or webhook configuration. The database update is authoritative and committed immediately; the changedetection engine watch is reconciled asynchronously by the monitor worker and the returned monitor reports convergence through sync_state/sync_next_retry_at/sync_error_reason instead of claiming engine success. Reconciliation failures retry with a bounded backoff budget and surface as sync_state=\"failed\" (a new PATCH re-arms it). An active monitor's schedule reflects the new preset promptly: changing frequency recomputes next_run_at from the change time using the new preset, and resuming a paused monitor schedules the next run one interval after the resume (never an immediate run), so the engine and the canonical schedule cannot drift onto different cadences. Immutable fields (url, detector) are rejected.",
  "x-generated": "2026-10-30",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/replynodes-com-openapi.json#/components/schemas/MonitorUpdateRequest",
  "type": "object",
  "properties": {
    "frequency": {
      "type": "string",
      "enum": [
        "15m",
        "1h",
        "6h",
        "12h",
        "24h"
      ]
    },
    "paused": {
      "type": "boolean"
    },
    "webhook": {
      "$ref": "#/$defs/MonitorWebhook",
      "nullable": true
    }
  },
  "$defs": {
    "MonitorWebhook": {
      "type": "object",
      "required": [
        "url"
      ],
      "description": "Signed webhook notification endpoint (issue #485). The URL must be a public HTTPS target; localhost/private/link-local/metadata/CGNAT destinations and non-HTTPS schemes are rejected unless the service is explicitly configured otherwise for a non-production harness. The secret is AES-256-GCM encrypted at rest. When a monitor change is detected the service POSTs the MonitorChangeEvent payload to this URL with headers X-ReplyNodes-Event-Id (<event_id>), X-ReplyNodes-Timestamp (Unix seconds of this attempt) and X-ReplyNodes-Signature (sha256=<hex> HMAC-SHA256 over timestamp + '.' + raw request body). Receivers should verify against the exact raw body bytes and enforce a 5-minute timestamp tolerance; retries re-sign with a fresh timestamp and the same event_id. Destination identity is URL-based and rotation is replace-on-update with no overlap: a PATCH changing only webhook.secret keeps the same destination identity and in-flight deliveries are signed with the current secret, while a PATCH changing the URL finalizes rows for the old URL as destination_replaced. When HTTPS is required, every redirect is revalidated and a redirect to a cleartext http target is rejected; the secret is write-only, AES-256-GCM encrypted at rest, and never returned or logged.",
      "properties": {
        "url": {
          "type": "string",
          "format": "uri"
        },
        "secret": {
          "type": "string",
          "writeOnly": true,
          "description": "HMAC secret used to sign deliveries. Write-only: it is never returned, logged, or rendered into the payload."
        }
      }
    }
  }
}