[{"data":1,"prerenderedAt":597},["ShallowReactive",2],{"navigation":3,"\u002Freference\u002Fwebhooks":189,"\u002Freference\u002Fwebhooks-surround":592},[4,23,40,51,74,116,157,177],{"title":5,"path":6,"stem":7,"children":8,"icon":22},"Get Started","\u002Fget-started","1.get-started\u002F1.index",[9,12,17],{"title":10,"path":6,"stem":7,"icon":11},"Introduction","i-lucide-house",{"title":13,"path":14,"stem":15,"icon":16},"Prerequisites","\u002Fget-started\u002Fprerequisites","1.get-started\u002F2.prerequisites","i-lucide-list-checks",{"title":18,"path":19,"stem":20,"icon":21},"Installation","\u002Fget-started\u002Finstallation","1.get-started\u002F3.installation","i-lucide-settings","i-lucide-rocket",{"title":24,"icon":25,"path":26,"stem":27,"children":28,"page":39},"Develop","i-lucide-code","\u002Fdevelop","2.develop",[29,34],{"title":30,"path":31,"stem":32,"icon":33},"Version Control","\u002Fdevelop\u002Fversion-control","2.develop\u002F1.version-control","i-lucide-git-branch",{"title":35,"path":36,"stem":37,"icon":38},"Claude Code","\u002Fdevelop\u002Fclaude-code","2.develop\u002F2.claude-code","i-lucide-sparkles",false,{"title":41,"icon":42,"path":43,"stem":44,"children":45,"page":39},"Launch","i-lucide-globe","\u002Flaunch","3.launch",[46],{"title":47,"path":48,"stem":49,"icon":50},"Cloudflare","\u002Flaunch\u002Fcloudflare","3.launch\u002F1.cloudflare","i-lucide-cloud-upload",{"title":52,"path":53,"stem":54,"children":55,"icon":73},"Plugins","\u002Fplugins","4.plugins\u002F1.index",[56,58,63,68],{"title":52,"path":53,"stem":54,"icon":57},"i-lucide-list",{"title":59,"path":60,"stem":61,"icon":62},"Public API","\u002Fplugins\u002Fapi-keys","4.plugins\u002F2.api-keys","i-lucide-key",{"title":64,"path":65,"stem":66,"icon":67},"Cron Jobs","\u002Fplugins\u002Fcron-jobs","4.plugins\u002F4.cron-jobs","i-lucide-clock",{"title":69,"path":70,"stem":71,"icon":72},"Rate Limiting","\u002Fplugins\u002Frate-limiting","4.plugins\u002F5.rate-limiting","i-lucide-gauge","i-lucide-puzzle",{"title":75,"path":76,"stem":77,"children":78,"icon":115},"Examples","\u002Fexamples","5.examples\u002F1.index",[79,80,85,90,95,100,105,110],{"title":75,"path":76,"stem":77,"icon":57},{"title":81,"path":82,"stem":83,"icon":84},"Job Management","\u002Fexamples\u002Fjob-management","5.examples\u002F2.job-management","i-lucide-briefcase",{"title":86,"path":87,"stem":88,"icon":89},"Kanban \u002F To-Do List","\u002Fexamples\u002Fkanban-todo","5.examples\u002F3.kanban-todo","i-lucide-kanban",{"title":91,"path":92,"stem":93,"icon":94},"Inventory Management","\u002Fexamples\u002Finventory-management","5.examples\u002F4.inventory-management","i-lucide-package",{"title":96,"path":97,"stem":98,"icon":99},"Mini CRM","\u002Fexamples\u002Fmini-crm","5.examples\u002F5.mini-crm","i-lucide-users",{"title":101,"path":102,"stem":103,"icon":104},"Sales Orders & Invoices","\u002Fexamples\u002Fsales-invoices","5.examples\u002F6.sales-invoices","i-lucide-receipt",{"title":106,"path":107,"stem":108,"icon":109},"Calendar & Booking","\u002Fexamples\u002Fcalendar-booking","5.examples\u002F7.calendar-booking","i-lucide-calendar",{"title":111,"path":112,"stem":113,"icon":114},"Support Tickets","\u002Fexamples\u002Fsupport-tickets","5.examples\u002F8.support-tickets","i-lucide-life-buoy","i-lucide-book-open",{"title":117,"icon":118,"path":119,"stem":120,"children":121,"page":39},"Reference","i-lucide-file-text","\u002Freference","6.reference",[122,127,132,137,142,147,152],{"title":123,"path":124,"stem":125,"icon":126},"Architecture","\u002Freference\u002Farchitecture","6.reference\u002F1.architecture","i-lucide-layers",{"title":128,"path":129,"stem":130,"icon":131},"Permissions","\u002Freference\u002Fpermissions","6.reference\u002F2.permissions","i-lucide-shield",{"title":133,"path":134,"stem":135,"icon":136},"Invitations","\u002Freference\u002Finvitations","6.reference\u002F3.invitations","i-lucide-mail",{"title":138,"path":139,"stem":140,"icon":141},"Webhooks","\u002Freference\u002Fwebhooks","6.reference\u002F4.webhooks","i-lucide-webhook",{"title":143,"path":144,"stem":145,"icon":146},"AI Chat","\u002Freference\u002Fai-chat","6.reference\u002F5.ai-chat","i-lucide-message-square",{"title":148,"path":149,"stem":150,"icon":151},"Activity Log","\u002Freference\u002Factivity-log","6.reference\u002F6.activity-log","i-lucide-scroll",{"title":153,"path":154,"stem":155,"icon":156},"Manual Setup","\u002Freference\u002Fmanual-setup","6.reference\u002F7.manual-setup","i-lucide-wrench",{"title":158,"icon":159,"path":160,"stem":161,"children":162,"page":39},"Legal","i-lucide-scale","\u002Flegal","7.legal",[163,168,172],{"title":164,"path":165,"stem":166,"icon":167},"License","\u002Flegal\u002Flicense","7.legal\u002F1.license","i-lucide-file-check",{"title":169,"path":170,"stem":171,"icon":118},"Terms and Conditions","\u002Flegal\u002Fterms","7.legal\u002F2.terms",{"title":173,"path":174,"stem":175,"icon":176},"Privacy Policy","\u002Flegal\u002Fprivacy","7.legal\u002F3.privacy","i-lucide-lock",{"title":178,"path":179,"stem":180,"children":181,"icon":183},"Upgrades","\u002Fupgrades","8.upgrades\u002F1.index",[182,184],{"title":178,"path":179,"stem":180,"icon":183},"i-lucide-arrow-up-circle",{"title":185,"path":186,"stem":187,"icon":188},"\u002Fapp\u002F* gated subtree routing","\u002Fupgrades\u002Fapp-subtree-routing","8.upgrades\u002F2.app-subtree-routing","i-lucide-route",{"id":190,"title":138,"body":191,"description":585,"extension":586,"links":587,"meta":588,"navigation":589,"path":139,"seo":590,"stem":140,"__hash__":591},"docs\u002F6.reference\u002F4.webhooks.md",{"type":192,"value":193,"toc":580},"minimark",[194,207,225,230,394,398,408,539,542,566,570,576],[195,196,197,198,202,203,206],"p",{},"All team-scoped mutations can fire a webhook to the team's configured\n",[199,200,201],"code",{},"webhook_url"," (set in Settings → General). Delivery is fire-and-forget: the\noriginating request never blocks on the webhook, and failures are silently\nignored. The pattern is general — add ",[199,204,205],{},"fireWebhook(...)"," anywhere a mutation\nhappens (announcements, profile updates, custom feature events) and external\ntools can react.",[195,208,209,210,213,214,213,217,220,221,224],{},"Payloads always include ",[199,211,212],{},"event",", ",[199,215,216],{},"team_id",[199,218,219],{},"team_name",", and ",[199,222,223],{},"timestamp",";\nevent-specific fields are listed below.",[226,227,229],"h2",{"id":228},"built-in-events","Built-in events",[231,232,233,249],"table",{},[234,235,236],"thead",{},[237,238,239,243,246],"tr",{},[240,241,242],"th",{},"Event",[240,244,245],{},"Fired when",[240,247,248],{},"Extra fields",[250,251,252,277,296,315,335,360,379],"tbody",{},[237,253,254,260,263],{},[255,256,257],"td",{},[199,258,259],{},"invitation.created",[255,261,262],{},"Admin invites someone",[255,264,265,213,268,213,271,213,274],{},[199,266,267],{},"email",[199,269,270],{},"role",[199,272,273],{},"invite_url",[199,275,276],{},"invited_by",[237,278,279,284,287],{},[255,280,281],{},[199,282,283],{},"invitation.accepted",[255,285,286],{},"Invitee accepts the invitation",[255,288,289,213,291,213,293],{},[199,290,267],{},[199,292,270],{},[199,294,295],{},"member_name",[237,297,298,303,306],{},[255,299,300],{},[199,301,302],{},"invitation.revoked",[255,304,305],{},"Admin revokes a pending invitation",[255,307,308,213,310,213,312],{},[199,309,267],{},[199,311,270],{},[199,313,314],{},"revoked_by",[237,316,317,322,325],{},[255,318,319],{},[199,320,321],{},"member.removed",[255,323,324],{},"Admin removes a member",[255,326,327,213,330,213,332],{},[199,328,329],{},"member_email",[199,331,295],{},[199,333,334],{},"removed_by",[237,336,337,342,345],{},[255,338,339],{},[199,340,341],{},"member.role_changed",[255,343,344],{},"Admin changes a member's role",[255,346,347,213,349,213,351,213,354,213,357],{},[199,348,329],{},[199,350,295],{},[199,352,353],{},"old_role",[199,355,356],{},"new_role",[199,358,359],{},"changed_by",[237,361,362,367,370],{},[255,363,364],{},[199,365,366],{},"team.updated",[255,368,369],{},"Team settings are saved",[255,371,372,375,376],{},[199,373,374],{},"changes"," (object of updated fields), ",[199,377,378],{},"updated_by",[237,380,381,386,389],{},[255,382,383],{},[199,384,385],{},"team.deleted",[255,387,388],{},"Owner deletes a team",[255,390,391],{},[199,392,393],{},"deleted_by",[226,395,397],{"id":396},"adding-your-own-events","Adding your own events",[195,399,400,403,404,407],{},[199,401,402],{},"fireWebhook"," lives in ",[199,405,406],{},"server\u002Futils\u002FfireWebhook.ts",". Two steps to add a new\nevent type:",[409,410,411,427],"ol",{},[412,413,414,415,418,419,422,423,426],"li",{},"Extend the ",[199,416,417],{},"WebhookEvent"," union in ",[199,420,421],{},"fireWebhook.ts"," with your event name\n(e.g. ",[199,424,425],{},"\"announcement.published\"",").",[412,428,429,430],{},"Call it from your server route after a mutation:",[431,432,437],"pre",{"className":433,"code":434,"language":435,"meta":436,"style":436},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","await fireWebhook(\n  serviceClient,\n  teamId,\n  \"announcement.published\",\n  { announcement_id: id, title, published_by: user.sub },\n);\n","ts","",[199,438,439,456,466,474,489,530],{"__ignoreMap":436},[440,441,444,448,452],"span",{"class":442,"line":443},"line",1,[440,445,447],{"class":446},"s7zQu","await",[440,449,451],{"class":450},"s2Zo4"," fireWebhook",[440,453,455],{"class":454},"sTEyZ","(\n",[440,457,459,462],{"class":442,"line":458},2,[440,460,461],{"class":454},"  serviceClient",[440,463,465],{"class":464},"sMK4o",",\n",[440,467,469,472],{"class":442,"line":468},3,[440,470,471],{"class":454},"  teamId",[440,473,465],{"class":464},[440,475,477,480,484,487],{"class":442,"line":476},4,[440,478,479],{"class":464},"  \"",[440,481,483],{"class":482},"sfazB","announcement.published",[440,485,486],{"class":464},"\"",[440,488,465],{"class":464},[440,490,492,495,499,502,505,508,511,513,516,518,521,524,527],{"class":442,"line":491},5,[440,493,494],{"class":464},"  {",[440,496,498],{"class":497},"swJcz"," announcement_id",[440,500,501],{"class":464},":",[440,503,504],{"class":454}," id",[440,506,507],{"class":464},",",[440,509,510],{"class":454}," title",[440,512,507],{"class":464},[440,514,515],{"class":497}," published_by",[440,517,501],{"class":464},[440,519,520],{"class":454}," user",[440,522,523],{"class":464},".",[440,525,526],{"class":454},"sub ",[440,528,529],{"class":464},"},\n",[440,531,533,536],{"class":442,"line":532},6,[440,534,535],{"class":454},")",[440,537,538],{"class":464},";\n",[195,540,541],{},"Natural extensions:",[543,544,545,550,556],"ul",{},[412,546,547,549],{},[199,548,483],{}," after creating a banner",[412,551,552,555],{},[199,553,554],{},"profile.updated"," when a user changes their display name or avatar",[412,557,558,561,562,565],{},[199,559,560],{},"\u003Cresource>.created"," \u002F ",[199,563,564],{},"\u003Cresource>.deleted"," for any feature you build on\ntop of the template",[226,567,569],{"id":568},"reliability","Reliability",[195,571,572,573,575],{},"Webhook delivery is fire-and-forget: failures are silently ignored and do not\nblock the originating request. If you need retries or delivery guarantees,\nreplace ",[199,574,406],{}," with a queue-backed implementation\n(BullMQ, Inngest, a Postgres job table, etc.).",[577,578,579],"style",{},"html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":436,"searchDepth":443,"depth":458,"links":581},[582,583,584],{"id":228,"depth":458,"text":229},{"id":396,"depth":458,"text":397},{"id":568,"depth":458,"text":569},"Fire-and-forget event dispatch for invites, member changes, team updates, and any mutation you want to expose.","md",null,{},{"icon":141},{"title":138,"description":585},"cgcWHRJlZ23UfrPN36LVifrK92TE4zimDzo3HNlos3E",[593,595],{"title":133,"path":134,"stem":135,"description":594,"icon":136,"children":-1},"How team invites work — webhook-only delivery, token flow, and how to add email later.",{"title":143,"path":144,"stem":145,"description":596,"icon":146,"children":-1},"How the baked-in AI assistant works, and how to make new tables available to it.",1777092171324]