> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sitespy.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Get the difference between two snapshots

> Generate a difference (comparison) between two historical snapshots of a web page change monitor (watch).

This endpoint compares content between two points in time and returns the differences in your chosen format.
Perfect for reviewing what changed between specific versions or comparing recent changes.

**Timestamp Keywords:**
- Use `'latest'` for the most recent snapshot (to_timestamp)
- Use `'previous'` for the second-most-recent snapshot (from_timestamp)
- Or use specific Unix timestamps from the watch history

**Format Options:**
- `text` (default): Plain text with (removed) and (added) prefixes
- `html`: HTML format with (removed) and (added) text
- `htmlcolor`: Rich HTML with colored highlights (green for additions, red for deletions)

**Word-Level Diffing:**
- Enable word-level granularity with `word_diff=true` for detailed inline comparisons
- Disable with `word_diff=false` for line-level comparisons only (default false/off, line-level mode by default)

**Raw Diff Output:**
- Use `no_markup=true` to get raw diff content without any formatting applied
- Returns content with placeholders for opening/closing tags of changes
- Allows you to implement your own custom colorisation or formatting
- Skips all HTML color application and service tweaks (added text, html color tags, etc)




## OpenAPI

````yaml /api-reference/openapi.yaml get /watch/{uuid}/difference/{from_timestamp}/{to_timestamp}
openapi: 3.1.0
info:
  title: Site Spy API
  description: >
    # Site Spy web page monitoring and notifications API


    REST API for managing page watches, group tags, and notifications.


    Site Spy can be driven by this simple REST API — the endpoint pages include
    `curl`, Python, and JavaScript examples to help you get started faster.


    ## Where to find my API key?


    Your API key is under [**Settings →
    API**](https://sitespy.app/dashboard/settings?tab=api) in the Site Spy
    dashboard.

    Simply click the API key to copy it to your clipboard.


    ## Connection URL


    All endpoints live under `https://detect.coolify.vkuprin.com/api/v1`, for
    example:

    `https://detect.coolify.vkuprin.com/api/v1/watch/cc0cfffa-f449-477b-83ea-0caafd1dc091/history`


    ## Authentication


    Almost all API requests require authentication, provided as an **API key**
    in the header of the HTTP request.


    For example: `x-api-key: YOUR_API_KEY`
  version: 0.1.6
  contact:
    name: Site Spy
    url: https://sitespy.app
  license:
    name: Apache 2.0
    url: https://www.apache.org/licenses/LICENSE-2.0.html
servers:
  - url: https://detect.coolify.vkuprin.com/api/v1
    description: Site Spy production
security:
  - ApiKeyAuth: []
tags:
  - name: Watch Management
    description: >
      Core functionality for managing web page monitors. Create, retrieve,
      update, and delete individual watches.

      Each watch represents a single URL being monitored for changes, with
      configurable settings for check intervals,

      notification preferences, and content filtering options.
  - name: Watch History
    description: |
      Get a list of timestamps of all changes detected for a watch.
  - name: Snapshots
    description: >
      Retrieve individual text snapshot of monitored content according to the
      `timestamp`. The text snapshot is the HTML

      to Text at page check time.


      Set the query argument `html` to any value to retrieve the last HTML
      fetched, the system only keeps the last two

      (2) HTML files fetched.


      Use the Watch History API endpoint to get a list of timestamps to pass to
      this query.
  - name: Favicon
    description: >
      Retrieve favicon images associated with monitored web pages. These are
      used in the dashboard interface

      to visually identify different watches in your monitoring list.
  - name: Tag Management
    description: >
      Organize your watches using tags and groups. Tags (also known as Groups)
      allow you to categorize monitors, set group-wide

      notification preferences, and perform bulk operations like mass rechecking
      or status changes across

      multiple related watches.
  - name: Notifications
    description: >
      Configure global notification endpoints that can be used across all your
      watches. Supports various

      notification services including email, Discord, Slack, webhooks, and many
      other popular platforms.

      These settings serve as defaults that can be overridden at the individual
      watch or tag level.


      The notification syntax uses
      [https://github.com/caronc/apprise](https://github.com/caronc/apprise).
  - name: User Settings
    description: >
      Manage user-specific settings such as default recheck intervals. These
      settings are stored per API key

      and apply to all watches created by that user unless overridden at the
      watch level.
  - name: Search
    description: >
      Search and filter your watches by URL patterns, titles, or tags. Useful
      for quickly finding specific

      monitors in large collections or identifying watches that match certain
      criteria.
  - name: Import
    description: >
      Bulk import multiple URLs for monitoring. Accepts plain text lists of URLs
      and can automatically

      apply tags, proxy settings, and other configurations to all imported
      watches simultaneously.
  - name: System Information
    description: >
      Retrieve system status and statistics about your Site Spy instance,
      including total watch

      counts, uptime information, and version details.
  - name: Email Verification
    description: >
      Manage email notification settings for your API key. Each API key can have
      one email address

      associated with it for receiving notifications. The email must be verified
      before notifications

      can be sent to it.
  - name: Telegram Notifications
    description: >
      Connect your Telegram account to receive instant change notifications.

      Generate a connect link, open it in Telegram, tap Start — done. Free for
      all plans.
  - name: Web Push Notifications
    description: >
      Subscribe to browser push notifications for instant alerts when watched
      pages change.

      Uses the Web Push protocol (RFC 8030) with VAPID authentication. Free for
      all plans.
  - name: RSS Feeds
    description: >
      Manage per-user RSS feed access tokens and retrieve feed URLs. Each user
      can generate a

      personal RSS token that provides access to their watches via standard RSS
      readers. Feeds

      are scoped to the user's watches only, ensuring multi-tenant privacy.
  - name: API Key Management
    description: >
      Generate and manage API keys. API keys are used to authenticate all
      requests to the API.

      Each API key is associated with a unique user and their watches.
  - name: Feature Flags
    description: >
      Retrieve feature flags for the current API key. Feature flags control
      which features are

      enabled or disabled for specific users.
  - name: Authentication
    description: >
      User account registration and authentication. Users can create accounts
      with email/password

      and receive an API key that links to their account. This enables syncing
      watches across

      the browser extension and web dashboard.
  - name: Plan
    description: >
      Retrieve the current subscription plan and usage for the authenticated API
      key. Plans control

      the maximum number of watches a user can create (Free: 2, Starter: 25,
      Pro: 100).
  - name: Billing
    description: >
      Manage subscriptions via Lemon Squeezy. Create checkout sessions to
      upgrade, access the

      customer billing portal, and receive webhook events from Lemon Squeezy.
  - name: Feedback
    description: >
      Collect product research responses from authenticated users. One-time PMF
      (Sean Ellis)

      survey submission per user.
  - name: Screenshots
    description: >
      Retrieve the history of visual snapshots captured for a watch. Use the
      returned timestamps

      with the Visual Diff endpoints to compare any two captures.
  - name: Visual Diff
    description: >
      Retrieve individual screenshots and pixel-level visual comparisons between
      any two captured

      snapshots of a watch, including difference metadata such as changed
      regions.
paths:
  /watch/{uuid}/difference/{from_timestamp}/{to_timestamp}:
    get:
      tags:
        - Watch History
      summary: Get the difference between two snapshots
      description: >
        Generate a difference (comparison) between two historical snapshots of a
        web page change monitor (watch).


        This endpoint compares content between two points in time and returns
        the differences in your chosen format.

        Perfect for reviewing what changed between specific versions or
        comparing recent changes.


        **Timestamp Keywords:**

        - Use `'latest'` for the most recent snapshot (to_timestamp)

        - Use `'previous'` for the second-most-recent snapshot (from_timestamp)

        - Or use specific Unix timestamps from the watch history


        **Format Options:**

        - `text` (default): Plain text with (removed) and (added) prefixes

        - `html`: HTML format with (removed) and (added) text

        - `htmlcolor`: Rich HTML with colored highlights (green for additions,
        red for deletions)


        **Word-Level Diffing:**

        - Enable word-level granularity with `word_diff=true` for detailed
        inline comparisons

        - Disable with `word_diff=false` for line-level comparisons only
        (default false/off, line-level mode by default)


        **Raw Diff Output:**

        - Use `no_markup=true` to get raw diff content without any formatting
        applied

        - Returns content with placeholders for opening/closing tags of changes

        - Allows you to implement your own custom colorisation or formatting

        - Skips all HTML color application and service tweaks (added text, html
        color tags, etc)
      operationId: getWatchHistoryDiff
      parameters:
        - name: uuid
          in: path
          required: true
          description: Web page change monitor (watch) unique ID
          schema:
            type: string
            format: uuid
        - name: from_timestamp
          in: path
          required: true
          description: >-
            Starting snapshot timestamp, 'previous' for second-most-recent, or
            specific Unix timestamp
          schema:
            oneOf:
              - type: integer
                description: Unix timestamp of the starting snapshot
              - type: string
                enum:
                  - previous
                description: >-
                  Use 'previous' to automatically select the second-most-recent
                  snapshot
          example: previous
        - name: to_timestamp
          in: path
          required: true
          description: >-
            Ending snapshot timestamp, 'latest' for most recent, or specific
            Unix timestamp
          schema:
            oneOf:
              - type: integer
                description: Unix timestamp of the ending snapshot
              - type: string
                enum:
                  - latest
                description: Use 'latest' to automatically select the most recent snapshot
          example: latest
        - name: format
          in: query
          description: >
            Output format for the diff:

            - `text` (default): Plain text with (removed) and (added) prefixes

            - `html`: Basic HTML format

            - `htmlcolor`: Rich HTML with colored backgrounds (red for
            deletions, green for additions)

            - `markdown`: Markdown format with HTML rendering
          schema:
            type: string
            enum:
              - text
              - html
              - htmlcolor
              - markdown
            default: text
        - name: word_diff
          in: query
          description: >
            Enable word-level diffing for more granular comparisons.

            When enabled, changes are highlighted at the word level rather than
            line level.

            Default is false (line-level mode).

            Accepts: true, false, 1, 0, yes, no, on, off
          schema:
            type: string
            enum:
              - 'true'
              - 'false'
              - '1'
              - '0'
              - 'yes'
              - 'no'
              - 'on'
              - 'off'
            default: 'false'
        - name: no_markup
          in: query
          description: >
            When set to true, returns the raw diff content without any markup
            formatting.

            The content will include placeholders for opening/closing tags of
            the changes,

            allowing you to implement your own custom colorisation or
            formatting.

            This skips all HTML color application and service tweaks.

            Accepts: true, false, 1, 0, yes, no, on, off
          schema:
            type: string
            enum:
              - 'true'
              - 'false'
              - '1'
              - '0'
              - 'yes'
              - 'no'
              - 'on'
              - 'off'
            default: 'false'
        - name: type
          in: query
          description: >
            Diff granularity type:

            - `diffLines` (default): Line-level comparison, showing which lines
            changed

            - `diffWords`: Word-level comparison, showing which words changed
            within lines


            This parameter is an alternative to `word_diff` for better alignment
            with the UI.

            If both are specified, `type=diffWords` will enable word-level
            diffing.
          schema:
            type: string
            enum:
              - diffLines
              - diffWords
            default: diffLines
        - name: changesOnly
          in: query
          description: >
            When enabled, only show lines/content that changed (no surrounding
            context).

            When disabled, include unchanged lines for context around changes.

            Accepts: true, false, 1, 0, yes, no, on, off
          schema:
            type: string
            enum:
              - 'true'
              - 'false'
              - '1'
              - '0'
              - 'yes'
              - 'no'
              - 'on'
              - 'off'
            default: 'true'
        - name: ignoreWhitespace
          in: query
          description: >
            When enabled, ignore whitespace-only changes (spaces, tabs,
            newlines).

            Useful for focusing on content changes and ignoring formatting
            differences.

            Accepts: true, false, 1, 0, yes, no, on, off
          schema:
            type: string
            enum:
              - 'true'
              - 'false'
              - '1'
              - '0'
              - 'yes'
              - 'no'
              - 'on'
              - 'off'
            default: 'false'
        - name: removed
          in: query
          description: |
            Include removed/deleted content in the diff output.
            When disabled, content that was deleted will not appear in the diff.
            Accepts: true, false, 1, 0, yes, no, on, off
          schema:
            type: string
            enum:
              - 'true'
              - 'false'
              - '1'
              - '0'
              - 'yes'
              - 'no'
              - 'on'
              - 'off'
            default: 'true'
        - name: added
          in: query
          description: |
            Include added/new content in the diff output.
            When disabled, content that was added will not appear in the diff.
            Accepts: true, false, 1, 0, yes, no, on, off
          schema:
            type: string
            enum:
              - 'true'
              - 'false'
              - '1'
              - '0'
              - 'yes'
              - 'no'
              - 'on'
              - 'off'
            default: 'true'
        - name: replaced
          in: query
          description: >
            Include replaced/modified content in the diff output.

            When disabled, content that was modified (changed from one value to
            another) will not appear in the diff.

            Accepts: true, false, 1, 0, yes, no, on, off
          schema:
            type: string
            enum:
              - 'true'
              - 'false'
              - '1'
              - '0'
              - 'yes'
              - 'no'
              - 'on'
              - 'off'
            default: 'true'
      responses:
        '200':
          description: Formatted diff between the two snapshots
          content:
            text/plain:
              schema:
                type: string
                description: Plain text diff with change markers
            text/html:
              schema:
                type: string
                description: HTML formatted diff with styling
        '400':
          description: Invalid format parameter or invalid request
        '404':
          description: Watch not found, timestamps not found, or insufficient history
      x-codeSamples:
        - lang: curl
          source: >
            # Compare previous snapshot to latest with colored HTML

            curl -X GET
            "https://detect.coolify.vkuprin.com/api/v1/watch/095be615-a8ad-4c33-8e9c-c7612fbf6c9f/difference/previous/latest?format=htmlcolor"
            \
              -H "x-api-key: YOUR_API_KEY"

            # Compare two specific timestamps in plain text with word-level diff

            curl -X GET
            "https://detect.coolify.vkuprin.com/api/v1/watch/095be615-a8ad-4c33-8e9c-c7612fbf6c9f/difference/1640995200/1640998800?format=text&word_diff=true"
            \
              -H "x-api-key: YOUR_API_KEY"

            # Show only additions (hide removed/replaced content), ignore
            whitespace

            curl -X GET
            "https://detect.coolify.vkuprin.com/api/v1/watch/095be615-a8ad-4c33-8e9c-c7612fbf6c9f/difference/previous/latest?format=htmlcolor&removed=false&replaced=false&ignoreWhitespace=true"
            \
              -H "x-api-key: YOUR_API_KEY"
        - lang: Python
          source: |
            import requests

            headers = {'x-api-key': 'YOUR_API_KEY'}
            uuid = '095be615-a8ad-4c33-8e9c-c7612fbf6c9f'

            # Compare previous to latest with colored HTML output
            response = requests.get(
                f'https://detect.coolify.vkuprin.com/api/v1/watch/{uuid}/difference/previous/latest',
                headers=headers,
                params={'format': 'htmlcolor'}
            )
            print(response.text)

            # Compare specific timestamps with word-level diff
            from_ts = '1640995200'
            to_ts = '1640998800'
            response = requests.get(
                f'https://detect.coolify.vkuprin.com/api/v1/watch/{uuid}/difference/{from_ts}/{to_ts}',
                headers=headers,
                params={'format': 'text', 'word_diff': 'true'}
            )
            print(response.text)

            # Show only additions, ignore whitespace and use word-level diff
            response = requests.get(
                f'https://detect.coolify.vkuprin.com/api/v1/watch/{uuid}/difference/previous/latest',
                headers=headers,
                params={
                    'format': 'htmlcolor',
                    'type': 'diffWords',
                    'removed': 'false',
                    'replaced': 'false',
                    'ignoreWhitespace': 'true'
                }
            )
            print(response.text)
components:
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
      description: >-
        API key for authentication. You can find your API key in the Site Spy
        dashboard under Settings → API.

````