Documentation Menu

REST API Reference

Integrate RegressionBot with any programming language or automated CI system. All requests must target the standard gateway base URL:

https://api.regressionbot.com
🔑 Prerequisite: API Key RequiredAll REST requests require the authentication header to run successfully.
Get API Key →

Authentication Header

Pass your API key using the Authorization: Bearer header (recommended) or the legacy x-api-key header:

# Recommended
curl -H "Authorization: Bearer your_api_key_here" https://api.regressionbot.com/job/job_7x9kLm2p

# Legacy (also accepted)
curl -H "x-api-key: your_api_key_here" https://api.regressionbot.com/job/job_7x9kLm2p

Endpoint Reference

post/crawl

Start a visual regression job

Triggers a new visual regression job for a single URL or a sitemap.

Example Request

curl -X POST "https://api.regressionbot.com/crawl" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "project": "string",
    "autoApprove": false,
    "testOrigin": "string",
    "url": "string",
    "sitemapUrl": "string",
    "baseOrigin": "string",
    "devices": [
      "string"
    ],
    "paths": [
      {
        "path": "string",
        "label": "string"
      }
    ],
    "scans": [
      {
        "pattern": "string",
        "options": null
      }
    ],
    "masks": [
      "string"
    ],
    "customCss": "string",
    "concurrency": 0,
    "runContext": {
      "changeDescription": "string",
      "gitCommitSha": "string",
      "gitCommitMessage": "string",
      "prTitle": "string",
      "prDescription": "string",
      "expectedChanges": [
        "string"
      ],
      "scope": [
        "string"
      ]
    }
  }'

Request Body Schema

{
  "project": "string",
  "autoApprove": false,
  "testOrigin": "string",
  "url": "string",
  "sitemapUrl": "string",
  "baseOrigin": "string",
  "devices": [
    "string"
  ],
  "paths": [
    {
      "path": "string",
      "label": "string"
    }
  ],
  "scans": [
    {
      "pattern": "string",
      "options": null
    }
  ],
  "masks": [
    "string"
  ],
  "customCss": "string",
  "concurrency": 0,
  "runContext": {
    "changeDescription": "string",
    "gitCommitSha": "string",
    "gitCommitMessage": "string",
    "prTitle": "string",
    "prDescription": "string",
    "expectedChanges": [
      "string"
    ],
    "scope": [
      "string"
    ]
  }
}

Response Codes

200Job started successfully
{
  "message": "Visual regression job started",
  "jobId": "550e8400-e29b-41d4-a716-446655440000"
}
400Invalid input
500Internal server error
get/job/{jobId}

Get job status

Retrieve the current status and progress of a visual regression job.

Example Request

curl -H "Authorization: Bearer YOUR_API_KEY" \
  "https://api.regressionbot.com/job/{jobId}"

Response Codes

200Job status retrieved successfully
{
  "jobId": "string",
  "environment": "staging",
  "baseEnvironment": "production",
  "intentProvided": false,
  "comparisonMode": "string",
  "status": "string",
  "summaryStatus": "string",
  "progress": {
    "total": 0,
    "completed": 0,
    "percent": "50.00"
  },
  "executionTime": 0,
  "results": [
    {
      "url": "string",
      "variantName": "Desktop Chrome",
      "status": "string",
      "errorMessage": "string",
      "isNewBaseline": false,
      "changed": false,
      "contentChanged": false,
      "metadataChanged": false,
      "changeGroup": "string",
      "changes": [
        null
      ],
      "diffPercentage": 0,
      "visualMatchScore": 0,
      "regressionbotSummary": [
        {
          "label": "string",
          "text": "string",
          "verdict": null
        }
      ],
      "verdict": null,
      "currentUrl": "string",
      "baselineUrl": "string",
      "diffUrl": "string",
      "domAssistSkipReason": "string",
      "triageStatus": "string",
      "triagedAt": "string",
      "triagedBy": "string",
      "triagedVerdict": "string",
      "triageNote": "string"
    }
  ],
  "createdAt": "string"
}
404Job not found
get/job/{jobId}/summary

Get job summary with signed URLs

Retrieve a summary of the completed job, including pre-signed URLs for the captures and each changed page's inspect link.

Example Request

curl -H "Authorization: Bearer YOUR_API_KEY" \
  "https://api.regressionbot.com/job/{jobId}/summary"

Response Codes

200Job summary retrieved successfully
{
  "jobId": "string",
  "environment": "staging",
  "baseEnvironment": "production",
  "status": "string",
  "totalUrls": 0,
  "completedCount": 0,
  "overallScore": 98.5,
  "executionTime": 0,
  "regressionCount": 0,
  "matchCount": 0,
  "newBaselineCount": 0,
  "errorCount": 0,
  "runSummary": "string",
  "intentAssessment": {
    "decision": "string",
    "intentProvided": false,
    "bugCount": 0,
    "intentionalCount": 0,
    "noiseCount": 0,
    "needsReviewCount": 0,
    "allAccountedFor": false,
    "summary": "string"
  },
  "runContext": {
    "changeDescription": "string",
    "gitCommitSha": "string",
    "gitCommitMessage": "string",
    "prTitle": "string",
    "prDescription": "string",
    "expectedChanges": [
      "string"
    ],
    "scope": [
      "string"
    ]
  },
  "regressions": [
    {
      "url": "string",
      "variantName": "Desktop Chrome",
      "status": "string",
      "errorMessage": "string",
      "isNewBaseline": false,
      "changed": false,
      "contentChanged": false,
      "metadataChanged": false,
      "changeGroup": "string",
      "changes": [
        null
      ],
      "diffPercentage": 0,
      "visualMatchScore": 0,
      "regressionbotSummary": [
        {
          "label": "string",
          "text": "string",
          "verdict": null
        }
      ],
      "verdict": null,
      "currentUrl": "string",
      "baselineUrl": "string",
      "diffUrl": "string",
      "domAssistSkipReason": "string",
      "triageStatus": "string",
      "triagedAt": "string",
      "triagedBy": "string",
      "triagedVerdict": "string",
      "triageNote": "string"
    }
  ],
  "matches": [
    {
      "url": "string",
      "variantName": "Desktop Chrome",
      "status": "string",
      "errorMessage": "string",
      "isNewBaseline": false,
      "changed": false,
      "contentChanged": false,
      "metadataChanged": false,
      "changeGroup": "string",
      "changes": [
        null
      ],
      "diffPercentage": 0,
      "visualMatchScore": 0,
      "regressionbotSummary": [
        {
          "label": "string",
          "text": "string",
          "verdict": null
        }
      ],
      "verdict": null,
      "currentUrl": "string",
      "baselineUrl": "string",
      "diffUrl": "string",
      "domAssistSkipReason": "string",
      "triageStatus": "string",
      "triagedAt": "string",
      "triagedBy": "string",
      "triagedVerdict": "string",
      "triageNote": "string"
    }
  ],
  "newBaselines": [
    {
      "url": "string",
      "variantName": "string"
    }
  ],
  "errors": [
    {
      "url": "string",
      "errorMessage": "string"
    }
  ]
}
400Job not completed yet
404Job not found
post/approve

Approve job baselines

Promote the current captures of a job (screenshot, DOM tree and saved page) to be the new baselines. Three forms, one endpoint. `{ jobId }` approves every page. `{ jobId, where: { decision: [...] } }` approves only the changed pages whose verdict.decision is in the list and leaves the rest pending, which is the call to make after reading a summary whose intentAssessment.decision is `review`. `{ jobId, url, variantName, action }` approves or rejects one page. Every approve or reject is recorded on the page's result as triageStatus, triagedAt, triagedBy and triagedVerdict.

Example Request

curl -X POST "https://api.regressionbot.com/approve" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "jobId": "e8087afe-e534-4378-b308-b7db11fdbfc5",
    "where": {
      "decision": [
        "intentional",
        "noise"
      ]
    }
  }'

Request Body Schema

{
  "jobId": "e8087afe-e534-4378-b308-b7db11fdbfc5",
  "where": {
    "decision": [
      "intentional",
      "noise"
    ]
  }
}

Response Codes

200Baselines approved successfully
{
  "message": "Job baseline approved",
  "jobId": "string",
  "approvedUrlsCount": 0,
  "skippedUrlsCount": 0,
  "conflictedUrls": [
    "string"
  ],
  "triageStatus": "string"
}
400where combined with url, or an unknown decision in where.decision
404Job not found
409The baseline moved under this page since the job ran; nothing was approved
get/projects

List all projects

Retrieve all saved project configurations for the authenticated organization.

Example Request

curl -H "Authorization: Bearer YOUR_API_KEY" \
  "https://api.regressionbot.com/projects"

Response Codes

200Projects list retrieved successfully
[
  {
    "name": "my-billing-app",
    "testOrigin": "https://staging.myapp.com",
    "baseOrigin": "https://myapp.com",
    "sitemapUrl": "https://staging.myapp.com/sitemap.xml",
    "paths": [
      {
        "path": "string",
        "label": "string"
      }
    ],
    "scans": [
      {
        "pattern": "string",
        "options": null
      }
    ],
    "devices": [
      "string"
    ],
    "masks": [
      "string"
    ],
    "customCss": "string",
    "concurrency": 0,
    "createdAt": "string",
    "updatedAt": "string",
    "lastRunAt": "string",
    "lastJobId": "string",
    "baselineInvalidatedAt": "string",
    "baselineVersion": "string"
  }
]
401Unauthorized
403Forbidden
get/project/{name}

Get project configuration

Retrieve the stored configuration for a named project.

Example Request

curl -H "Authorization: Bearer YOUR_API_KEY" \
  "https://api.regressionbot.com/project/{name}"

Response Codes

200Project configuration retrieved successfully
{
  "name": "my-billing-app",
  "testOrigin": "https://staging.myapp.com",
  "baseOrigin": "https://myapp.com",
  "sitemapUrl": "https://staging.myapp.com/sitemap.xml",
  "paths": [
    {
      "path": "string",
      "label": "string"
    }
  ],
  "scans": [
    {
      "pattern": "string",
      "options": null
    }
  ],
  "devices": [
    "string"
  ],
  "masks": [
    "string"
  ],
  "customCss": "string",
  "concurrency": 0,
  "createdAt": "string",
  "updatedAt": "string",
  "lastRunAt": "string",
  "lastJobId": "string",
  "baselineInvalidatedAt": "string",
  "baselineVersion": "string",
  "baselinePolicy": "rolling",
  "schedule": "daily",
  "scheduleHourUtc": 3,
  "scheduleKeyId": "key_7x9kLm2p",
  "lastScheduledRunAt": "2026-08-05T09:20:11.000Z",
  "intent": "Content is edited in the CMS daily; navigation, pricing and layout must not change.",
  "environment": "staging",
  "baseEnvironment": "production"
}
401Unauthorized
403Forbidden
404Project not found
put/project/{name}

Update project configuration

Update the configuration settings for a named project. Changing anything that decides what a capture looks like — testOrigin, baseOrigin, sitemapUrl, paths, scans, devices, masks, customCss, or a gate credential — invalidates the stored baselines by bumping baselineVersion, and the next run re-captures them instead of comparing. Everything else (schedule, baselinePolicy, concurrency, AI settings) leaves baselines alone. Re-sending an identical value is not a change. This is also where unattended checks are turned on: schedule (daily or weekly) with baselinePolicy 'rolling'. See Scheduled Checks under Project Configs.

Example Request

curl -X PUT "https://api.regressionbot.com/project/{name}" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "testOrigin": "https://staging.myapp.com",
    "baseOrigin": "https://myapp.com",
    "sitemapUrl": "https://staging.myapp.com/sitemap.xml",
    "paths": [
      {
        "path": "string",
        "label": "string"
      }
    ],
    "scans": [
      {
        "pattern": "string",
        "options": null
      }
    ],
    "devices": [
      "string"
    ],
    "masks": [
      "string"
    ],
    "customCss": "string",
    "concurrency": 0,
    "baselinePolicy": "string",
    "schedule": "string",
    "scheduleHourUtc": 3,
    "scheduleKeyId": "key_7x9kLm2p",
    "environment": "staging",
    "baseEnvironment": "production",
    "intent": "Content is edited in the CMS daily; navigation, pricing and layout must not change."
  }'

Request Body Schema

{
  "testOrigin": "https://staging.myapp.com",
  "baseOrigin": "https://myapp.com",
  "sitemapUrl": "https://staging.myapp.com/sitemap.xml",
  "paths": [
    {
      "path": "string",
      "label": "string"
    }
  ],
  "scans": [
    {
      "pattern": "string",
      "options": null
    }
  ],
  "devices": [
    "string"
  ],
  "masks": [
    "string"
  ],
  "customCss": "string",
  "concurrency": 0,
  "baselinePolicy": "string",
  "schedule": "string",
  "scheduleHourUtc": 3,
  "scheduleKeyId": "key_7x9kLm2p",
  "environment": "staging",
  "baseEnvironment": "production",
  "intent": "Content is edited in the CMS daily; navigation, pricing and layout must not change."
}

Response Codes

200Project configuration updated and baselines invalidated successfully
{
  "message": "Project configuration updated and baselines invalidated successfully",
  "project": {
    "name": "string",
    "testOrigin": "string",
    "baseOrigin": "string",
    "sitemapUrl": "string",
    "baselineVersion": "string",
    "baselineInvalidatedAt": "string",
    "updatedAt": "string"
  }
}
401Unauthorized
403Forbidden
404Project not found
post/project/{name}/run

Run project visual regression job

Run a visual regression job using the saved project configuration. Fields you send must match the stored configuration (a differing value is rejected with 400, never applied); fields you omit are taken from it.

Example Request

curl -X POST "https://api.regressionbot.com/project/{name}/run" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "testOrigin": "string",
    "url": "string",
    "sitemapUrl": "string",
    "baseOrigin": "string",
    "devices": [
      "string"
    ],
    "paths": [
      {
        "path": "string",
        "label": "string"
      }
    ],
    "scans": [
      {
        "pattern": "string",
        "options": null
      }
    ],
    "masks": [
      "string"
    ],
    "customCss": "string",
    "concurrency": 0,
    "autoApprove": false,
    "runContext": {
      "changeDescription": "string",
      "gitCommitSha": "string",
      "gitCommitMessage": "string",
      "prTitle": "string",
      "prDescription": "string",
      "expectedChanges": [
        "string"
      ],
      "scope": [
        "string"
      ]
    }
  }'

Request Body Schema

{
  "testOrigin": "string",
  "url": "string",
  "sitemapUrl": "string",
  "baseOrigin": "string",
  "devices": [
    "string"
  ],
  "paths": [
    {
      "path": "string",
      "label": "string"
    }
  ],
  "scans": [
    {
      "pattern": "string",
      "options": null
    }
  ],
  "masks": [
    "string"
  ],
  "customCss": "string",
  "concurrency": 0,
  "autoApprove": false,
  "runContext": {
    "changeDescription": "string",
    "gitCommitSha": "string",
    "gitCommitMessage": "string",
    "prTitle": "string",
    "prDescription": "string",
    "expectedChanges": [
      "string"
    ],
    "scope": [
      "string"
    ]
  }
}

Response Codes

200Job started successfully
{
  "message": "Visual regression job started",
  "jobId": "550e8400-e29b-41d4-a716-446655440000"
}
400Invalid input or URL validation failure
401Unauthorized
403Forbidden
404Project not found
post/ci/job/init

Initialize a client-driven visual regression job

Initiates a visual regression job when screenshots are captured locally (e.g. using the Playwright integration SDK). Sets up metadata and returns a jobId.

Example Request

curl -X POST "https://api.regressionbot.com/ci/job/init" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "project": "string",
    "testOrigin": "string",
    "branch": "string",
    "commit": "string",
    "devices": [
      "string"
    ],
    "runContext": {
      "changeDescription": "string",
      "gitCommitSha": "string",
      "gitCommitMessage": "string",
      "prTitle": "string",
      "prDescription": "string",
      "expectedChanges": [
        "string"
      ],
      "scope": [
        "string"
      ]
    }
  }'

Request Body Schema

{
  "project": "string",
  "testOrigin": "string",
  "branch": "string",
  "commit": "string",
  "devices": [
    "string"
  ],
  "runContext": {
    "changeDescription": "string",
    "gitCommitSha": "string",
    "gitCommitMessage": "string",
    "prTitle": "string",
    "prDescription": "string",
    "expectedChanges": [
      "string"
    ],
    "scope": [
      "string"
    ]
  }
}

Response Codes

200Job initialized successfully
{
  "jobId": "550e8400-e29b-41d4-a716-446655440000"
}
400Invalid input or validation failure
401Unauthorized
403Forbidden
post/ci/job/upload-url

Request presigned URLs to upload one page's capture

Generates short-lived presigned PUT URLs for one locally captured page: its screenshot (uploadUrl) and its DOM tree (domUploadUrl). Upload both. Since 2026-09-28 the comparison reads the DOM tree, and a page uploaded without it ends in ERROR ("This capture has no DOM tree").

Example Request

curl -X POST "https://api.regressionbot.com/ci/job/upload-url" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "jobId": "string",
    "url": "string",
    "variantName": "string"
  }'

Request Body Schema

{
  "jobId": "string",
  "url": "string",
  "variantName": "string"
}

Response Codes

200Presigned upload URL generated successfully
{
  "uploadUrl": "string",
  "domUploadUrl": "string",
  "currentKey": "string"
}
400Invalid input
401Unauthorized
403Forbidden
404Job not found
post/ci/job/finalize

Finalize a client-driven visual regression job

Instructs the server that all screenshots have been uploaded and triggers the parallel comparison flow in the cloud.

Example Request

curl -X POST "https://api.regressionbot.com/ci/job/finalize" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "jobId": "string"
  }'

Request Body Schema

{
  "jobId": "string"
}

Response Codes

200Job finalized and comparison started
{
  "message": "Job execution finalized and comparison started",
  "jobId": "550e8400-e29b-41d4-a716-446655440000"
}
400Invalid input or state validation failure
401Unauthorized
403Forbidden
404Job not found