Well thats me out of ideas.
Looks like you are
- constructing a valid URL.
- redirecting to twitch
- as yourself, granting access to your bots application
- coming back to your code as the redirect_uri
- exchanging the code from the URL for a valid token
And using that token correctly with your cURL calls.
And refreshing when needed (user tokens are good only for about four hours, and you mentioned you are refreshing and getting a new token)
This reads like you authed your bot to you application, rather than you to your application, but that shouldn’t make a difference to the cURL calls you are doing.
Normally you’d make a oAuth key representing you and your bot would then use that token for the relevant calls to the API where a subscriber/bits scope is needed.
When you refresh you are using the new access token, and not the refresh token as a token right?