POST /api/v2/oauth/token keeps returning 403 with {“error”:“invalid_grant”,“error_description”:“refresh_token expired”} after the first job finishes. Trying to lock down a persistent token for our GitHub Actions workflow so the Terraform provider doesn’t choke on hourly rotations. I’m hitting the endpoint with client_credentials and passing a refresh token pulled straight from the admin console. The raw request looks like curl -X POST https://{{env}}.mypurecloud.com/api/v2/oauth/token -H “Content-Type: application/x-www-form-urlencoded” -d “grant_type=refresh_token&client_id=$GC_ID&client_secret=$GC_SECRET&refresh_token=$GC_REFRESH”. It’s only valid for twenty minutes. Then the next run fails hard.
I’ve checked the API integration settings first. Refresh token expiration sits at thirty days. The platform docs mention offline_access scope next, but stuffing it into the initial auth request just throws a 401. I’m wondering if the Embeddable Client SDK handles rotation differently than bare HTTP calls. Maybe the platform expects a specific header for headless runners. The pipeline executes on a self-hosted agent in London. Clock drift isn’t the culprit. Token storage in GitHub secrets looks fine too. Stepping through the SDK source code for automatic refresh logic might save some headache. Just need the token to survive past the first deployment step.