Bug Report: Refresh Tokens do not get stored when testing custom integrations

  • 21 February 2024
  • 0 replies

I am currently building a custom integration for a app which has a Laravel backend with a OAuth passport integration

When testing the OAuth refresh mechanism I experienced some flakiness which I was able to boil down to a bug:

For development purpose I set down the access_token TTL to 10 seconds, so I can check if the refresh mechanism works.

When getting an 401 from the backend, zapier automatically tries to get a new token via the refresh token endpoint. This also invalidates the old refresh_token, that's why in the response a new refresh_token is issued. This lead to a refresh_token method, which looks like this:

const options = {

  url: '',

  method: 'POST',

  headers: {

    'content-type': 'application/x-www-form-urlencoded',

    'accept': 'application/json'


  params: {


  body: {

    'refresh_token': bundle.authData.refresh_token,

    'grant_type': 'refresh_token',

    'client_id': process.env.CLIENT_ID,

    'client_secret': process.env.CLIENT_SECRET,



return z.request(options)

  .then((response) => {


    const results = response.json;

    // You can do any parsing you need for results here before returning them


    // NOTE from Julian: I have found a zapier bug, when hitting test auth button

    //    and it refreshes the access/refresh token in this request, the refresh token

    //    is not stored correctly in the plattform and the next request will fail

    return {

      access_token : results.access_token,

      refresh_token : results.refresh_token ? results.refresh_token : bundle.authData.refresh_token,




This works flawlessly, with normal zapier request. When displaying the accounts here:

Zapier ALWAYS checks the currently selected account by calling the test API . When the test API is called and a 401 is returned, it also automatically updated the access/refresh token. This will result to a new working access/refresh token pair, which directly can be used in the “Test Authentication” button (in future referenced as test auth)

However, when a 401 is returned when hitting the test auth, the access/refresh token is updated correctly unless you get an 401 error in the account overview again, because then zapier uses the OLD refresh token. 

My guess is: When using the test auth button, the request runs in a different scope, which only updates the refresh token in his own scope and therefore, the next check request on the account view, which runs in the normal scope, fails, because it doesn’t have the updated refresh_token.


Steps to reproduce:

  1. Create a custom integration and connect it via OAuth to a OAuth server with the following config
    1. TTL of access_tokens is somewhere around 10 secs
    2. TTL of refresh_tokens is longer (in my case 1 year)
    3. When updating access_tokens, it also returns a new refresh_token in the response and invalidates the used refresh_token (which is the normal configuration when using Laravel Passport)
  2. Configure the custom integration to
    1. Also update the refresh_token on a access_token refresh event
  3. Connect your account via OAuth
  4. Check that the refresh token function works by switching tabs between “Test Setup” and “Response” to force zapier to check the account displayed by calling the test API (at least 3 times, so makes sure we have cycled through at least 2 refresh_tokens)
  5. Wait 10 seconds to make the access_token invalid 
  6. Hit test auth (this should lead to a refresh access token event and the request succeed)
  7. Wait 10 seconds to make the access_token invalid
  8. Go back by either clicking on “Test Setup” or “Try again” 
  9. The test call for the account will fail and the account will be invalidated (because zapier will use and old refresh_token and NOT the one, which was generated by the test auth request)


Can you please update me, on checking this bug? Or correct me, if the problem is on MY side and you think I made a mistake here :)

0 replies

Be the first to reply!