[{"data":1,"prerenderedAt":1754},["ShallowReactive",2],{"navigation_docs":3,"-docs-webhooks-receiver-examples":352,"-docs-webhooks-receiver-examples-surround":1749},[4,22,35,60,81,137,223,254,282,306,327],{"title":5,"path":6,"stem":7,"children":8,"page":21},"Getting Started","\u002Fdocs\u002Fgetting-started","docs\u002F1.getting-started",[9,13,17],{"title":10,"path":11,"stem":12},"Overview","\u002Fdocs\u002Fgetting-started\u002Foverview","docs\u002F1.getting-started\u002F1.overview",{"title":14,"path":15,"stem":16},"Integration checklist","\u002Fdocs\u002Fgetting-started\u002Fintegration-checklist","docs\u002F1.getting-started\u002F2.integration-checklist",{"title":18,"path":19,"stem":20},"Environments and base URLs","\u002Fdocs\u002Fgetting-started\u002Fenvironments-and-base-urls","docs\u002F1.getting-started\u002F3.environments-and-base-urls",false,{"title":23,"path":24,"stem":25,"children":26,"page":21},"Troubleshooting","\u002Fdocs\u002Ftroubleshooting","docs\u002F10.troubleshooting",[27,31],{"title":28,"path":29,"stem":30},"Common errors","\u002Fdocs\u002Ftroubleshooting\u002Fcommon-errors","docs\u002F10.troubleshooting\u002F1.common-errors",{"title":32,"path":33,"stem":34},"Support escalation","\u002Fdocs\u002Ftroubleshooting\u002Fsupport-escalation","docs\u002F10.troubleshooting\u002F2.support-escalation",{"title":36,"path":37,"stem":38,"children":39,"page":21},"Polyflight","\u002Fdocs\u002Fpolyflight","docs\u002F11.polyflight",[40,44,48,52,56],{"title":41,"path":42,"stem":43},"Polyflight overview and launch","\u002Fdocs\u002Fpolyflight\u002Foverview-and-launch","docs\u002F11.polyflight\u002F1.overview-and-launch",{"title":45,"path":46,"stem":47},"Native wallet contract","\u002Fdocs\u002Fpolyflight\u002Fnative-wallet-contract","docs\u002F11.polyflight\u002F2.native-wallet-contract",{"title":49,"path":50,"stem":51},"API, events, and proof","\u002Fdocs\u002Fpolyflight\u002Fapi-events-and-proof","docs\u002F11.polyflight\u002F3.api-events-and-proof",{"title":53,"path":54,"stem":55},"Terms, statements, and settlement","\u002Fdocs\u002Fpolyflight\u002Fterms-statements-and-settlement","docs\u002F11.polyflight\u002F4.terms-statements-and-settlement",{"title":57,"path":58,"stem":59},"Operations, reconciliation, and rollback","\u002Fdocs\u002Fpolyflight\u002Foperations-reconciliation-and-rollback","docs\u002F11.polyflight\u002F5.operations-reconciliation-and-rollback",{"title":61,"path":62,"stem":63,"children":64,"page":21},"Integration Flow","\u002Fdocs\u002Fintegration-flow","docs\u002F2.integration-flow",[65,69,73,77],{"title":66,"path":67,"stem":68},"Architecture","\u002Fdocs\u002Fintegration-flow\u002Farchitecture","docs\u002F2.integration-flow\u002F1.architecture",{"title":70,"path":71,"stem":72},"Launch session model","\u002Fdocs\u002Fintegration-flow\u002Flaunch-session-model","docs\u002F2.integration-flow\u002F2.launch-session-model",{"title":74,"path":75,"stem":76},"Order and wallet saga","\u002Fdocs\u002Fintegration-flow\u002Forder-and-wallet-saga","docs\u002F2.integration-flow\u002F3.order-and-wallet-saga",{"title":78,"path":79,"stem":80},"FX fees and rounding","\u002Fdocs\u002Fintegration-flow\u002Ffx-fees-and-rounding","docs\u002F2.integration-flow\u002F4.fx-fees-and-rounding",{"title":82,"path":83,"stem":84,"children":85,"page":21},"Dashboard","\u002Fdocs\u002Fdashboard","docs\u002F3.dashboard",[86,89,93,97,101,105,109,113,117,121,125,129,133],{"title":10,"path":87,"stem":88},"\u002Fdocs\u002Fdashboard\u002Foverview","docs\u002F3.dashboard\u002F1.overview",{"title":90,"path":91,"stem":92},"Webhook Deliveries","\u002Fdocs\u002Fdashboard\u002Fwebhook-deliveries","docs\u002F3.dashboard\u002F10.webhook-deliveries",{"title":94,"path":95,"stem":96},"Staffs","\u002Fdocs\u002Fdashboard\u002Fstaffs","docs\u002F3.dashboard\u002F11.staffs",{"title":98,"path":99,"stem":100},"Simulator","\u002Fdocs\u002Fdashboard\u002Fsimulator","docs\u002F3.dashboard\u002F12.simulator",{"title":102,"path":103,"stem":104},"API Playground","\u002Fdocs\u002Fdashboard\u002Fapi-playground","docs\u002F3.dashboard\u002F13.api-playground",{"title":106,"path":107,"stem":108},"API keys","\u002Fdocs\u002Fdashboard\u002Fapi-keys","docs\u002F3.dashboard\u002F2.api-keys",{"title":110,"path":111,"stem":112},"Wallet adapter settings","\u002Fdocs\u002Fdashboard\u002Fwallet-adapter-settings","docs\u002F3.dashboard\u002F3.wallet-adapter-settings",{"title":114,"path":115,"stem":116},"Webhook endpoints","\u002Fdocs\u002Fdashboard\u002Fwebhook-endpoints","docs\u002F3.dashboard\u002F4.webhook-endpoints",{"title":118,"path":119,"stem":120},"Markets and visibility","\u002Fdocs\u002Fdashboard\u002Fmarket-visibility","docs\u002F3.dashboard\u002F5.market-visibility",{"title":122,"path":123,"stem":124},"Users","\u002Fdocs\u002Fdashboard\u002Fusers","docs\u002F3.dashboard\u002F6.users",{"title":126,"path":127,"stem":128},"Trades","\u002Fdocs\u002Fdashboard\u002Ftrades","docs\u002F3.dashboard\u002F7.trades",{"title":130,"path":131,"stem":132},"Resolutions","\u002Fdocs\u002Fdashboard\u002Fresolutions","docs\u002F3.dashboard\u002F8.resolutions",{"title":134,"path":135,"stem":136},"Balance Operations","\u002Fdocs\u002Fdashboard\u002Fbalance-operations","docs\u002F3.dashboard\u002F9.balance-operations",{"title":138,"path":139,"stem":140,"children":141,"page":21},"Operator Api","\u002Fdocs\u002Foperator-api","docs\u002F4.operator-api",[142,146,149,153,156,160,163,167,171,175,179,183,186,190,194,198,202,206,209,213,216,219],{"title":143,"path":144,"stem":145},"Authentication","\u002Fdocs\u002Foperator-api\u002Fauthentication","docs\u002F4.operator-api\u002F1.authentication",{"title":114,"path":147,"stem":148},"\u002Fdocs\u002Foperator-api\u002Fwebhook-endpoints","docs\u002F4.operator-api\u002F10.webhook-endpoints",{"title":150,"path":151,"stem":152},"Webhook deliveries","\u002Fdocs\u002Foperator-api\u002Fwebhook-deliveries","docs\u002F4.operator-api\u002F11.webhook-deliveries",{"title":98,"path":154,"stem":155},"\u002Fdocs\u002Foperator-api\u002Fsimulator","docs\u002F4.operator-api\u002F12.simulator",{"title":157,"path":158,"stem":159},"Wallet adapter","\u002Fdocs\u002Foperator-api\u002Fwallet-adapter","docs\u002F4.operator-api\u002F13.wallet-adapter",{"title":94,"path":161,"stem":162},"\u002Fdocs\u002Foperator-api\u002Fstaffs","docs\u002F4.operator-api\u002F14.staffs",{"title":164,"path":165,"stem":166},"Error codes","\u002Fdocs\u002Foperator-api\u002Ferror-codes","docs\u002F4.operator-api\u002F15.error-codes",{"title":168,"path":169,"stem":170},"Redemptions","\u002Fdocs\u002Foperator-api\u002Fredemptions","docs\u002F4.operator-api\u002F16.redemptions",{"title":172,"path":173,"stem":174},"Polyflight overview","\u002Fdocs\u002Foperator-api\u002Fpolyflight","docs\u002F4.operator-api\u002F17.polyflight",{"title":176,"path":177,"stem":178},"Polyflight flights","\u002Fdocs\u002Foperator-api\u002Fpolyflight-flights","docs\u002F4.operator-api\u002F18.polyflight-flights",{"title":180,"path":181,"stem":182},"Polyflight tickets","\u002Fdocs\u002Foperator-api\u002Fpolyflight-tickets","docs\u002F4.operator-api\u002F19.polyflight-tickets",{"title":106,"path":184,"stem":185},"\u002Fdocs\u002Foperator-api\u002Fapi-keys","docs\u002F4.operator-api\u002F2.api-keys",{"title":187,"path":188,"stem":189},"Polyflight balance operations","\u002Fdocs\u002Foperator-api\u002Fpolyflight-balance-operations","docs\u002F4.operator-api\u002F20.polyflight-balance-operations",{"title":191,"path":192,"stem":193},"Polyflight terms","\u002Fdocs\u002Foperator-api\u002Fpolyflight-terms","docs\u002F4.operator-api\u002F21.polyflight-terms",{"title":195,"path":196,"stem":197},"Polyflight settlement reports","\u002Fdocs\u002Foperator-api\u002Fpolyflight-settlement-reports","docs\u002F4.operator-api\u002F22.polyflight-settlement-reports",{"title":199,"path":200,"stem":201},"Session","\u002Fdocs\u002Foperator-api\u002Fsession","docs\u002F4.operator-api\u002F3.session",{"title":203,"path":204,"stem":205},"Launch","\u002Fdocs\u002Foperator-api\u002Flaunch","docs\u002F4.operator-api\u002F4.launch",{"title":122,"path":207,"stem":208},"\u002Fdocs\u002Foperator-api\u002Fusers","docs\u002F4.operator-api\u002F5.users",{"title":210,"path":211,"stem":212},"Markets","\u002Fdocs\u002Foperator-api\u002Fmarkets","docs\u002F4.operator-api\u002F6.markets",{"title":126,"path":214,"stem":215},"\u002Fdocs\u002Foperator-api\u002Ftrades","docs\u002F4.operator-api\u002F7.trades",{"title":130,"path":217,"stem":218},"\u002Fdocs\u002Foperator-api\u002Fresolutions","docs\u002F4.operator-api\u002F8.resolutions",{"title":220,"path":221,"stem":222},"Balance operations","\u002Fdocs\u002Foperator-api\u002Fbalance-operations","docs\u002F4.operator-api\u002F9.balance-operations",{"title":224,"path":225,"stem":226,"children":227,"page":21},"Wallet Adapter","\u002Fdocs\u002Fwallet-adapter","docs\u002F5.wallet-adapter",[228,231,234,238,242,246,250],{"title":10,"path":229,"stem":230},"\u002Fdocs\u002Fwallet-adapter\u002Foverview","docs\u002F5.wallet-adapter\u002F1.overview",{"title":143,"path":232,"stem":233},"\u002Fdocs\u002Fwallet-adapter\u002Fauthentication","docs\u002F5.wallet-adapter\u002F2.authentication",{"title":235,"path":236,"stem":237},"Balance","\u002Fdocs\u002Fwallet-adapter\u002Fbalance","docs\u002F5.wallet-adapter\u002F3.balance",{"title":239,"path":240,"stem":241},"Debit","\u002Fdocs\u002Fwallet-adapter\u002Fdebit","docs\u002F5.wallet-adapter\u002F4.debit",{"title":243,"path":244,"stem":245},"Credit","\u002Fdocs\u002Fwallet-adapter\u002Fcredit","docs\u002F5.wallet-adapter\u002F5.credit",{"title":247,"path":248,"stem":249},"Debit reversal","\u002Fdocs\u002Fwallet-adapter\u002Fdebit-reversal","docs\u002F5.wallet-adapter\u002F6.debit-reversal",{"title":251,"path":252,"stem":253},"Idempotency","\u002Fdocs\u002Fwallet-adapter\u002Fidempotency","docs\u002F5.wallet-adapter\u002F7.idempotency",{"title":255,"path":256,"stem":257,"children":258,"page":21},"Webhooks","\u002Fdocs\u002Fwebhooks","docs\u002F6.webhooks",[259,262,266,270,274,278],{"title":10,"path":260,"stem":261},"\u002Fdocs\u002Fwebhooks\u002Foverview","docs\u002F6.webhooks\u002F1.overview",{"title":263,"path":264,"stem":265},"Signatures","\u002Fdocs\u002Fwebhooks\u002Fsignatures","docs\u002F6.webhooks\u002F2.signatures",{"title":267,"path":268,"stem":269},"Event envelope","\u002Fdocs\u002Fwebhooks\u002Fevent-envelope","docs\u002F6.webhooks\u002F3.event-envelope",{"title":271,"path":272,"stem":273},"Event types","\u002Fdocs\u002Fwebhooks\u002Fevent-types","docs\u002F6.webhooks\u002F4.event-types",{"title":275,"path":276,"stem":277},"Retry and replay","\u002Fdocs\u002Fwebhooks\u002Fretry-and-replay","docs\u002F6.webhooks\u002F5.retry-and-replay",{"title":279,"path":280,"stem":281},"Receiver examples","\u002Fdocs\u002Fwebhooks\u002Freceiver-examples","docs\u002F6.webhooks\u002F6.receiver-examples",{"title":283,"path":284,"stem":285,"children":286,"page":21},"Testing And Staging","\u002Fdocs\u002Ftesting-and-staging","docs\u002F7.testing-and-staging",[287,291,294,298,302],{"title":288,"path":289,"stem":290},"Staging overview","\u002Fdocs\u002Ftesting-and-staging\u002Fstaging-overview","docs\u002F7.testing-and-staging\u002F1.staging-overview",{"title":98,"path":292,"stem":293},"\u002Fdocs\u002Ftesting-and-staging\u002Fsimulator","docs\u002F7.testing-and-staging\u002F2.simulator",{"title":295,"path":296,"stem":297},"Wallet failure drills","\u002Fdocs\u002Ftesting-and-staging\u002Fwallet-failure-drills","docs\u002F7.testing-and-staging\u002F3.wallet-failure-drills",{"title":299,"path":300,"stem":301},"Webhook drills","\u002Fdocs\u002Ftesting-and-staging\u002Fwebhook-drills","docs\u002F7.testing-and-staging\u002F4.webhook-drills",{"title":303,"path":304,"stem":305},"Production cutover rehearsal","\u002Fdocs\u002Ftesting-and-staging\u002Fproduction-cutover-rehearsal","docs\u002F7.testing-and-staging\u002F5.production-cutover-rehearsal",{"title":307,"path":308,"stem":309,"children":310,"page":21},"Production Readiness","\u002Fdocs\u002Fproduction-readiness","docs\u002F8.production-readiness",[311,315,319,323],{"title":312,"path":313,"stem":314},"Checklist","\u002Fdocs\u002Fproduction-readiness\u002Fchecklist","docs\u002F8.production-readiness\u002F1.checklist",{"title":316,"path":317,"stem":318},"Operational runbook","\u002Fdocs\u002Fproduction-readiness\u002Foperational-runbook","docs\u002F8.production-readiness\u002F2.operational-runbook",{"title":320,"path":321,"stem":322},"Security","\u002Fdocs\u002Fproduction-readiness\u002Fsecurity","docs\u002F8.production-readiness\u002F3.security",{"title":324,"path":325,"stem":326},"Rollback","\u002Fdocs\u002Fproduction-readiness\u002Frollback","docs\u002F8.production-readiness\u002F4.rollback",{"title":328,"path":329,"stem":330,"children":331,"page":21},"Reference","\u002Fdocs\u002Freference","docs\u002F9.reference",[332,336,340,344,348],{"title":333,"path":334,"stem":335},"Statuses","\u002Fdocs\u002Freference\u002Fstatuses","docs\u002F9.reference\u002F1.statuses",{"title":337,"path":338,"stem":339},"Scopes","\u002Fdocs\u002Freference\u002Fscopes","docs\u002F9.reference\u002F2.scopes",{"title":341,"path":342,"stem":343},"Units and money","\u002Fdocs\u002Freference\u002Funits-and-money","docs\u002F9.reference\u002F3.units-and-money",{"title":345,"path":346,"stem":347},"Changelog","\u002Fdocs\u002Freference\u002Fchangelog","docs\u002F9.reference\u002F4.changelog",{"title":349,"path":350,"stem":351},"Virtual AMM","\u002Fdocs\u002Freference\u002Fvirtual-amm","docs\u002F9.reference\u002F5.virtual-amm",{"id":353,"title":279,"body":354,"description":1743,"extension":1744,"links":1745,"meta":1746,"navigation":442,"path":280,"seo":1747,"stem":281,"__hash__":1748},"docs\u002Fdocs\u002F6.webhooks\u002F6.receiver-examples.md",{"type":355,"value":356,"toc":1737},"minimark",[357,361,365,370,1654,1657,1661,1669,1673,1703,1707,1733],[358,359,279],"h1",{"id":360},"receiver-examples",[362,363,364],"p",{},"Examples below show safe minimum flow.",[366,367,369],"h2",{"id":368},"node-example","Node example",[371,372,377],"pre",{"className":373,"code":374,"language":375,"meta":376,"style":376},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import { createHmac, timingSafeEqual } from 'node:crypto'\nimport express from 'express'\n\nconst app = express()\napp.use('\u002Fwebhooks\u002Fopenpoly', express.raw({ type: 'application\u002Fjson' }))\n\nconst processedEventIds = new Set\u003Cstring>()\nconst secret = process.env.OPENPOLY_WEBHOOK_SECRET!\nconst maxSkewMs = 5 * 60_000\n\nfunction sign(timestamp: string, rawBody: Buffer) {\n  const payload = `${timestamp}.${rawBody.toString('utf8')}`\n  const digest = createHmac('sha256', secret).update(payload).digest('hex')\n  return `v1=${digest}`\n}\n\napp.post('\u002Fwebhooks\u002Fopenpoly', async (req, res) => {\n  const eventId = String(req.header('x-polynion-event-id') || '')\n  const timestamp = String(req.header('x-polynion-timestamp') || '')\n  const signature = String(req.header('x-polynion-signature') || '')\n  const rawBody = Buffer.isBuffer(req.body) ? req.body : Buffer.from('')\n\n  if (!eventId || !timestamp || !signature) {\n    return res.status(401).json({ error: 'MISSING_SIGNATURE_HEADERS' })\n  }\n\n  const parsedTs = Date.parse(timestamp)\n  if (!Number.isFinite(parsedTs) || Math.abs(Date.now() - parsedTs) > maxSkewMs) {\n    return res.status(401).json({ error: 'TIMESTAMP_SKEW_TOO_LARGE' })\n  }\n\n  const expected = sign(timestamp, rawBody)\n  const expectedBuf = Buffer.from(expected)\n  const gotBuf = Buffer.from(signature)\n  if (expectedBuf.length !== gotBuf.length || !timingSafeEqual(expectedBuf, gotBuf)) {\n    return res.status(401).json({ error: 'INVALID_SIGNATURE' })\n  }\n\n  const payload = JSON.parse(rawBody.toString('utf8'))\n  if (payload.event_id !== eventId) {\n    return res.status(400).json({ error: 'EVENT_ID_MISMATCH' })\n  }\n\n  if (processedEventIds.has(eventId)) {\n    return res.status(409).json({ error: 'DUPLICATE_EVENT_ID' })\n  }\n\n  await persistIncomingEvent(payload)\n  await applyBusinessSideEffects(payload)\n  processedEventIds.add(eventId)\n\n  return res.status(200).json({ ok: true })\n})\n","ts","",[378,379,380,419,437,444,464,520,525,553,579,599,604,640,687,744,762,768,773,814,856,893,930,983,988,1022,1067,1073,1078,1102,1165,1205,1210,1215,1237,1260,1282,1326,1366,1371,1376,1410,1432,1473,1478,1483,1506,1547,1552,1557,1572,1586,1603,1608,1647],"code",{"__ignoreMap":376},[381,382,385,389,393,397,400,403,406,409,412,416],"span",{"class":383,"line":384},"line",1,[381,386,388],{"class":387},"s7zQu","import",[381,390,392],{"class":391},"sMK4o"," {",[381,394,396],{"class":395},"sTEyZ"," createHmac",[381,398,399],{"class":391},",",[381,401,402],{"class":395}," timingSafeEqual",[381,404,405],{"class":391}," }",[381,407,408],{"class":387}," from",[381,410,411],{"class":391}," '",[381,413,415],{"class":414},"sfazB","node:crypto",[381,417,418],{"class":391},"'\n",[381,420,422,424,427,430,432,435],{"class":383,"line":421},2,[381,423,388],{"class":387},[381,425,426],{"class":395}," express ",[381,428,429],{"class":387},"from",[381,431,411],{"class":391},[381,433,434],{"class":414},"express",[381,436,418],{"class":391},[381,438,440],{"class":383,"line":439},3,[381,441,443],{"emptyLinePlaceholder":442},true,"\n",[381,445,447,451,454,457,461],{"class":383,"line":446},4,[381,448,450],{"class":449},"spNyl","const",[381,452,453],{"class":395}," app ",[381,455,456],{"class":391},"=",[381,458,460],{"class":459},"s2Zo4"," express",[381,462,463],{"class":395},"()\n",[381,465,467,470,473,476,479,482,485,487,489,491,493,496,498,501,505,508,510,513,515,517],{"class":383,"line":466},5,[381,468,469],{"class":395},"app",[381,471,472],{"class":391},".",[381,474,475],{"class":459},"use",[381,477,478],{"class":395},"(",[381,480,481],{"class":391},"'",[381,483,484],{"class":414},"\u002Fwebhooks\u002Fopenpoly",[381,486,481],{"class":391},[381,488,399],{"class":391},[381,490,460],{"class":395},[381,492,472],{"class":391},[381,494,495],{"class":459},"raw",[381,497,478],{"class":395},[381,499,500],{"class":391},"{",[381,502,504],{"class":503},"swJcz"," type",[381,506,507],{"class":391},":",[381,509,411],{"class":391},[381,511,512],{"class":414},"application\u002Fjson",[381,514,481],{"class":391},[381,516,405],{"class":391},[381,518,519],{"class":395},"))\n",[381,521,523],{"class":383,"line":522},6,[381,524,443],{"emptyLinePlaceholder":442},[381,526,528,530,533,535,538,541,544,548,551],{"class":383,"line":527},7,[381,529,450],{"class":449},[381,531,532],{"class":395}," processedEventIds ",[381,534,456],{"class":391},[381,536,537],{"class":391}," new",[381,539,540],{"class":459}," Set",[381,542,543],{"class":391},"\u003C",[381,545,547],{"class":546},"sBMFI","string",[381,549,550],{"class":391},">",[381,552,463],{"class":395},[381,554,556,558,561,563,566,568,571,573,576],{"class":383,"line":555},8,[381,557,450],{"class":449},[381,559,560],{"class":395}," secret ",[381,562,456],{"class":391},[381,564,565],{"class":395}," process",[381,567,472],{"class":391},[381,569,570],{"class":395},"env",[381,572,472],{"class":391},[381,574,575],{"class":395},"OPENPOLY_WEBHOOK_SECRET",[381,577,578],{"class":391},"!\n",[381,580,582,584,587,589,593,596],{"class":383,"line":581},9,[381,583,450],{"class":449},[381,585,586],{"class":395}," maxSkewMs ",[381,588,456],{"class":391},[381,590,592],{"class":591},"sbssI"," 5",[381,594,595],{"class":391}," *",[381,597,598],{"class":591}," 60_000\n",[381,600,602],{"class":383,"line":601},10,[381,603,443],{"emptyLinePlaceholder":442},[381,605,607,610,613,615,619,621,624,626,629,631,634,637],{"class":383,"line":606},11,[381,608,609],{"class":449},"function",[381,611,612],{"class":459}," sign",[381,614,478],{"class":391},[381,616,618],{"class":617},"sHdIc","timestamp",[381,620,507],{"class":391},[381,622,623],{"class":546}," string",[381,625,399],{"class":391},[381,627,628],{"class":617}," rawBody",[381,630,507],{"class":391},[381,632,633],{"class":546}," Buffer",[381,635,636],{"class":391},")",[381,638,639],{"class":391}," {\n",[381,641,643,646,649,652,655,657,660,662,665,668,670,673,675,677,680,682,684],{"class":383,"line":642},12,[381,644,645],{"class":449},"  const",[381,647,648],{"class":395}," payload",[381,650,651],{"class":391}," =",[381,653,654],{"class":391}," `${",[381,656,618],{"class":395},[381,658,659],{"class":391},"}",[381,661,472],{"class":414},[381,663,664],{"class":391},"${",[381,666,667],{"class":395},"rawBody",[381,669,472],{"class":391},[381,671,672],{"class":459},"toString",[381,674,478],{"class":395},[381,676,481],{"class":391},[381,678,679],{"class":414},"utf8",[381,681,481],{"class":391},[381,683,636],{"class":395},[381,685,686],{"class":391},"}`\n",[381,688,690,692,695,697,699,701,703,706,708,710,713,715,717,720,722,725,727,729,732,734,736,739,741],{"class":383,"line":689},13,[381,691,645],{"class":449},[381,693,694],{"class":395}," digest",[381,696,651],{"class":391},[381,698,396],{"class":459},[381,700,478],{"class":503},[381,702,481],{"class":391},[381,704,705],{"class":414},"sha256",[381,707,481],{"class":391},[381,709,399],{"class":391},[381,711,712],{"class":395}," secret",[381,714,636],{"class":503},[381,716,472],{"class":391},[381,718,719],{"class":459},"update",[381,721,478],{"class":503},[381,723,724],{"class":395},"payload",[381,726,636],{"class":503},[381,728,472],{"class":391},[381,730,731],{"class":459},"digest",[381,733,478],{"class":503},[381,735,481],{"class":391},[381,737,738],{"class":414},"hex",[381,740,481],{"class":391},[381,742,743],{"class":503},")\n",[381,745,747,750,753,756,758,760],{"class":383,"line":746},14,[381,748,749],{"class":387},"  return",[381,751,752],{"class":391}," `",[381,754,755],{"class":414},"v1=",[381,757,664],{"class":391},[381,759,731],{"class":395},[381,761,686],{"class":391},[381,763,765],{"class":383,"line":764},15,[381,766,767],{"class":391},"}\n",[381,769,771],{"class":383,"line":770},16,[381,772,443],{"emptyLinePlaceholder":442},[381,774,776,778,780,783,785,787,789,791,793,796,799,802,804,807,809,812],{"class":383,"line":775},17,[381,777,469],{"class":395},[381,779,472],{"class":391},[381,781,782],{"class":459},"post",[381,784,478],{"class":395},[381,786,481],{"class":391},[381,788,484],{"class":414},[381,790,481],{"class":391},[381,792,399],{"class":391},[381,794,795],{"class":449}," async",[381,797,798],{"class":391}," (",[381,800,801],{"class":617},"req",[381,803,399],{"class":391},[381,805,806],{"class":617}," res",[381,808,636],{"class":391},[381,810,811],{"class":449}," =>",[381,813,639],{"class":391},[381,815,817,819,822,824,827,829,831,833,836,838,840,843,845,848,851,854],{"class":383,"line":816},18,[381,818,645],{"class":449},[381,820,821],{"class":395}," eventId",[381,823,651],{"class":391},[381,825,826],{"class":459}," String",[381,828,478],{"class":503},[381,830,801],{"class":395},[381,832,472],{"class":391},[381,834,835],{"class":459},"header",[381,837,478],{"class":503},[381,839,481],{"class":391},[381,841,842],{"class":414},"x-polynion-event-id",[381,844,481],{"class":391},[381,846,847],{"class":503},") ",[381,849,850],{"class":391},"||",[381,852,853],{"class":391}," ''",[381,855,743],{"class":503},[381,857,859,861,864,866,868,870,872,874,876,878,880,883,885,887,889,891],{"class":383,"line":858},19,[381,860,645],{"class":449},[381,862,863],{"class":395}," timestamp",[381,865,651],{"class":391},[381,867,826],{"class":459},[381,869,478],{"class":503},[381,871,801],{"class":395},[381,873,472],{"class":391},[381,875,835],{"class":459},[381,877,478],{"class":503},[381,879,481],{"class":391},[381,881,882],{"class":414},"x-polynion-timestamp",[381,884,481],{"class":391},[381,886,847],{"class":503},[381,888,850],{"class":391},[381,890,853],{"class":391},[381,892,743],{"class":503},[381,894,896,898,901,903,905,907,909,911,913,915,917,920,922,924,926,928],{"class":383,"line":895},20,[381,897,645],{"class":449},[381,899,900],{"class":395}," signature",[381,902,651],{"class":391},[381,904,826],{"class":459},[381,906,478],{"class":503},[381,908,801],{"class":395},[381,910,472],{"class":391},[381,912,835],{"class":459},[381,914,478],{"class":503},[381,916,481],{"class":391},[381,918,919],{"class":414},"x-polynion-signature",[381,921,481],{"class":391},[381,923,847],{"class":503},[381,925,850],{"class":391},[381,927,853],{"class":391},[381,929,743],{"class":503},[381,931,933,935,937,939,941,943,946,948,950,952,955,957,960,963,965,967,970,972,974,976,978,981],{"class":383,"line":932},21,[381,934,645],{"class":449},[381,936,628],{"class":395},[381,938,651],{"class":391},[381,940,633],{"class":395},[381,942,472],{"class":391},[381,944,945],{"class":459},"isBuffer",[381,947,478],{"class":503},[381,949,801],{"class":395},[381,951,472],{"class":391},[381,953,954],{"class":395},"body",[381,956,847],{"class":503},[381,958,959],{"class":391},"?",[381,961,962],{"class":395}," req",[381,964,472],{"class":391},[381,966,954],{"class":395},[381,968,969],{"class":391}," :",[381,971,633],{"class":395},[381,973,472],{"class":391},[381,975,429],{"class":459},[381,977,478],{"class":503},[381,979,980],{"class":391},"''",[381,982,743],{"class":503},[381,984,986],{"class":383,"line":985},22,[381,987,443],{"emptyLinePlaceholder":442},[381,989,991,994,996,999,1002,1005,1008,1010,1012,1014,1017,1019],{"class":383,"line":990},23,[381,992,993],{"class":387},"  if",[381,995,798],{"class":503},[381,997,998],{"class":391},"!",[381,1000,1001],{"class":395},"eventId",[381,1003,1004],{"class":391}," ||",[381,1006,1007],{"class":391}," !",[381,1009,618],{"class":395},[381,1011,1004],{"class":391},[381,1013,1007],{"class":391},[381,1015,1016],{"class":395},"signature",[381,1018,847],{"class":503},[381,1020,1021],{"class":391},"{\n",[381,1023,1025,1028,1030,1032,1035,1037,1040,1042,1044,1047,1049,1051,1054,1056,1058,1061,1063,1065],{"class":383,"line":1024},24,[381,1026,1027],{"class":387},"    return",[381,1029,806],{"class":395},[381,1031,472],{"class":391},[381,1033,1034],{"class":459},"status",[381,1036,478],{"class":503},[381,1038,1039],{"class":591},"401",[381,1041,636],{"class":503},[381,1043,472],{"class":391},[381,1045,1046],{"class":459},"json",[381,1048,478],{"class":503},[381,1050,500],{"class":391},[381,1052,1053],{"class":503}," error",[381,1055,507],{"class":391},[381,1057,411],{"class":391},[381,1059,1060],{"class":414},"MISSING_SIGNATURE_HEADERS",[381,1062,481],{"class":391},[381,1064,405],{"class":391},[381,1066,743],{"class":503},[381,1068,1070],{"class":383,"line":1069},25,[381,1071,1072],{"class":391},"  }\n",[381,1074,1076],{"class":383,"line":1075},26,[381,1077,443],{"emptyLinePlaceholder":442},[381,1079,1081,1083,1086,1088,1091,1093,1096,1098,1100],{"class":383,"line":1080},27,[381,1082,645],{"class":449},[381,1084,1085],{"class":395}," parsedTs",[381,1087,651],{"class":391},[381,1089,1090],{"class":395}," Date",[381,1092,472],{"class":391},[381,1094,1095],{"class":459},"parse",[381,1097,478],{"class":503},[381,1099,618],{"class":395},[381,1101,743],{"class":503},[381,1103,1105,1107,1109,1111,1114,1116,1119,1121,1124,1126,1128,1131,1133,1136,1138,1141,1143,1146,1149,1152,1154,1156,1158,1161,1163],{"class":383,"line":1104},28,[381,1106,993],{"class":387},[381,1108,798],{"class":503},[381,1110,998],{"class":391},[381,1112,1113],{"class":395},"Number",[381,1115,472],{"class":391},[381,1117,1118],{"class":459},"isFinite",[381,1120,478],{"class":503},[381,1122,1123],{"class":395},"parsedTs",[381,1125,847],{"class":503},[381,1127,850],{"class":391},[381,1129,1130],{"class":395}," Math",[381,1132,472],{"class":391},[381,1134,1135],{"class":459},"abs",[381,1137,478],{"class":503},[381,1139,1140],{"class":395},"Date",[381,1142,472],{"class":391},[381,1144,1145],{"class":459},"now",[381,1147,1148],{"class":503},"() ",[381,1150,1151],{"class":391},"-",[381,1153,1085],{"class":395},[381,1155,847],{"class":503},[381,1157,550],{"class":391},[381,1159,1160],{"class":395}," maxSkewMs",[381,1162,847],{"class":503},[381,1164,1021],{"class":391},[381,1166,1168,1170,1172,1174,1176,1178,1180,1182,1184,1186,1188,1190,1192,1194,1196,1199,1201,1203],{"class":383,"line":1167},29,[381,1169,1027],{"class":387},[381,1171,806],{"class":395},[381,1173,472],{"class":391},[381,1175,1034],{"class":459},[381,1177,478],{"class":503},[381,1179,1039],{"class":591},[381,1181,636],{"class":503},[381,1183,472],{"class":391},[381,1185,1046],{"class":459},[381,1187,478],{"class":503},[381,1189,500],{"class":391},[381,1191,1053],{"class":503},[381,1193,507],{"class":391},[381,1195,411],{"class":391},[381,1197,1198],{"class":414},"TIMESTAMP_SKEW_TOO_LARGE",[381,1200,481],{"class":391},[381,1202,405],{"class":391},[381,1204,743],{"class":503},[381,1206,1208],{"class":383,"line":1207},30,[381,1209,1072],{"class":391},[381,1211,1213],{"class":383,"line":1212},31,[381,1214,443],{"emptyLinePlaceholder":442},[381,1216,1218,1220,1223,1225,1227,1229,1231,1233,1235],{"class":383,"line":1217},32,[381,1219,645],{"class":449},[381,1221,1222],{"class":395}," expected",[381,1224,651],{"class":391},[381,1226,612],{"class":459},[381,1228,478],{"class":503},[381,1230,618],{"class":395},[381,1232,399],{"class":391},[381,1234,628],{"class":395},[381,1236,743],{"class":503},[381,1238,1240,1242,1245,1247,1249,1251,1253,1255,1258],{"class":383,"line":1239},33,[381,1241,645],{"class":449},[381,1243,1244],{"class":395}," expectedBuf",[381,1246,651],{"class":391},[381,1248,633],{"class":395},[381,1250,472],{"class":391},[381,1252,429],{"class":459},[381,1254,478],{"class":503},[381,1256,1257],{"class":395},"expected",[381,1259,743],{"class":503},[381,1261,1263,1265,1268,1270,1272,1274,1276,1278,1280],{"class":383,"line":1262},34,[381,1264,645],{"class":449},[381,1266,1267],{"class":395}," gotBuf",[381,1269,651],{"class":391},[381,1271,633],{"class":395},[381,1273,472],{"class":391},[381,1275,429],{"class":459},[381,1277,478],{"class":503},[381,1279,1016],{"class":395},[381,1281,743],{"class":503},[381,1283,1285,1287,1289,1292,1294,1297,1300,1302,1304,1306,1308,1310,1313,1315,1317,1319,1321,1324],{"class":383,"line":1284},35,[381,1286,993],{"class":387},[381,1288,798],{"class":503},[381,1290,1291],{"class":395},"expectedBuf",[381,1293,472],{"class":391},[381,1295,1296],{"class":395},"length",[381,1298,1299],{"class":391}," !==",[381,1301,1267],{"class":395},[381,1303,472],{"class":391},[381,1305,1296],{"class":395},[381,1307,1004],{"class":391},[381,1309,1007],{"class":391},[381,1311,1312],{"class":459},"timingSafeEqual",[381,1314,478],{"class":503},[381,1316,1291],{"class":395},[381,1318,399],{"class":391},[381,1320,1267],{"class":395},[381,1322,1323],{"class":503},")) ",[381,1325,1021],{"class":391},[381,1327,1329,1331,1333,1335,1337,1339,1341,1343,1345,1347,1349,1351,1353,1355,1357,1360,1362,1364],{"class":383,"line":1328},36,[381,1330,1027],{"class":387},[381,1332,806],{"class":395},[381,1334,472],{"class":391},[381,1336,1034],{"class":459},[381,1338,478],{"class":503},[381,1340,1039],{"class":591},[381,1342,636],{"class":503},[381,1344,472],{"class":391},[381,1346,1046],{"class":459},[381,1348,478],{"class":503},[381,1350,500],{"class":391},[381,1352,1053],{"class":503},[381,1354,507],{"class":391},[381,1356,411],{"class":391},[381,1358,1359],{"class":414},"INVALID_SIGNATURE",[381,1361,481],{"class":391},[381,1363,405],{"class":391},[381,1365,743],{"class":503},[381,1367,1369],{"class":383,"line":1368},37,[381,1370,1072],{"class":391},[381,1372,1374],{"class":383,"line":1373},38,[381,1375,443],{"emptyLinePlaceholder":442},[381,1377,1379,1381,1383,1385,1388,1390,1392,1394,1396,1398,1400,1402,1404,1406,1408],{"class":383,"line":1378},39,[381,1380,645],{"class":449},[381,1382,648],{"class":395},[381,1384,651],{"class":391},[381,1386,1387],{"class":395}," JSON",[381,1389,472],{"class":391},[381,1391,1095],{"class":459},[381,1393,478],{"class":503},[381,1395,667],{"class":395},[381,1397,472],{"class":391},[381,1399,672],{"class":459},[381,1401,478],{"class":503},[381,1403,481],{"class":391},[381,1405,679],{"class":414},[381,1407,481],{"class":391},[381,1409,519],{"class":503},[381,1411,1413,1415,1417,1419,1421,1424,1426,1428,1430],{"class":383,"line":1412},40,[381,1414,993],{"class":387},[381,1416,798],{"class":503},[381,1418,724],{"class":395},[381,1420,472],{"class":391},[381,1422,1423],{"class":395},"event_id",[381,1425,1299],{"class":391},[381,1427,821],{"class":395},[381,1429,847],{"class":503},[381,1431,1021],{"class":391},[381,1433,1435,1437,1439,1441,1443,1445,1448,1450,1452,1454,1456,1458,1460,1462,1464,1467,1469,1471],{"class":383,"line":1434},41,[381,1436,1027],{"class":387},[381,1438,806],{"class":395},[381,1440,472],{"class":391},[381,1442,1034],{"class":459},[381,1444,478],{"class":503},[381,1446,1447],{"class":591},"400",[381,1449,636],{"class":503},[381,1451,472],{"class":391},[381,1453,1046],{"class":459},[381,1455,478],{"class":503},[381,1457,500],{"class":391},[381,1459,1053],{"class":503},[381,1461,507],{"class":391},[381,1463,411],{"class":391},[381,1465,1466],{"class":414},"EVENT_ID_MISMATCH",[381,1468,481],{"class":391},[381,1470,405],{"class":391},[381,1472,743],{"class":503},[381,1474,1476],{"class":383,"line":1475},42,[381,1477,1072],{"class":391},[381,1479,1481],{"class":383,"line":1480},43,[381,1482,443],{"emptyLinePlaceholder":442},[381,1484,1486,1488,1490,1493,1495,1498,1500,1502,1504],{"class":383,"line":1485},44,[381,1487,993],{"class":387},[381,1489,798],{"class":503},[381,1491,1492],{"class":395},"processedEventIds",[381,1494,472],{"class":391},[381,1496,1497],{"class":459},"has",[381,1499,478],{"class":503},[381,1501,1001],{"class":395},[381,1503,1323],{"class":503},[381,1505,1021],{"class":391},[381,1507,1509,1511,1513,1515,1517,1519,1522,1524,1526,1528,1530,1532,1534,1536,1538,1541,1543,1545],{"class":383,"line":1508},45,[381,1510,1027],{"class":387},[381,1512,806],{"class":395},[381,1514,472],{"class":391},[381,1516,1034],{"class":459},[381,1518,478],{"class":503},[381,1520,1521],{"class":591},"409",[381,1523,636],{"class":503},[381,1525,472],{"class":391},[381,1527,1046],{"class":459},[381,1529,478],{"class":503},[381,1531,500],{"class":391},[381,1533,1053],{"class":503},[381,1535,507],{"class":391},[381,1537,411],{"class":391},[381,1539,1540],{"class":414},"DUPLICATE_EVENT_ID",[381,1542,481],{"class":391},[381,1544,405],{"class":391},[381,1546,743],{"class":503},[381,1548,1550],{"class":383,"line":1549},46,[381,1551,1072],{"class":391},[381,1553,1555],{"class":383,"line":1554},47,[381,1556,443],{"emptyLinePlaceholder":442},[381,1558,1560,1563,1566,1568,1570],{"class":383,"line":1559},48,[381,1561,1562],{"class":387},"  await",[381,1564,1565],{"class":459}," persistIncomingEvent",[381,1567,478],{"class":503},[381,1569,724],{"class":395},[381,1571,743],{"class":503},[381,1573,1575,1577,1580,1582,1584],{"class":383,"line":1574},49,[381,1576,1562],{"class":387},[381,1578,1579],{"class":459}," applyBusinessSideEffects",[381,1581,478],{"class":503},[381,1583,724],{"class":395},[381,1585,743],{"class":503},[381,1587,1589,1592,1594,1597,1599,1601],{"class":383,"line":1588},50,[381,1590,1591],{"class":395},"  processedEventIds",[381,1593,472],{"class":391},[381,1595,1596],{"class":459},"add",[381,1598,478],{"class":503},[381,1600,1001],{"class":395},[381,1602,743],{"class":503},[381,1604,1606],{"class":383,"line":1605},51,[381,1607,443],{"emptyLinePlaceholder":442},[381,1609,1611,1613,1615,1617,1619,1621,1624,1626,1628,1630,1632,1634,1637,1639,1643,1645],{"class":383,"line":1610},52,[381,1612,749],{"class":387},[381,1614,806],{"class":395},[381,1616,472],{"class":391},[381,1618,1034],{"class":459},[381,1620,478],{"class":503},[381,1622,1623],{"class":591},"200",[381,1625,636],{"class":503},[381,1627,472],{"class":391},[381,1629,1046],{"class":459},[381,1631,478],{"class":503},[381,1633,500],{"class":391},[381,1635,1636],{"class":503}," ok",[381,1638,507],{"class":391},[381,1640,1642],{"class":1641},"sfNiH"," true",[381,1644,405],{"class":391},[381,1646,743],{"class":503},[381,1648,1650,1652],{"class":383,"line":1649},53,[381,1651,659],{"class":391},[381,1653,743],{"class":395},[362,1655,1656],{},"Replace in-memory dedupe with DB table or durable cache.",[366,1658,1660],{"id":1659},"generic-pseudocode","Generic pseudocode",[371,1662,1667],{"className":1663,"code":1665,"language":1666,"meta":376},[1664],"language-text","read raw_body\nread event_id, timestamp, signature headers\nif any missing -> 401\n\nif timestamp older\u002Fnewer than allowed skew -> 401\n\nexpected = hmac_sha256_hex(secret, \"{timestamp}.{raw_body}\")\nif \"v1={expected}\" != signature using constant-time compare -> 401\n\npayload = parse_json(raw_body)\nif payload.event_id != header event_id -> 400\n\nif event_id already processed -> 409\n\nbegin durable transaction\n  store inbound event log\n  apply business effect\n  mark event_id processed\ncommit\n\nreturn 200\n","text",[378,1668,1665],{"__ignoreMap":376},[366,1670,1672],{"id":1671},"response-behavior","Response behavior",[1674,1675,1676,1687,1692,1697],"ul",{},[1677,1678,1679,1680,1682,1683,1686],"li",{},"return ",[378,1681,1623],{}," or other ",[378,1684,1685],{},"2xx"," after durable success",[1677,1688,1679,1689,1691],{},[378,1690,1039],{}," for missing or bad signature",[1677,1693,1679,1694,1696],{},[378,1695,1521],{}," for duplicate already-processed event",[1677,1698,1679,1699,1702],{},[378,1700,1701],{},"500"," for transient internal failure -> OpenPoly retries",[366,1704,1706],{"id":1705},"common-mistakes","Common mistakes",[1674,1708,1709,1712,1715,1724,1730],{},[1677,1710,1711],{},"parsing JSON before reading raw body",[1677,1713,1714],{},"rebuilding JSON string before signature verification",[1677,1716,1717,1718,1721,1722],{},"deduping by ",[378,1719,1720],{},"aggregate_id"," instead of ",[378,1723,1423],{},[1677,1725,1726,1727,1729],{},"returning ",[378,1728,1623],{}," before durable commit",[1677,1731,1732],{},"deleting dedupe record too early",[1734,1735,1736],"style",{},"html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}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 .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}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 .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 .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":376,"searchDepth":421,"depth":421,"links":1738},[1739,1740,1741,1742],{"id":368,"depth":421,"text":369},{"id":1659,"depth":421,"text":1660},{"id":1671,"depth":421,"text":1672},{"id":1705,"depth":421,"text":1706},"Implementation examples for verifying and storing webhook deliveries.","md",null,{},{"title":279,"description":1743},"Jh_255AahOiOSlny3iAPMXoudYeZe_2KjQxVk5vG_v8",[1750,1752],{"title":275,"path":276,"stem":277,"description":1751,"children":-1},"Retry policy, terminal failures, and dashboard replay behavior.",{"title":288,"path":289,"stem":290,"description":1753,"children":-1},"Use staging to validate the same integration contract before production.",1789570133625]