> ## 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.

# Update a board watch

> Partially update a watch you own. Omitted fields are left unchanged. Use `isActive: false` to pause and `isActive: true` to resume -- a paused watch is skipped by every future notification but keeps its history and config. `webhookUrl`/`webhookSecret` (webhook/both channel) and `emailAddress` (email/both channel) can be rotated, but not cleared, and not set on a watch whose channel does not use them. To change channel itself, delete and recreate the watch.

**Free.**



## OpenAPI

````yaml https://api.vaquill.ai/external/openapi.json patch /api/v1/watches/{watch_id}
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}:
    patch:
      tags:
        - Board Watches
      summary: Update a board watch
      description: >-
        Partially update a watch you own. Omitted fields are left unchanged. Use
        `isActive: false` to pause and `isActive: true` to resume -- a paused
        watch is skipped by every future notification but keeps its history and
        config. `webhookUrl`/`webhookSecret` (webhook/both channel) and
        `emailAddress` (email/both channel) can be rotated, but not cleared, and
        not set on a watch whose channel does not use them. To change channel
        itself, delete and recreate the watch.


        **Free.**
      operationId: update_watch_api_v1_watches__watch_id__patch
      parameters:
        - name: watch_id
          in: path
          required: true
          schema:
            type: string
            title: Watch Id
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateWatchRequest'
      responses:
        '200':
          description: The updated watch.
          content:
            application/json:
              schema: {}
              example:
                data:
                  id: 9f2b1e0a-1234-4a11-8b1c-abcdef123456
                  corpusType: state
                  state: wa
                  channel: webhook
                  webhookUrl: https://example.com/hooks/law-changes
                  isActive: false
                  createdAt: '2026-08-01T12:00:00Z'
                  updatedAt: '2026-08-07T09:05:00Z'
                  lastNotifiedAt: '2026-08-05T07:00:00Z'
                  lastStatus: 200
                meta:
                  processingTimeMs: 22.7
                  creditsConsumed: 0
        '400':
          description: >-
            Invalid update (field does not apply to this channel, a rejected
            webhook target, or an invalid scope).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiDetailError'
        '401':
          description: Invalid or missing API key.
          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.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiDetailError'
        '409':
          description: >-
            The new scope collides with another watch you already hold on this
            board and channel.
          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:
    UpdateWatchRequest:
      properties:
        isActive:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Isactive
          description: Pause (false) or resume (true) the watch.
        webhookUrl:
          anyOf:
            - type: string
            - type: 'null'
          title: Webhookurl
          description: >-
            New webhook URL. Only valid on a webhook/both channel watch.
            Re-validated against the SSRF blocklist. Cannot be cleared.
        webhookSecret:
          anyOf:
            - type: string
            - type: 'null'
          title: Webhooksecret
          description: >-
            New signing secret, or empty string to stop signing deliveries. Only
            valid on a webhook/both channel watch.
        scope:
          anyOf:
            - additionalProperties:
                type: string
              type: object
            - type: 'null'
          title: Scope
          description: >-
            Optional narrowing so this alert covers one citation instead of an
            entire source. Three mutually exclusive forms.


            **Hierarchy prefix** -- keys `title`, `chapter`, `part`, `section`,
            e.g. `{"title": "21", "part": "314"}` for 21 CFR part 314. Every
            level you set must match, so each one narrows further. `title` is
            required whenever any narrower level is set, and `section` also
            needs `chapter` or `part`: a bare part number matches across
            unrelated titles. Only sources whose documents carry a
            title/chapter/part hierarchy accept this form; the rest return 400.


            **Exact section** -- `{"actId": "CFR_T21_P314_S314_50"}`, using the
            `actId` returned by search results and change events.
            Case-sensitive, and validated at create time against the corpus: an
            act_id we do not hold, or one belonging to a different source, is a
            400 rather than a watch that could never fire. This form works on
            EVERY source, including flat ones with no hierarchy, so it is the
            only way to follow a single Federal Register document.


            Omit entirely to watch the whole source, which is the default and
            the pre-existing behavior.


            **Named source** -- `{"source": "fdic_fil"}`, for the corpora that
            fold several independent bodies of law behind one `corpusType`.
            `agency_guidance` alone carries 30 named sources across 16 agencies,
            so an unscoped watch on it delivers FDIC letters, IRS notices, USPTO
            examining procedure and DOE appliance standards together. The
            vocabulary is exactly the `source` filter published on `POST
            /us/statutes/search`. Accepted on `agency_guidance`,
            `agency_manuals` and `cfr` (where it selects FAR or DFARS, which
            share every hierarchy field and are distinguishable only by source);
            anything else returns 400.
          examples:
            - part: '314'
              title: '21'
        emailAddress:
          anyOf:
            - type: string
            - type: 'null'
          title: Emailaddress
          description: >-
            New email address. Only valid on an email/both channel watch. Cannot
            be cleared.
        webhookAuth:
          anyOf:
            - $ref: '#/components/schemas/WebhookAuthRequest'
            - type: 'null'
          description: >-
            Replace the outbound credential config. Sent as a whole object, not
            field by field: a scheme without a credential is not a partial edit,
            it is a broken config. Send `{"scheme": "none"}` to remove auth
            entirely. Keeping the same scheme and omitting `secret` retains the
            stored credential, so you can rename a header without re-entering
            the token.
      type: object
      title: UpdateWatchRequest
    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
    WebhookAuthRequest:
      properties:
        scheme:
          type: string
          enum:
            - none
            - bearer
            - basic
            - header
          title: Scheme
          description: >-
            `bearer` sends `Authorization: Bearer <secret>`. `basic` sends
            `Authorization: Basic <secret>` with the secret already
            base64-encoded by you. `header` sends `<headerName>: <secret>`, for
            gateways that read something like `X-Api-Key`. `none` removes any
            credential currently stored.
          default: none
        secret:
          anyOf:
            - type: string
            - type: 'null'
          title: Secret
          description: >-
            The credential value. Stored encrypted and never returned. Required
            when setting a scheme for the first time or changing scheme; on
            PATCH you may omit it to keep the stored one while changing only
            `headerName`.
        headerName:
          anyOf:
            - type: string
            - type: 'null'
          title: Headername
          description: >-
            Header to send the credential on. Required for `header`, and
            rejected for every other scheme. Cannot be `Authorization` (use
            `bearer`/`basic`), a transport header, or one of ours.
          examples:
            - X-Api-Key
      type: object
      title: WebhookAuthRequest
      description: |-
        How a delivery should authenticate itself to your endpoint.

        SEPARATE FROM `webhookSecret`, and the distinction is the point.
        `webhookSecret` signs the body so you can prove it is intact and ours.
        This sends a credential so your gateway can reject anything else before
        it reaches your handler. Most integrations want the second, many want
        both, and the two are set independently.
    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_...`

````