Refresh Token not in /oauth/token payload

I cannot seem to get a refresh token in my call to the /oauth/token endpoint. First I authorize myself like so:

const redirectUrl = chrome.identity.getRedirectURL('auth0');
const clientId = "CLIENT_ID";
const options = {
    client_id: clientId,
    redirect_uri: redirectUrl,
    response_type: 'code',
    scope: "offline_access",
    audience: "API_IDENTIFIER",
const qs = parse.qs;
const domain = "DOMAIN";
const url = `https://${domain}/authorize?${qs.stringify(options)}`;
const resultUrl: string = await new Promise((resolve, reject) => {
        url: url,
        interactive: true
    }, (callbackURL) => {

This seems to work fine, I then perform the following based on the response I get from the URL:

const response = parse(resultUrl, true).query;
const code = response.code;
const body = JSON.stringify({
    redirect_uri: redirectUrl,
    grant_type: 'authorization_code',
    client_id: clientId,
    client_secret: "CLIENT_SECRET",
    scope: "offline_access",
const result = await fetch(`https://${domain}/oauth/token`, {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json'

After this the response JSON I get contains “access_token”, “scope”, “expires_in”, “token_type”. There is no “refresh_token” as described in this documentation:

I should also note that the “audience” I use in the authorize call is the right API identifier, and this API has “Allow Offline Access” set to “Enabled”.

So I’m at a bit of a loss, does anyone know what I need to do to get these refresh tokens working?


Welcome to Auth0 community.

It is not very clear what is going wrong. Few things to check:

Another important thing to check Rule code, if you modify the scope inside the rule , that can have an impact. You can try including console.log statement in the Rule and monitor the output Realtime Webtask Extension

I can confirm that the application has Refresh Token Grand Type enabled, and it is OIDC conformant. I can also confirm I have no rules.

Something I did try was changing the application from “Single Page Application” to “Native”. This had the interesting effect of not showing the login screen when “chrome.identity.launchWebAuthFlow” was called, and just returning me a new access_token. It’s hard to say what exactly is going on here, maybe the refresh token is handled by the browser internally, but I will know more in 24 hours (when the original access token expires).

Do you have Refresh Token Rotation enabled? What do the logs on your Auth0 tenant say?