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

# API Self-Hosted v3 – Getting comparison results as JSON via the change-details endpoint

> The change-details endpoint allows you to retrieve comparison results from your API Self-Hosted v3 instance as a structured JSON response, including individual changes, style information, positional data, and a summary of all differences found.

<Note>
  This article covers **API Self-Hosted v3**. The endpoint behaves the same way on [API Self-Hosted v2](/hc/en-us/articles/37873874456985-Getting-Comparison-Results-as-a-JSON-via-the-Change-Details-Endpoint-API-Self-Hosted) and on the [Draftable cloud API](/hc/en-us/articles/37873922031129-Getting-Comparison-Results-as-a-JSON-via-the-Change-Details-Endpoint-API).
</Note>

The **change-details** endpoint returns a detailed JSON breakdown of every change detected between two compared documents. This includes the type of change, the affected text, positional coordinates on each page, font and style information, and a statistical summary.

## Endpoint

```bash theme={null}
GET https://<your-self-hosted-domain>/api/v1/comparisons/<Comparison_ID>/change-details
```

* **your-self-hosted-domain**: The base URL of your API Self-Hosted v3 instance — the same host you use for all other API calls (the load balancer or ingress in front of the `apish-web` service).
* **Comparison\_ID**: The unique identifier for the comparison (returned when you create a comparison via the API).

### Authentication

Include your API token in the `Authorization` header:

```bash theme={null}
Authorization: Token your_access_token
```

### Example request

```bash theme={null}
curl -H "Authorization: Token your_access_token" \
  "https://your-server.example.com/api/v1/comparisons/LxBGpPTO/change-details"
```

## Response structure

The JSON response contains three top-level keys:

| Key        | Description                                                                                                             |
| ---------- | ----------------------------------------------------------------------------------------------------------------------- |
| `changes`  | Array of change objects representing every matched, inserted, deleted, or replaced segment                              |
| `summary`  | Statistical summary of the comparison including change counts and document metadata                                     |
| `s3_links` | Links for downloading highlighted PDFs, original documents, and viewer data files (see [Storage links](#storage-links)) |

<Note>
  The key is named `s3_links` regardless of which storage backend your instance uses. On a default v3 deployment, which stores comparison files on a local volume, the values are **relative paths on your own instance**, not AWS presigned URLs. See [Storage links](#storage-links).
</Note>

## Change objects

Each object in the `changes` array represents a segment of text that was either matched, inserted, deleted, or replaced between the left (older) and right (newer) documents.

### Change kinds

| Kind      | Description                                                                      | Text fields             | Region fields               |
| --------- | -------------------------------------------------------------------------------- | ----------------------- | --------------------------- |
| `match`   | Text is identical in both documents                                              | `text`                  | `leftRegion`, `rightRegion` |
| `insert`  | Text exists only in the right document                                           | `rightText`             | `rightRegion`               |
| `delete`  | Text exists only in the left document                                            | `leftText`              | `leftRegion`                |
| `replace` | Text in the left document was replaced with different text in the right document | `leftText`, `rightText` | `leftRegion`, `rightRegion` |

### Common fields on all change objects

| Field              | Type           | Description                                                                                           |
| ------------------ | -------------- | ----------------------------------------------------------------------------------------------------- |
| `kind`             | string         | The type of change: `match`, `insert`, `delete`, or `replace`                                         |
| `moveId`           | string or null | If present, indicates this change is part of a move operation (see [Move detection](#move-detection)) |
| `stylesInfo`       | object         | Font, color, and emphasis information for the text (see [Styles info](#styles-info))                  |
| `viewerProperties` | object         | Properties used by the Draftable viewer (typically an empty object)                                   |

### Additional fields by kind

| Field           | Present on                   | Type   | Description                                                                          |
| --------------- | ---------------------------- | ------ | ------------------------------------------------------------------------------------ |
| `text`          | `match`                      | string | The matched text content                                                             |
| `leftText`      | `delete`, `replace`          | string | Text from the left (older) document                                                  |
| `rightText`     | `insert`, `replace`          | string | Text from the right (newer) document                                                 |
| `leftRegion`    | `match`, `delete`, `replace` | object | Position of the text in the left document (see [Region objects](#region-objects))    |
| `rightRegion`   | `match`, `insert`, `replace` | object | Position of the text in the right document (see [Region objects](#region-objects))   |
| `deletionMark`  | `delete`, `replace`          | object | Marker position in the left document margin (see [Marker objects](#marker-objects))  |
| `insertionMark` | `insert`, `replace`          | object | Marker position in the right document margin (see [Marker objects](#marker-objects)) |

## Examples by change kind

### Match

A `match` change represents text that is identical in both documents.

```json theme={null}
{
  "kind": "match",
  "text": "ANNUAL REPORT",
  "leftRegion": {
    "pageIndex": 0,
    "rectangles": [
      { "left": 270.0, "top": 297.85, "right": 373.53, "bottom": 311.17 }
    ],
    "regionOutlines": [
      {
        "points": [
          [373.53, 297.85],
          [270.0, 297.85],
          [270.0, 311.17],
          [373.53, 311.17]
        ]
      }
    ]
  },
  "rightRegion": {
    "pageIndex": 0,
    "rectangles": [
      { "left": 270.0, "top": 297.85, "right": 373.53, "bottom": 311.17 }
    ],
    "regionOutlines": [
      {
        "points": [
          [373.53, 297.85],
          [270.0, 297.85],
          [270.0, 311.17],
          [373.53, 311.17]
        ]
      }
    ]
  },
  "stylesInfo": {
    "leftStyles": [
      { "color": "#000000", "font": "Arial-BoldMT", "emphasis": "bold", "size": 12.0 }
    ],
    "rightStyles": [
      { "color": "#000000", "font": "Arial-BoldMT", "emphasis": "bold", "size": 12.0 }
    ],
    "leftStyleMap": ["0-12"],
    "rightStyleMap": ["0-12"],
    "styleChanges": []
  },
  "viewerProperties": {}
}
```

### Insert

An `insert` change represents text that exists only in the right (newer) document.

```json theme={null}
{
  "kind": "insert",
  "rightText": "See comment above",
  "rightRegion": {
    "pageIndex": 3,
    "rectangles": [
      { "left": 12.8, "top": 449.05, "right": 121.79, "bottom": 462.54 }
    ],
    "regionOutlines": [
      {
        "points": [
          [121.79, 449.05],
          [12.8, 449.05],
          [12.8, 462.54],
          [121.79, 462.54]
        ]
      }
    ]
  },
  "stylesInfo": {
    "rightStyles": [
      { "color": "#FF0000", "font": "Chrom Sans OTF", "emphasis": "", "size": 12.0 }
    ],
    "rightStyleMap": ["0-16"]
  },
  "insertionMark": {
    "pageIndex": 3,
    "point": [66.68, 477.6]
  },
  "viewerProperties": {}
}
```

### Delete

A `delete` change represents text that exists only in the left (older) document.

```json theme={null}
{
  "kind": "delete",
  "leftText": "$9,500",
  "leftRegion": {
    "pageIndex": 3,
    "rectangles": [
      { "left": 71.13, "top": 533.38, "right": 98.62, "bottom": 543.63 }
    ],
    "regionOutlines": [
      {
        "points": [
          [98.62, 533.38],
          [71.13, 533.38],
          [71.13, 543.63],
          [98.62, 543.63]
        ]
      }
    ]
  },
  "stylesInfo": {
    "leftStyles": [
      { "color": "#000000", "font": "ArialMT", "emphasis": "", "size": 9.24 }
    ],
    "leftStyleMap": ["0-5"]
  },
  "deletionMark": {
    "pageIndex": 3,
    "point": [98.62, 521.62]
  },
  "viewerProperties": {}
}
```

### Replace

A `replace` change represents text that was changed between the left and right documents.

```json theme={null}
{
  "kind": "replace",
  "leftText": "21",
  "rightText": "20",
  "leftRegion": {
    "pageIndex": 1,
    "rectangles": [
      { "left": 555.07, "top": 371.1, "right": 564.97, "bottom": 383.31 }
    ],
    "regionOutlines": [
      {
        "points": [
          [564.97, 371.1],
          [555.07, 371.1],
          [555.07, 383.31],
          [564.97, 383.31]
        ]
      }
    ]
  },
  "rightRegion": {
    "pageIndex": 1,
    "rectangles": [
      { "left": 555.07, "top": 371.1, "right": 566.45, "bottom": 383.31 }
    ],
    "regionOutlines": [
      {
        "points": [
          [566.45, 371.1],
          [555.07, 371.1],
          [555.07, 383.31],
          [566.45, 383.31]
        ]
      }
    ]
  },
  "stylesInfo": {
    "leftStyles": [
      { "color": "#000000", "font": "ArialMT", "emphasis": "", "size": 11.0 }
    ],
    "rightStyles": [
      { "color": "#000000", "font": "ArialMT", "emphasis": "", "size": 11.0 }
    ],
    "leftStyleMap": ["0-1"],
    "rightStyleMap": ["0-1"]
  },
  "deletionMark": {
    "pageIndex": 1,
    "point": [35.99, 409.32]
  },
  "insertionMark": {
    "pageIndex": 1,
    "point": [35.99, 409.32]
  },
  "viewerProperties": {}
}
```

## Move detection

When Draftable detects that a block of text was **moved** (cut from one location and pasted to another), the individual `insert` and `delete` changes that make up the move are linked together using the `moveId` field. This allows you to distinguish a true move from unrelated insertions and deletions.

### The moveId format

The `moveId` is a string in the format `"{moveGroup}-{subIndex}"`:

| Component   | Description                                                                                                                        |
| ----------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| `moveGroup` | Identifies which move operation this change belongs to. All changes sharing the same `moveGroup` number are part of the same move. |
| `subIndex`  | When a moved block is split across paragraphs or pages, each chunk receives its own sub-index (e.g., `0-0`, `0-1`, `0-2`).         |

Changes that are not part of a move operation will not have a `moveId` field.

### How moves appear in the changes array

A move is represented as **paired** `delete` and `insert` entries:

* A `delete` change with `moveId` — the text was removed from this location in the left document
* An `insert` change with the same `moveId` — the text was placed at this location in the right document

```json theme={null}
// Text moved from page 2 to page 5
{
  "kind": "delete",
  "moveId": "0-0",
  "leftText": "This paragraph was moved to a different section.",
  "leftRegion": {
    "pageIndex": 1,
    "rectangles": [
      { "left": 72.0, "top": 200.0, "right": 540.0, "bottom": 214.0 }
    ],
    "regionOutlines": [...]
  },
  "stylesInfo": { ... },
  "deletionMark": { "pageIndex": 1, "point": [36.0, 207.0] },
  "viewerProperties": {}
}
```

```json theme={null}
{
  "kind": "insert",
  "moveId": "0-0",
  "rightText": "This paragraph was moved to a different section.",
  "rightRegion": {
    "pageIndex": 4,
    "rectangles": [
      { "left": 72.0, "top": 350.0, "right": 540.0, "bottom": 364.0 }
    ],
    "regionOutlines": [...]
  },
  "stylesInfo": { ... },
  "insertionMark": { "pageIndex": 4, "point": [36.0, 357.0] },
  "viewerProperties": {}
}
```

### Gaps in the sub-index sequence

When a moved block also contains **edits** (text that was changed within the moved content), the sub-index sequence will have gaps. For example, you might see `moveId` values of `"0-0"` and `"0-2"` but no `"0-1"`. The gap positions represent portions of the moved text that were edited — those edits appear as regular `replace`, `insert`, or `delete` changes **without** a `moveId`.

Example sequence for a move with internal edits:

| moveId        | Kind                     | Description                                              |
| ------------- | ------------------------ | -------------------------------------------------------- |
| `"0-0"`       | `delete` / `insert` pair | First chunk of moved text (unchanged)                    |
| *(no moveId)* | `replace`                | An edit within the moved text (the "gap" at sub-index 1) |
| `"0-2"`       | `delete` / `insert` pair | Next chunk of moved text (unchanged)                     |

### Reconstructing move regions

Each individual change that is part of a move still carries its own `leftRegion` or `rightRegion` with full bounding box coordinates. To get the complete regions for an entire move operation, group changes by their `moveGroup` and collect the regions:

```python theme={null}
from collections import defaultdict

def group_moves(changes):
    """Group move-related changes by their move group."""
    moves = defaultdict(lambda: {"deletes": [], "inserts": []})

    for change in changes:
        move_id = change.get("moveId")
        if not move_id:
            continue

        move_group = move_id.split("-")[0]

        if change["kind"] == "delete":
            moves[move_group]["deletes"].append(change)
        elif change["kind"] == "insert":
            moves[move_group]["inserts"].append(change)

    return dict(moves)

# Reconstruct left/right regions for each move
for group_id, move_data in group_moves(changes).items():
    left_regions = [c["leftRegion"] for c in move_data["deletes"]]
    right_regions = [c["rightRegion"] for c in move_data["inserts"]]
    print(f"Move {group_id}: {len(left_regions)} source region(s), "
          f"{len(right_regions)} destination region(s)")
```

<Note>
  The `moveId` field is only present on `delete` and `insert` changes that Draftable has identified as part of a move operation. Not all deletions and insertions are moves — only those where the comparison engine has matched the removed text to inserted text elsewhere in the document.
</Note>

## Region objects

Region objects describe the physical location of text on a page. They appear as `leftRegion` and `rightRegion` on change objects. These regions correspond directly to the colored highlight boxes visible in the Draftable viewer and in the highlighted PDF exports available via `s3_links`.

| Field            | Type    | Description                                                                                                                                                                                                                                                                                                                    |
| ---------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `pageIndex`      | integer | Zero-based page number where the text appears                                                                                                                                                                                                                                                                                  |
| `rectangles`     | array   | Bounding rectangles for the text region. Each rectangle has `left`, `top`, `right`, and `bottom` coordinates (in points from the top-left corner of the page). Text spanning multiple lines or non-contiguous areas (such as chart labels) will have multiple rectangles.                                                      |
| `regionOutlines` | array   | Outline polygons for the text region. Each outline has a `points` array of `[x, y]` coordinate pairs defining the exact highlight shape. For simple rectangular regions, this will be a four-point polygon matching the rectangle. For complex or multi-line regions, this defines the precise shape of the highlight overlay. |

<Note>
  Coordinates are measured in **points** (1 point = 1/72 of an inch) from the top-left corner of the page. A standard A4 page is approximately 595 x 842 points. A US Letter page is approximately 612 x 792 points.
</Note>

## Marker objects

Marker objects (`deletionMark` and `insertionMark`) indicate where change markers appear in the document margin. These correspond to the small indicators shown alongside changes in the Draftable viewer and highlighted PDF exports — they allow you to identify which margin marker corresponds to which change.

| Field       | Type    | Description                                                                        |
| ----------- | ------- | ---------------------------------------------------------------------------------- |
| `pageIndex` | integer | Zero-based page number where the marker appears                                    |
| `point`     | array   | An `[x, y]` coordinate pair indicating the marker position on the page (in points) |

## Styles info

The `stylesInfo` object provides font, color, and emphasis data for the text in a change. It allows you to understand the formatting of the text and detect style-only changes.

| Field           | Type  | Description                                                                                                     |
| --------------- | ----- | --------------------------------------------------------------------------------------------------------------- |
| `leftStyles`    | array | Array of style objects applied to the left document text (absent on `insert` changes)                           |
| `rightStyles`   | array | Array of style objects applied to the right document text (absent on `delete` changes)                          |
| `leftStyleMap`  | array | Maps character ranges to styles in `leftStyles` (see below)                                                     |
| `rightStyleMap` | array | Maps character ranges to styles in `rightStyles` (see below)                                                    |
| `styleChanges`  | array | List of style-only changes detected (present on `match` changes where text is identical but formatting differs) |

### Style objects

Each style object in `leftStyles` or `rightStyles` describes the formatting for a range of characters in the **original source document**:

| Field      | Type   | Description                                                                                            |
| ---------- | ------ | ------------------------------------------------------------------------------------------------------ |
| `color`    | string | Hex color code of the text in the original document (e.g., `"#000000"` for black, `"#FF0000"` for red) |
| `font`     | string | Font name (e.g., `"ArialMT"`, `"Arial-BoldMT"`)                                                        |
| `emphasis` | string | Text emphasis: `""` (none), `"bold"`, `"italics"`, or `"bold italics"`                                 |
| `size`     | number | Font size in points                                                                                    |

<Warning>
  The `color` field represents the text color from the **original document**, not the comparison highlight color. For example, if a PDF contains a red annotation comment, its `color` will be `"#FF0000"` because that is the original text color — not because Draftable highlighted it.
</Warning>

### Style map format

The `leftStyleMap` and `rightStyleMap` arrays map character ranges in the text to entries in the corresponding styles array. Each entry is a string in the format `"start-end"`, where `start` and `end` are zero-based character indices (inclusive).

When a text segment has a single style, the style map contains one entry:

```json theme={null}
"leftStyleMap": ["0-12"]
```

When a text segment has multiple styles (e.g., mixed font sizes), the style map contains multiple comma-separated ranges per entry or multiple entries:

```json theme={null}
"leftStyleMap": ["0-25", "26-26"]
```

This means characters 0 through 25 use the first style in `leftStyles`, and character 26 uses the second style.

## Summary object

The `summary` object provides an overview of the comparison results.

```json theme={null}
{
  "anyChanges": true,
  "anyMatches": true,
  "changeSummary": {
    "matches": 998,
    "deletions": 24,
    "insertions": 19,
    "replacements": 67,
    "matchingWords": 16738,
    "deletedLeftWords": 163,
    "replacedLeftWords": 70,
    "insertedRightWords": 139,
    "replacedRightWords": 69,
    "styleChanges": 0
  },
  "leftDocumentSummary": {
    "pageCount": 32,
    "characterCount": 75721,
    "wordCount": 16862
  },
  "rightDocumentSummary": {
    "pageCount": 32,
    "characterCount": 75092,
    "wordCount": 16836
  }
}
```

### Summary fields

| Field        | Type    | Description                                                   |
| ------------ | ------- | ------------------------------------------------------------- |
| `anyChanges` | boolean | `true` if any differences were detected between the documents |
| `anyMatches` | boolean | `true` if any matching text was found between the documents   |

### Change summary fields

| Field                | Type    | Description                                                             |
| -------------------- | ------- | ----------------------------------------------------------------------- |
| `matches`            | integer | Number of matched (unchanged) text segments                             |
| `deletions`          | integer | Number of deleted text segments                                         |
| `insertions`         | integer | Number of inserted text segments                                        |
| `replacements`       | integer | Number of replaced text segments                                        |
| `matchingWords`      | integer | Total word count across all matched segments                            |
| `deletedLeftWords`   | integer | Total word count of deleted text from the left document                 |
| `replacedLeftWords`  | integer | Total word count of replaced text from the left document                |
| `insertedRightWords` | integer | Total word count of inserted text in the right document                 |
| `replacedRightWords` | integer | Total word count of replacement text in the right document              |
| `styleChanges`       | integer | Number of style-only changes (text is identical but formatting differs) |

### Document summary fields

Both `leftDocumentSummary` and `rightDocumentSummary` contain:

| Field            | Type    | Description                           |
| ---------------- | ------- | ------------------------------------- |
| `pageCount`      | integer | Total number of pages in the document |
| `characterCount` | integer | Total character count                 |
| `wordCount`      | integer | Total word count                      |

## How the JSON maps to the visual comparison

The change-details JSON provides the same underlying data that powers the Draftable viewer and highlighted PDF exports. Here is how the key fields relate to what you see visually:

| JSON field                       | Visual representation                                                                                                                                                                                                               |
| -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `kind`                           | Determines the highlight color: deletions and the left side of replacements appear as red strikethrough in the left document; insertions and the right side of replacements appear as colored highlight boxes in the right document |
| `rectangles`                     | Define the exact bounding boxes of each highlight region on the page                                                                                                                                                                |
| `regionOutlines`                 | Define the precise polygon shape of each highlight overlay (important for multi-line or irregularly shaped regions)                                                                                                                 |
| `deletionMark` / `insertionMark` | Correspond to the small margin indicators shown next to each change in the viewer                                                                                                                                                   |
| `stylesInfo`                     | Captures the original document formatting — useful for detecting style-only changes, but does **not** represent comparison highlight colors                                                                                         |

<Tip>
  You can use the `rectangles` coordinates to programmatically draw your own highlight overlays on the original PDFs, or to build custom change navigation (e.g., "jump to change on page 5").
</Tip>

## Storage links

The `s3_links` object contains links for downloading the documents and viewer data files associated with the comparison.

| Key                 | Description                                                                                                                            |
| ------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `left`              | Original left (older) document                                                                                                         |
| `right`             | Original right (newer) document                                                                                                        |
| `left_highlighted`  | Left document with comparison highlights applied (PDF) — deletions shown with red strikethrough, left side of replacements highlighted |
| `right_highlighted` | Right document with comparison highlights applied (PDF) — insertions and right side of replacements shown with colored highlight boxes |
| `scrollmap`         | Scroll synchronization data used by the Draftable viewer                                                                               |
| `changelist`        | Change list data used by the Draftable viewer                                                                                          |

<Note>
  The `left_highlighted` and `right_highlighted` PDFs are the same highlighted documents used in the Draftable combined comparison export. The combined export interleaves them page-by-page (left page 1, right page 1, left page 2, right page 2, etc.).
</Note>

### Link format depends on your storage backend

The form these links take depends on how your instance is configured to store comparison files.

<Tabs>
  <Tab title="Local volume storage (default)">
    A v3 instance stores comparison files on a local volume unless you configure object storage. In this mode each value is a **relative path** on your own instance, under `/api/v1/content/`:

    ```json theme={null}
    {
      "left_highlighted": "/api/v1/content/comparisons/your-account/LxBGpPTO/left/highlighted.pdf",
      "changelist": "/api/v1/content/comparisons/your-account/LxBGpPTO/changes.json"
    }
    ```

    Prepend your instance's base URL to download the file:

    ```bash theme={null}
    curl -H "Authorization: Token your_access_token" \
      -o highlighted.pdf \
      "https://your-server.example.com/api/v1/content/comparisons/your-account/LxBGpPTO/left/highlighted.pdf"
    ```

    These paths do not expire on their own — they remain valid until the comparison itself expires and its files are deleted.
  </Tab>

  <Tab title="S3 object storage">
    If your instance is configured to use S3 for comparison storage, each value is a fully qualified **presigned URL** to the object in your bucket. Presigned URLs are temporary. If one has expired, call the change-details endpoint again to get a fresh set.

    If you have a CloudFront distribution configured in front of your bucket, the presigned URLs are rewritten to use the CloudFront hostname.
  </Tab>
</Tabs>

## Fetching change-details via code (Python)

You can access the change-details endpoint programmatically. Below is an example using Python.

<Note>
  The change-details endpoint is **not** part of any existing Draftable client library. You will need to call it directly using an HTTP client.
</Note>

```python theme={null}
import requests
import json

# Replace with your self-hosted domain, API access token, and comparison ID
base_url = "https://your-server.example.com"
access_token = "your_access_token"
comparison_id = "your_comparison_id"

url = f"{base_url}/api/v1/comparisons/{comparison_id}/change-details"

headers = {
    "Authorization": f"Token {access_token}",
}

response = requests.get(url, headers=headers)

if response.status_code == 200:
    data = response.json()

    # Access the summary
    summary = data["summary"]
    print(f"Changes found: {summary['anyChanges']}")
    print(f"Deletions: {summary['changeSummary']['deletions']}")
    print(f"Insertions: {summary['changeSummary']['insertions']}")
    print(f"Replacements: {summary['changeSummary']['replacements']}")

    # Iterate through changes
    for change in data["changes"]:
        if change["kind"] == "replace":
            print(f"Replaced '{change['leftText']}' with '{change['rightText']}'")
        elif change["kind"] == "insert":
            print(f"Inserted: '{change['rightText']}'")
        elif change["kind"] == "delete":
            print(f"Deleted: '{change['leftText']}'")
elif response.status_code == 202:
    print("Comparison is not ready yet. Check its status and retry.")
else:
    print(f"Request failed with status code: {response.status_code}")
```

## Important considerations

1. **Authentication**: You must include a valid API token in the `Authorization` header. Ensure your token has access to the comparison you are querying.
2. **Comparison must be complete**: The change-details endpoint is only available after a comparison has finished processing. Check the comparison status via the main comparisons endpoint before requesting change details.
3. **Error handling**: Handle these HTTP status codes in your code:
   * `202 Accepted` — The comparison is still processing. The response body advises checking the comparison endpoint for its status before retrying. Treat this as "not ready yet", not as success, and note that a `202` carries no change data.
   * `401 Unauthorized` — Invalid or missing API token
   * `404 Not Found` — The comparison ID does not exist, has expired, belongs to a different account, or the comparison failed
4. **Data privacy**: The response contains the full text content of both compared documents. Ensure appropriate security measures are in place when storing or transmitting this data.
5. **Link expiry**: How long the values in `s3_links` remain usable depends on your storage backend. See [Link format depends on your storage backend](#link-format-depends-on-your-storage-backend).

For more information on other API endpoints, refer to the API documentation served by your own instance.

If you encounter any issues accessing the endpoint or need assistance, reach out to our support team.
