mbiletech
mbiletech
Home / Mobile Publishing and Monetization / Shopify Bulk Jobs Now Need Separate Permissions

Shopify Bulk Jobs Now Need Separate Permissions

Check Shopify's new bulk query and mutation permissions, the 31-day rule, and the IP deadline before your next catalog job.

Two workers handle catalog cards separately, one copying product records and the other stamping tags.

Primary topic Mobile Publishing and Monetization

A Shopify app can export a catalog on Sunday and get an access denied error when it tries to update prices on Monday. On November 6, 2026, Shopify made bulk reads and bulk writes separate permissions for Partner-built apps. Each can lapse on its own. If you’re counting on a scheduled update to put the right price or stock status in front of shoppers, check the job that writes those values before you trust a green export.

Check two independent controls: the operation type in the Partner Dashboard, and the worker’s outbound network in the Dev Dashboard. Public apps face an additional IP allowlist deadline on November 12. A successful export proves neither that bulk writes are enabled nor that every worker can pass the network check.

What to check before a Shopify bulk job
Who runs the job When to check Action
Public Partner app Before next job and November 12 cutoff Check operation type and enforce allowlist
Custom Partner app Before next bulk job Enable the operation type it uses
Merchant-created app Before troubleshooting access denied Check API permissions and request path
Merchant using an outside app Before a scheduled catalog change Ask for proof the test completed

Check the operation that will actually run

In the Partner Dashboard, open Apps and select the app that sends the request. Confirm its identity against the scheduled integration, then open API access requests → Run bulk operations. The extra permission controls whether Shopify accepts a bulk operation; it does not grant access to the underlying store data.

  • Allow bulk queries enables bulkOperationRunQuery, used for reads such as catalog exports.
  • Allow bulk mutations enables bulkOperationRunMutation, used for batch writes such as price changes.

Enable only the types the app uses. If a type already shows as enabled, leave it enabled. Access applies to every installed store, across all GraphQL Admin API versions. No app configuration change, release or merchant reinstall is required. Changing API versions will not bypass this permission.

Count starts separately for reads and writes

Existing bulk users had access enabled automatically, but an unused type can lapse. The 31-day window counts whether the app started that type, rather than whether a job completed.

Take a hypothetical seasonal promotion: the app starts an export on November 8, 2026, last started a bulk price update on October 1, and plans its next update for November 9. The write side has been idle for 39 days. That recent export does not preserve mutation access. Check Allow bulk mutations before the update and re-enable it if disabled.

Partner-created custom apps need the switches too. Apps merchants create in Shopify admin or the Dev Dashboard are exempt at this time. An older November 5 security announcement describes future scopes, app configuration changes and a 180-day lookback. For the permission available now, use the November 6 dashboard instructions and 31-day window.

Run the documented product test

Use a dev store to verify bulk-query admission and result handling. With product-read access such as read_products, run this official product query through its backend Admin API client:

mutation {
  bulkOperationRunQuery(
    query: """
    {
      products {
        edges {
          node { id title }
        }
      }
    }
    """
  ) {
    bulkOperation { id status }
    userErrors { field message }
  }
}

The documented response returns operation ID gid://shopify/BulkOperation/720918, status CREATED and an empty userErrors list. Your ID will differ. Save it: the request has been admitted, while Shopify fetches the products asynchronously. It will later expose a download URL.

  1. Prefer the bulk_operations/finish webhook to repeated polling. A finish notification can mean success, failure or cancellation, so inspect its status.
  2. After success, query the node field with the webhook’s admin_graphql_api_id to retrieve the result url. Download the JSONL and check product IDs and titles against the dev store.
  3. If a webhook does not arrive, recover by polling. On API versions 2026-01 and later, use bulkOperation(id:); older versions use currentBulkOperation. Check status and error details before downloading.

For writes, use a disposable dev-store product and change a field the app actually updates through its normal worker. Inspect the final result and fetch the product again to verify the value. A query test only exercises query access; it cannot approve the mutation path.

Start diagnosis at the first failed step

  • HTTP 403: inspect the actual outbound address and allowlist first, including requests whose source Shopify cannot confirm.
  • Bulk access denied: verify the app identity and matching operation switch. Record the operation name, time and redacted response.
  • Data permission error: test an ordinary query for the same fields. Bulk queries require the same data permissions as ordinary queries; check scopes and the store installation.
  • Operation admitted, then failed: inspect final status, errors and available output before replaying. For a write, reconcile what changed before retrying the batch.

Use the GraphQL Admin API backend for these tests. Admin UI extension Direct API access does not support bulk operations; connect the extension to its backend. The Storefront API cannot run them either.

Test the outbound network the worker uses

Public apps must turn on the IP allowlist by November 12, 2026, at 11:59 p.m. Eastern to keep bulk queries and mutations running. That is November 13 at 04:59 UTC, 4:59 a.m. in the UK and 5:59 a.m. in Central Europe. Custom apps are not required to have an allowlist, though Shopify recommends one.

The next public-app deadline is November 20, 2026, at 11:59 p.m. Eastern: missing the allowlist means delisting, blocked new installs and a flag in merchant settings. Existing installations retain ordinary API access until April 1, 2027, with an admin warning from January 15, 2027. Bulk jobs are already subject to the earlier cutoff. Expiring offline tokens have a separate January 1, 2027, listing deadline.

Three Shopify access checks in November 2026 November 6: check operation switches for Partner apps. November 12 at 11:59 p.m. Eastern: public apps must enforce IP allowlists for bulk jobs. November 20 at 11:59 p.m. Eastern: public app listing and new installs require the allowlist. Nov 6 · Partner apps Check query and mutation switches Nov 12 · 11:59 p.m. ET Public apps: allowlist for bulk jobs Nov 20 · 11:59 p.m. ET Public apps: listing / install cutoff
November 2026 action timeline, unscaled. The public-app bulk cutoff precedes the listing cutoff. Sources: bulk access release and security deadlines.

Open the app in Dev Dashboard → Settings → IP allowlist → Manage. Prefer public outbound IP addresses when they are stable. For a worker behind NAT, use the gateway’s public addresses and include IPv6 if it reaches Shopify that way. Under Allow requests from, select IP addresses or Networks (ASN).

  • IP mode accepts up to 100 addresses or CIDR ranges. Use IPv4 /16 or narrower and IPv6 /32 or narrower. A range must start at its network address; for example, 203.0.113.0/24, not 203.0.113.7/24.
  • For dynamic egress, use up to 10 public hosting-provider ASNs and narrow them with up to 10 countries. A hosting network is shared with other customers, so static addresses are the safer default where available.

ASN and country matching uses MaxMind GeoLite’s classification of the request’s source address. A missing ASN, or a missing country when you apply a country filter, causes rejection. Check the worker addresses in Dev Dashboard API logs and your provider’s network details before selecting those rules. Allowlist rules and compatibility apply to both GraphQL and REST Admin API requests.

Click Run test under Test against recent traffic to check the past 30 days, correct blocked legitimate addresses, then turn on Enforcement and Save. Exercise occasional workers too: historical traffic can miss a seasonal process, and recent requests can take a few minutes to appear. Confirm a normal backend token request succeeds from the allowed worker and fails with HTTP 403 from outside the list.

Use backend requests for that network test. Dev preview requests on dev stores, embedded-page Direct API requests and POS UI extension Direct API requests are exempt from rejection. Conversely, Shopify Flow’s Send HTTP request action and GraphQL Admin API calls from Oxygen-hosted storefronts are incompatible with enforced allowlists because Shopify cannot confirm their source IP. Identify those paths before enabling enforcement and resolve them with the integration owner.

Make the next dormant job predictable

Add the app ID, operation type, last accepted start, owner, worker egress and latest result evidence to the integration’s runbook. Put the dashboard preflight before an infrequent job’s next scheduled run. Prefer checking real job activity over starting synthetic bulk jobs merely to keep access alive: those starts change the inactivity window and can hide the condition you need to detect.

What merchants can verify before a price change

Open Settings → Apps in Shopify admin to see recent activity and whether the app uses expiring tokens and enforced IP restrictions. Send the developer the exact job name and ask them to run a small batch from the worker that normally handles it. For an export, ask when the feed last refreshed. For a write, ask which product was tested and verify its new value on the store.

If that proof is missing on launch day, hold the affected batch. Check a representative product page on a phone and compare its displayed price or availability with the intended value in Shopify admin. Keep unrelated jobs running. Release the batch when the owner can point to a completed test and the correct value where a shopper sees it.