diff --git a/package.json b/package.json
index 38b42a9ac5ccfcbcf6873b75a2b7b1673f5f6755..507482981e2dfe116aa5b8b599a71cc6f9d947ae 100644
--- a/package.json
+++ b/package.json
@@ -10,6 +10,7 @@
   },
   "dependencies": {
     "axios": "^0.19.0",
+    "axios-auth-refresh": "^1.0.7",
     "core-js": "^2.6.5",
     "lodash": "^4.17.11",
     "material-icons": "^0.3.1",
diff --git a/src/sources/funkwhale.js b/src/sources/funkwhale.js
index dd650911b82778af6679a3cb0a39ec380fa84519..18ce13ca7cde8aa22af992b2b319a68c32c167a0 100644
--- a/src/sources/funkwhale.js
+++ b/src/sources/funkwhale.js
@@ -1,8 +1,8 @@
 import axios from 'axios'
+import createAuthRefreshInterceptor from 'axios-auth-refresh';
 import moment from 'moment'
 import Form from '../components/FunkwhaleForm.vue'
 import get from 'lodash/get'
-
 import {getAbsoluteUrl} from "@/utils"
 
 export const SCOPES = "read:profile read:listenings"
@@ -37,6 +37,51 @@ export async function createApp(ax, {baseUrl}) {
   return response
 }
 
+function getAuthorizationHeader (account, state) {
+  const token = state.sources.funkwhale.appTokens[`${account.username}@${account.domain}`].access_token
+  return `Bearer ${token}`
+
+}
+
+export function getOauthAxios ({axiosParams, account, store}) {
+  // an axios instance with autorefreshing for oauth tokens
+  let client = axios.create(axiosParams || {})
+  client.interceptors.request.use(request => {
+    request.headers['Authorization'] = getAuthorizationHeader(account, store.state)
+    return request
+  })
+  createAuthRefreshInterceptor(client, (failedRequest) => {
+    console.log('Request failed, OAuth token probably expired, fetching a new one…')
+    const refreshToken = store.state.sources.funkwhale.appTokens[`${account.username}@${account.domain}`].refresh_token
+    const app = store.state.sources.funkwhale.appCredentials[account.domain]
+    const payload = {
+      client_id: app.client_id,
+      client_secret: app.client_secret,
+      grant_type: "refresh_token",
+      refresh_token: refreshToken,
+    }
+    return client.post(
+      `/api/v1/oauth/token/`,
+      asForm(payload),
+      {headers: {'Content-Type': 'multipart/form-data'}}
+    ).then((tokenRefreshResponse) => {
+      store.commit('setRecursiveState', {key: "sources.funkwhale.appTokens", suffix: `${account.username}@${account.domain}`, value: tokenRefreshResponse.data})
+      let newHeader = getAuthorizationHeader(account, store.state)
+      failedRequest.response.config.headers['Authorization'] = newHeader
+      return Promise.resolve()
+    })
+  })
+  return client
+}
+
+function asForm (obj) {
+  let data = new FormData()
+  Object.entries(obj).forEach((e) => {
+    data.set(e[0], e[1])
+  })
+  return data
+}
+
 
 export default {
   id: "funkwhale",
@@ -76,11 +121,11 @@ export default {
       code: query.code,
       redirect_uri: `${baseUrl}/connect/funkwhale/callback`
     }
-    let data = new FormData()
-    Object.entries(payload).forEach((e) => {
-      data.set(e[0], e[1])
-    })
-    const response = await ax.post(`https://${domain}/api/v1/oauth/token/`, data, {headers: {'Content-Type': 'multipart/form-data'}})
+    const response = await ax.post(
+      `https://${domain}/api/v1/oauth/token/`,
+      asForm(payload),
+      {headers: {'Content-Type': 'multipart/form-data'}}
+    )
     const token = response.data.access_token
     const client = axios.create({
       baseURL: `https://${domain}`,
@@ -95,9 +140,10 @@ export default {
   async fetch ({account, store, results, maxDays}) {
     results.status = `Fetching listenings...`
     const token = store.state.sources.funkwhale.appTokens[`${account.username}@${account.domain}`].access_token
-    const client = axios.create({
-      baseURL: `https://${account.domain}`,
-      headers: {'Authorization': `Bearer ${token}`},
+    const client = getOauthAxios({
+      axiosParams: {baseURL: `https://${account.domain}`},
+      store: store,
+      account: account
     })
     const dateLimit = moment().subtract(maxDays, 'days')
     let url = null
diff --git a/yarn.lock b/yarn.lock
index 27445b249e2c5af3e8ebed775b5e15828943d789..4900c74e617d550cb945c002c5c58b61406389ac 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1491,6 +1491,21 @@ aws4@^1.8.0:
   resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f"
   integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==
 
+axios-auth-refresh@^1.0.7:
+  version "1.0.7"
+  resolved "https://registry.yarnpkg.com/axios-auth-refresh/-/axios-auth-refresh-1.0.7.tgz#b9f39131ef39190c753d386746e9aa6e7114212b"
+  integrity sha512-TQl1tF+MY+iDG93WpiqcnwGb1lvdJLKzi0IN/7hBkYFlpOC6xv4S+cW3QHZOBjKpFWRWqHg9fXd/PDsCvJ3uLA==
+  dependencies:
+    axios "^0.18.0"
+
+axios@^0.18.0:
+  version "0.18.1"
+  resolved "https://registry.yarnpkg.com/axios/-/axios-0.18.1.tgz#ff3f0de2e7b5d180e757ad98000f1081b87bcea3"
+  integrity sha512-0BfJq4NSfQXd+SkFdrvFbG7addhYSBA2mQwISr46pD6E5iqkWg02RAs8vyTT/j0RTnoYmeXauBuSv1qKwR179g==
+  dependencies:
+    follow-redirects "1.5.10"
+    is-buffer "^2.0.2"
+
 axios@^0.19.0:
   version "0.19.0"
   resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.0.tgz#8e09bff3d9122e133f7b8101c8fbdd00ed3d2ab8"