beta
Documentation

Diff Batches

A diff batch compares two capture batches page by page: the reference and the candidate. Each page compared is a diff task.

Start a diff batch

endpoint
POST /api/v1/projects/{project_id}/diff-batches

Compares two finished capture batches of the project. Minimum key role: Member.

shell
curl -X POST https://deploydiff.com/api/v1/projects/{project_id}/diff-batches \
  -H "Authorization: Bearer dd_…" \
  -H "Content-Type: application/json" \
  -d '{"reference_capture_batch_id": "00000000-0000-0000-0000-000000000003", "candidate_capture_batch_id": "00000000-0000-0000-0000-000000000002"}'
Body fieldTypeValue
reference_capture_batch_iduuid stringThe capture batch to compare against.
candidate_capture_batch_iduuid stringThe capture batch to review. Another batch.

The two can be of the same environment or of two environments of the project. Both must be finished: DONE or WARN.

Answers 201 with the new diff_batch, tasks included, and its address in the Location header. The diff belongs to the candidate's environment.

StatuscodeWhen
400invalid_bodyThe body is not a JSON object with both ids as UUIDs, or names the same batch twice.
404not_foundOne of the batches is not in the project, or its environment was deleted.
409capture_not_doneOne of the batches is not finished.
402usage_limit_reachedThe organization's usage limit is reached for the period.
402billing_blockedThe organization has an unpaid invoice that was cancelled.

The batch carries "trigger": "API". Diffs have no interval: you can start as many as you need.

Read a diff batch

endpoint
GET /api/v1/projects/{project_id}/diff-batches/{diff_batch_id}

One diff_batch, with its tasks. Minimum key role: Participant.

List diff batches

endpoint
GET /api/v1/projects/{project_id}/environments/{environment_id}/diff-batches

The diff batches whose candidate is in this environment, newest first, as a list of diff_batch objects without their tasks. Takes limit and cursor. Minimum key role: Participant.

The diff_batch object

diff_batch
{
  "object": "diff_batch",
  "id": "00000000-0000-0000-0000-000000000004",
  "environment_id": "00000000-0000-0000-0000-000000000001",
  "status": "DONE",
  "verdict": "FAIL",
  "trigger": "AUTO",
  "error": null,
  "reference": {
    "environment_id": "00000000-0000-0000-0000-000000000001",
    "environment_title": "Production",
    "capture_batch_id": "00000000-0000-0000-0000-000000000003",
    "captured_at": "2026-11-05T10:00:00.2+00:00"
  },
  "candidate": {
    "environment_id": "00000000-0000-0000-0000-000000000001",
    "environment_title": "Production",
    "capture_batch_id": "00000000-0000-0000-0000-000000000002",
    "captured_at": "2026-11-06T10:00:00.31+00:00"
  },
  "task_counts": {
    "pending": 0,
    "running": 0,
    "done": 11,
    "error": 0,
    "cancelled": 1
  },
  "verdict_counts": {
    "pass": 10,
    "warn": 1,
    "fail": 1,
    "skipped": 0
  },
  "tasks": [
    {
      "id": "00000000-0000-0000-0000-000000000008",
      "page": {
        "path": "/pricing",
        "title": "Pricing"
      },
      "status": "DONE",
      "verdict": "FAIL",
      "cancellation_reason": null,
      "match_pct": 87.4,
      "error_code": null
    }
  ],
  "created_at": "2026-11-06T10:02:11.6+00:00",
  "updated_at": "2026-11-06T10:03:40.1+00:00"
}
FieldTypeValue
environment_iduuid stringThe candidate's environment, which the diff belongs to.
statusstringPENDING, RUNNING, DONE, CANCELLED or ERROR — see lifecycle. DONE, CANCELLED and ERROR are final.
verdictstring | nullPASS, WARN, FAIL or SKIPPED, the result over all its pages — see verdict. null while no page has one, and on a batch in Error.
triggerstringWhat started it: MANUAL (from the dashboard), AUTO (after a capture, by the environment's automated diffing), API (an API call).
errorobject | nullWhy the batch failed as a whole, when it did: code and message (see below). null otherwise.
reference, candidateobjectThe two sides.
….environment_iduuid string | nullThe side's environment.
….environment_titlestring | nullIts name today, or when the diff was made if it was deleted since.
….capture_batch_iduuid string | nullThe side's capture batch; null when there was none, or once that batch has been deleted — just after a deletion, its id may still be there and read 404.
….captured_attimestamp | nullWhen that capture batch was created; null when there was none.
task_countsobjectIts tasks by status: pending, running, done, error, cancelled.
verdict_countsobjectIts tasks by verdict: pass, warn, fail, skipped.
tasksarrayOne entry per page compared. Not in lists.
tasks[].iduuid stringThe diff task's id.
tasks[].pageobject | nullpath and title of the page, as when the diff was made.
tasks[].statusstringPENDING, RUNNING, DONE, CANCELLED or ERROR.
tasks[].verdictstring | nullPASS, WARN, FAIL or SKIPPED; null until decided.
tasks[].cancellation_reasonstring | nullWhy the page was not compared, when it was CANCELLED — see diff tasks.
tasks[].match_pctnumber | nullHow much of the page matched, in percent; null until compared.
tasks[].error_codestring | nullWhy the comparison failed — see when a page comparison fails.

Batch errors

A diff started automatically can fail as a whole, when there is nothing to compare against: the batch is in ERROR, has no tasks and no verdict, and error says why. Test code in your code; show message to people as it is.

error.codeWhenerror.message
NO_REFERENCE_CAPTUREThe reference environment has no finished capture yet.The reference environment "Staging" has no successful capture to compare against.
REFERENCE_ENVIRONMENT_DELETEDThe reference environment was deleted.The reference environment "Staging" has been deleted. Pick another one in this environment's automation settings.

A batch can also end in ERROR with error at null, when it could not be started on our side: start it again.

diff_batch
{
  "object": "diff_batch",
  "id": "00000000-0000-0000-0000-000000000011",
  "environment_id": "00000000-0000-0000-0000-000000000001",
  "status": "ERROR",
  "verdict": null,
  "trigger": "AUTO",
  "error": {
    "code": "NO_REFERENCE_CAPTURE",
    "message": "The reference environment \"Staging\" has no successful capture to compare against."
  },
  "reference": {
    "environment_id": "00000000-0000-0000-0000-000000000010",
    "environment_title": "Staging",
    "capture_batch_id": null,
    "captured_at": null
  },
  "candidate": {
    "environment_id": "00000000-0000-0000-0000-000000000001",
    "environment_title": "Production",
    "capture_batch_id": "00000000-0000-0000-0000-000000000002",
    "captured_at": "2026-11-06T10:00:00.31+00:00"
  },
  "task_counts": {
    "pending": 0,
    "running": 0,
    "done": 0,
    "error": 0,
    "cancelled": 0
  },
  "verdict_counts": {
    "pass": 0,
    "warn": 0,
    "fail": 0,
    "skipped": 0
  },
  "tasks": [],
  "created_at": "2026-11-06T10:02:11.6+00:00",
  "updated_at": "2026-11-06T10:02:11.6+00:00"
}