# riddle_visual_diff

Screenshot two URLs and compute a pixel-level diff. See exactly what changed.

Plain text for agents: https://riddledc.com/docs/visual-diff/markdown.md

## Overview

`riddle_visual_diff` takes screenshots of two URLs and compares them pixel by pixel. It returns the change percentage, total changed pixels, and URLs for the before, after, and diff images.

You get back a numeric change percentage, changed pixel count, and three image URLs: before, after, and a highlighted diff overlay showing exactly which pixels changed.

## Endpoint

POST /v1/visual-diff

```bash
curl -X POST "https://api.riddledc.com/v1/visual-diff" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url_before": "https://example.com", "url_after": "https://staging.example.com"}'
```

## Parameters

| Parameter | Type | Description |
| --- | --- | --- |
| `url_before` | string | Required. The before URL to screenshot. |
| `url_after` | string | Required. The after URL to screenshot. |
| `viewport` | object | Browser viewport size. Default: `{ "width": 1920, "height": 1080 }`. |
| `threshold` | number | Pixel match sensitivity from 0 to 1. Lower is stricter. Default: `0.1`. |
| `selector` | string | CSS selector to diff a specific element instead of the full page. |
| `delay_ms` | number | Wait time in milliseconds after page load before capturing. Useful for animations. |
| `full_page` | boolean | Capture the full scrollable page, not just the viewport. Default: `false`. |

## Response

```json
{
  "change_percentage": 2.3,
  "changed_pixels": 4521,
  "images": {
    "before": "https://api.riddledc.com/v1/artifacts/img_before_abc123",
    "after": "https://api.riddledc.com/v1/artifacts/img_after_abc123",
    "diff": "https://api.riddledc.com/v1/artifacts/img_diff_abc123"
  }
}
```

## Examples

### JavaScript

```javascript
const response = await fetch("https://api.riddledc.com/v1/visual-diff", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${RIDDLE_API_KEY}`,
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    url_before: "https://example.com",
    url_after: "https://staging.example.com"
  })
});

const { change_percentage, changed_pixels, images } = await response.json();
console.log(`${change_percentage}% changed (${changed_pixels} pixels)`);
console.log("Diff image:", images.diff);
```

### Full Page With Custom Viewport

```javascript
const diff = await fetch("https://api.riddledc.com/v1/visual-diff", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${RIDDLE_API_KEY}`,
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    url_before: "https://example.com",
    url_after: "https://staging.example.com",
    full_page: true,
    viewport: { width: 1440, height: 900 },
    threshold: 0.05,
    delay_ms: 1000
  })
}).then((response) => response.json());
```

### Component-Level Diff

Use `selector` to compare a specific element instead of the full page:

```javascript
const diff = await fetch("https://api.riddledc.com/v1/visual-diff", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${RIDDLE_API_KEY}`,
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    url_before: "https://example.com",
    url_after: "https://staging.example.com",
    selector: ".hero-section",
    threshold: 0.1
  })
}).then((response) => response.json());
```

Tip: set `delay_ms` to wait for animations or lazy-loaded content to settle before capturing. This avoids false positives in the diff.

## Use Cases

- Visual regression testing: compare production vs. staging after every deploy to catch unintended CSS or layout changes.
- Deployment verification: confirm that a deploy looks correct by diffing pre- and post-deploy screenshots.
- A/B comparison: visually compare two variants of a page to verify design differences are as intended.
- Change monitoring: periodically diff a URL against a baseline to detect unexpected visual changes on third-party sites.

