Start comparison
start_comparisonFree up to 40 pages a day per client address, no key needed; sample report: https://difficat.com/agents/sample/report.json. Compares Site A against Site B on page existence, content and visual regression, priced per page compared. For a migration or redesign check, sourceUrl and targetUrl let discovery pick the pages (maxPages caps them), or urls names the pairs; then wait_for_comparison until it ends and get_report with failedOnly: true. For a single page, use capture_screenshot. dryRun: true answers the page count and price (0.02 USD a page, 0.01 beyond 1000) without charging, and freeCovers without a key; a job above the remaining free allowance is refused with a payment challenge with nextSteps for your human. maxPriceUsd refuses a dearer job before any challenge, never a free job. Example: { "urls": [{ "source": "https://old.example/a", "target": "https://new.example/a" }] }. Answers with jobId, jobToken, status, pagesCharged and, on a free run, sample and allowanceRemaining.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| urls | No | Explicit page pairs to compare (at most 50000); skips discovery and is priced per pair. One pair is a single-page comparison and needs no sourceUrl. | |
| dryRun | No | Quote only: runs every check and the pricing, then answers the page count and exact amount. Nothing is charged, the free allowance is not used and no job starts; the same body without dryRun is priced from the retained result. | |
| visual | No | Capture rules applied to both sides. | |
| maxPages | No | Optional ceiling on the pages compared and charged for. The job is priced on the pages it compares: the urls list, or the pages discovery finds, at most this many. There is no page limit. | |
| checkMode | No | What each page is checked on: full (existence, content and visual, the default), text-only (existence and content, no screenshots) or existence-only (only that every page exists and answers, as for a site translated into another language; content and visual are reported as skipped with reason not-requested). | |
| sourceUrl | No | Site A, the reference site (full URL). Required unless urls is given. | |
| targetUrl | No | Site B, the migrated site. Omit to capture screenshots of Site A only. | |
| threshold | No | Visual diff tolerance as a fraction from 0 (exact) to 1: 0.05 means 5%. The web app takes a percentage; the API does not. | |
| sitemapUrl | No | Sitemap to discover pages from. | |
| sourceAuth | No | HTTP basic auth for Site A. | |
| targetAuth | No | HTTP basic auth for Site B. | |
| callbackUrl | No | Optional https URL (port 443) that receives one JSON POST when the job ends (jobId, status, summary, links; never the jobToken), a nudge to read the job. Public hosts only, no redirects followed, retried twice; delivery never affects the job. | |
| maxPriceUsd | No | Optional spend cap in USD. A job priced above it is refused before any challenge, so an auto-paying client is never asked for more. | |
| viewportWidth | No | Capture width in px. | |
| idempotencyKey | No | Optional opaque string a retry repeats: under a prepaid balance the same value within 24 hours is not charged again and answers DUPLICATE_REQUEST with the jobId of the first call. |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| code | No | ||
| error | No | ||
| jobId | No | ||
| amount | No | ||
| dryRun | No | ||
| sample | No | ||
| status | No | ||
| payment | No | ||
| currency | No | ||
| jobToken | No | ||
| freeCovers | No | ||
| pagesPriced | No | ||
| pagesCharged | No | ||
| allowanceRemaining | No | ||
| pagesFromAllowance | No |