My app is still in Draft status so I cant use expiring tokens?

I am trying to test my app by installing one of my development stores after making updates to handle expiring tokens. The app has passed all the automated checks now.

In my oauth callback, i try to first setup a fulfillment service using the access token I fetch, but when calling the code below…

Im getting a HTTP 403 calling Shopify GraphQL Admin API: {“errors”:"[API] Non-expiring access tokens are no longer accepted for the Admin API

const string serviceMutation = @"
mutation FulfillmentServiceCreate(
$name: String!,
$callbackUrl: URL!,
$trackingSupport: Boolean!,
$inventoryManagement: Boolean!
) {
fulfillmentServiceCreate(
name: $name
callbackUrl: $callbackUrl
trackingSupport: $trackingSupport
inventoryManagement: $inventoryManagement
) {
fulfillmentService {
id
serviceName
callbackUrl
location { id }
}
userErrors { field message }
}
}";

Hey @Randal_B The 403 you’re seeing is because of a recent enforcement change. As of April 1, 2026, all new public apps are required to use expiring offline access tokens. If your app’s distribution is set to public in the Partner Dashboard, that enforcement applies even while the app is in draft, and Shopify will reject non-expiring tokens with the 403 you’re seeing.

The fix is to add expiring=1 to your POST to /admin/oauth/access_token when you exchange the authorization code. So your token request body should include that parameter alongside client_id, client_secret, and code. Once you do that, the response will include expires_in, refresh_token, and refresh_token_expires_in fields in addition to the access_token.

You’ll also need to implement refresh logic since the access token now expires after about 60 minutes. Before it expires, POST to the same endpoint with grant_type=refresh_token and the refresh token to get a new pair. The offline access tokens docs cover the full flow including the refresh request format.

Another developer ran into this same issue and documented their fix here if you want more detail on the implementation side. Hope this helps get up and running!

Donal-Shopify - reporting back now, that seemed to do the trick. Webhook registrations are working now via the admin api with the token that was fetched (and the response is sending a refresh token). Im already updated to handle the token refresh.
thanks!