curl --request PATCH \
--url https://api.vaquill.ai/api/v1/watches/{watch_id} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"isActive": true,
"webhookUrl": "<string>",
"webhookSecret": "<string>",
"scope": {
"part": "314",
"title": "21"
},
"emailAddress": "<string>",
"webhookAuth": {
"scheme": "none",
"secret": "<string>",
"headerName": "X-Api-Key"
}
}
'import requests
url = "https://api.vaquill.ai/api/v1/watches/{watch_id}"
payload = {
"isActive": True,
"webhookUrl": "<string>",
"webhookSecret": "<string>",
"scope": {
"part": "314",
"title": "21"
},
"emailAddress": "<string>",
"webhookAuth": {
"scheme": "none",
"secret": "<string>",
"headerName": "X-Api-Key"
}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
isActive: true,
webhookUrl: '<string>',
webhookSecret: '<string>',
scope: {part: '314', title: '21'},
emailAddress: '<string>',
webhookAuth: {scheme: 'none', secret: '<string>', headerName: 'X-Api-Key'}
})
};
fetch('https://api.vaquill.ai/api/v1/watches/{watch_id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.vaquill.ai/api/v1/watches/{watch_id}"
payload := strings.NewReader("{\n \"isActive\": true,\n \"webhookUrl\": \"<string>\",\n \"webhookSecret\": \"<string>\",\n \"scope\": {\n \"part\": \"314\",\n \"title\": \"21\"\n },\n \"emailAddress\": \"<string>\",\n \"webhookAuth\": {\n \"scheme\": \"none\",\n \"secret\": \"<string>\",\n \"headerName\": \"X-Api-Key\"\n }\n}")
req, _ := http.NewRequest("PATCH", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}{
"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
}
}{
"detail": "Insufficient API credits."
}{
"detail": "Insufficient API credits."
}{
"detail": "Insufficient API credits."
}{
"detail": "Insufficient API credits."
}{
"detail": "Insufficient API credits."
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>"
}
]
}{
"detail": "Insufficient API credits."
}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.
curl --request PATCH \
--url https://api.vaquill.ai/api/v1/watches/{watch_id} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"isActive": true,
"webhookUrl": "<string>",
"webhookSecret": "<string>",
"scope": {
"part": "314",
"title": "21"
},
"emailAddress": "<string>",
"webhookAuth": {
"scheme": "none",
"secret": "<string>",
"headerName": "X-Api-Key"
}
}
'import requests
url = "https://api.vaquill.ai/api/v1/watches/{watch_id}"
payload = {
"isActive": True,
"webhookUrl": "<string>",
"webhookSecret": "<string>",
"scope": {
"part": "314",
"title": "21"
},
"emailAddress": "<string>",
"webhookAuth": {
"scheme": "none",
"secret": "<string>",
"headerName": "X-Api-Key"
}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
isActive: true,
webhookUrl: '<string>',
webhookSecret: '<string>',
scope: {part: '314', title: '21'},
emailAddress: '<string>',
webhookAuth: {scheme: 'none', secret: '<string>', headerName: 'X-Api-Key'}
})
};
fetch('https://api.vaquill.ai/api/v1/watches/{watch_id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.vaquill.ai/api/v1/watches/{watch_id}"
payload := strings.NewReader("{\n \"isActive\": true,\n \"webhookUrl\": \"<string>\",\n \"webhookSecret\": \"<string>\",\n \"scope\": {\n \"part\": \"314\",\n \"title\": \"21\"\n },\n \"emailAddress\": \"<string>\",\n \"webhookAuth\": {\n \"scheme\": \"none\",\n \"secret\": \"<string>\",\n \"headerName\": \"X-Api-Key\"\n }\n}")
req, _ := http.NewRequest("PATCH", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}{
"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
}
}{
"detail": "Insufficient API credits."
}{
"detail": "Insufficient API credits."
}{
"detail": "Insufficient API credits."
}{
"detail": "Insufficient API credits."
}{
"detail": "Insufficient API credits."
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>"
}
]
}{
"detail": "Insufficient API credits."
}Authorizations
API key issued from the developer dashboard. Pass as Authorization: Bearer vq_key_...
Path Parameters
Body
Pause (false) or resume (true) the watch.
New webhook URL. Only valid on a webhook/both channel watch. Re-validated against the SSRF blocklist. Cannot be cleared.
New signing secret, or empty string to stop signing deliveries. Only valid on a webhook/both channel watch.
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.
Show child attributes
Show child attributes
{ "part": "314", "title": "21" }
New email address. Only valid on an email/both channel watch. Cannot be cleared.
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.
Show child attributes
Show child attributes
Response
The updated watch.
Was this page helpful?

