[{"data":1,"prerenderedAt":4121},["ShallowReactive",2],{"navigation_docs":3,"-integrations-and-extensibility-webhooks-quickstart":1582,"-integrations-and-extensibility-webhooks-quickstart-surround":4116},[4,237,583,622,898,988,1106,1240,1578],{"title":5,"path":6,"stem":7,"children":8,"page":84},"Getting Started","/getting-started","01.getting-started",[9,15,226,231],{"title":10,"path":11,"stem":12,"children":13},"Creating Your Account","/getting-started/creating-your-account","01.getting-started/00.creating-your-account/index",[14],{"title":10,"path":11,"stem":12},{"title":16,"order":17,"path":18,"stem":19,"children":20,"page":84},"Admin Onboarding: Getting Started",1,"/getting-started/admin-onboarding-getting-started","01.getting-started/01.admin-onboarding-getting-started",[21,25,29,33,40,44,51,85,134,147,158,162,175,179,188,205,213,219],{"title":22,"path":23,"stem":24},"Setting the Stage: How Predictability becomes Reality in DevStride","/getting-started/admin-onboarding-getting-started/setting-the-stage","01.getting-started/01.admin-onboarding-getting-started/01.setting-the-stage",{"title":26,"path":27,"stem":28},"Admin Onboarding - Getting Started","/getting-started/admin-onboarding-getting-started/admin-onboarding-guide","01.getting-started/01.admin-onboarding-getting-started/02.admin-onboarding-guide",{"title":30,"path":31,"stem":32},"Basic Terms","/getting-started/admin-onboarding-getting-started/basic-terms","01.getting-started/01.admin-onboarding-getting-started/03.basic-terms",{"title":34,"path":35,"stem":36,"children":37},"Setting Up Users and Teams","/getting-started/admin-onboarding-getting-started/setting-up-users-and-teams","01.getting-started/01.admin-onboarding-getting-started/04.setting-up-users-and-teams/index",[38],{"title":39,"path":35,"stem":36},"Admin Onboarding - Setting up Users and Teams",{"title":41,"path":42,"stem":43},"Admin Onboarding - Configuring Your Work Model","/getting-started/admin-onboarding-getting-started/configuring-your-work-model","01.getting-started/01.admin-onboarding-getting-started/05.configuring-your-work-model",{"title":45,"path":46,"stem":47,"children":48},"Map Value: WorkStreams","/getting-started/admin-onboarding-getting-started/map-value-workstreams","01.getting-started/01.admin-onboarding-getting-started/06.map-value-workstreams/index",[49],{"title":50,"path":46,"stem":47},"Admin Onboarding: Understanding Workstreams",{"title":52,"path":53,"stem":54,"children":55,"page":84},"Items","/getting-started/admin-onboarding-getting-started/items","01.getting-started/01.admin-onboarding-getting-started/07.items",[56,60,67,73,80],{"title":57,"path":58,"stem":59},"Setting up Your Item Type Hierarchy","/getting-started/admin-onboarding-getting-started/items/setting-up-item-type-hierarchy","01.getting-started/01.admin-onboarding-getting-started/07.items/01.setting-up-item-type-hierarchy",{"title":61,"path":62,"stem":63,"children":64},"Items: Setting Up Custom Fields","/getting-started/admin-onboarding-getting-started/items/setting-up-custom-fields","01.getting-started/01.admin-onboarding-getting-started/07.items/02.setting-up-custom-fields/index",[65],{"title":66,"path":62,"stem":63},"Admin Onboarding - Setting up Custom Fields",{"title":68,"path":69,"stem":70,"children":71},"Admin Onboarding - Setting up Tags","/getting-started/admin-onboarding-getting-started/items/setting-up-tags","01.getting-started/01.admin-onboarding-getting-started/07.items/03.setting-up-tags/index",[72],{"title":68,"path":69,"stem":70},{"title":74,"path":75,"stem":76,"children":77},"Items: Creating and Managing Forms","/getting-started/admin-onboarding-getting-started/items/creating-and-managing-forms","01.getting-started/01.admin-onboarding-getting-started/07.items/04.creating-and-managing-forms/index",[78],{"title":79,"path":75,"stem":76},"Admin Onboarding - Creating and Managing Forms",{"title":81,"path":82,"stem":83},"Create Items with AI","/getting-started/admin-onboarding-getting-started/items/create-items-with-ai","01.getting-started/01.admin-onboarding-getting-started/07.items/05.create-items-with-ai",false,{"title":86,"path":87,"stem":88,"children":89,"page":84},"Item Workspace Tour","/getting-started/admin-onboarding-getting-started/item-workspace-tour","01.getting-started/01.admin-onboarding-getting-started/08.item-workspace-tour",[90,94,98,102,106,110,114,118,122,126,130],{"title":91,"path":92,"stem":93},"Admin Onboarding - Item Workspace Header","/getting-started/admin-onboarding-getting-started/item-workspace-tour/header","01.getting-started/01.admin-onboarding-getting-started/08.item-workspace-tour/01.header",{"title":95,"path":96,"stem":97},"Admin Onboarding - Item Workspace Tabs","/getting-started/admin-onboarding-getting-started/item-workspace-tour/tabs","01.getting-started/01.admin-onboarding-getting-started/08.item-workspace-tour/02.tabs",{"title":99,"path":100,"stem":101},"Item Workspace Quick Links","/getting-started/admin-onboarding-getting-started/item-workspace-tour/quick-links","01.getting-started/01.admin-onboarding-getting-started/08.item-workspace-tour/03.quick-links",{"title":103,"path":104,"stem":105},"Admin Onboarding - Item Workspace - Right Bar: Team through Status","/getting-started/admin-onboarding-getting-started/item-workspace-tour/right-bar-team-through-status","01.getting-started/01.admin-onboarding-getting-started/08.item-workspace-tour/04.right-bar-team-through-status",{"title":107,"path":108,"stem":109},"Admin Onboarding - Item Workspace - Right Bar: Point Estimates","/getting-started/admin-onboarding-getting-started/item-workspace-tour/right-bar-point-estimates","01.getting-started/01.admin-onboarding-getting-started/08.item-workspace-tour/05.right-bar-point-estimates",{"title":111,"path":112,"stem":113},"Admin Onboarding - Item Workspace - Right Bar: Time Estimates","/getting-started/admin-onboarding-getting-started/item-workspace-tour/right-bar-time-estimates","01.getting-started/01.admin-onboarding-getting-started/08.item-workspace-tour/06.right-bar-time-estimates",{"title":115,"path":116,"stem":117},"Admin Onboarding - Item Workspace -Right Bar: Best Practice time estimates","/getting-started/admin-onboarding-getting-started/item-workspace-tour/right-bar-best-practice-time-estimates","01.getting-started/01.admin-onboarding-getting-started/08.item-workspace-tour/07.right-bar-best-practice-time-estimates",{"title":119,"path":120,"stem":121},"Admin Onboarding - Item Workspace - Right Bar: Time Spent","/getting-started/admin-onboarding-getting-started/item-workspace-tour/right-bar-time-spent","01.getting-started/01.admin-onboarding-getting-started/08.item-workspace-tour/08.right-bar-time-spent",{"title":123,"path":124,"stem":125},"Admin Onboarding - Item Workspace - Right Bar: Priority","/getting-started/admin-onboarding-getting-started/item-workspace-tour/right-bar-priority","01.getting-started/01.admin-onboarding-getting-started/08.item-workspace-tour/09.right-bar-priority",{"title":127,"path":128,"stem":129},"Admin Onboarding - Item Workspace - Right Bar: Start Dates and Due Dates","/getting-started/admin-onboarding-getting-started/item-workspace-tour/right-bar-start-dates-and-due-dates","01.getting-started/01.admin-onboarding-getting-started/08.item-workspace-tour/10.right-bar-start-dates-and-due-dates",{"title":131,"path":132,"stem":133},"Admin Onboarding - Item Workspace - Right Bar: Progress Tracking","/getting-started/admin-onboarding-getting-started/item-workspace-tour/right-bar-progress-tracking","01.getting-started/01.admin-onboarding-getting-started/08.item-workspace-tour/11.right-bar-progress-tracking",{"title":135,"path":136,"stem":137,"children":138,"page":84},"Creating and Using Statuses","/getting-started/admin-onboarding-getting-started/creating-and-using-statuses","01.getting-started/01.admin-onboarding-getting-started/09.creating-and-using-statuses",[139,143],{"title":140,"path":141,"stem":142},"Admin Onboarding - Setting Up Workflow Statuses","/getting-started/admin-onboarding-getting-started/creating-and-using-statuses/setting-up-workflow-statuses","01.getting-started/01.admin-onboarding-getting-started/09.creating-and-using-statuses/01.setting-up-workflow-statuses",{"title":144,"path":145,"stem":146},"Admin Onboarding - Create Custom Status Collections","/getting-started/admin-onboarding-getting-started/creating-and-using-statuses/create-custom-status-collections","01.getting-started/01.admin-onboarding-getting-started/09.creating-and-using-statuses/02.create-custom-status-collections",{"title":148,"path":149,"stem":150,"children":151},"Populating and Managing WorkStreams","/getting-started/admin-onboarding-getting-started/populating-and-managing-workstreams","01.getting-started/01.admin-onboarding-getting-started/10.populating-and-managing-workstreams/index",[152,154],{"title":153,"path":149,"stem":150},"Admin Onboarding - Populating and Managing Workstreams",{"title":155,"path":156,"stem":157},"Import Templates","/getting-started/admin-onboarding-getting-started/populating-and-managing-workstreams/import-templates","01.getting-started/01.admin-onboarding-getting-started/10.populating-and-managing-workstreams/01.import-templates",{"title":159,"path":160,"stem":161},"Boards: Managing Workflow and Statuses","/getting-started/admin-onboarding-getting-started/boards-managing-workflow-and-statuses","01.getting-started/01.admin-onboarding-getting-started/11.boards-managing-workflow-and-statuses",{"title":163,"path":164,"stem":165,"children":166,"page":84},"Creating Cadences","/getting-started/admin-onboarding-getting-started/creating-cadences","01.getting-started/01.admin-onboarding-getting-started/12.creating-cadences",[167,171],{"title":168,"path":169,"stem":170},"Admin Onboarding - Organizing the When: Understanding Planning Cadences","/getting-started/admin-onboarding-getting-started/creating-cadences/understanding-planning-cadences","01.getting-started/01.admin-onboarding-getting-started/12.creating-cadences/01.understanding-planning-cadences",{"title":172,"path":173,"stem":174},"Admin Onboarding - Setting Up Cadences and Timeboxes","/getting-started/admin-onboarding-getting-started/creating-cadences/setting-up-cadences-and-timeboxes","01.getting-started/01.admin-onboarding-getting-started/12.creating-cadences/02.setting-up-cadences-and-timeboxes",{"title":176,"path":177,"stem":178},"Track Progress - Gantt Charts","/getting-started/admin-onboarding-getting-started/track-progress-gantt-charts","01.getting-started/01.admin-onboarding-getting-started/13.track-progress-gantt-charts",{"title":180,"path":181,"stem":182,"children":183,"page":84},"Using AI in DevStride","/getting-started/admin-onboarding-getting-started/using-ai-in-devstride","01.getting-started/01.admin-onboarding-getting-started/14.using-ai-in-devstride",[184],{"title":185,"path":186,"stem":187},"Creating Items with AI","/getting-started/admin-onboarding-getting-started/using-ai-in-devstride/create-items-with-ai","01.getting-started/01.admin-onboarding-getting-started/14.using-ai-in-devstride/01.create-items-with-ai",{"title":189,"path":190,"stem":191,"children":192,"page":84},"More on Permissions","/getting-started/admin-onboarding-getting-started/permissions","01.getting-started/01.admin-onboarding-getting-started/15.permissions",[193,197,201],{"title":194,"path":195,"stem":196},"Understanding Permissions","/getting-started/admin-onboarding-getting-started/permissions/understanding-permissions","01.getting-started/01.admin-onboarding-getting-started/15.permissions/01.understanding-permissions",{"title":198,"path":199,"stem":200},"Roles & Permissions","/getting-started/admin-onboarding-getting-started/permissions/roles-and-permissions","01.getting-started/01.admin-onboarding-getting-started/15.permissions/02.roles-and-permissions",{"title":202,"path":203,"stem":204},"Sharing & Access","/getting-started/admin-onboarding-getting-started/permissions/sharing-and-access","01.getting-started/01.admin-onboarding-getting-started/15.permissions/03.sharing-and-access",{"title":206,"path":207,"stem":208,"children":209,"page":84},"API Keys","/getting-started/admin-onboarding-getting-started/api-keys","01.getting-started/01.admin-onboarding-getting-started/16.api-keys",[210],{"title":206,"path":211,"stem":212},"/getting-started/admin-onboarding-getting-started/api-keys/api-keys","01.getting-started/01.admin-onboarding-getting-started/16.api-keys/01.api-keys",{"title":214,"path":215,"stem":216,"children":217},"Pulling it all together: Planned Value to Delivery","/getting-started/admin-onboarding-getting-started/overall-flow-and-best-practices","01.getting-started/01.admin-onboarding-getting-started/17.overall-flow-and-best-practices/index",[218],{"title":214,"path":215,"stem":216},{"title":220,"path":221,"stem":222,"children":223},"Best Practices for Project Management in DevStride","/getting-started/admin-onboarding-getting-started/best-practices-for-project-management","01.getting-started/01.admin-onboarding-getting-started/18.best-practices-for-project-management/index",[224],{"title":225,"path":221,"stem":222},"Handling incomplete items from Sprint to Sprint",{"title":30,"path":227,"stem":228,"children":229},"/getting-started/basic-terms","01.getting-started/02.basic-terms/index",[230],{"title":30,"path":227,"stem":228},{"title":232,"path":233,"stem":234,"children":235},"Keyboard Shortcuts","/getting-started/keyboard-shortcuts","01.getting-started/03.keyboard-shortcuts/index",[236],{"title":232,"path":233,"stem":234},{"title":238,"path":239,"stem":240,"children":241,"page":84},"Major Modules","/major-modules","02.major-modules",[242,300,354,375,441,502,530],{"title":243,"order":244,"path":245,"stem":246,"children":247,"page":84},"Map Value: Workstreams and Work Items",2,"/major-modules/workstreams-and-work-items","02.major-modules/01.workstreams-and-work-items",[248,252,256,259,263,267,271,275,278],{"title":249,"path":250,"stem":251},"Creating Items","/major-modules/workstreams-and-work-items/creating-work-items","02.major-modules/01.workstreams-and-work-items/01.creating-work-items",{"title":253,"path":254,"stem":255},"The Items Table","/major-modules/workstreams-and-work-items/manage-items-table","02.major-modules/01.workstreams-and-work-items/02.manage-items-table",{"title":185,"path":257,"stem":258},"/major-modules/workstreams-and-work-items/ai-item-creation","02.major-modules/01.workstreams-and-work-items/03.ai-item-creation",{"title":260,"path":261,"stem":262},"Shared Lists","/major-modules/workstreams-and-work-items/published-lists","02.major-modules/01.workstreams-and-work-items/04.published-lists",{"title":264,"path":265,"stem":266},"Using the Map","/major-modules/workstreams-and-work-items/using-the-map","02.major-modules/01.workstreams-and-work-items/05.using-the-map",{"title":268,"path":269,"stem":270},"Dependency Graph","/major-modules/workstreams-and-work-items/dependency-graph","02.major-modules/01.workstreams-and-work-items/06.dependency-graph",{"title":272,"path":273,"stem":274},"Workstream & Item Permissions","/major-modules/workstreams-and-work-items/workstream-and-item-permissions","02.major-modules/01.workstreams-and-work-items/07.workstream-and-item-permissions",{"title":155,"path":276,"stem":277},"/major-modules/workstreams-and-work-items/import-templates","02.major-modules/01.workstreams-and-work-items/08.import-templates",{"title":279,"order":280,"path":281,"stem":282,"children":283,"page":84},"Workspace Capabilities",8,"/major-modules/workstreams-and-work-items/workspace-capabilities","02.major-modules/01.workstreams-and-work-items/09.workspace-capabilities",[284,288,292,296],{"title":285,"path":286,"stem":287},"Explore the Workspace","/major-modules/workstreams-and-work-items/workspace-capabilities/explore-the-workspace","02.major-modules/01.workstreams-and-work-items/09.workspace-capabilities/01.explore-the-workspace",{"title":289,"path":290,"stem":291},"Workspace Editor & Collaboration","/major-modules/workstreams-and-work-items/workspace-capabilities/workspace-sidebar","02.major-modules/01.workstreams-and-work-items/09.workspace-capabilities/02.workspace-sidebar",{"title":293,"path":294,"stem":295},"Themes & Appearance","/major-modules/workstreams-and-work-items/workspace-capabilities/themes-and-appearance","02.major-modules/01.workstreams-and-work-items/09.workspace-capabilities/03.themes-and-appearance",{"title":297,"path":298,"stem":299},"Getting Help & Support","/major-modules/workstreams-and-work-items/workspace-capabilities/getting-help-and-support","02.major-modules/01.workstreams-and-work-items/09.workspace-capabilities/04.getting-help-and-support",{"title":301,"order":302,"path":303,"stem":304,"children":305,"page":84},"Plan Delivery: Boards",3,"/major-modules/boards","02.major-modules/02.boards",[306,310,314,318,322,326,330,334,338,342,346,350],{"title":307,"path":308,"stem":309},"How DevStride manages the When: Perpetual vs. Cycle-based Boards","/major-modules/boards/how-devstride-manages-the-when","02.major-modules/02.boards/01.how-devstride-manages-the-when",{"title":311,"path":312,"stem":313},"Working Group Folders: Organizing the Who of the work","/major-modules/boards/working-group-folders","02.major-modules/02.boards/02.working-group-folders",{"title":315,"path":316,"stem":317},"Understanding Board Views","/major-modules/boards/understanding-board-views","02.major-modules/02.boards/03.understanding-board-views",{"title":319,"path":320,"stem":321},"Import Stories and Epics into Boards","/major-modules/boards/import-stories-and-epics-into-boards","02.major-modules/02.boards/04.import-stories-and-epics-into-boards",{"title":323,"path":324,"stem":325},"Adding a Folder","/major-modules/boards/adding-a-folder","02.major-modules/02.boards/05.adding-a-folder",{"title":327,"path":328,"stem":329},"Manage and Edit Dependencies","/major-modules/boards/manage-and-edit-dependencies","02.major-modules/02.boards/06.manage-and-edit-dependencies",{"title":331,"path":332,"stem":333},"Creating Subfolders in DevStride","/major-modules/boards/creating-subfolders-in-devstride","02.major-modules/02.boards/07.creating-subfolders-in-devstride",{"title":335,"path":336,"stem":337},"Setting up and Using Perpetual Boards","/major-modules/boards/setting-up-and-using-perpetual-boards","02.major-modules/02.boards/08.setting-up-and-using-perpetual-boards",{"title":339,"path":340,"stem":341},"Using Cycle Boards","/major-modules/boards/using-cycle-boards","02.major-modules/02.boards/09.using-cycle-boards",{"title":343,"path":344,"stem":345},"Track and Move Work with Board Views","/major-modules/boards/track-and-move-work-with-board-views","02.major-modules/02.boards/10.track-and-move-work-with-board-views",{"title":347,"path":348,"stem":349},"Boards and WIP Limiters","/major-modules/boards/boards-and-wip-limiters","02.major-modules/02.boards/11.boards-and-wip-limiters",{"title":351,"path":352,"stem":353},"Board & Folder Permissions","/major-modules/boards/board-and-folder-permissions","02.major-modules/02.boards/12.board-and-folder-permissions",{"title":355,"path":356,"stem":357,"children":358,"page":84},"Track Progress: Gantts","/major-modules/track-progress-gantts","02.major-modules/03.track-progress-gantts",[359,363,367,371],{"title":360,"path":361,"stem":362},"Track Progress: Setting Up Gantt Charts","/major-modules/track-progress-gantts/setting-up-gantt-charts","02.major-modules/03.track-progress-gantts/01.setting-up-gantt-charts",{"title":364,"path":365,"stem":366},"Viewing Gantt Charts","/major-modules/track-progress-gantts/viewing-gantt-charts","02.major-modules/03.track-progress-gantts/02.viewing-gantt-charts",{"title":368,"path":369,"stem":370},"Using Gantt Charts: Navigating the timeline","/major-modules/track-progress-gantts/navigating-the-timeline","02.major-modules/03.track-progress-gantts/03.navigating-the-timeline",{"title":372,"path":373,"stem":374},"Using Gantt Charts: Navigating the table","/major-modules/track-progress-gantts/navigating-the-table","02.major-modules/03.track-progress-gantts/04.navigating-the-table",{"title":376,"order":377,"path":378,"stem":379,"children":380,"page":84},"Measure Performance: Reports",4,"/major-modules/measure-performance-reports","02.major-modules/04.measure-performance-reports",[381,385,389,393,397,401,405,409,413,417,421,425,429,433,437],{"title":382,"path":383,"stem":384},"Reports Overview","/major-modules/measure-performance-reports/viewing-optimization","02.major-modules/04.measure-performance-reports/01.viewing-optimization",{"title":386,"path":387,"stem":388},"Using AI for powerful reports","/major-modules/measure-performance-reports/using-ai-for-powerful-reports","02.major-modules/04.measure-performance-reports/02.using-ai-for-powerful-reports",{"title":390,"path":391,"stem":392},"Report Customization Options","/major-modules/measure-performance-reports/report-filters-and-options","02.major-modules/04.measure-performance-reports/03.report-filters-and-options",{"title":394,"path":395,"stem":396},"Report: Current Progress","/major-modules/measure-performance-reports/current-progress","02.major-modules/04.measure-performance-reports/04.current-progress",{"title":398,"path":399,"stem":400},"Report: Trending Progress","/major-modules/measure-performance-reports/trending-progress","02.major-modules/04.measure-performance-reports/05.trending-progress",{"title":402,"path":403,"stem":404},"Report: Cycle Time","/major-modules/measure-performance-reports/cycle-time","02.major-modules/04.measure-performance-reports/06.cycle-time",{"title":406,"path":407,"stem":408},"Report: Throughput","/major-modules/measure-performance-reports/throughput","02.major-modules/04.measure-performance-reports/07.throughput",{"title":410,"path":411,"stem":412},"Report: Cumulative Flow","/major-modules/measure-performance-reports/cumulative-flow","02.major-modules/04.measure-performance-reports/08.cumulative-flow",{"title":414,"path":415,"stem":416},"Report: Velocity","/major-modules/measure-performance-reports/velocity","02.major-modules/04.measure-performance-reports/09.velocity",{"title":418,"path":419,"stem":420},"Report: Burn Up","/major-modules/measure-performance-reports/burn-up","02.major-modules/04.measure-performance-reports/10.burn-up",{"title":422,"path":423,"stem":424},"Report: Burn Down","/major-modules/measure-performance-reports/burn-down","02.major-modules/04.measure-performance-reports/11.burn-down",{"title":426,"path":427,"stem":428},"Report: User Time Completed","/major-modules/measure-performance-reports/user-time-completed","02.major-modules/04.measure-performance-reports/12.user-time-completed",{"title":430,"path":431,"stem":432},"Report: Churn","/major-modules/measure-performance-reports/churn","02.major-modules/04.measure-performance-reports/13.churn",{"title":434,"path":435,"stem":436},"Report: Time Allocation Matrix","/major-modules/measure-performance-reports/time-allocation-matrix","02.major-modules/04.measure-performance-reports/14.time-allocation-matrix",{"title":438,"path":439,"stem":440},"Report: Cycle Carry-Forward","/major-modules/measure-performance-reports/cycle-carry-forward","02.major-modules/04.measure-performance-reports/15.cycle-carry-forward",{"title":442,"order":280,"path":443,"stem":444,"children":445,"page":84},"Service Desk","/major-modules/service-desk","02.major-modules/05.service-desk",[446,450,454,458,462,466,470,474,478,482,486,490,494,498],{"title":447,"path":448,"stem":449},"Overview","/major-modules/service-desk/overview","02.major-modules/05.service-desk/01.overview",{"title":451,"path":452,"stem":453},"Enabling Service Desk","/major-modules/service-desk/enabling-service-desk","02.major-modules/05.service-desk/02.enabling-service-desk",{"title":455,"path":456,"stem":457},"Email Channels & Setup","/major-modules/service-desk/email-channels","02.major-modules/05.service-desk/03.email-channels",{"title":459,"path":460,"stem":461},"Requesters & Companies","/major-modules/service-desk/requesters-and-companies","02.major-modules/05.service-desk/04.requesters-and-companies",{"title":463,"path":464,"stem":465},"Customer Support Portal","/major-modules/service-desk/customer-support-portal","02.major-modules/05.service-desk/05.customer-support-portal",{"title":467,"path":468,"stem":469},"Working a Ticket","/major-modules/service-desk/working-a-ticket","02.major-modules/05.service-desk/06.working-a-ticket",{"title":471,"path":472,"stem":473},"Request Forms","/major-modules/service-desk/request-forms","02.major-modules/05.service-desk/07.request-forms",{"title":475,"path":476,"stem":477},"The Suspended Queue","/major-modules/service-desk/suspended-messages","02.major-modules/05.service-desk/08.suspended-messages",{"title":479,"path":480,"stem":481},"Finding & Filtering Tickets","/major-modules/service-desk/finding-and-filtering-tickets","02.major-modules/05.service-desk/09.finding-and-filtering-tickets",{"title":483,"path":484,"stem":485},"Permissions","/major-modules/service-desk/permissions","02.major-modules/05.service-desk/10.permissions",{"title":487,"path":488,"stem":489},"Service Level Agreements (SLA)","/major-modules/service-desk/sla","02.major-modules/05.service-desk/10.sla",{"title":491,"path":492,"stem":493},"Time-Based Ticket Automations","/major-modules/service-desk/time-based-automations","02.major-modules/05.service-desk/11.time-based-automations",{"title":495,"path":496,"stem":497},"Reports","/major-modules/service-desk/reports","02.major-modules/05.service-desk/12.reports",{"title":499,"path":500,"stem":501},"How email replies find their ticket","/major-modules/service-desk/how-email-replies-find-their-ticket","02.major-modules/05.service-desk/13.how-email-replies-find-their-ticket",{"title":503,"path":504,"stem":505,"children":506,"page":84},"Templates","/major-modules/templates","02.major-modules/06.templates",[507,510,514,518,522,526],{"title":447,"path":508,"stem":509},"/major-modules/templates/overview","02.major-modules/06.templates/01.overview",{"title":511,"path":512,"stem":513},"Creating a template","/major-modules/templates/creating-a-template","02.major-modules/06.templates/02.creating-a-template",{"title":515,"path":516,"stem":517},"Variables","/major-modules/templates/variables","02.major-modules/06.templates/03.variables",{"title":519,"path":520,"stem":521},"Applying a template","/major-modules/templates/applying-a-template","02.major-modules/06.templates/04.applying-a-template",{"title":523,"path":524,"stem":525},"Sharing templates","/major-modules/templates/sharing-templates","02.major-modules/06.templates/05.sharing-templates",{"title":527,"path":528,"stem":529},"Template health","/major-modules/templates/template-health","02.major-modules/06.templates/06.template-health",{"title":531,"path":532,"stem":533,"children":534,"page":84},"Knowledge Base","/major-modules/knowledge-base","02.major-modules/07.knowledge-base",[535,539,543,547,551,555,559,563,567,571,575,579],{"title":536,"path":537,"stem":538},"Knowledge Base Overview","/major-modules/knowledge-base/overview","02.major-modules/07.knowledge-base/01.overview",{"title":540,"path":541,"stem":542},"Write and Publish Your First Article","/major-modules/knowledge-base/write-and-publish-your-first-article","02.major-modules/07.knowledge-base/02.write-and-publish-your-first-article",{"title":544,"path":545,"stem":546},"Organizing with Categories","/major-modules/knowledge-base/organizing-with-categories","02.major-modules/07.knowledge-base/03.organizing-with-categories",{"title":548,"path":549,"stem":550},"Who Can See an Article","/major-modules/knowledge-base/who-can-see-an-article","02.major-modules/07.knowledge-base/04.who-can-see-an-article",{"title":552,"path":553,"stem":554},"The Article Lifecycle and URLs","/major-modules/knowledge-base/article-lifecycle-and-urls","02.major-modules/07.knowledge-base/05.article-lifecycle-and-urls",{"title":556,"path":557,"stem":558},"Article History and Restore","/major-modules/knowledge-base/article-history-and-restore","02.major-modules/07.knowledge-base/06.article-history-and-restore",{"title":560,"path":561,"stem":562},"Searching and Browsing","/major-modules/knowledge-base/searching-and-browsing","02.major-modules/07.knowledge-base/07.searching-and-browsing",{"title":564,"path":565,"stem":566},"The Customer Help Center","/major-modules/knowledge-base/the-customer-help-center","02.major-modules/07.knowledge-base/08.the-customer-help-center",{"title":568,"path":569,"stem":570},"Sharing Articles and Categories","/major-modules/knowledge-base/sharing-articles-and-categories","02.major-modules/07.knowledge-base/09.sharing-articles-and-categories",{"title":572,"path":573,"stem":574},"Article Review Comments","/major-modules/knowledge-base/article-review-comments","02.major-modules/07.knowledge-base/10.article-review-comments",{"title":576,"path":577,"stem":578},"Knowledge Base Permissions","/major-modules/knowledge-base/knowledge-base-permissions","02.major-modules/07.knowledge-base/11.knowledge-base-permissions",{"title":580,"path":581,"stem":582},"Customer Comments on Articles","/major-modules/knowledge-base/customer-comments-on-articles","02.major-modules/07.knowledge-base/12.customer-comments-on-articles",{"title":584,"path":585,"stem":586,"children":587,"page":84},"Personal Workspace","/personal-workspace","03.personal-workspace",[588,594,608,619],{"title":589,"path":590,"stem":591,"children":592},"My Work","/personal-workspace/my-work","03.personal-workspace/01.my-work/index",[593],{"title":589,"path":590,"stem":591},{"title":595,"order":596,"path":597,"stem":598,"children":599,"page":84},"Notifications",7,"/personal-workspace/notifications","03.personal-workspace/02.notifications",[600,604],{"title":601,"path":602,"stem":603},"Notifications in DevStride","/personal-workspace/notifications/overview-of-notification-options","03.personal-workspace/02.notifications/01.overview-of-notification-options",{"title":605,"path":606,"stem":607},"Customizing Notification Settings","/personal-workspace/notifications/customizing-notification-settings-for-individuals-and-teams","03.personal-workspace/02.notifications/02.customizing-notification-settings-for-individuals-and-teams",{"title":609,"path":610,"stem":611,"children":612,"page":84},"My Account","/personal-workspace/my-account","03.personal-workspace/03.my-account",[613,616],{"title":447,"path":614,"stem":615},"/personal-workspace/my-account/overview","03.personal-workspace/03.my-account/01.overview",{"title":206,"path":617,"stem":618},"/personal-workspace/my-account/api-keys","03.personal-workspace/03.my-account/02.api-keys",{"title":232,"path":620,"stem":621},"/personal-workspace/keyboard-shortcuts","03.personal-workspace/04.keyboard-shortcuts",{"title":623,"path":624,"stem":625,"children":626,"page":84},"Workspace Administration","/workspace-administration","04.workspace-administration",[627,647,657,802,815,894],{"title":628,"path":629,"stem":630,"children":631,"page":84},"Manage Items Module","/workspace-administration/manage-items","04.workspace-administration/01.manage-items",[632,635,639,643],{"title":447,"path":633,"stem":634},"/workspace-administration/manage-items/overview","04.workspace-administration/01.manage-items/01.overview",{"title":636,"path":637,"stem":638},"Finding & Filtering Items","/workspace-administration/manage-items/finding-and-filtering-items","04.workspace-administration/01.manage-items/02.finding-and-filtering-items",{"title":640,"path":641,"stem":642},"Creating & Sharing Views","/workspace-administration/manage-items/creating-and-sharing-views","04.workspace-administration/01.manage-items/03.creating-and-sharing-views",{"title":644,"path":645,"stem":646},"Item Hierarchy","/workspace-administration/manage-items/item-hierarchy","04.workspace-administration/01.manage-items/04.item-hierarchy",{"title":648,"order":649,"path":650,"stem":651,"children":652,"page":84},"Automate Workflows",5,"/workspace-administration/automations","04.workspace-administration/02.automations",[653],{"title":654,"path":655,"stem":656},"Setting Up Basic Automations","/workspace-administration/automations/setting-up-basic-automations","04.workspace-administration/02.automations/01.setting-up-basic-automations",{"title":658,"order":659,"path":660,"stem":661,"children":662,"page":84},"Configure Settings",6,"/workspace-administration/settings","04.workspace-administration/03.settings",[663,708,745,754,798],{"title":664,"path":665,"stem":666,"children":667,"page":84},"Organization","/workspace-administration/settings/organization","04.workspace-administration/03.settings/01.organization",[668,672,676,680,684,688,692,696,700,704],{"title":669,"path":670,"stem":671},"Org Configuration","/workspace-administration/settings/organization/org-profile","04.workspace-administration/03.settings/01.organization/01.org-profile",{"title":673,"path":674,"stem":675},"Users, Roles & MFA","/workspace-administration/settings/organization/users-roles-and-mfa","04.workspace-administration/03.settings/01.organization/02.users-roles-and-mfa",{"title":677,"path":678,"stem":679},"Time Tracking Lock & Soft Close","/workspace-administration/settings/organization/time-tracking-lock","04.workspace-administration/03.settings/01.organization/03.time-tracking-lock",{"title":681,"path":682,"stem":683},"Training Sandboxes","/workspace-administration/settings/organization/training-sandboxes","04.workspace-administration/03.settings/01.organization/04.training-sandboxes",{"title":685,"path":686,"stem":687},"Training Sandbox Guide","/workspace-administration/settings/organization/training-sandbox-guide","04.workspace-administration/03.settings/01.organization/05.training-sandbox-guide",{"title":689,"path":690,"stem":691},"Personas","/workspace-administration/settings/organization/personas","04.workspace-administration/03.settings/01.organization/06.personas",{"title":693,"path":694,"stem":695},"Teams","/workspace-administration/settings/organization/teams","04.workspace-administration/03.settings/01.organization/07.teams",{"title":697,"path":698,"stem":699},"Import History","/workspace-administration/settings/organization/import-history","04.workspace-administration/03.settings/01.organization/08.import-history",{"title":701,"path":702,"stem":703},"Formatting Rules","/workspace-administration/settings/organization/formatting-rules","04.workspace-administration/03.settings/01.organization/09.formatting-rules",{"title":705,"path":706,"stem":707},"Subtask Statuses","/workspace-administration/settings/organization/subtask-statuses","04.workspace-administration/03.settings/01.organization/10.subtask-statuses",{"title":709,"path":710,"stem":711,"children":712,"page":84},"Data Model","/workspace-administration/settings/data-model","04.workspace-administration/03.settings/02.data-model",[713,717,721,725,729,733,737,741],{"title":714,"path":715,"stem":716},"Cadences","/workspace-administration/settings/data-model/cadences","04.workspace-administration/03.settings/02.data-model/01.cadences",{"title":718,"path":719,"stem":720},"Item Types","/workspace-administration/settings/data-model/item-types","04.workspace-administration/03.settings/02.data-model/02.item-types",{"title":722,"path":723,"stem":724},"Tags","/workspace-administration/settings/data-model/tags","04.workspace-administration/03.settings/02.data-model/03.tags",{"title":726,"path":727,"stem":728},"Custom Fields","/workspace-administration/settings/data-model/custom-fields","04.workspace-administration/03.settings/02.data-model/04.custom-fields",{"title":730,"path":731,"stem":732},"Priority Levels","/workspace-administration/settings/data-model/priority-levels","04.workspace-administration/03.settings/02.data-model/05.priority-levels",{"title":734,"path":735,"stem":736},"Effort Points and Time Estimation","/workspace-administration/settings/data-model/effort-points-and-time-estimation","04.workspace-administration/03.settings/02.data-model/06.effort-points-and-time-estimation",{"title":738,"path":739,"stem":740},"Statuses and WIP Limiters","/workspace-administration/settings/data-model/statuses-and-wip-limiters","04.workspace-administration/03.settings/02.data-model/07.statuses-and-wip-limiters",{"title":742,"path":743,"stem":744},"Customizing the Item Drawer","/workspace-administration/settings/data-model/customizing-the-item-drawer","04.workspace-administration/03.settings/02.data-model/08.customizing-the-item-drawer",{"title":746,"path":747,"stem":748,"children":749,"page":84},"Forms","/workspace-administration/settings/forms","04.workspace-administration/03.settings/03.forms",[750],{"title":751,"path":752,"stem":753},"Item Request Forms","/workspace-administration/settings/forms/item-request-forms","04.workspace-administration/03.settings/03.forms/item-request-forms",{"title":755,"path":756,"stem":757,"children":758,"page":84},"Integrations","/workspace-administration/settings/integrations","04.workspace-administration/03.settings/04.integrations",[759,763,767,771,775,778,782,786,790,794],{"title":760,"path":761,"stem":762},"GitHub","/workspace-administration/settings/integrations/github","04.workspace-administration/03.settings/04.integrations/01.github",{"title":764,"path":765,"stem":766},"Connect AI & the MCP Server","/workspace-administration/settings/integrations/connect-ai-and-mcp","04.workspace-administration/03.settings/04.integrations/02.connect-ai-and-mcp",{"title":768,"path":769,"stem":770},"Database Access for BI Tools","/workspace-administration/settings/integrations/database-access","04.workspace-administration/03.settings/04.integrations/03.database-access",{"title":772,"path":773,"stem":774},"Jira Integration","/workspace-administration/settings/integrations/jira","04.workspace-administration/03.settings/04.integrations/04.jira",{"title":206,"path":776,"stem":777},"/workspace-administration/settings/integrations/api-keys","04.workspace-administration/03.settings/04.integrations/05.api-keys",{"title":779,"path":780,"stem":781},"Enterprise SSO","/workspace-administration/settings/integrations/enterprise-sso","04.workspace-administration/03.settings/04.integrations/06.enterprise-sso",{"title":783,"path":784,"stem":785},"Microsoft Teams","/workspace-administration/settings/integrations/microsoft-teams","04.workspace-administration/03.settings/04.integrations/07.microsoft-teams",{"title":787,"path":788,"stem":789},"Slack","/workspace-administration/settings/integrations/slack","04.workspace-administration/03.settings/04.integrations/08.slack",{"title":791,"path":792,"stem":793},"Connected Apps","/workspace-administration/settings/integrations/connected-apps","04.workspace-administration/03.settings/04.integrations/09.connected-apps",{"title":795,"path":796,"stem":797},"Azure DevOps Integration","/workspace-administration/settings/integrations/azure-devops","04.workspace-administration/03.settings/04.integrations/10.azure-devops",{"title":799,"path":800,"stem":801},"Subscription & Billing","/workspace-administration/settings/subscription-and-billing","04.workspace-administration/03.settings/05.subscription-and-billing",{"title":483,"path":803,"stem":804,"children":805,"page":84},"/workspace-administration/permissions","04.workspace-administration/04.permissions",[806,809,812],{"title":194,"path":807,"stem":808},"/workspace-administration/permissions/understanding-permissions","04.workspace-administration/04.permissions/01.understanding-permissions",{"title":198,"path":810,"stem":811},"/workspace-administration/permissions/roles-and-permissions","04.workspace-administration/04.permissions/02.roles-and-permissions",{"title":202,"path":813,"stem":814},"/workspace-administration/permissions/sharing-and-access","04.workspace-administration/04.permissions/03.sharing-and-access",{"title":816,"order":817,"path":818,"stem":819,"children":820,"page":84},"Filters",10,"/workspace-administration/filters","04.workspace-administration/05.filters",[821,824,827,831,835,839,843,846,849,853,873],{"title":589,"path":822,"stem":823},"/workspace-administration/filters/my-work","04.workspace-administration/05.filters/01.my-work",{"title":595,"path":825,"stem":826},"/workspace-administration/filters/notifications","04.workspace-administration/05.filters/02.notifications",{"title":828,"path":829,"stem":830},"Workstreams","/workspace-administration/filters/workstreams","04.workspace-administration/05.filters/03.workstreams",{"title":832,"path":833,"stem":834},"Cycles","/workspace-administration/filters/cycles","04.workspace-administration/05.filters/04.cycles",{"title":836,"path":837,"stem":838},"Boards","/workspace-administration/filters/boards","04.workspace-administration/05.filters/05.boards",{"title":840,"path":841,"stem":842},"Gantt","/workspace-administration/filters/gantt","04.workspace-administration/05.filters/06.gantt",{"title":52,"path":844,"stem":845},"/workspace-administration/filters/items","04.workspace-administration/05.filters/07.items",{"title":495,"path":847,"stem":848},"/workspace-administration/filters/reports","04.workspace-administration/05.filters/08.reports",{"title":850,"path":851,"stem":852},"Automations","/workspace-administration/filters/automations","04.workspace-administration/05.filters/09.automations",{"title":854,"path":855,"stem":856,"children":857,"page":84},"Sort ","/workspace-administration/filters/sort","04.workspace-administration/05.filters/10.sort",[858,861,864,867,870],{"title":589,"path":859,"stem":860},"/workspace-administration/filters/sort/my-work","04.workspace-administration/05.filters/10.sort/01.my-work",{"title":828,"path":862,"stem":863},"/workspace-administration/filters/sort/workstreams","04.workspace-administration/05.filters/10.sort/02.workstreams",{"title":832,"path":865,"stem":866},"/workspace-administration/filters/sort/cycles","04.workspace-administration/05.filters/10.sort/03.cycles",{"title":836,"path":868,"stem":869},"/workspace-administration/filters/sort/boards","04.workspace-administration/05.filters/10.sort/04.boards",{"title":52,"path":871,"stem":872},"/workspace-administration/filters/sort/items","04.workspace-administration/05.filters/10.sort/05.items",{"title":874,"path":875,"stem":876,"children":877,"page":84},"Options","/workspace-administration/filters/options","04.workspace-administration/05.filters/11.options",[878,881,884,888,891],{"title":589,"path":879,"stem":880},"/workspace-administration/filters/options/my-work","04.workspace-administration/05.filters/11.options/01.my-work",{"title":828,"path":882,"stem":883},"/workspace-administration/filters/options/workstreams","04.workspace-administration/05.filters/11.options/02.workstreams",{"title":885,"path":886,"stem":887},"Cycle","/workspace-administration/filters/options/cycle","04.workspace-administration/05.filters/11.options/03.cycle",{"title":836,"path":889,"stem":890},"/workspace-administration/filters/options/boards","04.workspace-administration/05.filters/11.options/04.boards",{"title":52,"path":892,"stem":893},"/workspace-administration/filters/options/items","04.workspace-administration/05.filters/11.options/05.items",{"title":895,"path":896,"stem":897},"AI Assistant","/workspace-administration/ai-assistant","04.workspace-administration/06.ai-assistant",{"title":899,"path":900,"stem":901,"children":902,"page":84},"Planning Concepts & Use Cases","/planning-concepts-and-use-cases","05.planning-concepts-and-use-cases",[903,959],{"title":904,"order":905,"path":906,"stem":907,"children":908,"page":84},"Understanding Project Planning Tools",9,"/planning-concepts-and-use-cases/project-planning-tools","05.planning-concepts-and-use-cases/01.project-planning-tools",[909,942],{"title":910,"path":911,"stem":912,"children":913,"page":84},"Gantt Charts","/planning-concepts-and-use-cases/project-planning-tools/gantt-charts","05.planning-concepts-and-use-cases/01.project-planning-tools/gantt-charts",[914,918,922,926,930,934,938],{"title":915,"path":916,"stem":917},"Gantt Charts Basics","/planning-concepts-and-use-cases/project-planning-tools/gantt-charts/gantt-charts-basics","05.planning-concepts-and-use-cases/01.project-planning-tools/gantt-charts/01.gantt-charts-basics",{"title":919,"path":920,"stem":921},"Create New Gantt","/planning-concepts-and-use-cases/project-planning-tools/gantt-charts/create-new-gantt","05.planning-concepts-and-use-cases/01.project-planning-tools/gantt-charts/02.create-new-gantt",{"title":923,"path":924,"stem":925},"Add to Gantt","/planning-concepts-and-use-cases/project-planning-tools/gantt-charts/add-to-gantt","05.planning-concepts-and-use-cases/01.project-planning-tools/gantt-charts/03.add-to-gantt",{"title":927,"path":928,"stem":929},"Gantt Charts Toolbar","/planning-concepts-and-use-cases/project-planning-tools/gantt-charts/gantt-charts-toolbar","05.planning-concepts-and-use-cases/01.project-planning-tools/gantt-charts/04.gantt-charts-toolbar",{"title":931,"path":932,"stem":933},"Scenario Planning","/planning-concepts-and-use-cases/project-planning-tools/gantt-charts/scenario-planning","05.planning-concepts-and-use-cases/01.project-planning-tools/gantt-charts/05.scenario-planning",{"title":935,"path":936,"stem":937},"Tips for Effective Gantt Chart Planning","/planning-concepts-and-use-cases/project-planning-tools/gantt-charts/tips-for-effective-gantt-chart-planning","05.planning-concepts-and-use-cases/01.project-planning-tools/gantt-charts/06.tips-for-effective-gantt-chart-planning",{"title":939,"path":940,"stem":941},"Link Mode","/planning-concepts-and-use-cases/project-planning-tools/gantt-charts/link-mode","05.planning-concepts-and-use-cases/01.project-planning-tools/gantt-charts/07.link-mode",{"title":943,"path":944,"stem":945,"children":946,"page":84},"Kanban Boards","/planning-concepts-and-use-cases/project-planning-tools/kanban-boards","05.planning-concepts-and-use-cases/01.project-planning-tools/kanban-boards",[947,951,955],{"title":948,"path":949,"stem":950},"Setting Up Your Kanban Board","/planning-concepts-and-use-cases/project-planning-tools/kanban-boards/setting-up-your-kanban-board","05.planning-concepts-and-use-cases/01.project-planning-tools/kanban-boards/01.setting-up-your-kanban-board",{"title":952,"path":953,"stem":954},"Using Kanban for Workflow Visualization","/planning-concepts-and-use-cases/project-planning-tools/kanban-boards/using-kanban-for-workflow-visualization","05.planning-concepts-and-use-cases/01.project-planning-tools/kanban-boards/02.using-kanban-for-workflow-visualization",{"title":956,"path":957,"stem":958},"Kanban Best Practices","/planning-concepts-and-use-cases/project-planning-tools/kanban-boards/kanban-best-practices","05.planning-concepts-and-use-cases/01.project-planning-tools/kanban-boards/03.kanban-best-practices",{"title":960,"order":961,"path":962,"stem":963,"children":964,"page":84},"Use Cases",12,"/planning-concepts-and-use-cases/use-cases","05.planning-concepts-and-use-cases/02.use-cases",[965,968,972,976,980,984],{"title":910,"path":966,"stem":967},"/planning-concepts-and-use-cases/use-cases/gantt-charts","05.planning-concepts-and-use-cases/02.use-cases/01.gantt-charts",{"title":969,"path":970,"stem":971},"Plan a Sprint","/planning-concepts-and-use-cases/use-cases/plan-a-sprint","05.planning-concepts-and-use-cases/02.use-cases/02.plan-a-sprint",{"title":973,"path":974,"stem":975},"Conduct a Standup","/planning-concepts-and-use-cases/use-cases/conduct-a-standup","05.planning-concepts-and-use-cases/02.use-cases/03.conduct-a-standup",{"title":977,"path":978,"stem":979},"Manage Cadences","/planning-concepts-and-use-cases/use-cases/manage-cadences","05.planning-concepts-and-use-cases/02.use-cases/04.manage-cadences",{"title":981,"path":982,"stem":983},"Customizing Item Types","/planning-concepts-and-use-cases/use-cases/customizing-item-types","05.planning-concepts-and-use-cases/02.use-cases/05.customizing-item-types",{"title":985,"path":986,"stem":987},"Backlog Refinement","/planning-concepts-and-use-cases/use-cases/backlog-refinement","05.planning-concepts-and-use-cases/02.use-cases/06.backlog-refinement",{"title":989,"path":990,"stem":991,"children":992,"page":84},"Integrations & Extensibility","/integrations-and-extensibility","06.integrations-and-extensibility",[993,1018,1076],{"title":994,"path":995,"stem":996,"children":997,"page":84},"DevStride MCP Server","/integrations-and-extensibility/devstride-mcp-server","06.integrations-and-extensibility/01.devstride-mcp-server",[998,1002,1006,1010,1014],{"title":999,"path":1000,"stem":1001},"What Is the DevStride MCP Server?","/integrations-and-extensibility/devstride-mcp-server/what-is-the-devstride-mcp-server","06.integrations-and-extensibility/01.devstride-mcp-server/01.what-is-the-devstride-mcp-server",{"title":1003,"path":1004,"stem":1005},"Setting Up Your Connection","/integrations-and-extensibility/devstride-mcp-server/setting-up-your-connection","06.integrations-and-extensibility/01.devstride-mcp-server/02.setting-up-your-connection",{"title":1007,"path":1008,"stem":1009},"Doing Real Work with the DevStride MCP Server","/integrations-and-extensibility/devstride-mcp-server/doing-real-work-with-the-devstride-mcp-server","06.integrations-and-extensibility/01.devstride-mcp-server/03.doing-real-work-with-the-devstride-mcp-server",{"title":1011,"path":1012,"stem":1013},"Best Practices & Tips","/integrations-and-extensibility/devstride-mcp-server/best-practices-and-tips","06.integrations-and-extensibility/01.devstride-mcp-server/04.best-practices-and-tips",{"title":1015,"path":1016,"stem":1017},"Tool Reference","/integrations-and-extensibility/devstride-mcp-server/tool-reference","06.integrations-and-extensibility/01.devstride-mcp-server/05.tool-reference",{"title":1019,"path":1020,"stem":1021,"children":1022},"Plugins","/integrations-and-extensibility/plugins","06.integrations-and-extensibility/02.plugins/index",[1023,1025],{"title":1024,"path":1020,"stem":1021},"Getting Started With Plugins",{"title":1026,"path":1027,"stem":1028,"children":1029,"page":84},"Weekly Logs","/integrations-and-extensibility/plugins/weekly-logs","06.integrations-and-extensibility/02.plugins/01.weekly-logs",[1030,1033,1037,1041,1045,1049,1053,1057,1060,1064,1068,1072],{"title":447,"path":1031,"stem":1032},"/integrations-and-extensibility/plugins/weekly-logs/overview","06.integrations-and-extensibility/02.plugins/01.weekly-logs/01.overview",{"title":1034,"path":1035,"stem":1036},"Grid","/integrations-and-extensibility/plugins/weekly-logs/grid","06.integrations-and-extensibility/02.plugins/01.weekly-logs/02.grid",{"title":1038,"path":1039,"stem":1040},"Views","/integrations-and-extensibility/plugins/weekly-logs/views","06.integrations-and-extensibility/02.plugins/01.weekly-logs/03.views",{"title":1042,"path":1043,"stem":1044},"Navigation","/integrations-and-extensibility/plugins/weekly-logs/navigation","06.integrations-and-extensibility/02.plugins/01.weekly-logs/04.navigation",{"title":1046,"path":1047,"stem":1048},"Proposed Items","/integrations-and-extensibility/plugins/weekly-logs/proposed-items","06.integrations-and-extensibility/02.plugins/01.weekly-logs/05.proposed-items",{"title":1050,"path":1051,"stem":1052},"Search","/integrations-and-extensibility/plugins/weekly-logs/search","06.integrations-and-extensibility/02.plugins/01.weekly-logs/06.search",{"title":1054,"path":1055,"stem":1056},"Time Logging","/integrations-and-extensibility/plugins/weekly-logs/logging","06.integrations-and-extensibility/02.plugins/01.weekly-logs/07.logging",{"title":816,"path":1058,"stem":1059},"/integrations-and-extensibility/plugins/weekly-logs/filtering","06.integrations-and-extensibility/02.plugins/01.weekly-logs/08.filtering",{"title":1061,"path":1062,"stem":1063},"Team Logs","/integrations-and-extensibility/plugins/weekly-logs/team-logs","06.integrations-and-extensibility/02.plugins/01.weekly-logs/09.team-logs",{"title":1065,"path":1066,"stem":1067},"Organization Switch","/integrations-and-extensibility/plugins/weekly-logs/organization-switch","06.integrations-and-extensibility/02.plugins/01.weekly-logs/10.organization-switch",{"title":1069,"path":1070,"stem":1071},"Export","/integrations-and-extensibility/plugins/weekly-logs/export","06.integrations-and-extensibility/02.plugins/01.weekly-logs/11.export",{"title":1073,"path":1074,"stem":1075},"Meetings","/integrations-and-extensibility/plugins/weekly-logs/meetings","06.integrations-and-extensibility/02.plugins/01.weekly-logs/12.meetings",{"title":1077,"path":1078,"stem":1079,"children":1080},"Webhooks","/integrations-and-extensibility/webhooks","06.integrations-and-extensibility/03.webhooks/index",[1081,1082,1086,1090,1094,1098,1102],{"title":1077,"path":1078,"stem":1079},{"title":1083,"path":1084,"stem":1085},"Quickstart","/integrations-and-extensibility/webhooks/quickstart","06.integrations-and-extensibility/03.webhooks/01.quickstart",{"title":1087,"path":1088,"stem":1089},"Events & Payloads","/integrations-and-extensibility/webhooks/events-and-payloads","06.integrations-and-extensibility/03.webhooks/02.events-and-payloads",{"title":1091,"path":1092,"stem":1093},"Verifying Signatures","/integrations-and-extensibility/webhooks/verifying-signatures","06.integrations-and-extensibility/03.webhooks/03.verifying-signatures",{"title":1095,"path":1096,"stem":1097},"Delivery, Retries & Ordering","/integrations-and-extensibility/webhooks/delivery-retries-and-ordering","06.integrations-and-extensibility/03.webhooks/04.delivery-retries-and-ordering",{"title":1099,"path":1100,"stem":1101},"Managing Endpoints","/integrations-and-extensibility/webhooks/managing-endpoints","06.integrations-and-extensibility/03.webhooks/05.managing-endpoints",{"title":1103,"path":1104,"stem":1105},"Troubleshooting & Best Practices","/integrations-and-extensibility/webhooks/troubleshooting-and-best-practices","06.integrations-and-extensibility/03.webhooks/06.troubleshooting-and-best-practices",{"title":1107,"path":1108,"stem":1109,"children":1110,"page":84},"Developer Experience","/developer-experience","07.developer-experience",[1111,1147,1203],{"title":1112,"path":1113,"stem":1114,"children":1115,"page":84},"Developer Guide","/developer-experience/guide","07.developer-experience/00.guide",[1116,1119,1123,1127,1131,1135,1139,1143],{"title":447,"path":1117,"stem":1118},"/developer-experience/guide/overview","07.developer-experience/00.guide/01.overview",{"title":1120,"path":1121,"stem":1122},"Set up your machine","/developer-experience/guide/set-up-your-machine","07.developer-experience/00.guide/02.set-up-your-machine",{"title":1124,"path":1125,"stem":1126},"Credentials and access","/developer-experience/guide/credentials-and-access","07.developer-experience/00.guide/03.credentials-and-access",{"title":1128,"path":1129,"stem":1130},"Plan work","/developer-experience/guide/plan-work","07.developer-experience/00.guide/04.plan-work",{"title":1132,"path":1133,"stem":1134},"Develop","/developer-experience/guide/develop","07.developer-experience/00.guide/05.develop",{"title":1136,"path":1137,"stem":1138},"Release","/developer-experience/guide/release","07.developer-experience/00.guide/06.release",{"title":1140,"path":1141,"stem":1142},"Troubleshooting","/developer-experience/guide/troubleshooting","07.developer-experience/00.guide/07.troubleshooting",{"title":1144,"path":1145,"stem":1146},"For admins: access, keys and stages","/developer-experience/guide/for-admins","07.developer-experience/00.guide/08.for-admins",{"title":1148,"path":1149,"stem":1150,"children":1151,"page":84},"Intro","/developer-experience/intro","07.developer-experience/01.intro",[1152,1156,1159,1163,1167,1171,1175,1179,1183,1187,1191,1195,1199],{"title":1153,"path":1154,"stem":1155},"How DevStride Is Built, and Why","/developer-experience/intro/how-we-build","07.developer-experience/01.intro/00.how-we-build",{"title":5,"path":1157,"stem":1158},"/developer-experience/intro/getting-started","07.developer-experience/01.intro/01.getting-started",{"title":1160,"path":1161,"stem":1162},"Introduction to the ds CLI","/developer-experience/intro/introduction","07.developer-experience/01.intro/02.introduction",{"title":1164,"path":1165,"stem":1166},"Command Reference","/developer-experience/intro/command-reference","07.developer-experience/01.intro/03.command-reference",{"title":1168,"path":1169,"stem":1170},"Local Development","/developer-experience/intro/local-development","07.developer-experience/01.intro/04.local-development",{"title":1172,"path":1173,"stem":1174},"Dockerized Worktree Development","/developer-experience/intro/dockerized-worktree-development","07.developer-experience/01.intro/05.dockerized-worktree-development",{"title":1176,"path":1177,"stem":1178},"Golden Dataset","/developer-experience/intro/golden-dataset","07.developer-experience/01.intro/06.golden-dataset",{"title":1180,"path":1181,"stem":1182},"Deployment","/developer-experience/intro/deployment","07.developer-experience/01.intro/07.deployment",{"title":1184,"path":1185,"stem":1186},"API Development","/developer-experience/intro/api-development","07.developer-experience/01.intro/08.api-development",{"title":1188,"path":1189,"stem":1190},"Stripe Integration","/developer-experience/intro/stripe-integration","07.developer-experience/01.intro/09.stripe-integration",{"title":1192,"path":1193,"stem":1194},"Maintenance & Codebase Checks","/developer-experience/intro/maintenance-and-codebase-checks","07.developer-experience/01.intro/10.maintenance-and-codebase-checks",{"title":1196,"path":1197,"stem":1198},"AI Development","/developer-experience/intro/ai-development","07.developer-experience/01.intro/11.ai-development",{"title":1200,"path":1201,"stem":1202},"Data Conversion Utilities","/developer-experience/intro/data-conversion-utilities","07.developer-experience/01.intro/12.data-conversion-utilities",{"title":1204,"path":1205,"stem":1206,"children":1207,"page":84},"Agentic Skills","/developer-experience/agentic-skills","07.developer-experience/02.agentic-skills",[1208,1212,1216,1220,1224,1228,1232,1236],{"title":1209,"path":1210,"stem":1211},"The Idea Behind the Loop","/developer-experience/agentic-skills/the-idea-behind-the-loop","07.developer-experience/02.agentic-skills/00.the-idea-behind-the-loop",{"title":1213,"path":1214,"stem":1215},"DevStride for Claude Code","/developer-experience/agentic-skills/claude-code-skills-overview","07.developer-experience/02.agentic-skills/01.claude-code-skills-overview",{"title":1217,"path":1218,"stem":1219},"Getting the Skills","/developer-experience/agentic-skills/getting-the-skills","07.developer-experience/02.agentic-skills/02.getting-the-skills",{"title":1221,"path":1222,"stem":1223},"Guided Setup","/developer-experience/agentic-skills/setup-guide","07.developer-experience/02.agentic-skills/03.setup-guide",{"title":1225,"path":1226,"stem":1227},"Skill Audit","/developer-experience/agentic-skills/skill-audit","07.developer-experience/02.agentic-skills/04.skill-audit",{"title":1229,"path":1230,"stem":1231},"The Planning Loop","/developer-experience/agentic-skills/claude-skills-planning-loop","07.developer-experience/02.agentic-skills/05.claude-skills-planning-loop",{"title":1233,"path":1234,"stem":1235},"The Delivery Loop","/developer-experience/agentic-skills/claude-skills-delivery-loop","07.developer-experience/02.agentic-skills/06.claude-skills-delivery-loop",{"title":1237,"path":1238,"stem":1239},"Configuration Reference","/developer-experience/agentic-skills/configuration-reference","07.developer-experience/02.agentic-skills/07.configuration-reference",{"title":1241,"order":1242,"path":1243,"stem":1244,"children":1245,"page":84},"Release Notes",11,"/release-notes","08.release-notes",[1246,1250,1254,1258,1262,1266,1270,1274,1278,1282,1286,1290,1294,1298,1302,1306,1310,1314,1318,1322,1326,1330,1334,1338,1342,1346,1350,1354,1358,1362,1366,1370,1374,1378,1382,1386,1390,1394,1398,1402,1406,1410,1414,1418,1422,1426,1430,1434,1438,1442,1446,1450,1454,1458,1462,1466,1470,1474,1478,1482,1486,1490,1494,1498,1502,1506,1510,1514,1518,1522,1526,1530,1534,1538,1542,1546,1550,1554,1558,1562,1566,1570,1574],{"title":1247,"path":1248,"stem":1249},"2026-10-12","/release-notes/2026-10-12","08.release-notes/83.2026-10-12",{"title":1251,"path":1252,"stem":1253},"2026-10-03","/release-notes/2026-10-03","08.release-notes/82.2026-10-03",{"title":1255,"path":1256,"stem":1257},"2026-09-17","/release-notes/2026-09-17","08.release-notes/81.2026-09-17",{"title":1259,"path":1260,"stem":1261},"2026-09-13","/release-notes/2026-09-13","08.release-notes/80.2026-09-13",{"title":1263,"path":1264,"stem":1265},"2026-09-11","/release-notes/2026-09-11","08.release-notes/79.2026-09-11",{"title":1267,"path":1268,"stem":1269},"2026-09-01","/release-notes/2026-09-01","08.release-notes/78.2026-09-01",{"title":1271,"path":1272,"stem":1273},"2026-08-29","/release-notes/2026-08-29","08.release-notes/77.2026-08-29",{"title":1275,"path":1276,"stem":1277},"2026-08-27","/release-notes/2026-08-27","08.release-notes/76.2026-08-27",{"title":1279,"path":1280,"stem":1281},"2026-08-25","/release-notes/2026-08-25","08.release-notes/75.2026-08-25",{"title":1283,"path":1284,"stem":1285},"2026-08-22","/release-notes/2026-08-22","08.release-notes/74.2026-08-22",{"title":1287,"path":1288,"stem":1289},"2026-08-21","/release-notes/2026-08-21","08.release-notes/73.2026-08-21",{"title":1291,"path":1292,"stem":1293},"2026-08-17","/release-notes/2026-08-17","08.release-notes/72.2026-08-17",{"title":1295,"path":1296,"stem":1297},"2026-08-16","/release-notes/2026-08-16","08.release-notes/71.2026-08-16",{"title":1299,"path":1300,"stem":1301},"2026-08-14","/release-notes/2026-08-14","08.release-notes/70.2026-08-14",{"title":1303,"path":1304,"stem":1305},"2026-08-11","/release-notes/2026-08-11","08.release-notes/69.2026-08-11",{"title":1307,"path":1308,"stem":1309},"2026-08-07","/release-notes/2026-08-07","08.release-notes/68.2026-08-07",{"title":1311,"path":1312,"stem":1313},"2026-08-05","/release-notes/2026-08-05","08.release-notes/67.2026-08-05",{"title":1315,"path":1316,"stem":1317},"2026-08-01","/release-notes/2026-08-01","08.release-notes/66.2026-08-01",{"title":1319,"path":1320,"stem":1321},"2026-07-30","/release-notes/2026-07-30","08.release-notes/65.2026-07-30",{"title":1323,"path":1324,"stem":1325},"2026-07-28","/release-notes/2026-07-28","08.release-notes/64.2026-07-28",{"title":1327,"path":1328,"stem":1329},"2026-07-22","/release-notes/2026-07-22","08.release-notes/63.2026-07-22",{"title":1331,"path":1332,"stem":1333},"2026-07-19","/release-notes/2026-07-19","08.release-notes/62.2026-07-19",{"title":1335,"path":1336,"stem":1337},"2026-07-17","/release-notes/2026-07-17","08.release-notes/61.2026-07-17",{"title":1339,"path":1340,"stem":1341},"2026-07-15","/release-notes/2026-07-15","08.release-notes/60.2026-07-15",{"title":1343,"path":1344,"stem":1345},"2026-07-12","/release-notes/2026-07-12","08.release-notes/59.2026-07-12",{"title":1347,"path":1348,"stem":1349},"2026-07-11","/release-notes/2026-07-11","08.release-notes/58.2026-07-11",{"title":1351,"path":1352,"stem":1353},"2026-07-09","/release-notes/2026-07-09","08.release-notes/57.2026-07-09",{"title":1355,"path":1356,"stem":1357},"2026-07-07","/release-notes/2026-07-07","08.release-notes/56.2026-07-07",{"title":1359,"path":1360,"stem":1361},"2026-07-06","/release-notes/2026-07-06","08.release-notes/55.2026-07-06",{"title":1363,"path":1364,"stem":1365},"2026-07-02","/release-notes/2026-07-02","08.release-notes/54.2026-07-02",{"title":1367,"path":1368,"stem":1369},"2026-06-30","/release-notes/2026-06-30","08.release-notes/53.2026-06-30",{"title":1371,"path":1372,"stem":1373},"2026-06-17","/release-notes/2026-06-17","08.release-notes/52.2026-06-17",{"title":1375,"path":1376,"stem":1377},"2026-06-12","/release-notes/2026-06-12","08.release-notes/51.2026-06-12",{"title":1379,"path":1380,"stem":1381},"2026-05-29","/release-notes/2026-05-29","08.release-notes/50.2026-05-29",{"title":1383,"path":1384,"stem":1385},"2026-05-13","/release-notes/2026-05-13","08.release-notes/49.2026-05-13",{"title":1387,"path":1388,"stem":1389},"2026-04-29","/release-notes/2026-04-29","08.release-notes/48.2026-04-29",{"title":1391,"path":1392,"stem":1393},"2026-04-14","/release-notes/2026-04-14","08.release-notes/47.2026-04-14",{"title":1395,"path":1396,"stem":1397},"2026-04-09","/release-notes/2026-04-09","08.release-notes/46.2026-04-09",{"title":1399,"path":1400,"stem":1401},"2026-03-13","/release-notes/2026-03-13","08.release-notes/45.2026-03-13",{"title":1403,"path":1404,"stem":1405},"2026-02-16","/release-notes/2026-02-16","08.release-notes/44.2026-02-16",{"title":1407,"path":1408,"stem":1409},"2026-02-06","/release-notes/2026-02-06","08.release-notes/43.2026-02-06",{"title":1411,"path":1412,"stem":1413},"2026-01-30","/release-notes/2026-01-30","08.release-notes/42.2026-01-30",{"title":1415,"path":1416,"stem":1417},"2026-01-19","/release-notes/2026-01-19","08.release-notes/41.2026-01-19",{"title":1419,"path":1420,"stem":1421},"2025-09-27","/release-notes/2025-09-27","08.release-notes/40.2025-09-27",{"title":1423,"path":1424,"stem":1425},"2025-07-07","/release-notes/2025-07-07","08.release-notes/39.2025-07-07",{"title":1427,"path":1428,"stem":1429},"2025-06-16","/release-notes/2025-06-16","08.release-notes/38.2025-06-16",{"title":1431,"path":1432,"stem":1433},"2025-05-29","/release-notes/2025-05-29","08.release-notes/37.2025-05-29",{"title":1435,"path":1436,"stem":1437},"2025-04-28","/release-notes/2025-04-28","08.release-notes/36.2025-04-28",{"title":1439,"path":1440,"stem":1441},"2025-03-24","/release-notes/2025-03-24","08.release-notes/35.2025-03-24",{"title":1443,"path":1444,"stem":1445},"2024-12-20","/release-notes/2024-12-20","08.release-notes/34.2024-12-20",{"title":1447,"path":1448,"stem":1449},"2024-10-21","/release-notes/2024-10-21","08.release-notes/33.2024-10-21",{"title":1451,"path":1452,"stem":1453},"2024-10-11","/release-notes/2024-10-11","08.release-notes/32.2024-10-11",{"title":1455,"path":1456,"stem":1457},"2024-09-11","/release-notes/2024-09-11","08.release-notes/31.2024-09-11",{"title":1459,"path":1460,"stem":1461},"2024-08-28","/release-notes/2024-08-28","08.release-notes/30.2024-08-28",{"title":1463,"path":1464,"stem":1465},"2024-07-10","/release-notes/2024-07-10","08.release-notes/29.2024-07-10",{"title":1467,"path":1468,"stem":1469},"2024-06-24","/release-notes/2024-06-24","08.release-notes/28.2024-06-24",{"title":1471,"path":1472,"stem":1473},"2024-05-15","/release-notes/2024-05-15","08.release-notes/27.2024-05-15",{"title":1475,"path":1476,"stem":1477},"2024-04-29","/release-notes/2024-04-29","08.release-notes/26.2024-04-29",{"title":1479,"path":1480,"stem":1481},"2024-03-18","/release-notes/2024-03-18","08.release-notes/25.2024-03-18",{"title":1483,"path":1484,"stem":1485},"2024-03-04","/release-notes/2024-03-04","08.release-notes/24.2024-03-04",{"title":1487,"path":1488,"stem":1489},"2024-02-26","/release-notes/2024-02-26","08.release-notes/23.2024-02-26",{"title":1491,"path":1492,"stem":1493},"2024-01-17","/release-notes/2024-01-17","08.release-notes/22.2024-01-17",{"title":1495,"path":1496,"stem":1497},"2023-12-27","/release-notes/2023-12-27","08.release-notes/21.2023-12-27",{"title":1499,"path":1500,"stem":1501},"2023-11-08","/release-notes/2023-11-08","08.release-notes/20.2023-11-08",{"title":1503,"path":1504,"stem":1505},"2023-10-10","/release-notes/2023-10-10","08.release-notes/19.2023-10-10",{"title":1507,"path":1508,"stem":1509},"2023-09-27","/release-notes/2023-09-27","08.release-notes/18.2023-09-27",{"title":1511,"path":1512,"stem":1513},"2023-09-18","/release-notes/2023-09-18","08.release-notes/17.2023-09-18",{"title":1515,"path":1516,"stem":1517},"2023-09-04","/release-notes/2023-09-04","08.release-notes/16.2023-09-04",{"title":1519,"path":1520,"stem":1521},"2023-08-04","/release-notes/2023-08-04","08.release-notes/15.2023-08-04",{"title":1523,"path":1524,"stem":1525},"2023-07-11","/release-notes/2023-07-11","08.release-notes/14.2023-07-11",{"title":1527,"path":1528,"stem":1529},"2023-06-21","/release-notes/2023-06-21","08.release-notes/13.2023-06-21",{"title":1531,"path":1532,"stem":1533},"2023-05-24","/release-notes/2023-05-24","08.release-notes/12.2023-05-24",{"title":1535,"path":1536,"stem":1537},"2023-04-24","/release-notes/2023-04-24","08.release-notes/11.2023-04-24",{"title":1539,"path":1540,"stem":1541},"2023-04-20","/release-notes/2023-04-20","08.release-notes/10.2023-04-20",{"title":1543,"path":1544,"stem":1545},"2023-03-20","/release-notes/2023-03-20","08.release-notes/09.2023-03-20",{"title":1547,"path":1548,"stem":1549},"2023-02-28","/release-notes/2023-02-28","08.release-notes/08.2023-02-28",{"title":1551,"path":1552,"stem":1553},"2023-01-17","/release-notes/2023-01-17","08.release-notes/07.2023-01-17",{"title":1555,"path":1556,"stem":1557},"2023-01-23","/release-notes/2023-01-23","08.release-notes/06.2023-01-23",{"title":1559,"path":1560,"stem":1561},"2022-12-21","/release-notes/2022-12-21","08.release-notes/05.2022-12-21",{"title":1563,"path":1564,"stem":1565},"2022-12-06","/release-notes/2022-12-06","08.release-notes/04.2022-12-06",{"title":1567,"path":1568,"stem":1569},"2022-11-15","/release-notes/2022-11-15","08.release-notes/03.2022-11-15",{"title":1571,"path":1572,"stem":1573},"2022-11-02","/release-notes/2022-11-02","08.release-notes/02.2022-11-02",{"title":1575,"path":1576,"stem":1577},"2022-10-17","/release-notes/2022-10-17","08.release-notes/01.2022-10-17",{"title":1579,"path":1580,"target":1581},"API","https://api-docs.devstride.com/","_blank",{"id":1583,"title":1083,"body":1584,"description":4110,"extension":4111,"links":4112,"meta":4113,"navigation":1753,"path":1084,"seo":4114,"stem":1085,"__hash__":4115},"docs/06.integrations-and-extensibility/03.webhooks/01.quickstart.md",{"type":1585,"value":1586,"toc":4098},"minimark",[1587,1591,1625,1630,1633,1668,1675,1680,3300,3304,3448,3452,3582,3598,3613,3616,3620,3680,3686,3690,3706,3722,3728,3732,3743,3802,3808,4016,4020,4033,4070,4073,4077,4094],[1588,1589,1590],"p",{},"This page takes you from nothing to a working, verified webhook receiver. You need:",[1592,1593,1594,1609],"ul",{},[1595,1596,1597,1598,1602,1603,1608],"li",{},"The ",[1599,1600,1601],"strong",{},"Manage Webhooks"," permission (Owner and Admin have it; see ",[1604,1605,1607],"a",{"href":1606},"/integrations-and-extensibility/webhooks#who-can-manage-webhooks","Who can manage webhooks",").",[1595,1610,1611,1612,1615,1616,1620,1621,1624],{},"A URL that the public internet can reach over ",[1599,1613,1614],{},"HTTPS",", with a certificate a standard client trusts. While developing on your own machine, a tunnel such as ngrok or Cloudflare Tunnel gives you one. ",[1617,1618,1619],"code",{},"localhost",", private network addresses and plain ",[1617,1622,1623],{},"http://"," are refused.",[1626,1627,1629],"h2",{"id":1628},"step-1-build-a-receiver","Step 1: Build a receiver",[1588,1631,1632],{},"A receiver does four things, in this order:",[1634,1635,1636,1643,1650,1661],"ol",{},[1595,1637,1638,1639,1642],{},"Reads the request body as ",[1599,1640,1641],{},"raw bytes",", before any JSON parsing.",[1595,1644,1645,1646,1649],{},"Verifies the ",[1617,1647,1648],{},"X-DevStride-Signature"," header against those bytes with your signing secret.",[1595,1651,1652,1653,1656,1657,1660],{},"Answers with a ",[1617,1654,1655],{},"2xx"," status ",[1599,1658,1659],{},"quickly",": DevStride waits at most 10 seconds.",[1595,1662,1663,1664,1667],{},"Processes the event afterwards, skipping any event ",[1617,1665,1666],{},"id"," it has already handled.",[1588,1669,1670,1671,1674],{},"Pick your language. Each sample reads the secret from the ",[1617,1672,1673],{},"DEVSTRIDE_WEBHOOK_SECRET"," environment variable; you get the secret in step 3.",[1676,1677,1679],"h3",{"id":1678},"nodejs-typescript-express","Node.js (TypeScript, Express)",[1681,1682,1687],"pre",{"className":1683,"code":1684,"language":1685,"meta":1686,"style":1686},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import express from 'express';\nimport { createHmac, timingSafeEqual } from 'node:crypto';\n\n// From \"Verifying Signatures\", unchanged.\nfunction verifyDevStrideSignature(\n  signatureHeader: string | undefined,\n  rawBody: Buffer,\n  secret: string,\n  nowSeconds = Math.floor(Date.now() / 1000)\n): boolean {\n  if (!signatureHeader) return false;\n  let timestamp: number | undefined;\n  const signatures: Buffer[] = [];\n  for (const part of signatureHeader.split(',')) {\n    const [key, value] = part.trim().split('=');\n    if (key === 't' && value && /^\\d+$/.test(value)) timestamp = Number(value);\n    else if (key === 'v1' && value && /^[0-9a-f]{64}$/.test(value))\n      signatures.push(Buffer.from(value, 'hex'));\n  }\n  if (timestamp === undefined || signatures.length === 0) return false;\n  // Older (or newer) than 5 minutes: a replayed capture, or a clock to fix.\n  if (Math.abs(nowSeconds - timestamp) > 300) return false;\n  const expected = createHmac('sha256', secret)\n    .update(`${timestamp}.`)\n    .update(rawBody)\n    .digest();\n  // Two v1 values appear for 24 h after a rotation; either secret verifies.\n  return signatures.some(\n    (candidate) =>\n      candidate.length === expected.length &&\n      timingSafeEqual(candidate, expected)\n  );\n}\n\ninterface DevStrideEvent {\n  id: string;\n  type: string;\n  apiVersion: string;\n  occurredAt: string;\n  organizationId: string;\n  origin: { kind: string; actorId: string | null; correlationId: string };\n  data: Record\u003Cstring, unknown>;\n}\n\nconst secret = process.env.DEVSTRIDE_WEBHOOK_SECRET ?? '';\nconst handled = new Set\u003Cstring>(); // use a database table or Redis in production\n\nconst app = express();\n\napp.post(\n  '/devstride/webhooks',\n  // Raw bytes, not express.json(): the signature covers the exact body.\n  // Comment events can be a few hundred KB, above express.raw's 100 KB default.\n  express.raw({ type: 'application/json', limit: '1mb' }),\n  (req, res) => {\n    const rawBody = req.body as Buffer;\n    if (!verifyDevStrideSignature(req.get('X-DevStride-Signature'), rawBody, secret)) {\n      res.status(401).send('invalid signature');\n      return;\n    }\n    const event = JSON.parse(rawBody.toString('utf8')) as DevStrideEvent;\n    res.sendStatus(204); // acknowledge first, work afterwards\n\n    if (handled.has(event.id)) return; // a redelivery of an event you already have\n    handled.add(event.id);\n    setImmediate(() => handleEvent(event));\n  }\n);\n\nfunction handleEvent(event: DevStrideEvent): void {\n  switch (event.type) {\n    case 'item.created':\n    case 'item.status_changed':\n    case 'comment.created':\n    case 'sla.at_risk':\n    case 'sla.breached':\n      console.log(event.type, event.id, event.data);\n      break;\n    default:\n      // 'ping' from the Test button, or an event type added after you wrote this.\n      break;\n  }\n}\n\napp.listen(3000);\n","ts","",[1617,1688,1689,1718,1749,1755,1761,1774,1796,1808,1819,1857,1868,1895,1914,1938,1978,2027,2099,2155,2193,2199,2235,2241,2282,2310,2336,2350,2362,2368,2383,2397,2418,2434,2442,2448,2453,2464,2476,2488,2500,2512,2524,2568,2593,2598,2603,2634,2663,2668,2685,2690,2703,2716,2722,2728,2776,2797,2822,2865,2901,2909,2915,2960,2983,2988,3021,3044,3067,3072,3079,3084,3106,3125,3141,3155,3169,3183,3197,3237,3245,3253,3259,3266,3271,3276,3281],{"__ignoreMap":1686},[1690,1691,1693,1697,1701,1704,1708,1712,1715],"span",{"class":1692,"line":17},"line",[1690,1694,1696],{"class":1695},"s7zQu","import",[1690,1698,1700],{"class":1699},"sTEyZ"," express ",[1690,1702,1703],{"class":1695},"from",[1690,1705,1707],{"class":1706},"sMK4o"," '",[1690,1709,1711],{"class":1710},"sfazB","express",[1690,1713,1714],{"class":1706},"'",[1690,1716,1717],{"class":1706},";\n",[1690,1719,1720,1722,1725,1728,1731,1734,1737,1740,1742,1745,1747],{"class":1692,"line":244},[1690,1721,1696],{"class":1695},[1690,1723,1724],{"class":1706}," {",[1690,1726,1727],{"class":1699}," createHmac",[1690,1729,1730],{"class":1706},",",[1690,1732,1733],{"class":1699}," timingSafeEqual",[1690,1735,1736],{"class":1706}," }",[1690,1738,1739],{"class":1695}," from",[1690,1741,1707],{"class":1706},[1690,1743,1744],{"class":1710},"node:crypto",[1690,1746,1714],{"class":1706},[1690,1748,1717],{"class":1706},[1690,1750,1751],{"class":1692,"line":302},[1690,1752,1754],{"emptyLinePlaceholder":1753},true,"\n",[1690,1756,1757],{"class":1692,"line":377},[1690,1758,1760],{"class":1759},"sHwdD","// From \"Verifying Signatures\", unchanged.\n",[1690,1762,1763,1767,1771],{"class":1692,"line":649},[1690,1764,1766],{"class":1765},"spNyl","function",[1690,1768,1770],{"class":1769},"s2Zo4"," verifyDevStrideSignature",[1690,1772,1773],{"class":1706},"(\n",[1690,1775,1776,1780,1783,1787,1790,1793],{"class":1692,"line":659},[1690,1777,1779],{"class":1778},"sHdIc","  signatureHeader",[1690,1781,1782],{"class":1706},":",[1690,1784,1786],{"class":1785},"sBMFI"," string",[1690,1788,1789],{"class":1706}," |",[1690,1791,1792],{"class":1785}," undefined",[1690,1794,1795],{"class":1706},",\n",[1690,1797,1798,1801,1803,1806],{"class":1692,"line":596},[1690,1799,1800],{"class":1778},"  rawBody",[1690,1802,1782],{"class":1706},[1690,1804,1805],{"class":1785}," Buffer",[1690,1807,1795],{"class":1706},[1690,1809,1810,1813,1815,1817],{"class":1692,"line":280},[1690,1811,1812],{"class":1778},"  secret",[1690,1814,1782],{"class":1706},[1690,1816,1786],{"class":1785},[1690,1818,1795],{"class":1706},[1690,1820,1821,1824,1827,1830,1833,1836,1839,1841,1844,1847,1850,1854],{"class":1692,"line":905},[1690,1822,1823],{"class":1778},"  nowSeconds",[1690,1825,1826],{"class":1706}," =",[1690,1828,1829],{"class":1699}," Math",[1690,1831,1832],{"class":1706},".",[1690,1834,1835],{"class":1769},"floor",[1690,1837,1838],{"class":1699},"(Date",[1690,1840,1832],{"class":1706},[1690,1842,1843],{"class":1769},"now",[1690,1845,1846],{"class":1699},"() ",[1690,1848,1849],{"class":1706},"/",[1690,1851,1853],{"class":1852},"sbssI"," 1000",[1690,1855,1856],{"class":1699},")\n",[1690,1858,1859,1862,1865],{"class":1692,"line":817},[1690,1860,1861],{"class":1706},"):",[1690,1863,1864],{"class":1785}," boolean",[1690,1866,1867],{"class":1706}," {\n",[1690,1869,1870,1873,1877,1880,1883,1886,1889,1893],{"class":1692,"line":1242},[1690,1871,1872],{"class":1695},"  if",[1690,1874,1876],{"class":1875},"swJcz"," (",[1690,1878,1879],{"class":1706},"!",[1690,1881,1882],{"class":1699},"signatureHeader",[1690,1884,1885],{"class":1875},") ",[1690,1887,1888],{"class":1695},"return",[1690,1890,1892],{"class":1891},"sfNiH"," false",[1690,1894,1717],{"class":1706},[1690,1896,1897,1900,1903,1905,1908,1910,1912],{"class":1692,"line":961},[1690,1898,1899],{"class":1765},"  let",[1690,1901,1902],{"class":1699}," timestamp",[1690,1904,1782],{"class":1706},[1690,1906,1907],{"class":1785}," number",[1690,1909,1789],{"class":1706},[1690,1911,1792],{"class":1785},[1690,1913,1717],{"class":1706},[1690,1915,1917,1920,1923,1925,1927,1930,1933,1936],{"class":1692,"line":1916},13,[1690,1918,1919],{"class":1765},"  const",[1690,1921,1922],{"class":1699}," signatures",[1690,1924,1782],{"class":1706},[1690,1926,1805],{"class":1785},[1690,1928,1929],{"class":1875},"[] ",[1690,1931,1932],{"class":1706},"=",[1690,1934,1935],{"class":1875}," []",[1690,1937,1717],{"class":1706},[1690,1939,1941,1944,1946,1949,1952,1955,1958,1960,1963,1966,1968,1970,1972,1975],{"class":1692,"line":1940},14,[1690,1942,1943],{"class":1695},"  for",[1690,1945,1876],{"class":1875},[1690,1947,1948],{"class":1765},"const",[1690,1950,1951],{"class":1699}," part",[1690,1953,1954],{"class":1706}," of",[1690,1956,1957],{"class":1699}," signatureHeader",[1690,1959,1832],{"class":1706},[1690,1961,1962],{"class":1769},"split",[1690,1964,1965],{"class":1875},"(",[1690,1967,1714],{"class":1706},[1690,1969,1730],{"class":1710},[1690,1971,1714],{"class":1706},[1690,1973,1974],{"class":1875},")) ",[1690,1976,1977],{"class":1706},"{\n",[1690,1979,1981,1984,1987,1990,1992,1995,1998,2000,2002,2004,2007,2010,2012,2014,2016,2018,2020,2022,2025],{"class":1692,"line":1980},15,[1690,1982,1983],{"class":1765},"    const",[1690,1985,1986],{"class":1706}," [",[1690,1988,1989],{"class":1699},"key",[1690,1991,1730],{"class":1706},[1690,1993,1994],{"class":1699}," value",[1690,1996,1997],{"class":1706},"]",[1690,1999,1826],{"class":1706},[1690,2001,1951],{"class":1699},[1690,2003,1832],{"class":1706},[1690,2005,2006],{"class":1769},"trim",[1690,2008,2009],{"class":1875},"()",[1690,2011,1832],{"class":1706},[1690,2013,1962],{"class":1769},[1690,2015,1965],{"class":1875},[1690,2017,1714],{"class":1706},[1690,2019,1932],{"class":1710},[1690,2021,1714],{"class":1706},[1690,2023,2024],{"class":1875},")",[1690,2026,1717],{"class":1706},[1690,2028,2030,2033,2035,2037,2040,2042,2045,2047,2050,2052,2054,2057,2060,2063,2066,2069,2071,2073,2076,2078,2081,2083,2086,2088,2091,2093,2095,2097],{"class":1692,"line":2029},16,[1690,2031,2032],{"class":1695},"    if",[1690,2034,1876],{"class":1875},[1690,2036,1989],{"class":1699},[1690,2038,2039],{"class":1706}," ===",[1690,2041,1707],{"class":1706},[1690,2043,2044],{"class":1710},"t",[1690,2046,1714],{"class":1706},[1690,2048,2049],{"class":1706}," &&",[1690,2051,1994],{"class":1699},[1690,2053,2049],{"class":1706},[1690,2055,2056],{"class":1706}," /",[1690,2058,2059],{"class":1695},"^",[1690,2061,2062],{"class":1710},"\\d",[1690,2064,2065],{"class":1706},"+",[1690,2067,2068],{"class":1695},"$",[1690,2070,1849],{"class":1706},[1690,2072,1832],{"class":1706},[1690,2074,2075],{"class":1769},"test",[1690,2077,1965],{"class":1875},[1690,2079,2080],{"class":1699},"value",[1690,2082,1974],{"class":1875},[1690,2084,2085],{"class":1699},"timestamp",[1690,2087,1826],{"class":1706},[1690,2089,2090],{"class":1769}," Number",[1690,2092,1965],{"class":1875},[1690,2094,2080],{"class":1699},[1690,2096,2024],{"class":1875},[1690,2098,1717],{"class":1706},[1690,2100,2102,2105,2108,2110,2112,2114,2116,2119,2121,2123,2125,2127,2129,2131,2134,2137,2140,2142,2144,2146,2148,2150,2152],{"class":1692,"line":2101},17,[1690,2103,2104],{"class":1695},"    else",[1690,2106,2107],{"class":1695}," if",[1690,2109,1876],{"class":1875},[1690,2111,1989],{"class":1699},[1690,2113,2039],{"class":1706},[1690,2115,1707],{"class":1706},[1690,2117,2118],{"class":1710},"v1",[1690,2120,1714],{"class":1706},[1690,2122,2049],{"class":1706},[1690,2124,1994],{"class":1699},[1690,2126,2049],{"class":1706},[1690,2128,2056],{"class":1706},[1690,2130,2059],{"class":1695},[1690,2132,2133],{"class":1706},"[",[1690,2135,2136],{"class":1710},"0-9a-f",[1690,2138,2139],{"class":1706},"]{64}",[1690,2141,2068],{"class":1695},[1690,2143,1849],{"class":1706},[1690,2145,1832],{"class":1706},[1690,2147,2075],{"class":1769},[1690,2149,1965],{"class":1875},[1690,2151,2080],{"class":1699},[1690,2153,2154],{"class":1875},"))\n",[1690,2156,2158,2161,2163,2166,2168,2171,2173,2175,2177,2179,2181,2183,2186,2188,2191],{"class":1692,"line":2157},18,[1690,2159,2160],{"class":1699},"      signatures",[1690,2162,1832],{"class":1706},[1690,2164,2165],{"class":1769},"push",[1690,2167,1965],{"class":1875},[1690,2169,2170],{"class":1699},"Buffer",[1690,2172,1832],{"class":1706},[1690,2174,1703],{"class":1769},[1690,2176,1965],{"class":1875},[1690,2178,2080],{"class":1699},[1690,2180,1730],{"class":1706},[1690,2182,1707],{"class":1706},[1690,2184,2185],{"class":1710},"hex",[1690,2187,1714],{"class":1706},[1690,2189,2190],{"class":1875},"))",[1690,2192,1717],{"class":1706},[1690,2194,2196],{"class":1692,"line":2195},19,[1690,2197,2198],{"class":1706},"  }\n",[1690,2200,2202,2204,2206,2208,2210,2212,2215,2217,2219,2222,2224,2227,2229,2231,2233],{"class":1692,"line":2201},20,[1690,2203,1872],{"class":1695},[1690,2205,1876],{"class":1875},[1690,2207,2085],{"class":1699},[1690,2209,2039],{"class":1706},[1690,2211,1792],{"class":1706},[1690,2213,2214],{"class":1706}," ||",[1690,2216,1922],{"class":1699},[1690,2218,1832],{"class":1706},[1690,2220,2221],{"class":1699},"length",[1690,2223,2039],{"class":1706},[1690,2225,2226],{"class":1852}," 0",[1690,2228,1885],{"class":1875},[1690,2230,1888],{"class":1695},[1690,2232,1892],{"class":1891},[1690,2234,1717],{"class":1706},[1690,2236,2238],{"class":1692,"line":2237},21,[1690,2239,2240],{"class":1759},"  // Older (or newer) than 5 minutes: a replayed capture, or a clock to fix.\n",[1690,2242,2244,2246,2248,2251,2253,2256,2258,2261,2264,2266,2268,2271,2274,2276,2278,2280],{"class":1692,"line":2243},22,[1690,2245,1872],{"class":1695},[1690,2247,1876],{"class":1875},[1690,2249,2250],{"class":1699},"Math",[1690,2252,1832],{"class":1706},[1690,2254,2255],{"class":1769},"abs",[1690,2257,1965],{"class":1875},[1690,2259,2260],{"class":1699},"nowSeconds",[1690,2262,2263],{"class":1706}," -",[1690,2265,1902],{"class":1699},[1690,2267,1885],{"class":1875},[1690,2269,2270],{"class":1706},">",[1690,2272,2273],{"class":1852}," 300",[1690,2275,1885],{"class":1875},[1690,2277,1888],{"class":1695},[1690,2279,1892],{"class":1891},[1690,2281,1717],{"class":1706},[1690,2283,2285,2287,2290,2292,2294,2296,2298,2301,2303,2305,2308],{"class":1692,"line":2284},23,[1690,2286,1919],{"class":1765},[1690,2288,2289],{"class":1699}," expected",[1690,2291,1826],{"class":1706},[1690,2293,1727],{"class":1769},[1690,2295,1965],{"class":1875},[1690,2297,1714],{"class":1706},[1690,2299,2300],{"class":1710},"sha256",[1690,2302,1714],{"class":1706},[1690,2304,1730],{"class":1706},[1690,2306,2307],{"class":1699}," secret",[1690,2309,1856],{"class":1875},[1690,2311,2313,2316,2319,2321,2324,2326,2329,2331,2334],{"class":1692,"line":2312},24,[1690,2314,2315],{"class":1706},"    .",[1690,2317,2318],{"class":1769},"update",[1690,2320,1965],{"class":1875},[1690,2322,2323],{"class":1706},"`${",[1690,2325,2085],{"class":1699},[1690,2327,2328],{"class":1706},"}",[1690,2330,1832],{"class":1710},[1690,2332,2333],{"class":1706},"`",[1690,2335,1856],{"class":1875},[1690,2337,2339,2341,2343,2345,2348],{"class":1692,"line":2338},25,[1690,2340,2315],{"class":1706},[1690,2342,2318],{"class":1769},[1690,2344,1965],{"class":1875},[1690,2346,2347],{"class":1699},"rawBody",[1690,2349,1856],{"class":1875},[1690,2351,2353,2355,2358,2360],{"class":1692,"line":2352},26,[1690,2354,2315],{"class":1706},[1690,2356,2357],{"class":1769},"digest",[1690,2359,2009],{"class":1875},[1690,2361,1717],{"class":1706},[1690,2363,2365],{"class":1692,"line":2364},27,[1690,2366,2367],{"class":1759},"  // Two v1 values appear for 24 h after a rotation; either secret verifies.\n",[1690,2369,2371,2374,2376,2378,2381],{"class":1692,"line":2370},28,[1690,2372,2373],{"class":1695},"  return",[1690,2375,1922],{"class":1699},[1690,2377,1832],{"class":1706},[1690,2379,2380],{"class":1769},"some",[1690,2382,1773],{"class":1875},[1690,2384,2386,2389,2392,2394],{"class":1692,"line":2385},29,[1690,2387,2388],{"class":1706},"    (",[1690,2390,2391],{"class":1778},"candidate",[1690,2393,2024],{"class":1706},[1690,2395,2396],{"class":1765}," =>\n",[1690,2398,2400,2403,2405,2407,2409,2411,2413,2415],{"class":1692,"line":2399},30,[1690,2401,2402],{"class":1699},"      candidate",[1690,2404,1832],{"class":1706},[1690,2406,2221],{"class":1699},[1690,2408,2039],{"class":1706},[1690,2410,2289],{"class":1699},[1690,2412,1832],{"class":1706},[1690,2414,2221],{"class":1699},[1690,2416,2417],{"class":1706}," &&\n",[1690,2419,2421,2424,2426,2428,2430,2432],{"class":1692,"line":2420},31,[1690,2422,2423],{"class":1769},"      timingSafeEqual",[1690,2425,1965],{"class":1875},[1690,2427,2391],{"class":1699},[1690,2429,1730],{"class":1706},[1690,2431,2289],{"class":1699},[1690,2433,1856],{"class":1875},[1690,2435,2437,2440],{"class":1692,"line":2436},32,[1690,2438,2439],{"class":1875},"  )",[1690,2441,1717],{"class":1706},[1690,2443,2445],{"class":1692,"line":2444},33,[1690,2446,2447],{"class":1706},"}\n",[1690,2449,2451],{"class":1692,"line":2450},34,[1690,2452,1754],{"emptyLinePlaceholder":1753},[1690,2454,2456,2459,2462],{"class":1692,"line":2455},35,[1690,2457,2458],{"class":1765},"interface",[1690,2460,2461],{"class":1785}," DevStrideEvent",[1690,2463,1867],{"class":1706},[1690,2465,2467,2470,2472,2474],{"class":1692,"line":2466},36,[1690,2468,2469],{"class":1875},"  id",[1690,2471,1782],{"class":1706},[1690,2473,1786],{"class":1785},[1690,2475,1717],{"class":1706},[1690,2477,2479,2482,2484,2486],{"class":1692,"line":2478},37,[1690,2480,2481],{"class":1875},"  type",[1690,2483,1782],{"class":1706},[1690,2485,1786],{"class":1785},[1690,2487,1717],{"class":1706},[1690,2489,2491,2494,2496,2498],{"class":1692,"line":2490},38,[1690,2492,2493],{"class":1875},"  apiVersion",[1690,2495,1782],{"class":1706},[1690,2497,1786],{"class":1785},[1690,2499,1717],{"class":1706},[1690,2501,2503,2506,2508,2510],{"class":1692,"line":2502},39,[1690,2504,2505],{"class":1875},"  occurredAt",[1690,2507,1782],{"class":1706},[1690,2509,1786],{"class":1785},[1690,2511,1717],{"class":1706},[1690,2513,2515,2518,2520,2522],{"class":1692,"line":2514},40,[1690,2516,2517],{"class":1875},"  organizationId",[1690,2519,1782],{"class":1706},[1690,2521,1786],{"class":1785},[1690,2523,1717],{"class":1706},[1690,2525,2527,2530,2532,2534,2537,2539,2541,2544,2547,2549,2551,2553,2556,2558,2561,2563,2565],{"class":1692,"line":2526},41,[1690,2528,2529],{"class":1875},"  origin",[1690,2531,1782],{"class":1706},[1690,2533,1724],{"class":1706},[1690,2535,2536],{"class":1875}," kind",[1690,2538,1782],{"class":1706},[1690,2540,1786],{"class":1785},[1690,2542,2543],{"class":1706},";",[1690,2545,2546],{"class":1875}," actorId",[1690,2548,1782],{"class":1706},[1690,2550,1786],{"class":1785},[1690,2552,1789],{"class":1706},[1690,2554,2555],{"class":1785}," null",[1690,2557,2543],{"class":1706},[1690,2559,2560],{"class":1875}," correlationId",[1690,2562,1782],{"class":1706},[1690,2564,1786],{"class":1785},[1690,2566,2567],{"class":1706}," };\n",[1690,2569,2571,2574,2576,2579,2582,2585,2587,2590],{"class":1692,"line":2570},42,[1690,2572,2573],{"class":1875},"  data",[1690,2575,1782],{"class":1706},[1690,2577,2578],{"class":1785}," Record",[1690,2580,2581],{"class":1706},"\u003C",[1690,2583,2584],{"class":1785},"string",[1690,2586,1730],{"class":1706},[1690,2588,2589],{"class":1785}," unknown",[1690,2591,2592],{"class":1706},">;\n",[1690,2594,2596],{"class":1692,"line":2595},43,[1690,2597,2447],{"class":1706},[1690,2599,2601],{"class":1692,"line":2600},44,[1690,2602,1754],{"emptyLinePlaceholder":1753},[1690,2604,2606,2608,2611,2613,2616,2618,2621,2623,2626,2629,2632],{"class":1692,"line":2605},45,[1690,2607,1948],{"class":1765},[1690,2609,2610],{"class":1699}," secret ",[1690,2612,1932],{"class":1706},[1690,2614,2615],{"class":1699}," process",[1690,2617,1832],{"class":1706},[1690,2619,2620],{"class":1699},"env",[1690,2622,1832],{"class":1706},[1690,2624,2625],{"class":1699},"DEVSTRIDE_WEBHOOK_SECRET ",[1690,2627,2628],{"class":1706},"??",[1690,2630,2631],{"class":1706}," ''",[1690,2633,1717],{"class":1706},[1690,2635,2637,2639,2642,2644,2647,2650,2652,2654,2656,2658,2660],{"class":1692,"line":2636},46,[1690,2638,1948],{"class":1765},[1690,2640,2641],{"class":1699}," handled ",[1690,2643,1932],{"class":1706},[1690,2645,2646],{"class":1706}," new",[1690,2648,2649],{"class":1769}," Set",[1690,2651,2581],{"class":1706},[1690,2653,2584],{"class":1785},[1690,2655,2270],{"class":1706},[1690,2657,2009],{"class":1699},[1690,2659,2543],{"class":1706},[1690,2661,2662],{"class":1759}," // use a database table or Redis in production\n",[1690,2664,2666],{"class":1692,"line":2665},47,[1690,2667,1754],{"emptyLinePlaceholder":1753},[1690,2669,2671,2673,2676,2678,2681,2683],{"class":1692,"line":2670},48,[1690,2672,1948],{"class":1765},[1690,2674,2675],{"class":1699}," app ",[1690,2677,1932],{"class":1706},[1690,2679,2680],{"class":1769}," express",[1690,2682,2009],{"class":1699},[1690,2684,1717],{"class":1706},[1690,2686,2688],{"class":1692,"line":2687},49,[1690,2689,1754],{"emptyLinePlaceholder":1753},[1690,2691,2693,2696,2698,2701],{"class":1692,"line":2692},50,[1690,2694,2695],{"class":1699},"app",[1690,2697,1832],{"class":1706},[1690,2699,2700],{"class":1769},"post",[1690,2702,1773],{"class":1699},[1690,2704,2706,2709,2712,2714],{"class":1692,"line":2705},51,[1690,2707,2708],{"class":1706},"  '",[1690,2710,2711],{"class":1710},"/devstride/webhooks",[1690,2713,1714],{"class":1706},[1690,2715,1795],{"class":1706},[1690,2717,2719],{"class":1692,"line":2718},52,[1690,2720,2721],{"class":1759},"  // Raw bytes, not express.json(): the signature covers the exact body.\n",[1690,2723,2725],{"class":1692,"line":2724},53,[1690,2726,2727],{"class":1759},"  // Comment events can be a few hundred KB, above express.raw's 100 KB default.\n",[1690,2729,2731,2734,2736,2739,2741,2744,2747,2749,2751,2754,2756,2758,2761,2763,2765,2768,2770,2772,2774],{"class":1692,"line":2730},54,[1690,2732,2733],{"class":1699},"  express",[1690,2735,1832],{"class":1706},[1690,2737,2738],{"class":1769},"raw",[1690,2740,1965],{"class":1699},[1690,2742,2743],{"class":1706},"{",[1690,2745,2746],{"class":1875}," type",[1690,2748,1782],{"class":1706},[1690,2750,1707],{"class":1706},[1690,2752,2753],{"class":1710},"application/json",[1690,2755,1714],{"class":1706},[1690,2757,1730],{"class":1706},[1690,2759,2760],{"class":1875}," limit",[1690,2762,1782],{"class":1706},[1690,2764,1707],{"class":1706},[1690,2766,2767],{"class":1710},"1mb",[1690,2769,1714],{"class":1706},[1690,2771,1736],{"class":1706},[1690,2773,2024],{"class":1699},[1690,2775,1795],{"class":1706},[1690,2777,2779,2782,2785,2787,2790,2792,2795],{"class":1692,"line":2778},55,[1690,2780,2781],{"class":1706},"  (",[1690,2783,2784],{"class":1778},"req",[1690,2786,1730],{"class":1706},[1690,2788,2789],{"class":1778}," res",[1690,2791,2024],{"class":1706},[1690,2793,2794],{"class":1765}," =>",[1690,2796,1867],{"class":1706},[1690,2798,2800,2802,2805,2807,2810,2812,2815,2818,2820],{"class":1692,"line":2799},56,[1690,2801,1983],{"class":1765},[1690,2803,2804],{"class":1699}," rawBody",[1690,2806,1826],{"class":1706},[1690,2808,2809],{"class":1699}," req",[1690,2811,1832],{"class":1706},[1690,2813,2814],{"class":1699},"body",[1690,2816,2817],{"class":1695}," as",[1690,2819,1805],{"class":1785},[1690,2821,1717],{"class":1706},[1690,2823,2825,2827,2829,2831,2834,2836,2838,2840,2843,2845,2847,2849,2851,2853,2855,2857,2859,2861,2863],{"class":1692,"line":2824},57,[1690,2826,2032],{"class":1695},[1690,2828,1876],{"class":1875},[1690,2830,1879],{"class":1706},[1690,2832,2833],{"class":1769},"verifyDevStrideSignature",[1690,2835,1965],{"class":1875},[1690,2837,2784],{"class":1699},[1690,2839,1832],{"class":1706},[1690,2841,2842],{"class":1769},"get",[1690,2844,1965],{"class":1875},[1690,2846,1714],{"class":1706},[1690,2848,1648],{"class":1710},[1690,2850,1714],{"class":1706},[1690,2852,2024],{"class":1875},[1690,2854,1730],{"class":1706},[1690,2856,2804],{"class":1699},[1690,2858,1730],{"class":1706},[1690,2860,2307],{"class":1699},[1690,2862,1974],{"class":1875},[1690,2864,1977],{"class":1706},[1690,2866,2868,2871,2873,2876,2878,2881,2883,2885,2888,2890,2892,2895,2897,2899],{"class":1692,"line":2867},58,[1690,2869,2870],{"class":1699},"      res",[1690,2872,1832],{"class":1706},[1690,2874,2875],{"class":1769},"status",[1690,2877,1965],{"class":1875},[1690,2879,2880],{"class":1852},"401",[1690,2882,2024],{"class":1875},[1690,2884,1832],{"class":1706},[1690,2886,2887],{"class":1769},"send",[1690,2889,1965],{"class":1875},[1690,2891,1714],{"class":1706},[1690,2893,2894],{"class":1710},"invalid signature",[1690,2896,1714],{"class":1706},[1690,2898,2024],{"class":1875},[1690,2900,1717],{"class":1706},[1690,2902,2904,2907],{"class":1692,"line":2903},59,[1690,2905,2906],{"class":1695},"      return",[1690,2908,1717],{"class":1706},[1690,2910,2912],{"class":1692,"line":2911},60,[1690,2913,2914],{"class":1706},"    }\n",[1690,2916,2918,2920,2923,2925,2928,2930,2933,2935,2937,2939,2942,2944,2946,2949,2951,2953,2956,2958],{"class":1692,"line":2917},61,[1690,2919,1983],{"class":1765},[1690,2921,2922],{"class":1699}," event",[1690,2924,1826],{"class":1706},[1690,2926,2927],{"class":1699}," JSON",[1690,2929,1832],{"class":1706},[1690,2931,2932],{"class":1769},"parse",[1690,2934,1965],{"class":1875},[1690,2936,2347],{"class":1699},[1690,2938,1832],{"class":1706},[1690,2940,2941],{"class":1769},"toString",[1690,2943,1965],{"class":1875},[1690,2945,1714],{"class":1706},[1690,2947,2948],{"class":1710},"utf8",[1690,2950,1714],{"class":1706},[1690,2952,1974],{"class":1875},[1690,2954,2955],{"class":1695},"as",[1690,2957,2461],{"class":1785},[1690,2959,1717],{"class":1706},[1690,2961,2963,2966,2968,2971,2973,2976,2978,2980],{"class":1692,"line":2962},62,[1690,2964,2965],{"class":1699},"    res",[1690,2967,1832],{"class":1706},[1690,2969,2970],{"class":1769},"sendStatus",[1690,2972,1965],{"class":1875},[1690,2974,2975],{"class":1852},"204",[1690,2977,2024],{"class":1875},[1690,2979,2543],{"class":1706},[1690,2981,2982],{"class":1759}," // acknowledge first, work afterwards\n",[1690,2984,2986],{"class":1692,"line":2985},63,[1690,2987,1754],{"emptyLinePlaceholder":1753},[1690,2989,2991,2993,2995,2998,3000,3003,3005,3008,3010,3012,3014,3016,3018],{"class":1692,"line":2990},64,[1690,2992,2032],{"class":1695},[1690,2994,1876],{"class":1875},[1690,2996,2997],{"class":1699},"handled",[1690,2999,1832],{"class":1706},[1690,3001,3002],{"class":1769},"has",[1690,3004,1965],{"class":1875},[1690,3006,3007],{"class":1699},"event",[1690,3009,1832],{"class":1706},[1690,3011,1666],{"class":1699},[1690,3013,1974],{"class":1875},[1690,3015,1888],{"class":1695},[1690,3017,2543],{"class":1706},[1690,3019,3020],{"class":1759}," // a redelivery of an event you already have\n",[1690,3022,3024,3027,3029,3032,3034,3036,3038,3040,3042],{"class":1692,"line":3023},65,[1690,3025,3026],{"class":1699},"    handled",[1690,3028,1832],{"class":1706},[1690,3030,3031],{"class":1769},"add",[1690,3033,1965],{"class":1875},[1690,3035,3007],{"class":1699},[1690,3037,1832],{"class":1706},[1690,3039,1666],{"class":1699},[1690,3041,2024],{"class":1875},[1690,3043,1717],{"class":1706},[1690,3045,3047,3050,3052,3054,3056,3059,3061,3063,3065],{"class":1692,"line":3046},66,[1690,3048,3049],{"class":1769},"    setImmediate",[1690,3051,1965],{"class":1875},[1690,3053,2009],{"class":1706},[1690,3055,2794],{"class":1765},[1690,3057,3058],{"class":1769}," handleEvent",[1690,3060,1965],{"class":1875},[1690,3062,3007],{"class":1699},[1690,3064,2190],{"class":1875},[1690,3066,1717],{"class":1706},[1690,3068,3070],{"class":1692,"line":3069},67,[1690,3071,2198],{"class":1706},[1690,3073,3075,3077],{"class":1692,"line":3074},68,[1690,3076,2024],{"class":1699},[1690,3078,1717],{"class":1706},[1690,3080,3082],{"class":1692,"line":3081},69,[1690,3083,1754],{"emptyLinePlaceholder":1753},[1690,3085,3087,3089,3091,3093,3095,3097,3099,3101,3104],{"class":1692,"line":3086},70,[1690,3088,1766],{"class":1765},[1690,3090,3058],{"class":1769},[1690,3092,1965],{"class":1706},[1690,3094,3007],{"class":1778},[1690,3096,1782],{"class":1706},[1690,3098,2461],{"class":1785},[1690,3100,1861],{"class":1706},[1690,3102,3103],{"class":1785}," void",[1690,3105,1867],{"class":1706},[1690,3107,3109,3112,3114,3116,3118,3121,3123],{"class":1692,"line":3108},71,[1690,3110,3111],{"class":1695},"  switch",[1690,3113,1876],{"class":1875},[1690,3115,3007],{"class":1699},[1690,3117,1832],{"class":1706},[1690,3119,3120],{"class":1699},"type",[1690,3122,1885],{"class":1875},[1690,3124,1977],{"class":1706},[1690,3126,3128,3131,3133,3136,3138],{"class":1692,"line":3127},72,[1690,3129,3130],{"class":1695},"    case",[1690,3132,1707],{"class":1706},[1690,3134,3135],{"class":1710},"item.created",[1690,3137,1714],{"class":1706},[1690,3139,3140],{"class":1706},":\n",[1690,3142,3144,3146,3148,3151,3153],{"class":1692,"line":3143},73,[1690,3145,3130],{"class":1695},[1690,3147,1707],{"class":1706},[1690,3149,3150],{"class":1710},"item.status_changed",[1690,3152,1714],{"class":1706},[1690,3154,3140],{"class":1706},[1690,3156,3158,3160,3162,3165,3167],{"class":1692,"line":3157},74,[1690,3159,3130],{"class":1695},[1690,3161,1707],{"class":1706},[1690,3163,3164],{"class":1710},"comment.created",[1690,3166,1714],{"class":1706},[1690,3168,3140],{"class":1706},[1690,3170,3172,3174,3176,3179,3181],{"class":1692,"line":3171},75,[1690,3173,3130],{"class":1695},[1690,3175,1707],{"class":1706},[1690,3177,3178],{"class":1710},"sla.at_risk",[1690,3180,1714],{"class":1706},[1690,3182,3140],{"class":1706},[1690,3184,3186,3188,3190,3193,3195],{"class":1692,"line":3185},76,[1690,3187,3130],{"class":1695},[1690,3189,1707],{"class":1706},[1690,3191,3192],{"class":1710},"sla.breached",[1690,3194,1714],{"class":1706},[1690,3196,3140],{"class":1706},[1690,3198,3200,3203,3205,3208,3210,3212,3214,3216,3218,3220,3222,3224,3226,3228,3230,3233,3235],{"class":1692,"line":3199},77,[1690,3201,3202],{"class":1699},"      console",[1690,3204,1832],{"class":1706},[1690,3206,3207],{"class":1769},"log",[1690,3209,1965],{"class":1875},[1690,3211,3007],{"class":1699},[1690,3213,1832],{"class":1706},[1690,3215,3120],{"class":1699},[1690,3217,1730],{"class":1706},[1690,3219,2922],{"class":1699},[1690,3221,1832],{"class":1706},[1690,3223,1666],{"class":1699},[1690,3225,1730],{"class":1706},[1690,3227,2922],{"class":1699},[1690,3229,1832],{"class":1706},[1690,3231,3232],{"class":1699},"data",[1690,3234,2024],{"class":1875},[1690,3236,1717],{"class":1706},[1690,3238,3240,3243],{"class":1692,"line":3239},78,[1690,3241,3242],{"class":1695},"      break",[1690,3244,1717],{"class":1706},[1690,3246,3248,3251],{"class":1692,"line":3247},79,[1690,3249,3250],{"class":1695},"    default",[1690,3252,3140],{"class":1706},[1690,3254,3256],{"class":1692,"line":3255},80,[1690,3257,3258],{"class":1759},"      // 'ping' from the Test button, or an event type added after you wrote this.\n",[1690,3260,3262,3264],{"class":1692,"line":3261},81,[1690,3263,3242],{"class":1695},[1690,3265,1717],{"class":1706},[1690,3267,3269],{"class":1692,"line":3268},82,[1690,3270,2198],{"class":1706},[1690,3272,3274],{"class":1692,"line":3273},83,[1690,3275,2447],{"class":1706},[1690,3277,3279],{"class":1692,"line":3278},84,[1690,3280,1754],{"emptyLinePlaceholder":1753},[1690,3282,3284,3286,3288,3291,3293,3296,3298],{"class":1692,"line":3283},85,[1690,3285,2695],{"class":1699},[1690,3287,1832],{"class":1706},[1690,3289,3290],{"class":1769},"listen",[1690,3292,1965],{"class":1699},[1690,3294,3295],{"class":1852},"3000",[1690,3297,2024],{"class":1699},[1690,3299,1717],{"class":1706},[1676,3301,3303],{"id":3302},"python-flask","Python (Flask)",[1681,3305,3309],{"className":3306,"code":3307,"language":3308,"meta":1686,"style":1686},"language-python shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import json\nimport os\n\nfrom flask import Flask, request\n\nfrom devstride_webhooks import verify_devstride_signature  # from \"Verifying Signatures\"\n\nSECRET = os.environ[\"DEVSTRIDE_WEBHOOK_SECRET\"]\nhandled = set()  # use a database table or Redis in production\n\napp = Flask(__name__)\n\n\n@app.post(\"/devstride/webhooks\")\ndef devstride_webhook():\n    raw_body = request.get_data()  # the exact bytes received; never request.json here\n    if not verify_devstride_signature(\n        request.headers.get(\"X-DevStride-Signature\"), raw_body, SECRET\n    ):\n        return \"invalid signature\", 401\n    event = json.loads(raw_body)\n    if event[\"id\"] not in handled:\n        handled.add(event[\"id\"])\n        enqueue(event)  # hand off to a worker or job queue; do not process inline\n    return \"\", 204\n\n\ndef enqueue(event):\n    print(event[\"type\"], event[\"id\"])\n","python",[1617,3310,3311,3316,3321,3325,3330,3334,3339,3343,3348,3353,3357,3362,3366,3370,3375,3380,3385,3390,3395,3400,3405,3410,3415,3420,3425,3430,3434,3438,3443],{"__ignoreMap":1686},[1690,3312,3313],{"class":1692,"line":17},[1690,3314,3315],{},"import json\n",[1690,3317,3318],{"class":1692,"line":244},[1690,3319,3320],{},"import os\n",[1690,3322,3323],{"class":1692,"line":302},[1690,3324,1754],{"emptyLinePlaceholder":1753},[1690,3326,3327],{"class":1692,"line":377},[1690,3328,3329],{},"from flask import Flask, request\n",[1690,3331,3332],{"class":1692,"line":649},[1690,3333,1754],{"emptyLinePlaceholder":1753},[1690,3335,3336],{"class":1692,"line":659},[1690,3337,3338],{},"from devstride_webhooks import verify_devstride_signature  # from \"Verifying Signatures\"\n",[1690,3340,3341],{"class":1692,"line":596},[1690,3342,1754],{"emptyLinePlaceholder":1753},[1690,3344,3345],{"class":1692,"line":280},[1690,3346,3347],{},"SECRET = os.environ[\"DEVSTRIDE_WEBHOOK_SECRET\"]\n",[1690,3349,3350],{"class":1692,"line":905},[1690,3351,3352],{},"handled = set()  # use a database table or Redis in production\n",[1690,3354,3355],{"class":1692,"line":817},[1690,3356,1754],{"emptyLinePlaceholder":1753},[1690,3358,3359],{"class":1692,"line":1242},[1690,3360,3361],{},"app = Flask(__name__)\n",[1690,3363,3364],{"class":1692,"line":961},[1690,3365,1754],{"emptyLinePlaceholder":1753},[1690,3367,3368],{"class":1692,"line":1916},[1690,3369,1754],{"emptyLinePlaceholder":1753},[1690,3371,3372],{"class":1692,"line":1940},[1690,3373,3374],{},"@app.post(\"/devstride/webhooks\")\n",[1690,3376,3377],{"class":1692,"line":1980},[1690,3378,3379],{},"def devstride_webhook():\n",[1690,3381,3382],{"class":1692,"line":2029},[1690,3383,3384],{},"    raw_body = request.get_data()  # the exact bytes received; never request.json here\n",[1690,3386,3387],{"class":1692,"line":2101},[1690,3388,3389],{},"    if not verify_devstride_signature(\n",[1690,3391,3392],{"class":1692,"line":2157},[1690,3393,3394],{},"        request.headers.get(\"X-DevStride-Signature\"), raw_body, SECRET\n",[1690,3396,3397],{"class":1692,"line":2195},[1690,3398,3399],{},"    ):\n",[1690,3401,3402],{"class":1692,"line":2201},[1690,3403,3404],{},"        return \"invalid signature\", 401\n",[1690,3406,3407],{"class":1692,"line":2237},[1690,3408,3409],{},"    event = json.loads(raw_body)\n",[1690,3411,3412],{"class":1692,"line":2243},[1690,3413,3414],{},"    if event[\"id\"] not in handled:\n",[1690,3416,3417],{"class":1692,"line":2284},[1690,3418,3419],{},"        handled.add(event[\"id\"])\n",[1690,3421,3422],{"class":1692,"line":2312},[1690,3423,3424],{},"        enqueue(event)  # hand off to a worker or job queue; do not process inline\n",[1690,3426,3427],{"class":1692,"line":2338},[1690,3428,3429],{},"    return \"\", 204\n",[1690,3431,3432],{"class":1692,"line":2352},[1690,3433,1754],{"emptyLinePlaceholder":1753},[1690,3435,3436],{"class":1692,"line":2364},[1690,3437,1754],{"emptyLinePlaceholder":1753},[1690,3439,3440],{"class":1692,"line":2370},[1690,3441,3442],{},"def enqueue(event):\n",[1690,3444,3445],{"class":1692,"line":2385},[1690,3446,3447],{},"    print(event[\"type\"], event[\"id\"])\n",[1676,3449,3451],{"id":3450},"python-fastapi","Python (FastAPI)",[1681,3453,3455],{"className":3306,"code":3454,"language":3308,"meta":1686,"style":1686},"import json\nimport os\n\nfrom fastapi import BackgroundTasks, FastAPI, HTTPException, Request, Response\n\nfrom devstride_webhooks import verify_devstride_signature  # from \"Verifying Signatures\"\n\nSECRET = os.environ[\"DEVSTRIDE_WEBHOOK_SECRET\"]\nhandled = set()  # use a database table or Redis in production\n\napp = FastAPI()\n\n\n@app.post(\"/devstride/webhooks\")\nasync def devstride_webhook(request: Request, background_tasks: BackgroundTasks):\n    raw_body = await request.body()  # the exact bytes received\n    if not verify_devstride_signature(\n        request.headers.get(\"x-devstride-signature\"), raw_body, SECRET\n    ):\n        raise HTTPException(status_code=401, detail=\"invalid signature\")\n    event = json.loads(raw_body)\n    if event[\"id\"] not in handled:\n        handled.add(event[\"id\"])\n        background_tasks.add_task(handle_event, event)  # runs after the response is sent\n    return Response(status_code=204)\n\n\ndef handle_event(event):\n    print(event[\"type\"], event[\"id\"])\n",[1617,3456,3457,3461,3465,3469,3474,3478,3482,3486,3490,3494,3498,3503,3507,3511,3515,3520,3525,3529,3534,3538,3543,3547,3551,3555,3560,3565,3569,3573,3578],{"__ignoreMap":1686},[1690,3458,3459],{"class":1692,"line":17},[1690,3460,3315],{},[1690,3462,3463],{"class":1692,"line":244},[1690,3464,3320],{},[1690,3466,3467],{"class":1692,"line":302},[1690,3468,1754],{"emptyLinePlaceholder":1753},[1690,3470,3471],{"class":1692,"line":377},[1690,3472,3473],{},"from fastapi import BackgroundTasks, FastAPI, HTTPException, Request, Response\n",[1690,3475,3476],{"class":1692,"line":649},[1690,3477,1754],{"emptyLinePlaceholder":1753},[1690,3479,3480],{"class":1692,"line":659},[1690,3481,3338],{},[1690,3483,3484],{"class":1692,"line":596},[1690,3485,1754],{"emptyLinePlaceholder":1753},[1690,3487,3488],{"class":1692,"line":280},[1690,3489,3347],{},[1690,3491,3492],{"class":1692,"line":905},[1690,3493,3352],{},[1690,3495,3496],{"class":1692,"line":817},[1690,3497,1754],{"emptyLinePlaceholder":1753},[1690,3499,3500],{"class":1692,"line":1242},[1690,3501,3502],{},"app = FastAPI()\n",[1690,3504,3505],{"class":1692,"line":961},[1690,3506,1754],{"emptyLinePlaceholder":1753},[1690,3508,3509],{"class":1692,"line":1916},[1690,3510,1754],{"emptyLinePlaceholder":1753},[1690,3512,3513],{"class":1692,"line":1940},[1690,3514,3374],{},[1690,3516,3517],{"class":1692,"line":1980},[1690,3518,3519],{},"async def devstride_webhook(request: Request, background_tasks: BackgroundTasks):\n",[1690,3521,3522],{"class":1692,"line":2029},[1690,3523,3524],{},"    raw_body = await request.body()  # the exact bytes received\n",[1690,3526,3527],{"class":1692,"line":2101},[1690,3528,3389],{},[1690,3530,3531],{"class":1692,"line":2157},[1690,3532,3533],{},"        request.headers.get(\"x-devstride-signature\"), raw_body, SECRET\n",[1690,3535,3536],{"class":1692,"line":2195},[1690,3537,3399],{},[1690,3539,3540],{"class":1692,"line":2201},[1690,3541,3542],{},"        raise HTTPException(status_code=401, detail=\"invalid signature\")\n",[1690,3544,3545],{"class":1692,"line":2237},[1690,3546,3409],{},[1690,3548,3549],{"class":1692,"line":2243},[1690,3550,3414],{},[1690,3552,3553],{"class":1692,"line":2284},[1690,3554,3419],{},[1690,3556,3557],{"class":1692,"line":2312},[1690,3558,3559],{},"        background_tasks.add_task(handle_event, event)  # runs after the response is sent\n",[1690,3561,3562],{"class":1692,"line":2338},[1690,3563,3564],{},"    return Response(status_code=204)\n",[1690,3566,3567],{"class":1692,"line":2352},[1690,3568,1754],{"emptyLinePlaceholder":1753},[1690,3570,3571],{"class":1692,"line":2364},[1690,3572,1754],{"emptyLinePlaceholder":1753},[1690,3574,3575],{"class":1692,"line":2370},[1690,3576,3577],{},"def handle_event(event):\n",[1690,3579,3580],{"class":1692,"line":2385},[1690,3581,3447],{},[1588,3583,3584,3585,3588,3589,3592,3593,3597],{},"The Python samples import ",[1617,3586,3587],{},"verify_devstride_signature"," from a ",[1617,3590,3591],{},"devstride_webhooks.py"," module: copy the ",[1604,3594,3596],{"href":3595},"/integrations-and-extensibility/webhooks/verifying-signatures#python","Python verification function"," into it. Go, Ruby, PHP and C# versions are on the same page.",[3599,3600,1597,3603,3605,3606,3608,3609,1832],"alert",{"title":3601,"type":3602},"An in-memory set is for trying things out","tip",[1617,3604,2997],{}," set in these samples forgets everything on restart and is not shared between instances. In production, record each event ",[1617,3607,1666],{}," in a database table with a unique key (or Redis with a 30-day expiry) and check it before acting. See ",[1604,3610,3612],{"href":3611},"/integrations-and-extensibility/webhooks/troubleshooting-and-best-practices#deduplicate-by-event-id","Deduplicate by event id",[1588,3614,3615],{},"Start the receiver and make sure its public HTTPS URL is reachable.",[1626,3617,3619],{"id":3618},"step-2-register-the-endpoint","Step 2: Register the endpoint",[1634,3621,3622,3628,3639,3674],{},[1595,3623,3624,3625,1832],{},"Open ",[1599,3626,3627],{},"Configure Settings → Integrations → Webhooks",[1595,3629,3630,3631,3634,3635,3638],{},"Click ",[1599,3632,3633],{},"New endpoint",". The ",[1599,3636,3637],{},"New Webhook Endpoint"," dialog opens.",[1595,3640,3641,3642],{},"Fill in:\n",[1592,3643,3644,3658,3668],{},[1595,3645,3646,3649,3650,3653,3654,3657],{},[1599,3647,3648],{},"Endpoint URL",": your receiver's address, for example ",[1617,3651,3652],{},"https://hooks.example.com/devstride/webhooks",". It must start with ",[1617,3655,3656],{},"https://","; private, loopback and cloud-metadata addresses are refused.",[1595,3659,3660,3663,3664,1832],{},[1599,3661,3662],{},"Description"," (optional): a label for the list, for example ",[3665,3666,3667],"em",{},"CRM ticket sync",[1595,3669,3670,3673],{},[1599,3671,3672],{},"Events",": one or more of the five event types. Each option shows a one-line reminder of what fires it.",[1595,3675,3630,3676,3679],{},[1599,3677,3678],{},"Create",". DevStride checks the URL (including where its name resolves) and creates the endpoint, enabled.",[1588,3681,1597,3682,3685],{},[1599,3683,3684],{},"Signing secret"," dialog opens straight away.",[1626,3687,3689],{"id":3688},"step-3-copy-the-signing-secret","Step 3: Copy the signing secret",[1588,3691,3692,3693,3695,3696,3699,3700,3702,3703,1832],{},"The dialog shows the endpoint's ",[1599,3694,3684],{},", a value starting with ",[1617,3697,3698],{},"whsec_",". Copy it into your receiver's ",[1617,3701,1673],{}," setting (or your secret manager) and restart the receiver if needed, then click ",[1599,3704,3705],{},"Done",[3599,3707,3710,3713,3714,3717,3718,1832],{"title":3708,"type":3709},"The secret is shown once","danger",[3665,3711,3712],{},"\"This is the only time DevStride shows this secret.\""," DevStride cannot show it again. If you lose it, or it leaks, use ",[1599,3715,3716],{},"Rotate secret"," to issue a new one; see ",[1604,3719,3721],{"href":3720},"/integrations-and-extensibility/webhooks/managing-endpoints#rotate-the-signing-secret","Rotate the signing secret",[1588,3723,3724,3725,3727],{},"Use the whole value, including the ",[1617,3726,3698],{}," prefix, as the HMAC key. Do not decode it.",[1626,3729,3731],{"id":3730},"step-4-send-a-test-event","Step 4: Send a test event",[1588,3733,3734,3735,3738,3739,3742],{},"In the endpoint's row, click ",[1599,3736,3737],{},"Test",". DevStride immediately sends your endpoint a signed ",[1617,3740,3741],{},"ping"," event and shows what came back under the row:",[3744,3745,3746,3759],"table",{},[3747,3748,3749],"thead",{},[3750,3751,3752,3756],"tr",{},[3753,3754,3755],"th",{},"You see",[3753,3757,3758],{},"Meaning",[3760,3761,3762,3776,3792],"tbody",{},[3750,3763,3764,3770],{},[3765,3766,3767],"td",{},[3665,3768,3769],{},"Responded 204 in 143 ms",[3765,3771,3772,3773,3775],{},"Your endpoint answered ",[1617,3774,1655],{},". You are done with setup.",[3750,3777,3778,3783],{},[3765,3779,3780],{},[3665,3781,3782],{},"Responded 401 in 98 ms — a 2xx status is required",[3765,3784,3785,3786,3788,3789,3791],{},"It answered, but not with ",[1617,3787,1655],{},". A ",[1617,3790,2880],{}," from the samples above means the signature check failed: check the secret.",[3750,3793,3794,3799],{},[3765,3795,3796],{},[3665,3797,3798],{},"No response: … (15002 ms)",[3765,3800,3801],{},"Nothing came back: a timeout, a TLS or connection error, or a refused address. The reason is in the message.",[1588,3803,3804,3805,3807],{},"A test is not stored in the delivery log and is never retried. Your receiver should accept a ",[1617,3806,3741],{}," and do nothing with it; its body looks like this:",[1681,3809,3813],{"className":3810,"code":3811,"language":3812,"meta":1686,"style":1686},"language-json shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","{\n  \"id\": \"0f9a1c2b-3d4e-4f50-8a6b-7c8d9e0f1a2b\",\n  \"type\": \"ping\",\n  \"apiVersion\": \"2026-10-16\",\n  \"occurredAt\": \"2026-10-17T14:02:55.120Z\",\n  \"organizationId\": \"8f14e45f-ceea-4e7a-9b1d-3c5a2f6e9d10\",\n  \"origin\": { \"kind\": \"system\", \"actorId\": null, \"correlationId\": \"4c7d2e9a-1b3f-4a6e-8d5c-2f0b9e7a1c36\" },\n  \"data\": { \"endpointId\": \"3b0d2b8e-7f6a-4a46-9a3f-7a2c0f1a2b3c\" }\n}\n","json",[1617,3814,3815,3819,3841,3859,3879,3899,3919,3981,4012],{"__ignoreMap":1686},[1690,3816,3817],{"class":1692,"line":17},[1690,3818,1977],{"class":1706},[1690,3820,3821,3824,3826,3829,3831,3834,3837,3839],{"class":1692,"line":244},[1690,3822,3823],{"class":1706},"  \"",[1690,3825,1666],{"class":1765},[1690,3827,3828],{"class":1706},"\"",[1690,3830,1782],{"class":1706},[1690,3832,3833],{"class":1706}," \"",[1690,3835,3836],{"class":1710},"0f9a1c2b-3d4e-4f50-8a6b-7c8d9e0f1a2b",[1690,3838,3828],{"class":1706},[1690,3840,1795],{"class":1706},[1690,3842,3843,3845,3847,3849,3851,3853,3855,3857],{"class":1692,"line":302},[1690,3844,3823],{"class":1706},[1690,3846,3120],{"class":1765},[1690,3848,3828],{"class":1706},[1690,3850,1782],{"class":1706},[1690,3852,3833],{"class":1706},[1690,3854,3741],{"class":1710},[1690,3856,3828],{"class":1706},[1690,3858,1795],{"class":1706},[1690,3860,3861,3863,3866,3868,3870,3872,3875,3877],{"class":1692,"line":377},[1690,3862,3823],{"class":1706},[1690,3864,3865],{"class":1765},"apiVersion",[1690,3867,3828],{"class":1706},[1690,3869,1782],{"class":1706},[1690,3871,3833],{"class":1706},[1690,3873,3874],{"class":1710},"2026-10-16",[1690,3876,3828],{"class":1706},[1690,3878,1795],{"class":1706},[1690,3880,3881,3883,3886,3888,3890,3892,3895,3897],{"class":1692,"line":649},[1690,3882,3823],{"class":1706},[1690,3884,3885],{"class":1765},"occurredAt",[1690,3887,3828],{"class":1706},[1690,3889,1782],{"class":1706},[1690,3891,3833],{"class":1706},[1690,3893,3894],{"class":1710},"2026-10-17T14:02:55.120Z",[1690,3896,3828],{"class":1706},[1690,3898,1795],{"class":1706},[1690,3900,3901,3903,3906,3908,3910,3912,3915,3917],{"class":1692,"line":659},[1690,3902,3823],{"class":1706},[1690,3904,3905],{"class":1765},"organizationId",[1690,3907,3828],{"class":1706},[1690,3909,1782],{"class":1706},[1690,3911,3833],{"class":1706},[1690,3913,3914],{"class":1710},"8f14e45f-ceea-4e7a-9b1d-3c5a2f6e9d10",[1690,3916,3828],{"class":1706},[1690,3918,1795],{"class":1706},[1690,3920,3921,3923,3926,3928,3930,3932,3934,3937,3939,3941,3943,3946,3948,3950,3952,3955,3957,3959,3962,3964,3967,3969,3971,3973,3976,3978],{"class":1692,"line":596},[1690,3922,3823],{"class":1706},[1690,3924,3925],{"class":1765},"origin",[1690,3927,3828],{"class":1706},[1690,3929,1782],{"class":1706},[1690,3931,1724],{"class":1706},[1690,3933,3833],{"class":1706},[1690,3935,3936],{"class":1785},"kind",[1690,3938,3828],{"class":1706},[1690,3940,1782],{"class":1706},[1690,3942,3833],{"class":1706},[1690,3944,3945],{"class":1710},"system",[1690,3947,3828],{"class":1706},[1690,3949,1730],{"class":1706},[1690,3951,3833],{"class":1706},[1690,3953,3954],{"class":1785},"actorId",[1690,3956,3828],{"class":1706},[1690,3958,1782],{"class":1706},[1690,3960,3961],{"class":1706}," null,",[1690,3963,3833],{"class":1706},[1690,3965,3966],{"class":1785},"correlationId",[1690,3968,3828],{"class":1706},[1690,3970,1782],{"class":1706},[1690,3972,3833],{"class":1706},[1690,3974,3975],{"class":1710},"4c7d2e9a-1b3f-4a6e-8d5c-2f0b9e7a1c36",[1690,3977,3828],{"class":1706},[1690,3979,3980],{"class":1706}," },\n",[1690,3982,3983,3985,3987,3989,3991,3993,3995,3998,4000,4002,4004,4007,4009],{"class":1692,"line":280},[1690,3984,3823],{"class":1706},[1690,3986,3232],{"class":1765},[1690,3988,3828],{"class":1706},[1690,3990,1782],{"class":1706},[1690,3992,1724],{"class":1706},[1690,3994,3833],{"class":1706},[1690,3996,3997],{"class":1785},"endpointId",[1690,3999,3828],{"class":1706},[1690,4001,1782],{"class":1706},[1690,4003,3833],{"class":1706},[1690,4005,4006],{"class":1710},"3b0d2b8e-7f6a-4a46-9a3f-7a2c0f1a2b3c",[1690,4008,3828],{"class":1706},[1690,4010,4011],{"class":1706}," }\n",[1690,4013,4014],{"class":1692,"line":905},[1690,4015,2447],{"class":1706},[1626,4017,4019],{"id":4018},"step-5-watch-real-deliveries","Step 5: Watch real deliveries",[1588,4021,4022,4023,4025,4026,4028,4029,4032],{},"Now make a change that matches one of your events: create an item if you subscribed to ",[1617,4024,3135],{},", or comment on one for ",[1617,4027,3164],{},". Within seconds your receiver logs it, and the ",[1599,4030,4031],{},"Delivery log"," on the same settings page shows a row for it:",[1592,4034,4035,4051],{},[1595,4036,4037,4040,4041,4044,4045,4040,4048,4050],{},[1599,4038,4039],{},"Status"," ",[1617,4042,4043],{},"succeeded"," with ",[1599,4046,4047],{},"Last response",[1617,4049,2975],{},": all good.",[1595,4052,4053,4040,4055,4058,4059,4062,4063,4065,4066,4069],{},[1599,4054,4039],{},[1617,4056,4057],{},"pending"," with a ",[1599,4060,4061],{},"Next attempt"," time: your endpoint did not answer ",[1617,4064,1655],{}," and DevStride will retry. Click the arrow at the start of the row to see the exact ",[1599,4067,4068],{},"Payload"," and the last failed response.",[1588,4071,4072],{},"The page refreshes itself every 30 seconds while it is open.",[1626,4074,4076],{"id":4075},"next-steps","Next steps",[1592,4078,4079,4084,4089],{},[1595,4080,4081,4082,1832],{},"Learn what each event carries in ",[1604,4083,1087],{"href":1088},[1595,4085,4086,4087,1832],{},"Understand retries and ordering before you rely on them: ",[1604,4088,1095],{"href":1096},[1595,4090,4091,4092,1832],{},"Harden your receiver with ",[1604,4093,1103],{"href":1104},[4095,4096,4097],"style",{},"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);}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 .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 .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}",{"title":1686,"searchDepth":244,"depth":244,"links":4099},[4100,4105,4106,4107,4108,4109],{"id":1628,"depth":244,"text":1629,"children":4101},[4102,4103,4104],{"id":1678,"depth":302,"text":1679},{"id":3302,"depth":302,"text":3303},{"id":3450,"depth":302,"text":3451},{"id":3618,"depth":244,"text":3619},{"id":3688,"depth":244,"text":3689},{"id":3730,"depth":244,"text":3731},{"id":4018,"depth":244,"text":4019},{"id":4075,"depth":244,"text":4076},"Build a receiver that verifies DevStride's signature, register it under Settings → Webhooks, copy the one-time signing secret, send a test event and watch real deliveries arrive in the delivery log.","md",null,{},{"title":1083,"description":4110},"gyNNpLv7nAAlAljN3YLhGzKTj4-cmjKFkbbnvyqdkC4",[4117,4119],{"title":1077,"path":1078,"stem":1079,"description":4118,"children":-1},"DevStride POSTs a signed JSON event to your HTTPS endpoint the moment an item, comment or SLA timer changes, so your systems react in seconds instead of polling the API.",{"title":1087,"path":1088,"stem":1089,"description":4120,"children":-1},"The JSON envelope every DevStride webhook carries and every field of item.created, item.status_changed, comment.created, sla.at_risk and sla.breached, with when each fires and a realistic example of each.",1792296231477]