How To Get Shopify Offline Token For Permanent Access In Python Django

Topic summary

Public Shopify app experiencing intermittent API/webhook failures with HTTP 401 Unauthorized and error “[API] Invalid API key or access token (unrecognized login or wrong password).” Tokens seem to stop working after about one day; re-authenticating the shop yields a new token and temporarily resolves the issue.

Developer seeks to switch from online to offline tokens for persistent access. Online tokens are per-user and short-lived; offline tokens are per-shop and intended to be long-lived.

Setup details: Django AllAuth with SOCIALACCOUNT_PROVIDERS for Shopify, requested scopes (orders, customers, discounts, products, returns), and AUTH_PARAMS including grant_options: per-user, which indicates online (per-user) access.

Key questions: Does the current token expire by design due to per-user flow? How to obtain an offline token via OAuth configuration in Django/AllAuth (e.g., adjusting grant options) to keep webhooks authorized?

Status: No solution provided yet; the thread is a request for troubleshooting. The included code snippet is central to understanding the OAuth setup.

Summarized with AI on January 9. AI used: gpt-5.

Hi, I built a public app and everything was working smoothly but all of a sudden my webhooks and other APIs started giving
HTTP Error 401: Unauthorized b’{“errors”:“[API] Invalid API key or access token (unrecognized login or wrong password)”}’ for shopify . is there any expiry

This is happening for merchants and if I login my shop again via shopify then I get new shopify token and everything works but after 1 day or so this error starts coming again.

I did some RnD and got to know that there are 2 types of token .
i) Online token
ii) Offline Token

but how can I get this offline token,

These are my settings in django.

SOCIALACCOUNT_PROVIDERS = {
    "shopify": {
        "APP": {
            "client_id": os.getenv("SHOPIFY_API_KEY"),
            "secret": os.getenv("SHOPIFY_API_SECRET"),
            "key": "",
        },
        "SCOPE": ["read_orders", "read_customers", "write_customers", "write_discounts", "read_products", "read_returns"],
        "AUTH_PARAMS": {"grant_options[]": "per-user"},
    },

I am using AllAuth library in Django