I’m trying to use direct API access from an iOS POS UI extension, but every request to shopify:admin/api/graphql.json
comes back with 401 Unauthorized
. I’ve tested various GraphQL queries using direct API access which have all failed. The queries have also been tested in GraphiQL (launched from the CLI) where they’ve run successfully, contrary to the requests made in the app.
For debugging purposes, a new extension only app scaffold was created using the Shopify CLI, where the only changes are:
- Addition of a file called
Probe.jsx
(alongside necessary changes toshopify.app.toml
) which targets thepos.product-details.block.render
surface and performs a simple request to the GraphQL API to get the shop’s name. - Setting
scopes = "read_content"
in the mainshopify.app.toml
.
Environment
- Device: iPhone 15 Pro
- iOS version: 18.6.2
- Shopify POS iOS app version: 10.9.1
- Shopify CLI version: 3.84.0
shopify.extension.toml
api_version = "2025-07"
[[extensions]]
type = "ui_extension"
name = "pos-ui-post-purchase"
handle = "pos-ui-post-purchase"
description = "A react POS UI extension"
[[extensions.targeting]]
module = "./src/Action.jsx"
target = "pos.purchase.post.action.render"
[[extensions.targeting]]
module = "./src/Block.jsx"
target = "pos.purchase.post.block.render"
[[extensions.targeting]]
module = "./src/MenuItem.jsx"
target = "pos.purchase.post.action.menu-item.render"
[[extensions.targeting]]
module = "./src/Probe.jsx"
target = "pos.product-details.block.render"
shopify.app.toml
client_id = "[redacted]"
name = "my-app"
application_url = "https://shopify.dev/apps/default-app-home"
embedded = true
handle = "my-app"
[build]
include_config_on_deploy = true
[webhooks]
api_version = "2025-07"
[access_scopes]
scopes = "read_content"
[auth]
redirect_urls = [ "https://shopify.dev/apps/default-app-home/api/auth" ]
[pos]
embedded = false
Probe.jsx
import {
extension,
POSBlock,
POSBlockRow,
Text,
} from '@shopify/ui-extensions/point-of-sale';
async function queryShopName() {
const requestBody = {
query: `#graphql
query {
shop { name }
}
`,
};
try {
const res = await fetch('shopify:admin/api/graphql.json', {
method: 'POST',
body: JSON.stringify(requestBody),
});
const text = await res.text();
let json = null;
try {
json = JSON.parse(text);
} catch {
console.error('[Probe] JSON parse failed, raw body:', text);
return;
}
if (!res.ok) {
console.error('[Probe] Network Error:', res.status, res.statusText);
console.error('[Probe] Body:', text);
return;
}
if (json.errors) {
console.error('[Probe] GraphQL Errors:', json.errors);
return;
}
console.log('[Probe] Success:', json.data);
} catch (err) {
console.error('[Probe] Fetch exception:', err);
}
}
export default extension('pos.product-details.block.render', (root) => {
const resultText = root.createComponent(Text, { children: 'Running probe…' });
const row = root.createComponent(POSBlockRow);
row.append(resultText);
const block = root.createComponent(POSBlock);
block.append(row);
root.append(block);
queryShopName().then(() => {
resultText.replaceChildren('Done (check console)');
});
});
Repro steps
shopify app deploy
, install app in shop through browser.- Open browser preview, press “View mobile” for “pos-ui-post-purchase” handle, scan QR and launch POS app on iOS.
- On smart grid tap “Other Extension Targets” to run API request in
Probe.jsx
.
Probe logs
22:44:38 │ pos-ui-post-purchase │ ERROR: [Probe] Fetch exception: {
22:44:38 │ pos-ui-post-purchase │ "name": "ApolloError",
22:44:38 │ pos-ui-post-purchase │ "message": "Response not successful: Received status code 401"
22:44:38 │ pos-ui-post-purchase │ }
I’ve tried reinstalling the POS app, logging out and back in on both iOS and the CLI, creating a new development store, amongst other things I’m probably forgetting. Would appreciate any help, thank you!