replynodes-com Monitors API

The monitors API from replynodes-com — 4 operation(s) for monitors.

Operations 6

POST /v1/monitors Create a monitor asynchronously #
GET /v1/monitors List monitors for the authenticated organization #
GET /v1/monitors/{id} Get a monitor #
PATCH /v1/monitors/{id} Update frequency, pause state, or webhook #
GET /v1/monitors/{id}/changes List monitor changes #
GET /v1/monitors/{id}/runs List monitor runs #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/replynodes-com:replynodes-com-monitors-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

replynodes-com-monitors-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: ReplyNodes Fetcher Monitors API
  version: v1
  description: 'Read-only data APIs for AI agents. Bearer auth. Prepaid credits / free tier.


    Click **Authorize** and paste ONLY the API key (no "Bearer" prefix) — Swagger adds it automatically.'
servers:
- url: https://api.replynodes.com
security:
- bearerAuth: []
tags:
- name: Monitors
paths:
  /v1/monitors:
    post:
      operationId: monitor_create
      tags:
      - Monitors
      summary: Create a monitor asynchronously
      security:
      - bearerAuth: []
      parameters:
      - name: Idempotency-Key
        in: header
        required: true
        schema:
          type: string
          minLength: 1
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/MonitorCreateRequest'
      responses:
        '200':
          description: 'Idempotent replay: the same Idempotency-Key and request body already created this monitor. The existing monitor is returned instead of creating a duplicate.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MonitorEnvelope'
          headers:
            X-RateLimit-Limit:
              $ref: '#/components/headers/X-RateLimit-Limit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/X-RateLimit-Remaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/X-RateLimit-Reset'
        '202':
          description: 'Monitor accepted. Initialization is asynchronous: the worker creates the private watch and the monitor becomes schedulable only after it exists, so next_run_at is omitted from the returned monitor and meta.initialization="pending" names the ongoing initialization instead of implying an imminent run.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MonitorEnvelope'
          headers:
            X-RateLimit-Limit:
              $ref: '#/components/headers/X-RateLimit-Limit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/X-RateLimit-Remaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/X-RateLimit-Reset'
        '400':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: Insufficient scope
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '409':
          description: Idempotency conflict
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: 'Rate limit exceeded for this workspace (create/update/pause: 60 requests/min; get/list/history: 300 requests/min, configurable). Honor Retry-After.'
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Retry-After:
              $ref: '#/components/headers/Retry-After'
            X-RateLimit-Limit:
              $ref: '#/components/headers/X-RateLimit-Limit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/X-RateLimit-Remaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/X-RateLimit-Reset'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '503':
          description: 'Degraded: the backend authorizer or rate-limit enforcement is temporarily unavailable (CodeDegraded), or webhook encryption is not configured (service_unavailable). Fail-closed; retry later.'
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
    get:
      operationId: monitor_list
      tags:
      - Monitors
      summary: List monitors for the authenticated organization
      security:
      - bearerAuth: []
      parameters:
      - name: cursor
        in: query
        schema:
          type: string
      - name: limit
        in: query
        schema:
          type: integer
          minimum: 1
          maximum: 100
          default: 20
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MonitorPage'
          headers:
            X-RateLimit-Limit:
              $ref: '#/components/headers/X-RateLimit-Limit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/X-RateLimit-Remaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/X-RateLimit-Reset'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: Insufficient scope
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: 'Rate limit exceeded for this workspace (create/update/pause: 60 requests/min; get/list/history: 300 requests/min, configurable). Honor Retry-After.'
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Retry-After:
              $ref: '#/components/headers/Retry-After'
            X-RateLimit-Limit:
              $ref: '#/components/headers/X-RateLimit-Limit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/X-RateLimit-Remaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/X-RateLimit-Reset'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '503':
          description: 'Degraded: the backend authorizer or rate-limit enforcement is temporarily unavailable (CodeDegraded), or webhook encryption is not configured (service_unavailable). Fail-closed; retry later.'
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /v1/monitors/{id}:
    parameters:
    - name: id
      in: path
      required: true
      schema:
        type: string
        format: uuid
    get:
      operationId: monitor_get
      tags:
      - Monitors
      summary: Get a monitor
      security:
      - bearerAuth: []
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MonitorEnvelope'
          headers:
            X-RateLimit-Limit:
              $ref: '#/components/headers/X-RateLimit-Limit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/X-RateLimit-Remaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/X-RateLimit-Reset'
        '401':
          description: 'Unauthorized: missing, invalid, or expired token'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: Insufficient scope (forbidden_scope)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: 'Rate limit exceeded for this workspace (create/update/pause: 60 requests/min; get/list/history: 300 requests/min, configurable). Honor Retry-After.'
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Retry-After:
              $ref: '#/components/headers/Retry-After'
            X-RateLimit-Limit:
              $ref: '#/components/headers/X-RateLimit-Limit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/X-RateLimit-Remaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/X-RateLimit-Reset'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '503':
          description: 'Degraded: the backend authorizer or rate-limit enforcement is temporarily unavailable (CodeDegraded), or webhook encryption is not configured (service_unavailable). Fail-closed; retry later.'
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
    patch:
      operationId: monitor_update
      tags:
      - Monitors
      summary: Update frequency, pause state, or webhook
      security:
      - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/MonitorUpdateRequest'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MonitorEnvelope'
          headers:
            X-RateLimit-Limit:
              $ref: '#/components/headers/X-RateLimit-Limit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/X-RateLimit-Remaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/X-RateLimit-Reset'
        '400':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: 'Unauthorized: missing, invalid, or expired token'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: Insufficient scope (forbidden_scope)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: 'Rate limit exceeded for this workspace (create/update/pause: 60 requests/min; get/list/history: 300 requests/min, configurable). Honor Retry-After.'
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Retry-After:
              $ref: '#/components/headers/Retry-After'
            X-RateLimit-Limit:
              $ref: '#/components/headers/X-RateLimit-Limit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/X-RateLimit-Remaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/X-RateLimit-Reset'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '503':
          description: 'Degraded: the backend authorizer or rate-limit enforcement is temporarily unavailable (CodeDegraded), or webhook encryption is not configured (service_unavailable). Fail-closed; retry later.'
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
      description: Update frequency, pause state, or webhook configuration. The change is recorded immediately in the monitor service database (scheduling authority) and the external changedetection watch is reconciled asynchronously and with bounded retries; the response monitor object carries sync_state/sync_next_retry_at/sync_error_reason so a degraded engine (for example, a failed pause) is truthful and visible rather than silently dropped.
  /v1/monitors/{id}/changes:
    parameters:
    - name: id
      in: path
      required: true
      schema:
        type: string
        format: uuid
    get:
      operationId: monitor_changes
      tags:
      - Monitors
      summary: List monitor changes
      security:
      - bearerAuth: []
      parameters:
      - name: cursor
        in: query
        schema:
          type: string
      - name: limit
        in: query
        schema:
          type: integer
          minimum: 1
          maximum: 100
          default: 20
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MonitorHistoryPage'
          headers:
            X-RateLimit-Limit:
              $ref: '#/components/headers/X-RateLimit-Limit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/X-RateLimit-Remaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/X-RateLimit-Reset'
        '401':
          description: 'Unauthorized: missing, invalid, or expired token'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: Insufficient scope (forbidden_scope)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: 'Rate limit exceeded for this workspace (create/update/pause: 60 requests/min; get/list/history: 300 requests/min, configurable). Honor Retry-After.'
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Retry-After:
              $ref: '#/components/headers/Retry-After'
            X-RateLimit-Limit:
              $ref: '#/components/headers/X-RateLimit-Limit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/X-RateLimit-Remaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/X-RateLimit-Reset'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '503':
          description: 'Degraded: the backend authorizer or rate-limit enforcement is temporarily unavailable (CodeDegraded), or webhook encryption is not configured (service_unavailable). Fail-closed; retry later.'
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /v1/monitors/{id}/runs:
    parameters:
    - name: id
      in: path
      required: true
      schema:
        type: string
        format: uuid
    get:
      operationId: monitor_runs
      tags:
      - Monitors
      summary: List monitor runs
      security:
      - bearerAuth: []
      parameters:
      - name: cursor
        in: query
        schema:
          type: string
      - name: limit
        in: query
        schema:
          type: integer
          minimum: 1
          maximum: 100
          default: 20
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MonitorHistoryPage'
          headers:
            X-RateLimit-Limit:
              $ref: '#/components/headers/X-RateLimit-Limit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/X-RateLimit-Remaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/X-RateLimit-Reset'
        '401':
          description: 'Unauthorized: missing, invalid, or expired token'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: Insufficient scope (forbidden_scope)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: 'Rate limit exceeded for this workspace (create/update/pause: 60 requests/min; get/list/history: 300 requests/min, configurable). Honor Retry-After.'
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Retry-After:
              $ref: '#/components/headers/Retry-After'
            X-RateLimit-Limit:
              $ref: '#/components/headers/X-RateLimit-Limit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/X-RateLimit-Remaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/X-RateLimit-Reset'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '503':
          description: 'Degraded: the backend authorizer or rate-limit enforcement is temporarily unavailable (CodeDegraded), or webhook encryption is not configured (service_unavailable). Fail-closed; retry later.'
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
components:
  schemas:
    MonitorPageMeta:
      type: object
      required:
      - request_id
      - has_more
      properties:
        request_id:
          type: string
        next_cursor:
          type: string
        has_more:
          type: boolean
    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.'
    MonitorPage:
      type: object
      required:
      - data
      - meta
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/Monitor'
        meta:
          $ref: '#/components/schemas/MonitorPageMeta'
    MonitorCreateRequest:
      type: object
      required:
      - url
      - detector
      - frequency
      properties:
        url:
          type: string
          format: uri
        detector:
          type: string
          enum:
          - price
          - saas_pricing
          - product_change
        frequency:
          type: string
          enum:
          - 15m
          - 1h
          - 6h
          - 12h
          - 24h
        webhook:
          $ref: '#/components/schemas/MonitorWebhook'
    MonitorHistoryPage:
      type: object
      required:
      - data
      - meta
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/MonitorRun'
        meta:
          $ref: '#/components/schemas/MonitorPageMeta'
    MonitorRun:
      type: object
      properties:
        id:
          type: string
          format: uuid
        timestamp:
          type: string
          format: date-time
        status:
          type: string
        baseline:
          type: boolean
        changed:
          type: boolean
        credits:
          type: integer
    MonitorUpdateRequest:
      type: object
      properties:
        frequency:
          type: string
          enum:
          - 15m
          - 1h
          - 6h
          - 12h
          - 24h
        paused:
          type: boolean
        webhook:
          $ref: '#/components/schemas/MonitorWebhook'
      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.'
    Error:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
            message:
              type: string
            request_id:
              type: string
    Monitor:
      type: object
      required:
      - id
      - url
      - detector
      - frequency
      - paused
      properties:
        id:
          type: string
          format: uuid
        url:
          type: string
          format: uri
        detector:
          type: string
          enum:
          - price
          - saas_pricing
          - product_change
        frequency:
          type: string
          enum:
          - 15m
          - 1h
          - 6h
          - 12h
          - 24h
        paused:
          type: boolean
        baseline_completed:
          type: boolean
        next_run_at:
          type: string
          format: date-time
          description: 'Canonical next scheduled run in UTC. Reported only while the monitor is schedulable: a monitor whose private watch is still being initialized cannot be claimed (ClaimDue requires initialization_state=''ready''), so the field is omitted until initialization completes instead of implying an imminent run. Paused-but-initialized monitors still report their stored schedule; it is suspended until resume.'
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        initialization_state:
          type: string
          enum:
          - pending
          - initializing
          - retryable
          - ready
          - failed
          description: Asynchronous changedetection watch initialization state
        initialization_next_retry_at:
          type: string
          format: date-time
          description: Next worker retry time for retryable initialization
        initialization_error_reason:
          type: string
          description: Most recent changedetection initialization failure reason
        webhook:
          allOf:
          - $ref: '#/components/schemas/MonitorWebhook'
          description: Secret is write-only and never returned
        sync_state:
          type: string
          enum:
          - none
          - pending
          - running
          - retryable
          - failed
          - synced
          description: External changedetection watch reconciliation state. PATCH persists frequency/paused immediately (the database is the scheduling authority); the worker applies the change to the engine's watch asynchronously and exposes convergence here. "none" means no external watch exists yet; "pending"/"retryable" are awaiting or retrying the application; "running" is being applied; "failed" exhausted the bounded retry budget and needs a new PATCH to re-arm; "synced" means the engine watch matches the record.
        sync_next_retry_at:
          type: string
          format: date-time
          description: Next worker retry time for retryable engine watch reconciliation
        sync_error_reason:
          type: string
          description: Most recent changedetection engine watch reconciliation failure reason
    MonitorEnvelope:
      type: object
      required:
      - data
      - meta
      properties:
        data:
          $ref: '#/components/schemas/Monitor'
        meta:
          type: object
          required:
          - request_id
          properties:
            request_id:
              type: string
            initialization:
              type: string
              description: 'Present on the asynchronous 202 create response while the private watch is being initialized: "pending". The monitor is not schedulable until initialization completes, so next_run_at is omitted from the data block until then.'
  headers:
    X-RateLimit-Reset:
      description: Unix timestamp (seconds) when the current rate-limit window resets.
      schema:
        type: integer
        format: int64
    X-Request-Id:
      description: Correlation identifier returned by the gateway and echoed in meta.request_id.
      schema:
        type: string
    X-RateLimit-Limit:
      description: Maximum requests allowed per minute for this workspace and operation class (60 for create/update/pause, 300 for get/list/history by default).
      schema:
        type: integer
        minimum: 1
    Retry-After:
      description: Seconds until the workspace rate-limit window resets; present on 429 rate_limited monitor responses.
      schema:
        type: integer
        format: int64
        minimum: 1
    X-RateLimit-Remaining:
      description: Requests remaining in the current rate-limit window.
      schema:
        type: integer
        minimum: 0
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: rn_test_<64hex> or rn_live_<64hex>
      description: API key. Paste the raw key only (e.g. rn_test_...) — the "Bearer " prefix is added automatically.