[{"data":1,"prerenderedAt":1463},["ShallowReactive",2],{"doc:\u002Fv\u002F2026.3\u002Fbuild-with-ai\u002Frest-hooks-reference":3},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"section":10,"version":11,"lastUpdated":12,"body":13,"_type":1457,"_id":1458,"_source":1459,"_file":1460,"_stem":1461,"_extension":1462},"\u002Fv\u002F2026.3\u002Fbuild-with-ai\u002Frest-hooks-reference","build-with-ai",false,"","REST hooks reference (\u002Fv1\u002Fhooks)","Subscribe a URL to Workspace369 events with a personal access token, list and delete hooks, and fetch a sample event for a test trigger.","Build with AI","2026.3","2026-11-06",{"type":14,"children":15,"toc":1443},"root",[16,41,60,67,173,186,192,308,320,325,331,340,352,358,367,379,469,482,493,506,549,585,591,600,609,677,689,714,720,729,734,769,778,810,819,872,878,887,896,908,919,925,937,1025,1037,1043,1055,1333,1339,1399,1405],{"type":17,"tag":18,"props":19,"children":20},"element","p",{},[21,24,31,33,39],{"type":22,"value":23},"text","REST hooks let an automation platform such as Zapier, Make or n8n subscribe to Workspace369 events with a personal access token, without anyone opening the app. The Workspace369 app for Zapier (beta) uses them to start a Zap instantly; see ",{"type":17,"tag":25,"props":26,"children":28},"a",{"href":27},"\u002Fv\u002F2026.3\u002Fbuild-with-ai\u002Fconnect-zapier\u002F",[29],{"type":22,"value":30},"Connect Workspace369 to Zapier",{"type":22,"value":32},". The platform creates a hook when a user turns its flow on and deletes it when they turn it off. Workspace369 then sends each event to the hook's URL, signed, exactly like a webhook made in ",{"type":17,"tag":34,"props":35,"children":36},"strong",{},[37],{"type":22,"value":38},"Settings → Webhooks",{"type":22,"value":40},".",{"type":17,"tag":18,"props":42,"children":43},{},[44,46,50,52,58],{"type":22,"value":45},"A hook is a webhook. It shows up in ",{"type":17,"tag":34,"props":47,"children":48},{},[49],{"type":22,"value":38},{"type":22,"value":51},", uses the same 27 events, the same signature headers and the same retries. See the ",{"type":17,"tag":25,"props":53,"children":55},{"href":54},"\u002Fv\u002F2026.3\u002Fbuild-with-ai\u002Fwebhooks-reference\u002F",[56],{"type":22,"value":57},"Webhooks reference",{"type":22,"value":59}," for the payload, the signature check and retry behavior.",{"type":17,"tag":61,"props":62,"children":64},"h2",{"id":63},"who-can-use-it",[65],{"type":22,"value":66},"Who can use it",{"type":17,"tag":68,"props":69,"children":70},"ul",{},[71,100,119,139,144],{"type":17,"tag":72,"props":73,"children":74},"li",{},[75,77,84,86,92,94,98],{"type":22,"value":76},"Every paid plan (Cadet and up), including the 14-day trial once the card is saved. A workspace with no plan gets ",{"type":17,"tag":78,"props":79,"children":81},"code",{"className":80},[],[82],{"type":22,"value":83},"403",{"type":22,"value":85}," with ",{"type":17,"tag":78,"props":87,"children":89},{"className":88},[],[90],{"type":22,"value":91},"plan_required",{"type":22,"value":93}," when it creates, lists or samples hooks; it can still delete them. A webhook you add in ",{"type":17,"tag":34,"props":95,"children":96},{},[97],{"type":22,"value":38},{"type":22,"value":99}," works on the same plans.",{"type":17,"tag":72,"props":101,"children":102},{},[103,105,110,112,117],{"type":22,"value":104},"An admin must turn on AI connections for the workspace (",{"type":17,"tag":34,"props":106,"children":107},{},[108],{"type":22,"value":109},"Allow AI connections",{"type":22,"value":111}," under ",{"type":17,"tag":34,"props":113,"children":114},{},[115],{"type":22,"value":116},"AI connections",{"type":22,"value":118},").",{"type":17,"tag":72,"props":120,"children":121},{},[122,124,130,132,137],{"type":22,"value":123},"A personal access token (it starts with ",{"type":17,"tag":78,"props":125,"children":127},{"className":126},[],[128],{"type":22,"value":129},"mcp_pat_",{"type":22,"value":131},") with the ",{"type":17,"tag":34,"props":133,"children":134},{},[135],{"type":22,"value":136},"webhooks:manage",{"type":22,"value":138}," scope. Sign-in tokens from Claude or ChatGPT can't call these routes.",{"type":17,"tag":72,"props":140,"children":141},{},[142],{"type":22,"value":143},"You need the Manage webhooks permission yourself, which Managers and above have. A token never does more than your own role allows.",{"type":17,"tag":72,"props":145,"children":146},{},[147,149,155,157,163,165,171],{"type":22,"value":148},"Some events need more, because they carry people's details. A ",{"type":17,"tag":78,"props":150,"children":152},{"className":151},[],[153],{"type":22,"value":154},"lead.*",{"type":22,"value":156}," event needs access to Requests. A ",{"type":17,"tag":78,"props":158,"children":160},{"className":159},[],[161],{"type":22,"value":162},"booking.*",{"type":22,"value":164}," event needs access to the calendar and to every client's appointments. A ",{"type":17,"tag":78,"props":166,"children":168},{"className":167},[],[169],{"type":22,"value":170},"client.*",{"type":22,"value":172}," event needs you to see every client, not only your own. Owners and admins have all of these.",{"type":17,"tag":18,"props":174,"children":175},{},[176,178,184],{"type":22,"value":177},"Hook calls are free: they don't count toward AI usage. They count toward the ",{"type":17,"tag":78,"props":179,"children":181},{"className":180},[],[182],{"type":22,"value":183},"\u002Fv1",{"type":22,"value":185}," rate limit of 120 requests a minute per token and 600 a minute per workspace.",{"type":17,"tag":61,"props":187,"children":189},{"id":188},"create-a-token",[190],{"type":22,"value":191},"Create a token",{"type":17,"tag":193,"props":194,"children":195},"ol",{},[196,220,238,250,280,296],{"type":17,"tag":72,"props":197,"children":198},{},[199,201,206,208,213,215,219],{"type":22,"value":200},"Open ",{"type":17,"tag":34,"props":202,"children":203},{},[204],{"type":22,"value":205},"Settings",{"type":22,"value":207},", then under ",{"type":17,"tag":34,"props":209,"children":210},{},[211],{"type":22,"value":212},"AI",{"type":22,"value":214}," choose ",{"type":17,"tag":34,"props":216,"children":217},{},[218],{"type":22,"value":116},{"type":22,"value":40},{"type":17,"tag":72,"props":221,"children":222},{},[223,225,230,232,237],{"type":22,"value":224},"Under ",{"type":17,"tag":34,"props":226,"children":227},{},[228],{"type":22,"value":229},"Personal access tokens",{"type":22,"value":231},", choose ",{"type":17,"tag":34,"props":233,"children":234},{},[235],{"type":22,"value":236},"Create token",{"type":22,"value":40},{"type":17,"tag":72,"props":239,"children":240},{},[241,243,248],{"type":22,"value":242},"Enter a ",{"type":17,"tag":34,"props":244,"children":245},{},[246],{"type":22,"value":247},"Token name",{"type":22,"value":249}," that says what will use it, such as \"Zapier\".",{"type":17,"tag":72,"props":251,"children":252},{},[253,254,259,261,266,268,273,275,279],{"type":22,"value":224},{"type":17,"tag":34,"props":255,"children":256},{},[257],{"type":22,"value":258},"Permissions",{"type":22,"value":260},", select the scopes for any actions the platform will also run, such as ",{"type":17,"tag":34,"props":262,"children":263},{},[264],{"type":22,"value":265},"clients:write",{"type":22,"value":267},". Then, below them under ",{"type":17,"tag":34,"props":269,"children":270},{},[271],{"type":22,"value":272},"Automation triggers",{"type":22,"value":274}," (\"Lets Zapier, Make and n8n start your automations when something happens.\"), select ",{"type":17,"tag":34,"props":276,"children":277},{},[278],{"type":22,"value":136},{"type":22,"value":40},{"type":17,"tag":72,"props":281,"children":282},{},[283,284,289,291,295],{"type":22,"value":224},{"type":17,"tag":34,"props":285,"children":286},{},[287],{"type":22,"value":288},"Expiry",{"type":22,"value":290},", choose how long the token lasts, then choose ",{"type":17,"tag":34,"props":292,"children":293},{},[294],{"type":22,"value":236},{"type":22,"value":40},{"type":17,"tag":72,"props":297,"children":298},{},[299,301,306],{"type":22,"value":300},"In the ",{"type":17,"tag":34,"props":302,"children":303},{},[304],{"type":22,"value":305},"Token created",{"type":22,"value":307}," dialog, copy the value and store it. It is not shown again.",{"type":17,"tag":18,"props":309,"children":310},{},[311,313,318],{"type":22,"value":312},"See ",{"type":17,"tag":25,"props":314,"children":316},{"href":315},"\u002Fv\u002F2026.3\u002Fai-connections\u002Fpersonal-access-tokens\u002F",[317],{"type":22,"value":229},{"type":22,"value":319}," for expiry, review and revoking.",{"type":17,"tag":18,"props":321,"children":322},{},[323],{"type":22,"value":324},"The token works in the workspace you had open when you created it. Every hook it creates belongs to that workspace.",{"type":17,"tag":61,"props":326,"children":328},{"id":327},"base-url",[329],{"type":22,"value":330},"Base URL",{"type":17,"tag":18,"props":332,"children":333},{},[334],{"type":17,"tag":78,"props":335,"children":337},{"className":336},[],[338],{"type":22,"value":339},"https:\u002F\u002Fmcp.workspace369.com\u002Fv1",{"type":17,"tag":18,"props":341,"children":342},{},[343,345,351],{"type":22,"value":344},"Send the token on every call: ",{"type":17,"tag":78,"props":346,"children":348},{"className":347},[],[349],{"type":22,"value":350},"Authorization: Bearer mcp_pat_…",{"type":22,"value":40},{"type":17,"tag":61,"props":353,"children":355},{"id":354},"create-a-hook",[356],{"type":22,"value":357},"Create a hook",{"type":17,"tag":18,"props":359,"children":360},{},[361],{"type":17,"tag":78,"props":362,"children":364},{"className":363},[],[365],{"type":22,"value":366},"POST \u002Fv1\u002Fhooks",{"type":17,"tag":368,"props":369,"children":374},"pre",{"className":370,"code":372,"language":373,"meta":7},[371],"language-bash","curl -s https:\u002F\u002Fmcp.workspace369.com\u002Fv1\u002Fhooks \\\n  -H \"Authorization: Bearer $W369_TOKEN\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"target_url\":\"https:\u002F\u002Fhooks.example.com\u002Fw369\",\"events\":[\"invoice.paid\"]}'\n","bash",[375],{"type":17,"tag":78,"props":376,"children":377},{"__ignoreMap":7},[378],{"type":22,"value":372},{"type":17,"tag":380,"props":381,"children":382},"table",{},[383,407],{"type":17,"tag":384,"props":385,"children":386},"thead",{},[387],{"type":17,"tag":388,"props":389,"children":390},"tr",{},[391,397,402],{"type":17,"tag":392,"props":393,"children":394},"th",{},[395],{"type":22,"value":396},"Field",{"type":17,"tag":392,"props":398,"children":399},{},[400],{"type":22,"value":401},"Required",{"type":17,"tag":392,"props":403,"children":404},{},[405],{"type":22,"value":406},"Notes",{"type":17,"tag":408,"props":409,"children":410},"tbody",{},[411,442],{"type":17,"tag":388,"props":412,"children":413},{},[414,424,429],{"type":17,"tag":415,"props":416,"children":417},"td",{},[418],{"type":17,"tag":78,"props":419,"children":421},{"className":420},[],[422],{"type":22,"value":423},"target_url",{"type":17,"tag":415,"props":425,"children":426},{},[427],{"type":22,"value":428},"Yes",{"type":17,"tag":415,"props":430,"children":431},{},[432,434,440],{"type":22,"value":433},"An ",{"type":17,"tag":78,"props":435,"children":437},{"className":436},[],[438],{"type":22,"value":439},"https:\u002F\u002F",{"type":22,"value":441}," address on the standard port, with no username or password, on a public host.",{"type":17,"tag":388,"props":443,"children":444},{},[445,454,458],{"type":17,"tag":415,"props":446,"children":447},{},[448],{"type":17,"tag":78,"props":449,"children":451},{"className":450},[],[452],{"type":22,"value":453},"events",{"type":17,"tag":415,"props":455,"children":456},{},[457],{"type":22,"value":428},{"type":17,"tag":415,"props":459,"children":460},{},[461,463,468],{"type":22,"value":462},"One or more event names from the ",{"type":17,"tag":25,"props":464,"children":465},{"href":54},[466],{"type":22,"value":467},"event list",{"type":22,"value":40},{"type":17,"tag":18,"props":470,"children":471},{},[472,474,480],{"type":22,"value":473},"The answer is ",{"type":17,"tag":78,"props":475,"children":477},{"className":476},[],[478],{"type":22,"value":479},"201",{"type":22,"value":481},":",{"type":17,"tag":368,"props":483,"children":488},{"className":484,"code":486,"language":487,"meta":7},[485],"language-json","{\n  \"id\": \"Wq3…\",\n  \"target_url\": \"https:\u002F\u002Fhooks.example.com\u002Fw369\",\n  \"events\": [\"invoice.paid\"],\n  \"active\": true,\n  \"secret\": \"whsec_…\",\n  \"reused\": false\n}\n","json",[489],{"type":17,"tag":78,"props":490,"children":491},{"__ignoreMap":7},[492],{"type":22,"value":486},{"type":17,"tag":18,"props":494,"children":495},{},[496,498,504],{"type":22,"value":497},"Store ",{"type":17,"tag":78,"props":499,"children":501},{"className":500},[],[502],{"type":22,"value":503},"secret",{"type":22,"value":505}," now. It is the signing secret for this hook, and it is returned only here.",{"type":17,"tag":18,"props":507,"children":508},{},[509,511,516,518,524,526,532,534,539,541,547],{"type":22,"value":510},"If an active hook with the same ",{"type":17,"tag":78,"props":512,"children":514},{"className":513},[],[515],{"type":22,"value":423},{"type":22,"value":517}," and the same events already exists, the answer is ",{"type":17,"tag":78,"props":519,"children":521},{"className":520},[],[522],{"type":22,"value":523},"200",{"type":22,"value":525}," with that hook, ",{"type":17,"tag":78,"props":527,"children":529},{"className":528},[],[530],{"type":22,"value":531},"\"reused\": true",{"type":22,"value":533}," and a ",{"type":17,"tag":34,"props":535,"children":536},{},[537],{"type":22,"value":538},"new",{"type":22,"value":540}," secret. This happens when a platform retries a subscribe. The answer also has a ",{"type":17,"tag":78,"props":542,"children":544},{"className":543},[],[545],{"type":22,"value":546},"message",{"type":22,"value":548}," saying so. The previous secret stops working, so always keep the latest one.",{"type":17,"tag":18,"props":550,"children":551},{},[552,554,560,561,567,569,575,577,583],{"type":22,"value":553},"A workspace has a webhook limit, and it counts the webhooks made in the app too. Past it, the answer is ",{"type":17,"tag":78,"props":555,"children":557},{"className":556},[],[558],{"type":22,"value":559},"409",{"type":22,"value":85},{"type":17,"tag":78,"props":562,"children":564},{"className":563},[],[565],{"type":22,"value":566},"details.reason",{"type":22,"value":568}," set to ",{"type":17,"tag":78,"props":570,"children":572},{"className":571},[],[573],{"type":22,"value":574},"limit_reached",{"type":22,"value":576}," and ",{"type":17,"tag":78,"props":578,"children":580},{"className":579},[],[581],{"type":22,"value":582},"details.limit",{"type":22,"value":584}," holding the limit. Delete a hook you no longer use, then try again.",{"type":17,"tag":61,"props":586,"children":588},{"id":587},"list-hooks",[589],{"type":22,"value":590},"List hooks",{"type":17,"tag":18,"props":592,"children":593},{},[594],{"type":17,"tag":78,"props":595,"children":597},{"className":596},[],[598],{"type":22,"value":599},"GET \u002Fv1\u002Fhooks",{"type":17,"tag":368,"props":601,"children":604},{"className":602,"code":603,"language":373,"meta":7},[371],"curl -s \"https:\u002F\u002Fmcp.workspace369.com\u002Fv1\u002Fhooks?target_url=https:\u002F\u002Fhooks.example.com\u002Fw369\" \\\n  -H \"Authorization: Bearer $W369_TOKEN\"\n",[605],{"type":17,"tag":78,"props":606,"children":607},{"__ignoreMap":7},[608],{"type":22,"value":603},{"type":17,"tag":18,"props":610,"children":611},{},[612,614,619,620,626,628,634,636,641,642,647,648,654,655,661,662,668,669,675],{"type":22,"value":613},"Returns ",{"type":17,"tag":78,"props":615,"children":617},{"className":616},[],[618],{"type":22,"value":523},{"type":22,"value":85},{"type":17,"tag":78,"props":621,"children":623},{"className":622},[],[624],{"type":22,"value":625},"{\"hooks\":[…]}",{"type":22,"value":627},". Each hook has ",{"type":17,"tag":78,"props":629,"children":631},{"className":630},[],[632],{"type":22,"value":633},"id",{"type":22,"value":635},", ",{"type":17,"tag":78,"props":637,"children":639},{"className":638},[],[640],{"type":22,"value":423},{"type":22,"value":635},{"type":17,"tag":78,"props":643,"children":645},{"className":644},[],[646],{"type":22,"value":453},{"type":22,"value":635},{"type":17,"tag":78,"props":649,"children":651},{"className":650},[],[652],{"type":22,"value":653},"active",{"type":22,"value":635},{"type":17,"tag":78,"props":656,"children":658},{"className":657},[],[659],{"type":22,"value":660},"disabled_reason",{"type":22,"value":635},{"type":17,"tag":78,"props":663,"children":665},{"className":664},[],[666],{"type":22,"value":667},"created_at",{"type":22,"value":576},{"type":17,"tag":78,"props":670,"children":672},{"className":671},[],[673],{"type":22,"value":674},"last_delivery_at",{"type":22,"value":676},". The secret is never listed.",{"type":17,"tag":18,"props":678,"children":679},{},[680,682,687],{"type":22,"value":681},"The optional ",{"type":17,"tag":78,"props":683,"children":685},{"className":684},[],[686],{"type":22,"value":423},{"type":22,"value":688}," filter matches the address exactly. Use it to check whether a hook for your URL already exists.",{"type":17,"tag":18,"props":690,"children":691},{},[692,697,699,705,707,712],{"type":17,"tag":78,"props":693,"children":695},{"className":694},[],[696],{"type":22,"value":653},{"type":22,"value":698}," is ",{"type":17,"tag":78,"props":700,"children":702},{"className":701},[],[703],{"type":22,"value":704},"false",{"type":22,"value":706}," when the hook was switched off, and ",{"type":17,"tag":78,"props":708,"children":710},{"className":709},[],[711],{"type":22,"value":660},{"type":22,"value":713}," says why, for example when its address can't be reached safely.",{"type":17,"tag":61,"props":715,"children":717},{"id":716},"get-a-sample-event",[718],{"type":22,"value":719},"Get a sample event",{"type":17,"tag":18,"props":721,"children":722},{},[723],{"type":17,"tag":78,"props":724,"children":726},{"className":725},[],[727],{"type":22,"value":728},"GET \u002Fv1\u002Fhooks\u002Fsample?event=invoice.paid",{"type":17,"tag":18,"props":730,"children":731},{},[732],{"type":22,"value":733},"Platforms use this for their \"test trigger\" step, so a user can map fields before a real event happens.",{"type":17,"tag":68,"props":735,"children":736},{},[737,756],{"type":17,"tag":72,"props":738,"children":739},{},[740,742,748,749,755],{"type":22,"value":741},"For the workspace owner and admins, the answer is the most recent real delivery of that event from the last 30 days, with ",{"type":17,"tag":78,"props":743,"children":745},{"className":744},[],[746],{"type":22,"value":747},"\"sample\": false",{"type":22,"value":576},{"type":17,"tag":78,"props":750,"children":752},{"className":751},[],[753],{"type":22,"value":754},"delivered_at",{"type":22,"value":40},{"type":17,"tag":72,"props":757,"children":758},{},[759,761,767],{"type":22,"value":760},"Otherwise, or when there is no recent delivery, the answer is a made-up event with ",{"type":17,"tag":78,"props":762,"children":764},{"className":763},[],[765],{"type":22,"value":766},"\"sample\": true",{"type":22,"value":768},". It has the same envelope and field names as a real one, with placeholder values.",{"type":17,"tag":368,"props":770,"children":773},{"className":771,"code":772,"language":373,"meta":7},[371],"curl -s \"https:\u002F\u002Fmcp.workspace369.com\u002Fv1\u002Fhooks\u002Fsample?event=invoice.paid\" \\\n  -H \"Authorization: Bearer $W369_TOKEN\"\n",[774],{"type":17,"tag":78,"props":775,"children":776},{"__ignoreMap":7},[777],{"type":22,"value":772},{"type":17,"tag":18,"props":779,"children":780},{},[781,782,787,789,793,795,801,803,808],{"type":22,"value":473},{"type":17,"tag":78,"props":783,"children":785},{"className":784},[],[786],{"type":22,"value":523},{"type":22,"value":788},". It is the event envelope from the ",{"type":17,"tag":25,"props":790,"children":791},{"href":54},[792],{"type":22,"value":57},{"type":22,"value":794},", with ",{"type":17,"tag":78,"props":796,"children":798},{"className":797},[],[799],{"type":22,"value":800},"sample",{"type":22,"value":802}," added, and ",{"type":17,"tag":78,"props":804,"children":806},{"className":805},[],[807],{"type":22,"value":754},{"type":22,"value":809}," (milliseconds since 1970) when it is a real delivery:",{"type":17,"tag":368,"props":811,"children":814},{"className":812,"code":813,"language":487,"meta":7},[485],"{\n  \"sample\": true,\n  \"webhook_id\": \"…\",\n  \"event_type\": \"invoice.paid\",\n  \"entity_id\": \"sample_invoice\",\n  \"workspace_id\": \"…\",\n  \"subscription_id\": \"…\",\n  \"data\": { \"id\": \"sample_invoice\", \"is_paid\": true, \"invoice_status\": \"Paid\" }\n}\n",[815],{"type":17,"tag":78,"props":816,"children":817},{"__ignoreMap":7},[818],{"type":22,"value":813},{"type":17,"tag":18,"props":820,"children":821},{},[822,824,830,831,837,839,844,845,850,852,857,859,864,865,871],{"type":22,"value":823},"An unknown event name returns ",{"type":17,"tag":78,"props":825,"children":827},{"className":826},[],[828],{"type":22,"value":829},"422",{"type":22,"value":85},{"type":17,"tag":78,"props":832,"children":834},{"className":833},[],[835],{"type":22,"value":836},"invalid_request",{"type":22,"value":838}," and the list of valid names. A ",{"type":17,"tag":78,"props":840,"children":842},{"className":841},[],[843],{"type":22,"value":154},{"type":22,"value":635},{"type":17,"tag":78,"props":846,"children":848},{"className":847},[],[849],{"type":22,"value":162},{"type":22,"value":851}," or ",{"type":17,"tag":78,"props":853,"children":855},{"className":854},[],[856],{"type":22,"value":170},{"type":22,"value":858}," sample needs the same access as subscribing to that event does; without it the answer is ",{"type":17,"tag":78,"props":860,"children":862},{"className":861},[],[863],{"type":22,"value":83},{"type":22,"value":85},{"type":17,"tag":78,"props":866,"children":868},{"className":867},[],[869],{"type":22,"value":870},"forbidden",{"type":22,"value":40},{"type":17,"tag":61,"props":873,"children":875},{"id":874},"delete-a-hook",[876],{"type":22,"value":877},"Delete a hook",{"type":17,"tag":18,"props":879,"children":880},{},[881],{"type":17,"tag":78,"props":882,"children":884},{"className":883},[],[885],{"type":22,"value":886},"DELETE \u002Fv1\u002Fhooks\u002F{id}",{"type":17,"tag":368,"props":888,"children":891},{"className":889,"code":890,"language":373,"meta":7},[371],"curl -s -X DELETE https:\u002F\u002Fmcp.workspace369.com\u002Fv1\u002Fhooks\u002FWq3… \\\n  -H \"Authorization: Bearer $W369_TOKEN\"\n",[892],{"type":17,"tag":78,"props":893,"children":894},{"__ignoreMap":7},[895],{"type":22,"value":890},{"type":17,"tag":18,"props":897,"children":898},{},[899,900,906],{"type":22,"value":613},{"type":17,"tag":78,"props":901,"children":903},{"className":902},[],[904],{"type":22,"value":905},"204",{"type":22,"value":907},", also when the hook is already gone. Events stop at once. A platform retrying an unsubscribe is never told it failed.",{"type":17,"tag":18,"props":909,"children":910},{},[911,913,917],{"type":22,"value":912},"A workspace that has dropped to no plan can still delete its hooks, through the API or in ",{"type":17,"tag":34,"props":914,"children":915},{},[916],{"type":22,"value":38},{"type":22,"value":918},", so turning off a Zap still removes its hook. Its hooks keep sending events while it has any plan.",{"type":17,"tag":61,"props":920,"children":922},{"id":921},"signature-headers",[923],{"type":22,"value":924},"Signature headers",{"type":17,"tag":18,"props":926,"children":927},{},[928,930,935],{"type":22,"value":929},"Every event sent to a hook is signed with the hook's ",{"type":17,"tag":78,"props":931,"children":933},{"className":932},[],[934],{"type":22,"value":503},{"type":22,"value":936},", exactly like an event sent to a webhook made in the app:",{"type":17,"tag":380,"props":938,"children":939},{},[940,956],{"type":17,"tag":384,"props":941,"children":942},{},[943],{"type":17,"tag":388,"props":944,"children":945},{},[946,951],{"type":17,"tag":392,"props":947,"children":948},{},[949],{"type":22,"value":950},"Header",{"type":17,"tag":392,"props":952,"children":953},{},[954],{"type":22,"value":955},"Value",{"type":17,"tag":408,"props":957,"children":958},{},[959,976,993],{"type":17,"tag":388,"props":960,"children":961},{},[962,971],{"type":17,"tag":415,"props":963,"children":964},{},[965],{"type":17,"tag":78,"props":966,"children":968},{"className":967},[],[969],{"type":22,"value":970},"X-Webhook-Id",{"type":17,"tag":415,"props":972,"children":973},{},[974],{"type":22,"value":975},"A unique id for this event. The same event has the same id on every retry.",{"type":17,"tag":388,"props":977,"children":978},{},[979,988],{"type":17,"tag":415,"props":980,"children":981},{},[982],{"type":17,"tag":78,"props":983,"children":985},{"className":984},[],[986],{"type":22,"value":987},"X-Webhook-Timestamp",{"type":17,"tag":415,"props":989,"children":990},{},[991],{"type":22,"value":992},"The send time in milliseconds since 1970, as text.",{"type":17,"tag":388,"props":994,"children":995},{},[996,1005],{"type":17,"tag":415,"props":997,"children":998},{},[999],{"type":17,"tag":78,"props":1000,"children":1002},{"className":1001},[],[1003],{"type":22,"value":1004},"X-Webhook-Signature",{"type":17,"tag":415,"props":1006,"children":1007},{},[1008,1010,1015,1017,1023],{"type":22,"value":1009},"The hex HMAC-SHA256 of the raw request body followed by the timestamp text, using the whole ",{"type":17,"tag":78,"props":1011,"children":1013},{"className":1012},[],[1014],{"type":22,"value":503},{"type":22,"value":1016}," (with its ",{"type":17,"tag":78,"props":1018,"children":1020},{"className":1019},[],[1021],{"type":22,"value":1022},"whsec_",{"type":22,"value":1024}," prefix) as the key.",{"type":17,"tag":18,"props":1026,"children":1027},{},[1028,1030,1035],{"type":22,"value":1029},"Compute it over the raw bytes you received, and reject an event whose timestamp is more than five minutes from now. Each retry is signed again with a fresh timestamp. The ",{"type":17,"tag":25,"props":1031,"children":1033},{"href":1032},"\u002Fv\u002F2026.3\u002Fbuild-with-ai\u002Fwebhooks-reference\u002F#verify-the-signature",[1034],{"type":22,"value":57},{"type":22,"value":1036}," has a Node.js example.",{"type":17,"tag":61,"props":1038,"children":1040},{"id":1039},"errors",[1041],{"type":22,"value":1042},"Errors",{"type":17,"tag":18,"props":1044,"children":1045},{},[1046,1048,1054],{"type":22,"value":1047},"Every error has the shape ",{"type":17,"tag":78,"props":1049,"children":1051},{"className":1050},[],[1052],{"type":22,"value":1053},"{\"error\":{\"code\",\"message\",\"details\"}}",{"type":22,"value":40},{"type":17,"tag":380,"props":1056,"children":1057},{},[1058,1079],{"type":17,"tag":384,"props":1059,"children":1060},{},[1061],{"type":17,"tag":388,"props":1062,"children":1063},{},[1064,1069,1074],{"type":17,"tag":392,"props":1065,"children":1066},{},[1067],{"type":22,"value":1068},"Status",{"type":17,"tag":392,"props":1070,"children":1071},{},[1072],{"type":22,"value":1073},"Code",{"type":17,"tag":392,"props":1075,"children":1076},{},[1077],{"type":22,"value":1078},"Meaning",{"type":17,"tag":408,"props":1080,"children":1081},{},[1082,1104,1139,1172,1200,1233,1260,1290,1312],{"type":17,"tag":388,"props":1083,"children":1084},{},[1085,1090,1099],{"type":17,"tag":415,"props":1086,"children":1087},{},[1088],{"type":22,"value":1089},"401",{"type":17,"tag":415,"props":1091,"children":1092},{},[1093],{"type":17,"tag":78,"props":1094,"children":1096},{"className":1095},[],[1097],{"type":22,"value":1098},"unauthorized",{"type":17,"tag":415,"props":1100,"children":1101},{},[1102],{"type":22,"value":1103},"Missing or invalid token.",{"type":17,"tag":388,"props":1105,"children":1106},{},[1107,1111,1120],{"type":17,"tag":415,"props":1108,"children":1109},{},[1110],{"type":22,"value":83},{"type":17,"tag":415,"props":1112,"children":1113},{},[1114],{"type":17,"tag":78,"props":1115,"children":1117},{"className":1116},[],[1118],{"type":22,"value":1119},"insufficient_scope",{"type":17,"tag":415,"props":1121,"children":1122},{},[1123,1125,1129,1131,1137],{"type":22,"value":1124},"The token lacks ",{"type":17,"tag":34,"props":1126,"children":1127},{},[1128],{"type":22,"value":136},{"type":22,"value":1130},"; ",{"type":17,"tag":78,"props":1132,"children":1134},{"className":1133},[],[1135],{"type":22,"value":1136},"details.required_scope",{"type":22,"value":1138}," names it.",{"type":17,"tag":388,"props":1140,"children":1141},{},[1142,1146,1154],{"type":17,"tag":415,"props":1143,"children":1144},{},[1145],{"type":22,"value":83},{"type":17,"tag":415,"props":1147,"children":1148},{},[1149],{"type":17,"tag":78,"props":1150,"children":1152},{"className":1151},[],[1153],{"type":22,"value":870},{"type":17,"tag":415,"props":1155,"children":1156},{},[1157,1159,1164,1165,1171],{"type":22,"value":1158},"You don't have the Manage webhooks permission, the event needs access you lack (Requests, the calendar or every client), or AI connections are off (",{"type":17,"tag":78,"props":1160,"children":1162},{"className":1161},[],[1163],{"type":22,"value":566},{"type":22,"value":698},{"type":17,"tag":78,"props":1166,"children":1168},{"className":1167},[],[1169],{"type":22,"value":1170},"mcp_not_enabled",{"type":22,"value":118},{"type":17,"tag":388,"props":1173,"children":1174},{},[1175,1179,1187],{"type":17,"tag":415,"props":1176,"children":1177},{},[1178],{"type":22,"value":83},{"type":17,"tag":415,"props":1180,"children":1181},{},[1182],{"type":17,"tag":78,"props":1183,"children":1185},{"className":1184},[],[1186],{"type":22,"value":91},{"type":17,"tag":415,"props":1188,"children":1189},{},[1190,1192,1198],{"type":22,"value":1191},"The workspace has no plan (create, list and sample only; delete still works). ",{"type":17,"tag":78,"props":1193,"children":1195},{"className":1194},[],[1196],{"type":22,"value":1197},"details.required_tier_name",{"type":22,"value":1199}," names the plan needed.",{"type":17,"tag":388,"props":1201,"children":1202},{},[1203,1207,1216],{"type":17,"tag":415,"props":1204,"children":1205},{},[1206],{"type":22,"value":559},{"type":17,"tag":415,"props":1208,"children":1209},{},[1210],{"type":17,"tag":78,"props":1211,"children":1213},{"className":1212},[],[1214],{"type":22,"value":1215},"conflict",{"type":17,"tag":415,"props":1217,"children":1218},{},[1219,1221,1226,1227,1232],{"type":22,"value":1220},"The workspace is at its webhook limit (",{"type":17,"tag":78,"props":1222,"children":1224},{"className":1223},[],[1225],{"type":22,"value":566},{"type":22,"value":698},{"type":17,"tag":78,"props":1228,"children":1230},{"className":1229},[],[1231],{"type":22,"value":574},{"type":22,"value":118},{"type":17,"tag":388,"props":1234,"children":1235},{},[1236,1240,1248],{"type":17,"tag":415,"props":1237,"children":1238},{},[1239],{"type":22,"value":829},{"type":17,"tag":415,"props":1241,"children":1242},{},[1243],{"type":17,"tag":78,"props":1244,"children":1246},{"className":1245},[],[1247],{"type":22,"value":836},{"type":17,"tag":415,"props":1249,"children":1250},{},[1251,1253,1258],{"type":22,"value":1252},"The URL isn't allowed, an event name is unknown, or the id isn't valid. ",{"type":17,"tag":78,"props":1254,"children":1256},{"className":1255},[],[1257],{"type":22,"value":546},{"type":22,"value":1259}," says which.",{"type":17,"tag":388,"props":1261,"children":1262},{},[1263,1268,1277],{"type":17,"tag":415,"props":1264,"children":1265},{},[1266],{"type":22,"value":1267},"429",{"type":17,"tag":415,"props":1269,"children":1270},{},[1271],{"type":17,"tag":78,"props":1272,"children":1274},{"className":1273},[],[1275],{"type":22,"value":1276},"rate_limited",{"type":17,"tag":415,"props":1278,"children":1279},{},[1280,1282,1288],{"type":22,"value":1281},"Too many requests. Wait for ",{"type":17,"tag":78,"props":1283,"children":1285},{"className":1284},[],[1286],{"type":22,"value":1287},"Retry-After",{"type":22,"value":1289}," seconds.",{"type":17,"tag":388,"props":1291,"children":1292},{},[1293,1298,1307],{"type":17,"tag":415,"props":1294,"children":1295},{},[1296],{"type":22,"value":1297},"503",{"type":17,"tag":415,"props":1299,"children":1300},{},[1301],{"type":17,"tag":78,"props":1302,"children":1304},{"className":1303},[],[1305],{"type":22,"value":1306},"tool_disabled",{"type":17,"tag":415,"props":1308,"children":1309},{},[1310],{"type":22,"value":1311},"An admin has switched this action off for AI connections.",{"type":17,"tag":388,"props":1313,"children":1314},{},[1315,1319,1328],{"type":17,"tag":415,"props":1316,"children":1317},{},[1318],{"type":22,"value":1297},{"type":17,"tag":415,"props":1320,"children":1321},{},[1322],{"type":17,"tag":78,"props":1323,"children":1325},{"className":1324},[],[1326],{"type":22,"value":1327},"service_unavailable",{"type":17,"tag":415,"props":1329,"children":1330},{},[1331],{"type":22,"value":1332},"A temporary problem, such as a DNS check that didn't answer. Try again.",{"type":17,"tag":61,"props":1334,"children":1336},{"id":1335},"check-that-it-works",[1337],{"type":22,"value":1338},"Check that it works",{"type":17,"tag":193,"props":1340,"children":1341},{},[1342,1355,1367,1377,1389],{"type":17,"tag":72,"props":1343,"children":1344},{},[1345,1347,1353],{"type":22,"value":1346},"Create a hook for ",{"type":17,"tag":78,"props":1348,"children":1350},{"className":1349},[],[1351],{"type":22,"value":1352},"invoice.paid",{"type":22,"value":1354}," pointing at a request inspector you control.",{"type":17,"tag":72,"props":1356,"children":1357},{},[1358,1360,1365],{"type":22,"value":1359},"Call ",{"type":17,"tag":78,"props":1361,"children":1363},{"className":1362},[],[1364],{"type":22,"value":728},{"type":22,"value":1366}," and confirm the fields you need are there.",{"type":17,"tag":72,"props":1368,"children":1369},{},[1370,1371,1375],{"type":22,"value":200},{"type":17,"tag":34,"props":1372,"children":1373},{},[1374],{"type":22,"value":38},{"type":22,"value":1376}," in the app and confirm the hook is listed.",{"type":17,"tag":72,"props":1378,"children":1379},{},[1380,1382,1387],{"type":22,"value":1381},"Mark a test invoice paid and confirm the delivery arrives with an ",{"type":17,"tag":78,"props":1383,"children":1385},{"className":1384},[],[1386],{"type":22,"value":1004},{"type":22,"value":1388}," header that verifies with the hook's secret.",{"type":17,"tag":72,"props":1390,"children":1391},{},[1392,1394,1398],{"type":22,"value":1393},"Delete the hook and confirm it is gone from ",{"type":17,"tag":34,"props":1395,"children":1396},{},[1397],{"type":22,"value":38},{"type":22,"value":40},{"type":17,"tag":61,"props":1400,"children":1402},{"id":1401},"related",[1403],{"type":22,"value":1404},"Related",{"type":17,"tag":68,"props":1406,"children":1407},{},[1408,1417,1426],{"type":17,"tag":72,"props":1409,"children":1410},{},[1411,1415],{"type":17,"tag":25,"props":1412,"children":1413},{"href":27},[1414],{"type":22,"value":30},{"type":22,"value":1416},": the Workspace369 app for Zapier (beta) subscribes with these routes.",{"type":17,"tag":72,"props":1418,"children":1419},{},[1420,1424],{"type":17,"tag":25,"props":1421,"children":1422},{"href":54},[1423],{"type":22,"value":57},{"type":22,"value":1425},": the events, payloads, retries and recent deliveries.",{"type":17,"tag":72,"props":1427,"children":1428},{},[1429,1435,1437,1442],{"type":17,"tag":25,"props":1430,"children":1432},{"href":1431},"\u002Fv\u002F2026.3\u002Fbuild-with-ai\u002Fcall-workspace369-over-http-builder-api\u002F",[1433],{"type":22,"value":1434},"Call Workspace369 over HTTP (Builder API)",{"type":22,"value":1436},": the rest of ",{"type":17,"tag":78,"props":1438,"children":1440},{"className":1439},[],[1441],{"type":22,"value":183},{"type":22,"value":40},{"title":7,"searchDepth":1444,"depth":1444,"links":1445},2,[1446,1447,1448,1449,1450,1451,1452,1453,1454,1455,1456],{"id":63,"depth":1444,"text":66},{"id":188,"depth":1444,"text":191},{"id":327,"depth":1444,"text":330},{"id":354,"depth":1444,"text":357},{"id":587,"depth":1444,"text":590},{"id":716,"depth":1444,"text":719},{"id":874,"depth":1444,"text":877},{"id":921,"depth":1444,"text":924},{"id":1039,"depth":1444,"text":1042},{"id":1335,"depth":1444,"text":1338},{"id":1401,"depth":1444,"text":1404},"markdown","content:v:2026.3:build-with-ai:rest-hooks-reference.md","content","v\u002F2026.3\u002Fbuild-with-ai\u002Frest-hooks-reference.md","v\u002F2026.3\u002Fbuild-with-ai\u002Frest-hooks-reference","md",1794102722248]