Problem: A developer needed to detect app blocks and app embed blocks using GraphQL instead of the deprecated REST API for app installation automation.
Solution provided: Query the store’s themes via GraphQL and check the settings_data.json file (or other relevant template files) for app-related blocks. The approach involves:
Using the themes query to retrieve theme files
Parsing the file content to search for blocks matching the app’s namespace/type
Checking config/settings_data.json for app embed blocks specifically
Implementation challenges addressed:
Access denied errors: Requires proper theme-related access scopes granted to the app
JSON parsing issues: The settings_data.json file may contain comments (/* ... */) that break standard JSON parsing
Workarounds: Either manually strip comment blocks before parsing, or use the json5 library which handles comments natively
Key distinction: App embed blocks are typically found in settings_data.json, while regular app blocks may be stored in other template files.
The original poster confirmed the solution works successfully, enabling migration away from REST API.
Summarized with AI on October 24.
AI used: claude-sonnet-4-5-20250929.
If you want to identify whether a merchant has added app blocks to their theme, or enabled app embed blocks, you can use the Asset REST Admin API resource to look for blocks that match your app type. …
Hi @den232 ,
Foladun here from the Deluxe App team.
I solved this by querying the store’s themes and checking the settings_data.json file for app-related blocks.
In my case, the block I needed was in the settings_data.json file, but you can adapt this approach to check any template or file relevant to your app.
Here’s an example:
const response = await admin.graphql(`
query GetStoreThemes {
themes(first: 10) {
edges {
node {
files(filenames: ["config/settings_data.json"]) { // Replace with the file you're targeting
edges {
node {
body {
... on OnlineStoreThemeFileBodyText {
content
}
}
}
}
}
}
}
}
}
`);
const responseData = JSON.parse(await response.text()).data;
const themes = responseData.themes.edges;
themes.forEach(theme => {
const contentJson = JSON.parse(theme.node.files.edges[0].node.body.content);
const fileBlocks = contentJson?.current?.blocks || {};
const appBlockKey = Object.keys(fileBlocks).find(blockKey =>
fileBlocks[blockKey].type.includes('
In this example, I check the settings_data.json file because that's where my app block was located.
However, you can replace "*config/settings_data.json*" with any file or template you're targeting and adjust the block type accordingly (e.g., '*<replace-with-your-app-namespace>/blocks/<replace-with-your-block-type>'*'.
Let me know if this helps or if you need more information!
Best regards,
Foladun | **Deluxe: Account & Loyalty**
Hello, I try your way, but I face an error:
“errors”: [
{
“message”: “Access denied”,
“locations”: [
{
“line”: 7,
“column”: 9
}
],
“path”: [
“themes”,
“edges”,
4,
“node”,
“files”
]
}
]
How to fix it?
That’s correct, because if you’re retrieving config/settings_data.json to get app blocks you’ll probably get app embed blocks, as app blocks may not be stored in that file.
You can retrieve other specific template files to get app blocks.