Long-lived token for n8n CI pipeline failing after 1hr

Just noticed that the POST /api/v2/oauth/token response gives me an expires_in of exactly 3600s. My self-hosted n8n instance needs to run overnight without hitting the refresh endpoint every hour. Is there a way to generate a token that lasts longer via the API? I’ve tried tweaking the grant_type to client_credentials but it’s still short-lived. Any workaround?

If I remember correctly, you’re stuck with the 1hr limit. don’t fight it. just hook up a refresh token workflow in n8n to keep the session alive.

{
 "grant_type": "refresh_token",
 "refresh_token": "{{ $json.refresh_token }}"
}

You need to stop fighting the clock and just automate the refresh. the suggestion above is spot on, but you’ll need to handle the storage part correctly in n8n so your overnight jobs don’t crash when the token expires mid-flow. i work with OData and reporting pipelines all day, and even those heavy batch jobs die if you cache a token past that hard 3600s limit. the api doesn’t give you a “long-lived” toggle, it gives you a refresh token that lasts for days or weeks depending on your org settings.

here’s how you structure the n8n workflow to keep it alive without manual intervention. use a Code node or a HTTP Request node set to POST with the body below. make sure you’re storing the refresh_token in n8n’s Credentials or a JSON object in the workflow context so you can reuse it.

{
 "grant_type": "refresh_token",
 "refresh_token": "{{ $json.refresh_token }}",
 "client_id": "{{ $json.client_id }}",
 "client_secret": "{{ $json.client_secret }}"
}

don’t forget to set the Content-Type header to application/x-www-form-urlencoded. the response will give you a fresh access_token and a new refresh_token. you have to overwrite your old one. if you keep using the same refresh token, it might get invalidated or just stop working after a while.

also, check your Authorization header. it needs to be Basic <base64(client_id:client_secret)>. n8n can handle this if you use the Authorization field in the HTTP node, but sometimes it’s safer to construct it manually in a Set node to avoid encoding glitches.

i’ve seen people try to bypass this by calling the token endpoint in a loop, which is a bad idea. you’ll get rate-limited. just let the refresh mechanism do its job. if your pipeline is truly overnight, set up a cron job in n8n to refresh the token every 50 minutes. that way, the access token is always valid when your main reporting queries hit the /api/v2/analytics endpoints. it’s a bit more setup, but it’s the only reliable way.