[{"data":1,"prerenderedAt":679},["ShallowReactive",2],{"i-lucide:shapes":3,"i-lucide:server":8,"i-lucide:library":10,"i-lucide:list-checks":12,"i-lucide:waypoints":14,"i-lucide:calendar-range":16,"i-lucide:layers":18,"i-lucide:notebook-pen":20,"i-lucide:swords":22,"i-lucide:terminal":24,"i-lucide:list":26,"i-lucide:gauge":28,"i-lucide:webhook":30,"i-lucide:home":32,"i-lucide:layout-grid":34,"i-lucide:tag":36,"i-lucide:newspaper":38,"i-lucide:map":40,"i-lucide:flask-conical":42,"i-lucide:arrow-right":44,"i-lucide:book-open":46,"i-lucide:chevron-right":48,"i-lucide:search":50,"i-lucide:monitor":52,"content:\u002Fdocs\u002Fwebhooks":54,"i-lucide:triangle-alert":673,"i-lucide:info":675,"i-lucide:lightbulb":677,"i-lucide:rocket":670,"i-lucide:key-round":670,"i-lucide:git-compare":670,"i-lucide:bot":670,"i-lucide:octagon-alert":670,"i-lucide:blocks":670,"i-lucide:fingerprint":670},{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":7},0,24,false,"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M8.3 10a.7.7 0 0 1-.626-1.079L11.4 3a.7.7 0 0 1 1.198-.043L16.3 8.9a.7.7 0 0 1-.572 1.1Z\"\u002F>\u003Crect width=\"7\" height=\"7\" x=\"3\" y=\"14\" rx=\"1\"\u002F>\u003Ccircle cx=\"17.5\" cy=\"17.5\" r=\"3.5\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":9},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Crect width=\"20\" height=\"8\" x=\"2\" y=\"2\" rx=\"2\" ry=\"2\"\u002F>\u003Crect width=\"20\" height=\"8\" x=\"2\" y=\"14\" rx=\"2\" ry=\"2\"\u002F>\u003Cpath d=\"M6 6h.01M6 18h.01\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":11},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"m16 6l4 14M12 6v14M8 8v12M4 4v16\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":13},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M13 5h8m-8 7h8m-8 7h8M3 17l2 2l4-4M3 7l2 2l4-4\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":15},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"m10.586 5.414l-5.172 5.172m13.172 2.828l-5.172 5.172M6 12h12\"\u002F>\u003Ccircle cx=\"12\" cy=\"20\" r=\"2\"\u002F>\u003Ccircle cx=\"12\" cy=\"4\" r=\"2\"\u002F>\u003Ccircle cx=\"20\" cy=\"12\" r=\"2\"\u002F>\u003Ccircle cx=\"4\" cy=\"12\" r=\"2\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":17},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Crect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\"\u002F>\u003Cpath d=\"M16 2v3M3 9h18M8 2v3m9 8h-6m2 4H7m0-4h.01M17 17h.01\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":19},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83z\"\u002F>\u003Cpath d=\"M2 12a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 12\"\u002F>\u003Cpath d=\"M2 17a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 17\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":21},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M13.4 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-7.4M2 6h4m-4 4h4m-4 4h4m-4 4h4\"\u002F>\u003Cpath d=\"M21.378 5.626a1 1 0 1 0-3.004-3.004l-5.01 5.012a2 2 0 0 0-.506.854l-.837 2.87a.5.5 0 0 0 .62.62l2.87-.837a2 2 0 0 0 .854-.506z\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":23},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M14.5 17.5L3 6V3h3l11.5 11.5M13 19l6-6m-3 3l4 4m-1 1l2-2M14.5 6.5L18 3h3v3l-3.5 3.5M5 14l4 4m-2-1l-3 3m-1-1l2 2\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":25},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M12 19h8M4 17l6-6l-6-6\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":27},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M3 5h.01M3 12h.01M3 19h.01M8 5h13M8 12h13M8 19h13\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":29},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"m12 14l4-4M3.34 19a10 10 0 1 1 17.32 0\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":31},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M18 16.98h-5.99c-1.1 0-1.95.94-2.48 1.9A4 4 0 0 1 2 17c.01-.7.2-1.4.57-2\"\u002F>\u003Cpath d=\"m6 17l3.13-5.78c.53-.97.1-2.18-.5-3.1a4 4 0 1 1 6.89-4.06\"\u002F>\u003Cpath d=\"m12 6l3.13 5.73C15.66 12.7 16.9 13 18 13a4 4 0 0 1 0 8\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":33},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M15 21v-8a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v8\"\u002F>\u003Cpath d=\"M3 10a2 2 0 0 1 .709-1.528l7-6a2 2 0 0 1 2.582 0l7 6A2 2 0 0 1 21 10v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":35},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Crect width=\"7\" height=\"7\" x=\"3\" y=\"3\" rx=\"1\"\u002F>\u003Crect width=\"7\" height=\"7\" x=\"14\" y=\"3\" rx=\"1\"\u002F>\u003Crect width=\"7\" height=\"7\" x=\"14\" y=\"14\" rx=\"1\"\u002F>\u003Crect width=\"7\" height=\"7\" x=\"3\" y=\"14\" rx=\"1\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":37},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M12.586 2.586A2 2 0 0 0 11.172 2H4a2 2 0 0 0-2 2v7.172a2 2 0 0 0 .586 1.414l8.704 8.704a2.426 2.426 0 0 0 3.42 0l6.58-6.58a2.426 2.426 0 0 0 0-3.42z\"\u002F>\u003Ccircle cx=\"7.5\" cy=\"7.5\" r=\".5\" fill=\"currentColor\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":39},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M15 18h-5m8-4h-8m-6 8h16a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2H8a2 2 0 0 0-2 2v16a2 2 0 0 1-4 0v-9a2 2 0 0 1 2-2h2\"\u002F>\u003Crect width=\"8\" height=\"4\" x=\"10\" y=\"6\" rx=\"1\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":41},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M14.106 5.553a2 2 0 0 0 1.788 0l3.659-1.83A1 1 0 0 1 21 4.619v12.764a1 1 0 0 1-.553.894l-4.553 2.277a2 2 0 0 1-1.788 0l-4.212-2.106a2 2 0 0 0-1.788 0l-3.659 1.83A1 1 0 0 1 3 19.381V6.618a1 1 0 0 1 .553-.894l4.553-2.277a2 2 0 0 1 1.788 0zm.894.211v15M9 3.236v15\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":43},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M14 2v6a2 2 0 0 0 .245.96l5.51 10.08A2 2 0 0 1 18 22H6a2 2 0 0 1-1.755-2.96l5.51-10.08A2 2 0 0 0 10 8V2M6.453 15h11.094M8.5 2h7\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":45},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M5 12h14m-7-7l7 7l-7 7\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":47},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M12 5v16m8.001-2A2 2 0 0 0 22 17V5a2 2 0 0 0-1.999-2L16 3.002A5 5 0 0 0 12 5a5 5 0 0 0-4-2H4a2 2 0 0 0-2 2v12a2 2 0 0 0 1.999 2H8a5 5 0 0 1 4 2a5 5 0 0 1 4-2z\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":49},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"m9 18l6-6l-6-6\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":51},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"m21 21l-4.34-4.34\"\u002F>\u003Ccircle cx=\"11\" cy=\"11\" r=\"8\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":53},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Crect width=\"20\" height=\"14\" x=\"2\" y=\"3\" rx=\"2\"\u002F>\u003Cpath d=\"M8 21h8m-4-4v4\"\u002F>\u003C\u002Fg>",{"id":55,"title":56,"body":57,"description":663,"extension":664,"eyebrow":665,"hostedOnly":6,"meta":666,"navigation":667,"path":668,"seo":669,"short":670,"stem":671,"__hash__":672},"docs\u002Fdocs\u002Fwebhooks.md","Webhooks",{"type":58,"value":59,"toc":653},"minimark",[60,64,72,77,85,98,101,108,112,115,186,190,197,200,208,211,215,218,389,428,432,439,447,461,522,525,529,532,596,606,610,613,627,633,636,640,643,649],[61,62,63],"p",{},"A webhook is a URL Chronicler calls when something changes in a workspace. Instead of polling the API for new resources, you give us an address and we POST a signed JSON body to it every time a matching event fires. Use them to mirror content into your own database, kick off a build, post to a chat channel, or keep a search index warm.",[65,66,69],"callout",{"title":67,"tone":68},"Hosted feature","note",[61,70,71],{},"Outbound webhooks run on Chronicler hosted. A self-hosted core can read the same events off its own stream, but the managed delivery, retries, and signing described here are part of the hosted build.",[73,74,76],"h2",{"id":75},"set-up-an-endpoint","Set up an endpoint",[61,78,79,80,84],{},"Webhooks live on the workspace, not on a single chronicle. Open ",[81,82,83],"strong",{},"Workspace settings, then Webhooks",", and register an endpoint. You give it three things:",[86,87,88,92,95],"ul",{},[89,90,91],"li",{},"the URL we should POST to,",[89,93,94],{},"the events it should receive,",[89,96,97],{},"an optional chronicle filter, if you only want events from one chronicle in the workspace.",[61,99,100],{},"When you register the endpoint, Chronicler generates a signing secret and shows it to you once.",[65,102,105],{"title":103,"tone":104},"Copy the secret now","warning",[61,106,107],{},"The signing secret is shown a single time, at creation. Store it somewhere safe before you close the dialog. If you lose it, rotate the secret to get a new one. The old one stops working the moment you rotate.",[73,109,111],{"id":110},"choose-your-events","Choose your events",[61,113,114],{},"Each endpoint subscribes to a set of event types. You can change the set later without re-registering.",[116,117,118,131],"table",{},[119,120,121],"thead",{},[122,123,124,128],"tr",{},[125,126,127],"th",{},"Event",[125,129,130],{},"Fires when",[132,133,134,146,156,166,176],"tbody",{},[122,135,136,143],{},[137,138,139],"td",{},[140,141,142],"code",{},"resource.created",[137,144,145],{},"A resource is created.",[122,147,148,153],{},[137,149,150],{},[140,151,152],{},"resource.updated",[137,154,155],{},"A resource's name, summary, or images change.",[122,157,158,163],{},[137,159,160],{},[140,161,162],{},"resource.attributes_set",[137,164,165],{},"A resource's attribute values change.",[122,167,168,173],{},[137,169,170],{},[140,171,172],{},"resource.lore_set",[137,174,175],{},"A resource's lore is edited.",[122,177,178,183],{},[137,179,180],{},[140,181,182],{},"resource.deleted",[137,184,185],{},"A resource is deleted.",[73,187,189],{"id":188},"verify-the-endpoint","Verify the endpoint",[61,191,192,193,196],{},"A new endpoint starts unverified and delivers nothing. To turn it on, send it a verification ping from the endpoint's menu. We POST a small ",[140,194,195],{},"endpoint.verification"," body to your URL, and if your server answers with any 2xx status, the endpoint becomes verified and starts delivering.",[61,198,199],{},"Two things worth knowing:",[86,201,202,205],{},[89,203,204],{},"Receiving the ping is not enough. Your handler has to return a 2xx. If it logs the request but returns a 404 or a 500, verification fails and the endpoint stays off.",[89,206,207],{},"Changing an endpoint's URL clears its verified state, so a re-pointed endpoint waits for a fresh ping before it delivers again.",[61,209,210],{},"Some installations do not require verification. On those, an endpoint is marked \"skipped\" and delivers straight away.",[73,212,214],{"id":213},"what-a-delivery-looks-like","What a delivery looks like",[61,216,217],{},"Every delivery is a POST with a JSON body in this shape:",[219,220,225],"pre",{"className":221,"code":222,"language":223,"meta":224,"style":224},"language-json shiki shiki-themes github-light github-dark","{\n  \"id\": \"whd_6311hvq3sgvd7vsmyxtmsh0sas\",\n  \"type\": \"resource.updated\",\n  \"occurredAt\": \"2026-09-03T14:24:27Z\",\n  \"version\": \"2026-09-02\",\n  \"workspaceId\": \"wksp_6311hvq3sgvd7vsmyxtmsh0sas\",\n  \"chronicleId\": \"chron_6311hvq3sgvd7vsmyxtmsh0sas\",\n  \"data\": {\n    \"id\": \"res_6311hvq3sgvd7vsmyxtmsh0sas\",\n    \"kind\": \"character\",\n    \"name\": \"Bomanz\",\n    \"summary\": \"A wizard of the north.\"\n  }\n}\n","json","",[140,226,227,236,253,266,279,292,305,318,327,340,353,366,377,383],{"__ignoreMap":224},[228,229,232],"span",{"class":230,"line":231},"line",1,[228,233,235],{"class":234},"sVt8B","{\n",[228,237,239,243,246,250],{"class":230,"line":238},2,[228,240,242],{"class":241},"sj4cs","  \"id\"",[228,244,245],{"class":234},": ",[228,247,249],{"class":248},"sZZnC","\"whd_6311hvq3sgvd7vsmyxtmsh0sas\"",[228,251,252],{"class":234},",\n",[228,254,256,259,261,264],{"class":230,"line":255},3,[228,257,258],{"class":241},"  \"type\"",[228,260,245],{"class":234},[228,262,263],{"class":248},"\"resource.updated\"",[228,265,252],{"class":234},[228,267,269,272,274,277],{"class":230,"line":268},4,[228,270,271],{"class":241},"  \"occurredAt\"",[228,273,245],{"class":234},[228,275,276],{"class":248},"\"2026-09-03T14:24:27Z\"",[228,278,252],{"class":234},[228,280,282,285,287,290],{"class":230,"line":281},5,[228,283,284],{"class":241},"  \"version\"",[228,286,245],{"class":234},[228,288,289],{"class":248},"\"2026-09-02\"",[228,291,252],{"class":234},[228,293,295,298,300,303],{"class":230,"line":294},6,[228,296,297],{"class":241},"  \"workspaceId\"",[228,299,245],{"class":234},[228,301,302],{"class":248},"\"wksp_6311hvq3sgvd7vsmyxtmsh0sas\"",[228,304,252],{"class":234},[228,306,308,311,313,316],{"class":230,"line":307},7,[228,309,310],{"class":241},"  \"chronicleId\"",[228,312,245],{"class":234},[228,314,315],{"class":248},"\"chron_6311hvq3sgvd7vsmyxtmsh0sas\"",[228,317,252],{"class":234},[228,319,321,324],{"class":230,"line":320},8,[228,322,323],{"class":241},"  \"data\"",[228,325,326],{"class":234},": {\n",[228,328,330,333,335,338],{"class":230,"line":329},9,[228,331,332],{"class":241},"    \"id\"",[228,334,245],{"class":234},[228,336,337],{"class":248},"\"res_6311hvq3sgvd7vsmyxtmsh0sas\"",[228,339,252],{"class":234},[228,341,343,346,348,351],{"class":230,"line":342},10,[228,344,345],{"class":241},"    \"kind\"",[228,347,245],{"class":234},[228,349,350],{"class":248},"\"character\"",[228,352,252],{"class":234},[228,354,356,359,361,364],{"class":230,"line":355},11,[228,357,358],{"class":241},"    \"name\"",[228,360,245],{"class":234},[228,362,363],{"class":248},"\"Bomanz\"",[228,365,252],{"class":234},[228,367,369,372,374],{"class":230,"line":368},12,[228,370,371],{"class":241},"    \"summary\"",[228,373,245],{"class":234},[228,375,376],{"class":248},"\"A wizard of the north.\"\n",[228,378,380],{"class":230,"line":379},13,[228,381,382],{"class":234},"  }\n",[228,384,386],{"class":230,"line":385},14,[228,387,388],{"class":234},"}\n",[61,390,391,392,395,396,399,400,403,404,406,407,410,411,414,415,417,418,421,422,424,425,427],{},"The ",[140,393,394],{},"id"," is the delivery id. A retry resends the same id, so use it to dedupe on your side. ",[140,397,398],{},"chronicleId"," is present for chronicle-scoped events and left out for workspace-level ones. ",[140,401,402],{},"data"," changes per event type: ",[140,405,162],{}," carries the changed ",[140,408,409],{},"values"," and any ",[140,412,413],{},"cleared"," keys, ",[140,416,172],{}," carries a ",[140,419,420],{},"segmentCount",", and ",[140,423,182],{}," carries only the ",[140,426,394],{},", since the resource is already gone by the time you hear about it.",[73,429,431],{"id":430},"verify-the-signature","Verify the signature",[61,433,434,435,438],{},"Every delivery carries a ",[140,436,437],{},"Chronicler-Signature"," header so you can prove it came from us and was not changed in transit:",[219,440,445],{"className":441,"code":443,"language":444},[442],"language-text","Chronicler-Signature: t=1756909467,v1=5257a869e7ecebeda32affa62cdca3fa...\n","text",[140,446,443],{"__ignoreMap":224},[61,448,449,452,453,456,457,460],{},[140,450,451],{},"t"," is the Unix timestamp we signed at. ",[140,454,455],{},"v1"," is an HMAC-SHA256, keyed with your signing secret, over the string ",[140,458,459],{},"\"{t}.{raw body}\"",". Recompute it and compare:",[219,462,466],{"className":463,"code":464,"language":465,"meta":224,"style":224},"language-js shiki shiki-themes github-light github-dark","import crypto from \"node:crypto\"\n\nfunction verify(signatureHeader, rawBody, secret) {\n  const parts = Object.fromEntries(signatureHeader.split(\",\").map((p) => p.split(\"=\")))\n  const expected = crypto\n    .createHmac(\"sha256\", secret)\n    .update(`${parts.t}.${rawBody}`)\n    .digest(\"hex\")\n\n  return crypto.timingSafeEqual(Buffer.from(parts.v1), Buffer.from(expected))\n}\n","js",[140,467,468,473,479,484,489,494,499,504,509,513,518],{"__ignoreMap":224},[228,469,470],{"class":230,"line":231},[228,471,472],{},"import crypto from \"node:crypto\"\n",[228,474,475],{"class":230,"line":238},[228,476,478],{"emptyLinePlaceholder":477},true,"\n",[228,480,481],{"class":230,"line":255},[228,482,483],{},"function verify(signatureHeader, rawBody, secret) {\n",[228,485,486],{"class":230,"line":268},[228,487,488],{},"  const parts = Object.fromEntries(signatureHeader.split(\",\").map((p) => p.split(\"=\")))\n",[228,490,491],{"class":230,"line":281},[228,492,493],{},"  const expected = crypto\n",[228,495,496],{"class":230,"line":294},[228,497,498],{},"    .createHmac(\"sha256\", secret)\n",[228,500,501],{"class":230,"line":307},[228,502,503],{},"    .update(`${parts.t}.${rawBody}`)\n",[228,505,506],{"class":230,"line":320},[228,507,508],{},"    .digest(\"hex\")\n",[228,510,511],{"class":230,"line":329},[228,512,478],{"emptyLinePlaceholder":477},[228,514,515],{"class":230,"line":342},[228,516,517],{},"  return crypto.timingSafeEqual(Buffer.from(parts.v1), Buffer.from(expected))\n",[228,519,520],{"class":230,"line":355},[228,521,388],{},[61,523,524],{},"Sign the raw request body, before any JSON parsing reformats it. Reject the delivery if the signatures do not match, and reject a timestamp that is too old to guard against replays.",[73,526,528],{"id":527},"delivery-statuses","Delivery statuses",[61,530,531],{},"Every attempt is recorded in the endpoint's delivery log, each with a status:",[116,533,534,544],{},[119,535,536],{},[122,537,538,541],{},[125,539,540],{},"Status",[125,542,543],{},"What it means",[132,545,546,556,566,576,586],{},[122,547,548,553],{},[137,549,550],{},[140,551,552],{},"pending",[137,554,555],{},"Queued and waiting, or sitting between retries.",[122,557,558,563],{},[137,559,560],{},[140,561,562],{},"delivered",[137,564,565],{},"Your endpoint answered with a 2xx.",[122,567,568,573],{},[137,569,570],{},[140,571,572],{},"failed",[137,574,575],{},"Every retry was used up and the delivery was given up on.",[122,577,578,583],{},[137,579,580],{},[140,581,582],{},"permanent",[137,584,585],{},"Your endpoint returned a 4xx other than 429, so a resend would not help.",[122,587,588,593],{},[137,589,590],{},[140,591,592],{},"skipped",[137,594,595],{},"The endpoint was disabled, unverified, or removed when the delivery ran.",[65,597,600],{"title":598,"tone":599},"Stuck on skipped?","tip",[61,601,602,603,605],{},"A ",[140,604,592],{}," delivery almost always means the endpoint was not deliverable at the time. Check that it is enabled and verified, then redeliver the row from the log.",[73,607,609],{"id":608},"retries-and-back-off","Retries and back-off",[61,611,612],{},"How we treat a delivery depends on your response:",[86,614,615,618,621,624],{},[89,616,617],{},"A 2xx marks it delivered and clears the endpoint's failure count.",[89,619,620],{},"A 429 or any 5xx is treated as temporary. We retry.",[89,622,623],{},"A network or timeout error is also temporary. We retry.",[89,625,626],{},"Any other 4xx is permanent. We stop and mark it so.",[61,628,629,630,632],{},"Retries follow a fixed back-off: one minute, then five minutes, thirty minutes, two hours, six hours, and twelve hours. After the last one the delivery is marked ",[140,631,572],{},". You can redeliver any finished delivery by hand from the log, which resets it to pending and sends it again.",[61,634,635],{},"If an endpoint fails 15 deliveries in a row, Chronicler disables it so a dead URL stops piling up failures. Fix your side, then re-enable it. Re-enabling clears the failure count.",[73,637,639],{"id":638},"scope-workspaces-and-chronicles","Scope: workspaces and chronicles",[61,641,642],{},"This is the one thing that catches people out. An endpoint belongs to a workspace, and it only receives events from chronicles that workspace owns. A chronicle filter narrows that further to a single chronicle.",[65,644,646],{"title":645,"tone":104},"Right event, wrong workspace",[61,647,648],{},"If you register a webhook in one workspace but edit a chronicle that belongs to another, nothing arrives, and no error tells you why. The event fired for the workspace that owns the chronicle you changed, not the one you were looking at in settings. Register the endpoint in the workspace that owns the chronicle you want events from.",[650,651,652],"style",{},"html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":224,"searchDepth":238,"depth":238,"links":654},[655,656,657,658,659,660,661,662],{"id":75,"depth":238,"text":76},{"id":110,"depth":238,"text":111},{"id":188,"depth":238,"text":189},{"id":213,"depth":238,"text":214},{"id":430,"depth":238,"text":431},{"id":527,"depth":238,"text":528},{"id":608,"depth":238,"text":609},{"id":638,"depth":238,"text":639},"Get an HTTP call when something changes in your world. Point an endpoint at your server, pick the events you care about, and Chronicler POSTs each one as it happens.","md","Developers",{},{"title":56},"\u002Fdocs\u002Fwebhooks",{"title":56,"description":663},null,"docs\u002Fwebhooks","59bPMmGKri7O2q1GL1h7OYg8hb1zOQZbVq-xXmIyhn4",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":674},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"m21.73 18l-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3M12 9v4m0 4h.01\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":676},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Ccircle cx=\"12\" cy=\"12\" r=\"10\"\u002F>\u003Cpath d=\"M12 16v-4m0-4h.01\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":678},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M15 14c.2-1 .7-1.7 1.5-2.5c1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5c.7.7 1.3 1.5 1.5 2.5m0 4h6m-5 4h4\"\u002F>",1788784058108]