Ai.conversation.completed payload breaking JWT signature validation on Express webhook listener

Trying to pipe the new AI bot analytics into our existing Express middleware pipeline without rewriting the whole ingestion layer. GC is running 2024-12.960.0 and the ai.conversation.completed event keeps tripping up the signature check. The JWT decodes fine with the org secret, but the exp claim looks completely off. Clock skew isn’t the culprit. Server time is synced to NTP.

Problem
Middleware catches the POST, strips the Authorization header, and runs it through jsonwebtoken.verify. Returns a JsonWebTokenError claiming the signature is invalid. Payload structure shifted again. Looks like they nested the conversation metadata under a new botSession object instead of flattening it at the root.

app.post('/webhook/gc', (req, res) => {
 const token = req.headers.authorization.split(' ')[1];
 try {
 const decoded = jwt.verify(token, process.env.GC_JWT_SECRET, { algorithms: ['RS256'] });
 console.log('Valid token:', decoded.sub);
 res.status(200).send('OK');
 } catch (err) {
 console.error('JWT failed:', err.message);
 res.status(401).send('Unauthorized');
 }
});

Error log dumps invalid signature every single time. Checked the JWKS endpoint directly, pulled the public key, verified it matches the org config. Still fails. EventBridge consumer downstream times out after 30 seconds because the Express route keeps bailing on the 401. Mic stays hot while the bot session just spins. They don’t document the shift. It’s definitely mangling the base64url. Architect flow triggers the webhook right after the TransferToBot node completes. Node runtime is v20.11.0. Express sits at 4.18.2. Debug logs show the raw header length hitting 2.4KB. Base64 decoding throws garbage characters right at the signature boundary. Might just be a chunking issue on the outbound proxy. Leaving it running to catch the next batch.