Clarification on SHOP_MINIS_API_KEY Expiration & Best Practices for Backend Verification

Hi team,

I’m currently developing a Mini and ran into an issue regarding the SHOP_MINIS_API_KEY.

After running npx shop-minis setup, the CLI generated a SHOP_MINIS_API_KEY and placed it in my .env file. I used this key on my backend to call userTokenVerify, and everything worked perfectly — until the next day, when I suddenly started receiving an error saying that the Shop Minis token had expired.

The only way to fix it was to run shop-minis api-keys generate to produce a new key and update it manually in my backend. This workflow feels unstable and inconvenient.

So I have a few questions:

  1. How long is a SHOP_MINIS_API_KEY valid?

  2. Are these keys intentionally short-lived?

  3. If the key expires regularly, does it mean the backend must be updated with a new API key every time?

  4. Is there a recommended best practice for managing or refreshing this API key to avoid manual updates?

It’s a bit unclear how we’re expected to handle this in a production environment, and manually rotating the API key feels risky and error-prone.

Would appreciate any guidance or official clarification. Thanks!

They key you get from `npx shop-minis setup` is just for the cli to use when making submissions. In your code you need to follow the flow here Custom backend and use the useGenerateUserToken hook to generate a key to be used on your backend

Hi @steve-t-shopify, thanks for the clarification!

However, I think there may be a gap in the documentation flow, so I’d like to clarify my issue more concretely:

I did follow the “Custom backend” flow and used useGenerateUserToken.
But in order for useGenerateUserToken to work, I must provide a SHOP_MINIS_API_KEY inside the Mini frontend. And the only way to obtain this key is:

  • Running npx shop-minis setup, or

  • Running npx shop-minis api-keys generate

After that:

  1. useGenerateUserToken() generates a user_token.

  2. I send this token to my backend.

  3. My backend must also store the same SHOP_MINIS_API_KEY so it can call userTokenVerify.

The problem:

:backhand_index_pointing_right: The SHOP_MINIS_API_KEY generated by the CLI expires after ~1 day.
:backhand_index_pointing_right: When it expires, both useGenerateUserToken in the frontend and userTokenVerify in the backend start failing.
:backhand_index_pointing_right: The only fix is to manually run api-keys generate again and redeploy the backend with the new key.

This makes the workflow quite unstable for production, because:

  • Backend depends on a key that is short-lived.

  • Manual rotation is error–prone.

  • There is no documented way to auto-refresh or obtain a long-lived key.

I don’t think this is true - you can verify this key still works by using a command like npx shop-minis check-submission which uses that key to communicate with the admin api. Perhaps there is something else happening.

The token from useGenerateUserToken() expires - you can see the expiry from:

const {data} = await generateUserToken()
const {token, expiresAt, userState} = data
console.log({token, expiresAt, userState})

So you will need to get a new token from the mini using generateUserToken() once that expiry is passed - this should be tied to a user action as these tokens are not designed to be stored and re-used by a backend

Thanks for the clarification! I’ll double-check the validity period of the SHOP_MINIS_API_KEY on my side and monitor how long it remains active. I’ll update here once I have precise information.