Why is this call being made in Ajax.
Ajax suggests that this code is being performed via a front end which means you are leaking your hub.secret to the world…
I imagine the Ajax call with conten-type application/json is trying to be clever and is converting the data to JSON before sending it. As you declared (via the header) that you wish to send JSON. (Content-Type says I’m sending this, Accept is I expect that)
Try body instead of data or pass the arguments/data (url encoded) via querystring instead of post body.
I don’t post any body I pass by querystring:
topic = encodeURIComponent(topic);
var theurl = 'https://api.twitch.tv/helix/webhooks/hub'
+ '?hub.callback=' + callback
+ '&hub.mode=subscribe'
+ '&hub.topic=' + topic
+ '&hub.lease_seconds=' + lease
+ '&hub.secret=' + config.hook_secret;