DiffiCat Compares API

The Compares API from DiffiCat — 1 operation(s) for compares.

Operations 1

POST /compares Compare stored snapshots the account may read, at no charge: name the pairs, or… #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/difficat-com:difficat-com-compares-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

difficat-com-compares-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Difficat Com Compares API
  version: 3.149.0
  description: 'Operations tagged Compares across 2 of this provider''s published API definitions: difficat-com-agent-api-openapi.json, difficat-com-openapi.yml. Each path carries the servers of the definition it was published in.'
servers:
- url: https://app.difficat.com/api/v1
tags:
- name: Compares
paths:
  /compares:
    post:
      operationId: compareSnapshots
      summary: 'Compare stored snapshots the account may read, at no charge: name the pairs, or…'
      security:
      - prepaidKey: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/StoredCompareRequest'
      responses:
        '200':
          description: 'Dry run: the quote, 0.00, with no job started'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DryRunResponse'
              example:
                dryRun: true
                pagesPriced: 3
                amount: '0.06'
                currency: USD
                allowanceRemaining: 40
                freeCovers: true
        '201':
          description: Job started
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SnapshotCompareResponse'
              example:
                jobId: cmp-3c4d5e6f-7a8b-4c9d-8e0f-1a2b3c4d5e6f
                jobToken: dct_Qm9x2kL7pW3nR8vT1yB6cH0jF5sD2aG9eZ4uK7iN3oXb1
                status: running
                pagesCharged: 3
                payment:
                  amount: '0.06'
                  currency: USD
                links:
                  self: https://app.difficat.com/api/v1/jobs/cmp-3c4d5e6f-7a8b-4c9d-8e0f-1a2b3c4d5e6f
                  report: https://app.difficat.com/api/v1/jobs/cmp-3c4d5e6f-7a8b-4c9d-8e0f-1a2b3c4d5e6f/report
                  cancel: https://app.difficat.com/api/v1/jobs/cmp-3c4d5e6f-7a8b-4c9d-8e0f-1a2b3c4d5e6f/cancel
                compareId: cmp-3c4d5e6f-7a8b-4c9d-8e0f-1a2b3c4d5e6f
        '400':
          description: Invalid input, a blocked callbackUrl, or a pair not in the snapshot
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: No key, a share token, or a key with no active account behind it (credential_required or account_key_required)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: No such snapshot, or no access to it
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '409':
          description: The account holds its compare cap (compare_limit) or a snapshot is still capturing (snapshot_not_ready); nothing is charged. A snapshot the account archived answers 404 with snapshot_archived
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: The running-job limit or the hourly limit of unpaid requests for this address (Retry-After)
        '500':
          description: The start failed; a settled charge is final
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '503':
          description: Snapshots are not available on this deployment
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
      tags:
      - Compares
    servers:
    - url: https://app.difficat.com/api/v1
components:
  schemas:
    StoredCompareRequest:
      type: object
      description: Give pairs, or snapshotId with otherSnapshotId.
      properties:
        pairs:
          type: array
          minItems: 1
          maxItems: 200
          description: The snapshots to compare, pair by pair. Pairs may span sets and reuse one snapshot.
          items:
            type: object
            required:
            - a
            - b
            properties:
              a:
                $ref: '#/components/schemas/SnapshotRef'
              b:
                $ref: '#/components/schemas/SnapshotRef'
        snapshotId:
          type: string
          description: Site A, a set the account owns or may read.
        otherSnapshotId:
          type: string
          description: Site B, a set whose pages are paired with Site A’s by path.
        threshold:
          type: number
          minimum: 0
          maximum: 1
          description: '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. When omitted, the snapshot’s stored tolerance applies (snapshot A’s for two snapshots), and the default tolerance when it stored none.'
        maxPriceUsd:
          type: number
          exclusiveMinimum: 0
          description: 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.
        dryRun:
          type: boolean
          description: '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.'
        callbackUrl:
          type: string
          format: uri
          maxLength: 2048
          description: 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.
    Error:
      type: object
      required:
      - error
      properties:
        error:
          type: string
    Payment:
      type: object
      description: What this call was charged. The amount is a decimal USD string ("0.10"); by contrast, the x-payment-info.amount advertised on each paid operation is USD cents as an integer string ("10"). A call settled from a prepaid balance carries rail "prepaid" and the remaining balance. A call paid with a Pro account’s key carries rail "subscription", the captured pages drawn from the included allowance (2 per live pair) and the pages left; its amount is what any leftover balance and overage paid, "0.00" when the allowance covered the call.
      required:
      - amount
      - currency
      properties:
        amount:
          type: string
          example: '0.50'
        currency:
          type: string
        rail:
          type: string
          enum:
          - prepaid
          - subscription
        balance:
          type: string
          description: Remaining prepaid balance, decimal USD.
        pagesFromAllowance:
          type: integer
          description: 'Pro key: captured pages covered by the allowance, 2 per live pair.'
        allowanceRemaining:
          type: integer
          description: 'Pro key: captured pages left in the period.'
    SnapshotRef:
      type: object
      required:
      - snapshotId
      - n
      properties:
        snapshotId:
          type: string
          description: The snapshot set id, snap-<uuid>.
        n:
          type: integer
          description: A page number from the set’s page list.
    SnapshotCompareResponse:
      type: object
      required:
      - jobId
      - jobToken
      - status
      - pagesCharged
      - links
      properties:
        jobId:
          type: string
        jobToken:
          type: string
          description: Bearer token for every later call on this job. Shown once.
        status:
          type: string
          enum:
          - running
        pagesCharged:
          type: integer
          description: The page count the job was charged for; 0 on a free run.
        payment:
          $ref: '#/components/schemas/Payment'
        sample:
          type: boolean
          description: Present and true when the call ran under the free allowance; payment is then absent.
        allowanceRemaining:
          type: integer
          description: 'Free run: the units of this kind left for the address today.'
        links:
          type: object
          properties:
            self:
              type: string
            report:
              type: string
            cancel:
              type: string
        snapshotId:
          type: string
          description: 'The live form: the snapshot that played Site A.'
        compareId:
          type: string
          description: 'The stored form: the saved compare, equal to jobId.'
    DryRunResponse:
      type: object
      required:
      - dryRun
      - pagesPriced
      - amount
      - currency
      properties:
        dryRun:
          type: boolean
          enum:
          - true
        pagesPriced:
          type: integer
          description: The page count the job would be charged for.
        amount:
          type: string
          description: The exact amount the same body without dryRun is charged.
        currency:
          type: string
          enum:
          - USD
        allowanceRemaining:
          type: integer
          description: 'For a request with no credential and no prepaid key: the comparison pages the client address may still run free today, read without consuming any.'
        freeCovers:
          type: boolean
          description: 'For a request with no credential and no prepaid key: true when the same body sent now without dryRun would run free (the priced pages are within allowanceRemaining and the shared daily pool).'
  securitySchemes:
    payment:
      type: http
      scheme: Payment
      description: 'Machine Payments Protocol (mpp.dev). A first request without a credential is answered with 402 and a WWW-Authenticate: Payment challenge; the paid retry carries Authorization: Payment <credential>. Successful responses carry a Payment-Receipt header. x402 clients are accepted on the same routes for USDC on Base.'
    jobToken:
      type: http
      scheme: bearer
      description: The jobToken returned when the job or screenshot was created. The prepaid key that paid a job is accepted in its place.
    prepaidKey:
      type: http
      scheme: bearer
      description: A prepaid key (dck_…) from the account page at /account, where a signed-in human tops up by card through Stripe Checkout and copies the key. On a paid call the priced amount is debited from its balance instead of a 402 challenge; on job reads it stands in for the jobToken of the jobs it paid.
    shareToken:
      type: http
      scheme: bearer
      description: A share token (dcs_…) a snapshot’s owner issued in the web app. It reads that one snapshot and starts live compares against it; it never lists, manages or pays.
    shareTokenHeader:
      type: apiKey
      in: header
      name: X-DiffiCat-Share
      description: The same share token, sent beside a paying Authorization credential (a prepaid or Pro key, or a payment credential) on the two compare routes.
x-refined-from:
- difficat-com-agent-api-openapi.json
- difficat-com-openapi.yml
x-service-info:
  categories:
  - web
  - testing
  - monitoring
  docs:
    homepage: https://difficat.com
    llms: https://difficat.com/llms.txt
    apiReference: https://app.difficat.com/api/v1/openapi.json
  x-prepaid:
    topUp: https://app.difficat.com/account
    amountsUsd:
    - 5
    - 10
    - 25
  x-sample:
    report: https://difficat.com/agents/sample/report.json
    freePages: 40
    freeDiscoveries: 5
    freeScreenshots: 5