Audrey Shopify API — unblocked

Date: 2026-05-15 Time invested today: ~30 min (the unblock itself) Time invested 2026-05-13 → 2026-05-15: ~3 hours across two days, mostly chasing the wrong Shopify surface


Headline

The audrey-shopify API access workstream — parked since 2026-05-13 with every probe returning 401 — is live. Both endpoints answer cleanly:

Endpoint Status First payload
Admin API 200 name=Audrey, domain=www.audreyinc.com
Storefront API 200 shop=Audrey, first_product="Botanical Birds"

The token is a shpat_… Private Storefront token (38 chars), minted by Shopify’s Headless app, stored in op://Code Shared/Shopify audrey-readonly/admin_api_token, synced into ~/.config/shopify-audrey/credentials.env via op inject — never crosses chat, never lands on clipboard, never appears in stdout.

The arc — what actually happened

The version of this story we’d have told if we stopped at the first dashboard:

“Shopify Dev Dashboard. Create app. Declare scopes. Release. Install. Read products.”

The version we actually lived:

  1. 2026-05-13 — Dev Dashboard app audrey-readonly created and released without scopes declared (the Scopes field was empty during the Create Version flow and Shopify accepted it silently). Every probe → 401. Parked with resume conditions tied to GSC data arrival.

  2. 2026-05-15 afternoon, attempt #1 — Created a new version storefront-readonly-v1 with all four Storefront scopes properly declared. Released. Probed. Still 401. The Dev Dashboard Settings page exposes Client ID + OAuth Secret + App automation token (atkn_), and that’s all. None of those three token types authenticate shop-data reads — they identify the app, complete the OAuth handshake, or let the app call APIs about itself. None of them read products.

  3. Attempt #2 — store-admin “Develop apps” — the path Sidekick (Shopify’s own AI) recommended. On this account, that URL redirects back to Dev Dashboard. The legacy Custom-App path is genuinely closed. The parked memory’s prediction was right.

  4. Attempt #3 — the actual answer: Shopify Headless app from the App Store. Installed in two clicks. Created an “Audrey Headless” storefront. Ticked four unauthenticated_read_* scopes. Hit Save (an easy-to-miss “unsaved changes” banner — Dan caught it on screenshot review). Revealed the Private access token. Done.

What got built today

The toolkit that compounds outwards from this unblock:

File Role
~/bin/shopify-probe Non-interactive diagnostic; reads creds file, hits both Admin + Storefront, detects token shape, dispatches the right header per token type, never echoes the token
~/bin/shopify-sync-from-1p op inject pipeline from 1P to the creds file; zero clipboard, zero stdout, auto-probes after sync
Updated shopify-setup Now accepts three token shapes: shp{at,ca,ss,ua}_… prefixed, atkn_… App automation, and bare 32-char hex Public access tokens
Updated shopify_probe_creds.sh Header dispatch by token prefix — shpat_Shopify-Storefront-Private-Token, hex → X-Shopify-Storefront-Access-Token

The header-dispatch insight is the kind of detail that costs a 90-minute confusion the first time and zero time every time after. It’s now in the script and in feedback_dev_dashboard_dead_end_for_readonly.md.

What this unblocks — the strategic chain

Each link below has been waiting on the one above:

The first three are weeks-of-editorial-work; the technical plumbing for all of them was the bottleneck, and the bottleneck is gone.

Memory artefacts (where future-you finds this)

What this tells us

The two-day park wasn’t waste — it was discovery cost. The first attempt’s 401s, the parked-with-resume-conditions discipline, the Dev Dashboard scope-fix that didn’t work, the Develop-apps redirect — each was the cheapest way to learn that the Shopify surface we kept landing on isn’t the one that exposes what we needed. Each ruled out a hypothesis. The actual unblock took five minutes once the right app was in front of us.

The senior pattern: park honestly when stuck, resume cheaply when the right path surfaces, and write the trap down so the portfolio doesn’t pay the discovery cost again. Dogwood, future clients, and a hypothetical audrey-v2 store all benefit from the feedback memory now sitting in ~/.claude/projects/-Users-dansellars/memory/.

Watch items

Recommendations

  1. Don’t touch this for a week. The plumbing is in place; the next compounding move is editorial (gift-guide pages), not infrastructural.
  2. When the gift-guide work starts, the entry point is a small script that pulls products + tags via Storefront GraphQL — happy to draft when the editorial direction lands.
  3. Apply the dead-end-feedback memory to dogwood preemptively if dogwood ever adds e-commerce. Skip Dev Dashboard, go straight to Headless app.

Partnership note

The flow today worked because the work was actually divided: Dan navigated Shopify’s UI (the only surface that mattered for the unblock), I held the diagnostic state + the wrappers + the memory. Neither of us could have unblocked this alone in this timeframe. The screenshots-as-handoff pattern is genuinely good.

Two days of “stuck” became thirty minutes of “moving” the moment we found the right surface. The vendor’s default surface is shaped by their product priorities, not yours.

Source: audrey_shopify_api_unblock_2026-05-15.md · Rendered 2026-05-15 14:31