All docs
Shopify setup
Credential: Dev Dashboard app
The Shopify connector creates hidden blog articles — Shopify’s word for a draft — on a blog in your store. You publish them from Content → Blog posts.
Step 1 - create an app and install it
Shopify changed this in January 2026: you can no longer create custom apps in the Shopify admin, and new apps come from the Dev Dashboard.
- In your Shopify admin, go to Settings → Apps and sales channels → Develop apps, then Build apps in Dev Dashboard.
- Create app, name it
BirchSeek, and open its Access section. - Request the scope
write_content(addread_contenttoo — it costs nothing and makes the connection test more useful). - Release a version, then Install app on your store.
- Open the app’s Settings tab and copy the Client ID and Client secret.
The one restriction that cannot be worked around: Shopify’s client-credentials grant only works when the app and the store belong to the same Shopify organization. If you create the app under a partner organization, or under a different organization than the store, minting a token will fail no matter what you paste. The connection test names this case specifically.
Already have a token? Stores that created a custom app before January 2026 still hold a long-lived shpat_… Admin API token. Switch the connector’s auth mode to Access token and paste it directly — no client credentials, no minting. Shopify does not let you rotate these; changing one means uninstalling and reinstalling the app.
Step 2 - connect in BirchSeek
| Setting | Meaning |
|---|---|
| Shop domain | your-store.myshopify.com |
| Auth mode | Client credentials (new stores) or Access token (legacy) |
| Client ID + secret, or Access token | From step 1 |
| Blog | Which blog to publish into — pick it from the connection test’s list |
| Author name | Required. Shopify rejects an article with no byline |
The author name is not optional politeness: Shopify’s author field is non-null on create, so a connector without one cannot publish anything. BirchSeek uses your project’s author if it has one and falls back to this. The connection test refuses to go green without a resolvable byline, rather than letting you discover it at the last step of your first article.
Your store also needs at least one blog. Shopify creates a default “News” blog, but it can be deleted — if the connection test reports no blogs, create one under Content → Blog posts → Manage blogs first. BirchSeek will not create storefront objects on your behalf.
Step 3 - send a test
Send a test mints a token (client-credentials mode) and asks for the shop and its blogs in one GraphQL query. It reports your storefront’s primary domain and blog handle, and stores them — they are how BirchSeek builds the article’s public URL once you publish it.
What BirchSeek writes
Per article, via the GraphQL Admin API’s articleCreate mutation:
title,handle(your slug),body(HTML rendered from the article),summarytags,authorisPublished: false— this is what makes it a hidden draft- three metafields:
global.title_tagandglobal.description_tag(your SEO title and meta description), andbirchseek.article_id
body ends with a ## Sources block: a numbered list pairing each verified claim with the page it was checked against, rendered into the HTML like any other section. BirchSeek composes that body once, before any connector sees it, so every connector publishing to your own site writes the same block - there is nothing to append yourself. (A syndicated copy to dev.to, Hashnode or Medium carries the same block, and the canonical link back to your page besides. That copy is not covered by the project setting: those three platforms have no citation field of their own, so the body is the only place the evidence can travel.) The block is on by default, and there is no switch for it in the dashboard: it is a project setting called append_sources_section, and the only way to change it today is PATCH /v1/projects/{id} carrying the whole settings object, because that request replaces the object rather than merging into it.
That last metafield matters. It is how BirchSeek proves an article with your slug is its own before touching it. If a post with the same handle exists and was not created by BirchSeek, the publish refuses rather than overwriting a post you wrote.
On a refresh run the article is updated in place via articleUpdate, and isPublished is deliberately not sent — so an article you already reviewed and published stays published, with fresh content, rather than being yanked back to hidden.
Caveats
- SEO title and meta description are metafields, not article fields. Shopify has no field for them on an article, so BirchSeek sets
global.title_tagandglobal.description_tag, which is what Shopify’s own themes read. If another app or the admin SEO editor already created those metafields with a different type, the SEO write can fail — BirchSeek logs it loudly and keeps the article, because the content is already live at that point. - Shopify cannot set a canonical URL on an article. There is no such field anywhere in the Admin API; themes emit
{{ canonical_url }}, which always resolves to the page’s own URL. That is fine here — your Shopify blog is the canonical, and it is what BirchSeek hands to dev.to, Hashnode or Medium when you also syndicate. - API version. BirchSeek pins Shopify’s API version and bumps it on a schedule. Nothing for you to configure.
Troubleshooting
- “the app and the store must belong to the same Shopify organization” - see step 1. The app has to be created from this store’s own admin.
ACCESS_DENIED, or a scope list withoutwrite_content- add the scope in the Dev Dashboard under Access, release a new version, then reinstall the app on the store. Editing scopes alone is not enough.Handle has already been taken- a post with this slug exists. If BirchSeek created it, a retry converges onto it automatically. If someone else did, change the article’s slug.- “Throttled” - Shopify returns this with HTTP 200 rather than a 429. BirchSeek detects it and backs off; one article costs roughly 30 of the 100-2000 points per second your plan allows, so it is rarely the real problem.