n8n logon8n Automation Hub
Debugging notes

The Threads Generate Token Button Gave Me a Token That Expired in About 90 Minutes

Debugging notes · n8n workflow · September 19, 2026 · Updated October 13, 2026

A week earlier I had written down a shortcut for connecting a new Threads account to n8n: skip the OAuth flow, click Generate Token in the app dashboard, get a 60-day token. On the next account the shortcut produced a token that would have died before lunch. What caught it was a habit rather than luck: checking every new token with debug_token before storing it.

Workflow at a glance
  1. Setup for a new brand: a Meta app with the Threads API, the account added as a Threads tester, and the invite accepted from the account's own side
  2. The dashboard's Generate Token button returned a token that looked complete
  3. The debug_token endpoint reported an expiry roughly 1.5 hours away, not 60 days
  4. Exchanging it with the th_exchange_token grant, as Meta's documentation describes, returned the 60-day token, and that one went into the n8n credential
  5. The Facebook Page token needed the same check, with the opposite surprise: it never expires

The shortcut, and where my notes went wrong

The dashboard button is convenient: no redirect URI, no browser flow. My notes from the previous account said it returns a long-lived token directly and that the separate exchange step was optional. On the next setup the button returned a short-lived token. Whether Meta changed the behaviour or my earlier check was too shallow, I can't say. What I can say is that a token that looks fine is indistinguishable from a good one until you ask Meta about it.

Ask the token itself

Threads has a debug endpoint that takes the token as both the input and the credential:

GET https://graph.threads.net/debug_token?input_token=<TOKEN>&access_token=<TOKEN>

The response includes the scopes, the user id and expires_at as a Unix timestamp. Converting that timestamp is the whole test. Mine was about an hour and a half after generation.

The exchange

Meta's Threads documentation describes an exchange call that trades a short-lived user token for a long-lived one, using the th_exchange_token grant type together with the app's secret. Run it from the server, never from a browser or from a workflow that logs its inputs:

GET https://graph.threads.net/access_token?grant_type=th_exchange_token&client_secret=<APP_SECRET>&access_token=<SHORT_LIVED_TOKEN>

The response carries the long-lived token, and debug_token on it showed an expiry about 60 days out. That token went into an n8n HTTP query-auth credential and the short-lived one was discarded.

The Page token had the opposite surprise

For the Facebook Page side I assumed the token from the Page-accounts lookup was also a 60-day token. debug_token said expires_at: 0, which means it doesn't expire. Assuming 60 days would have put a pointless refresh job on the calendar. Assuming "forever" without checking would have been the more expensive mistake in the other direction.

What I do now

  1. Run debug_token on every token before it goes into a credential, and write the expiry date next to it.
  2. Schedule the refresh of a long-lived Threads token before it lapses (Meta documents a refresh call), rather than finding out on day 60 from a failed post.
  3. Keep the app secret out of any node that logs its parameters.

A different Threads failure, unrelated to tokens, is covered in a 500-character limit hiding behind a generic error.

Short-lived, long-lived, refreshed: the three Threads tokens

TokenWhere it comes fromLifetime (as checked with debug_token)
Short-lived user tokenOAuth flow, or the dashboard's Generate Token button in my caseAbout 1 to 2 hours
Long-lived user tokenth_exchange_token exchange with the app secretAbout 60 days
Refreshed long-lived tokenth_refresh_token call on a long-lived tokenA new 60-day window

The only reliable way to know which one you are holding is to ask the debug endpoint. The length or format of the token string tells you nothing.

Keeping the token alive inside n8n

Meta documents a refresh call for long-lived Threads tokens:

GET https://graph.threads.net/refresh_access_token?grant_type=th_refresh_token&access_token=<LONG_LIVED_TOKEN>

According to Meta's documentation the token has to be at least 24 hours old and still valid to be refreshed, so an expired token cannot be rescued this way. That makes the schedule the important part. What I use:

  1. Write the expiry date into a note or a sheet the moment the long-lived token is stored.
  2. Run a small scheduled workflow every few weeks that calls the refresh endpoint and writes the new token into the HTTP credential.
  3. If the refresh call fails, send a Telegram alert. A failed refresh at day 40 leaves almost three weeks to reconnect by hand. A failed post at day 60 leaves none.

Updating a credential from a workflow means calling the n8n API, and that call carries the token in its body. Keep that workflow's execution data saving off for successful runs, or the token ends up readable in the execution history.

A five-minute checklist for a new Threads account

Frequently asked questions

How long does a Threads access token last?

A short-lived token lasts about an hour or two, and a long-lived token about 60 days. Check the actual expiry of your token with the debug_token endpoint rather than relying on where it came from.

Can I refresh an expired Threads token?

No. Meta's refresh call only works on a long-lived token that is still valid. Once it has expired you have to go through the authorization again.

Where should the app secret live?

Only in the server-side call that does the exchange, or in an n8n credential. Never in a node parameter, because node inputs can be stored in execution data.

Does the Facebook Page token expire too?

The Page token in this setup reported expires_at 0 in debug_token, which means it does not expire. Check your own token, because the result depends on how it was obtained.

Social API tokens that quietly expire on you?

I set up Meta, YouTube and Threads connections with expiry checks and refresh jobs, so posts don't stop on day 60.