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

# Old-vs-new text for one change

> The section's text before and after this specific change, when available (see `hasDiff` on the change list above). Only meaningful for `amended` (both sides) and `removed` (before only); `added` has nothing to diff against, so `hasBefore`/`hasAfter` are always false there.

A missing side is not an error: `hasBefore`/`hasAfter` say which text is actually present, so a caller can render a graceful 'diff unavailable' state for older changes or a snapshot that failed to capture, instead of treating null as a failure.

**Cost**: 4 credits per call (see `/api-credits/pricing`). This is the only metered route in the alerts family: every other board and watch endpoint, including the `/changes` list this reads from, is free. A diff that resolves NEITHER side is refunded in full and reports `creditsConsumed: 0` -- an empty envelope is not an answer. A one-sided diff IS the complete answer for a `removed` or `added` change and is charged normally.



## OpenAPI

````yaml https://api.vaquill.ai/external/openapi.json get /api/v1/watches/{watch_id}/changes/{change_id}/diff
openapi: 3.1.0
info:
  title: Vaquill Developer API
  description: >-
    Public API for legal statutes and legislation.


    **Authentication**: Pass your API key via the `Authorization: Bearer
    vq_key_...` header.


    **Credits**: Each call costs API credits. See `GET
    /api/v1/api-credits/pricing` for the full pricing matrix.


    ## Jurisdictions


    | Jurisdiction | Coverage | `countryCode` |

    |---|---|---|

    | **United States** | USC, CFR, nearly all 50 state statutory codes (plus DC
    and Puerto Rico), state constitutions, and court rules. | `US` |


    See the full [Coverage page](https://www.vaquill.ai/docs/coverage) for the
    jurisdiction-by-jurisdiction breakdown, or call `/us/statutes/coverage` for
    live counts.


    ## Endpoints


    - **US Statutes**: Search and retrieve USC, CFR, state statutes,
    constitutions, court rules, executive orders, and regulations with full text

    - **Board Watches**: Subscribe to a corpus source and get a webhook or email
    when it refreshes with real changes (free, API key required)

    - **Pricing**: Credit costs per endpoint (no auth required)


    ## Rate limits


    Limits are enforced per API key and scale with your plan. A `429` response
    includes a `Retry-After` header.


    | Plan | Per minute | Per hour | Per day |

    |---|---|---|---|

    | Vaquill API Pro | 30 | 500 | 1,000 |

    | Vaquill API Business | 150 | 2,500 | 10,000 |


    For full documentation, visit the [API
    Reference](https://www.vaquill.ai/docs/api-reference/).
  version: 1.0.0
  contact:
    name: Vaquill API Support
    url: https://www.vaquill.ai
    email: support@vaquill.ai
  license:
    name: Proprietary
    url: https://www.vaquill.ai/terms
  termsOfService: https://www.vaquill.ai/terms
servers:
  - url: https://api.vaquill.ai
    description: Production
security:
  - ApiKeyAuth: []
tags:
  - name: US Statutes
    description: >-
      Search and retrieve US statutes. Covers the United States Code (USC), Code
      of Federal Regulations (CFR), all 50 state statutes, constitutions, court
      rules, executive orders, Federal Register agency rules, agency guidance,
      and state regulations. Scope a search with the `corpusType` filter.


      - **Search**: Search across all USC, CFR, state, and regulatory sections

      - **Section**: Get metadata, citation, hierarchy, and source links for a
      specific section

      - **Body**: Get the full text of a section
  - name: Board Watches
    description: >-
      Law-change alerts. Subscribe to a **board** (a tracked corpus source,
      identified by `corpusType` plus an optional `state`) and get a webhook or
      email whenever it refreshes with real changes, naming the exact sections
      that changed. Fetch old-vs-new text for any amended section via the change
      diff.


      Boards refresh on their own existing cadence; watching one does not change
      how often it refreshes. Every endpoint here is **free**: authenticated by
      API key and rate-limited, but not credit-metered.


      See the [Law Change Alerts
      guide](https://www.vaquill.ai/docs/api-guide/alerts) for the full
      walkthrough.
  - name: Pricing
    description: >-
      Credit pricing and conversion rates. No authentication required. 1 credit
      = $0.01 USD.
externalDocs:
  description: Full API Reference
  url: https://www.vaquill.ai/docs/api-reference/
paths:
  /api/v1/watches/{watch_id}/changes/{change_id}/diff:
    get:
      tags:
        - Board Watches
      summary: Old-vs-new text for one change
      description: >-
        The section's text before and after this specific change, when available
        (see `hasDiff` on the change list above). Only meaningful for `amended`
        (both sides) and `removed` (before only); `added` has nothing to diff
        against, so `hasBefore`/`hasAfter` are always false there.


        A missing side is not an error: `hasBefore`/`hasAfter` say which text is
        actually present, so a caller can render a graceful 'diff unavailable'
        state for older changes or a snapshot that failed to capture, instead of
        treating null as a failure.


        **Cost**: 4 credits per call (see `/api-credits/pricing`). This is the
        only metered route in the alerts family: every other board and watch
        endpoint, including the `/changes` list this reads from, is free. A diff
        that resolves NEITHER side is refunded in full and reports
        `creditsConsumed: 0` -- an empty envelope is not an answer. A one-sided
        diff IS the complete answer for a `removed` or `added` change and is
        charged normally.
      operationId: >-
        get_watch_change_diff_api_v1_watches__watch_id__changes__change_id__diff_get
      parameters:
        - name: watch_id
          in: path
          required: true
          schema:
            type: string
            title: Watch Id
        - name: change_id
          in: path
          required: true
          schema:
            type: integer
            title: Change Id
      responses:
        '200':
          description: The change's before/after text (either side may be absent).
          content:
            application/json:
              schema: {}
              example:
                data:
                  changeId: 91
                  changeKind: amended
                  beforeText: An application for approval of a new drug...
                  afterText: >-
                    An application for approval of a new drug or amended new
                    drug...
                  hasBefore: true
                  hasAfter: true
                meta:
                  processingTimeMs: 41
                  creditsConsumed: 4
        '401':
          description: Invalid or missing API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiDetailError'
        '402':
          description: Insufficient API credits.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiDetailError'
        '403':
          description: API key lacks `research:read` scope.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiDetailError'
        '404':
          description: Watch not found, or the change is not covered by this watch.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiDetailError'
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
        '429':
          description: Rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiDetailError'
components:
  schemas:
    ApiDetailError:
      properties:
        detail:
          type: string
          title: Detail
          description: >-
            Human-readable reason, safe to surface to an end user. Branch on the
            HTTP status rather than on this string: the wording is not part of
            the contract and may be reworded, but 401 (bad key), 402 (out of
            credits), 403 (missing scope), 404 (no such resource) and 429 (rate
            limited) are stable.
          examples:
            - Insufficient API credits.
      type: object
      required:
        - detail
      title: ApiDetailError
      description: |-
        Error envelope the API actually returns.

        All errors (401/402/403/404/422/429/5xx) come back as a single
        `detail` string (FastAPI default), e.g. `{"detail": "Insufficient API
        credits."}`. Documenting the real shape so client code can rely on it.
    HTTPValidationError:
      properties:
        detail:
          items:
            $ref: '#/components/schemas/ValidationError'
          type: array
          title: Detail
      type: object
      title: HTTPValidationError
    ValidationError:
      properties:
        loc:
          items:
            anyOf:
              - type: string
              - type: integer
          type: array
          title: Location
        msg:
          type: string
          title: Message
        type:
          type: string
          title: Error Type
      type: object
      required:
        - loc
        - msg
        - type
      title: ValidationError
  securitySchemes:
    ApiKeyAuth:
      type: http
      scheme: bearer
      bearerFormat: vq_key_*
      description: >-
        API key issued from the developer dashboard. Pass as `Authorization:
        Bearer vq_key_...`

````