---
title: "Document comparison"
method: POST
path: "/v1/compare"
tags: ["Document comparison"]
---

# Document comparison

`POST /v1/compare`

## Request

- Base URL: `https://api.thecompound.tech`
- URL: `https://api.thecompound.tech/v1/compare`
- Auth: HTTP bearer

ParseRail compares two versions of a contract or document and returns every material change, what it means, and the risk it carries.

Cost: 15 credits ($0.15) — charged only on success.

Accepts `async: true` for long documents — see the **Async & webhooks** guide.

## Headers

- `ParseRail-Dry-Run` '1' | 'true'
- `Idempotency-Key` string

## Request body

- object
  - `a` object, required: Provide the earlier version as a file, fileUrl, or text.
    - `file` object: Inline document.
      - `data` string, required: Base64-encoded file bytes.
      - `mimeType` string, required
    - `fileUrl` string, uri: Provide a public URL to a PDF or image.
    - `text` string: Provide raw text if you already have it.
  - `b` object, required: Provide the later version as a file, fileUrl, or text.
    - `file` object: Inline document.
      - `data` string, required: Base64-encoded file bytes.
      - `mimeType` string, required
    - `fileUrl` string, uri: Provide a public URL to a PDF or image.
    - `text` string: Provide raw text if you already have it.
  - `async` boolean: The endpoint processes the request outside the request/response cycle. It returns 202 with a `jobId` instead of the result. Poll `GET /v1/jobs/{id}`, or supply `callbackUrl`.
  - `callbackUrl` string, uri: The endpoint POSTs the finished job to a public https URL. The endpoint signs the request with your account's webhook secret, as described in the Async & webhooks guide. The endpoint ignores the URL unless `async` is true.

## Response `200`

The call succeeded. The response contains result fields and a usage envelope. With `ParseRail-Dry-Run: 1` the body is a DryRun object instead.

- union
  - object
    - `changes` object[], required
      - `section` string, required
      - `change` 'added' | 'removed' | 'modified', required
      - `before` string, nullable
      - `after` string, nullable
      - `materiality` 'low' | 'medium' | 'high', required
      - `note` string, required
    - `changeCount` integer, required
    - `summary` string, required
    - `riskNotes` string[], required
    - `usage` Usage, required
      - `credits` integer, required: Credits burned by this call.
      - `balanceRemaining` integer, required: Wallet balance after the charge.
  - DryRun: A dry run: auth, the per-key throttle, body validation and the balance precheck ran. No model ran and nothing was charged.
    - `dryRun` true, required
    - `valid` true, required: The body passed validation. An invalid body returns 400 instead.
    - `endpoint` string, required
    - `wouldCharge` integer, required: Credits a successful live call would charge.
    - `balance` integer, required: Your wallet balance now.
    - `liveStatus` 200 | 202 | 402, required: The status a live call with this body would get: 402 when the balance or the key's monthly cap cannot cover it, 202 for `async: true`, else 200.
    - `keyCapRemaining` integer: Present when the key carries a monthly cap: credits left under it this month.
    - `usage` Usage, required
      - `credits` integer, required: Credits burned by this call.
      - `balanceRemaining` integer, required: Wallet balance after the charge.
    - `requestId` string, required

## Other responses

- `202`: Accepted (`async: true`). The job is queued. Poll `GET /v1/jobs/{id}` or wait for the callback. Credits are charged when it succeeds, never on enqueue.
- `400`: Invalid request body.
- `401`: Missing or invalid API key.
- `402`: `insufficient_credits`: the balance cannot cover the call. `spend_cap_reached`: the key has reached its monthly cap. Nothing is charged.
- `429`: Rate limit exceeded.

---

[API](https://skmtc.dev/thecompound/apis/parserail.md) · [All operations](https://skmtc.dev/thecompound/apis/parserail/llms.txt) · [OpenAPI document](https://skmtc.dev/thecompound/apis/parserail/revisions/7895a3b7812b?raw)
