B
Back-mund
PIM · Humanji AB
setup guide
For the Shopify developer

Connect Shopify to Back-mund

Back-mund is the customer's product information manager. It will push products, variants, prices, images and inventory into Shopify automatically. You don't need to install any third-party Shopify app for this integration. Total setup on your side: ~20 minutes.

System status

back-mund · statuslive · refreshes every 30s
$curl back-mund.humanji.se/api/public/health
Loading…

TL;DR checklist

In the merchant's Shopify Admin: Settings → Apps and sales channels → Develop apps → Create an app named Back-mund PIM
Enable Admin API scopes (7 scopes — list below)
Install the app and immediately copy the Admin API access token — it is shown only once
Send the credentials to Humanji via a secure channel (1Password / encrypted email): shop domain, access token, location ID
Humanji sets four env vars on Vercel and triggers a redeploy
Verify by clicking Test connection at back-mund.humanji.se/admin/api → Connection. Green panel = done.

1. Pre-flight

What you need before starting

  • Admin access to the customer's Shopify store
  • The URL of the Back-mund admin (the URL of this page's parent: back-mund.humanji.se) — used only for the final verification step, not by you to log in
  • A secure channel (1Password, Bitwarden, encrypted email) to share the Shopify access token with Humanji

You don't need a Shopify Partners account — Custom Apps work without the App Store flow.

2. Create the Custom App

  1. Log in to the customer's Shopify Admin
  2. Go to Settings → Apps and sales channels → Develop apps
  3. If asked, click Allow custom app development (one-time consent)
  4. Click Create an app
  5. Name it Back-mund PIM
  6. Click Create app

3. Configure Admin API scopes

On the new app's page, click the Configuration tab → Configure under Admin API integration. Enable exactly these seven scopes:

ScopeWhy Back-mund needs it
read_productsLook up existing Shopify products by handle (idempotent upsert)
write_productsCreate or update product titles, variants, descriptions, prices
read_inventoryRead existing inventory levels (sanity check)
write_inventoryPush the merchant's stock levels from PIM into Shopify
read_locationsFind the merchant's default inventory location
read_filesPre-flight check that media uploads will work
write_filesUpload product image media via productCreateMedia

Click Save.

4. Install the app and copy the token

  1. Click Install app in the top-right corner
  2. Confirm the install
  3. On the API credentials tab, click Reveal token once
  4. Copy the Admin API access token (starts with shpat_)

⚠ Critical: the token is shown only once

Copy it directly into a password manager. If you lose it, the only fix is to revoke the app and create a new one. Shopify does not allow re-revealing existing tokens.

5. Hand the credentials to Humanji

Send these three values via 1Password / encrypted email — never in plaintext chat:

SHOPIFY_STORE_DOMAIN  =  <storename>.myshopify.com
SHOPIFY_ADMIN_TOKEN   =  shpat_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
SHOPIFY_LOCATION_ID   =  (optional — Back-mund auto-discovers if omitted)

Optional: tell Humanji which API version to pin. Default is 2026-04.

6. Humanji wires it up

(this step is on Humanji's side)

  1. Add four env vars on Vercel → back-mund project → Settings → Environment Variables:
SHOPIFY_STORE_DOMAIN=<storename>.myshopify.com
SHOPIFY_ADMIN_TOKEN=shpat_...
SHOPIFY_API_VERSION=2026-04          (optional)
SHOPIFY_LOCATION_ID=<numeric>        (optional)

Then redeploy so the function picks up the new values.

7. Verify

In the Back-mund admin: back-mund.humanji.se/admin/api → Connection tab → click Test connection.

Expected (green panel):

Connected to <Shop name>
Domain         <storename>.myshopify.com
Primary URL    https://<custom-domain>/
Currency       SEK
API version    2026-04
Location       gid://shopify/Location/<numeric>

If you get an error, see “Troubleshooting” below.

Field mapping

What Back-mund pushes into Shopify

Back-mundShopifyPushed by
products.slughandle (idempotency key)full upsert
products.titletitlefull upsert
products.descriptiondescriptionHtmlfull upsert
products.brandvendorfull upsert
products.colortagfull upsert
products.is_publishedstatus (ACTIVE / DRAFT)full upsert
product_variants.sizeoption Storlek valuefull upsert
product_variants.sell_pricepricefull upsert only
product_variants.skuskufull upsert
product_variants.eanbarcodefull upsert
product_variants.stockinventory @ default locationboth paths
product_images.url (first 10)media originalSourcefull upsert

Note: Back-mund won't overwrite manually-edited Shopify prices on the daily delta sync. Only a full upsert (when a product first appears, or a manual re-sync) writes price.

Daily flow after setup

After the env vars are in place, the merchant doesn't have to do anything. The pipeline runs itself:

  1. Every morning the supplier emails an .xlsx attachment to feed@inbound.humanji.se
  2. Postmark Inbound forwards it as a webhook to Back-mund
  3. Back-mund queues the rows; a Vercel Cron worker drains them in 100-row chunks every 2 minutes (~30–40 min total)
  4. When the import is done, productSet + inventorySetQuantities push changes into Shopify
  5. The merchant sees the result in /admin/api → History

Troubleshooting

"Connection failed" / 401 from Shopify+
  • Verify the token starts with shpat_ and has no leading/trailing spaces
  • Make sure all 7 scopes are enabled (the app's API credentials tab shows what's currently granted)
  • Confirm the app is installed, not just created (top-right button)
  • If you accidentally rotated the token, revoke + create new and resend
"Connection failed" / 404 on the shop+

SHOPIFY_STORE_DOMAIN must be the *.myshopify.com form, not the custom domain. Even if the public storefront is shop.example.com, the API hostname stays <storename>.myshopify.com.

inventorySetQuantities userErrors mention 'location'+

The store has multiple locations and Back-mund picked the wrong one. Set SHOPIFY_LOCATION_ID explicitly to the numeric ID from Shopify Admin → Settings → Locations → click the location → URL contains the ID.

Rate-limited+

Shopify GraphQL has a calculated query cost bucket. If a sync hits 429 the cron worker stops the batch and resumes from the unfinished item on the next 2-minute tick. No manual intervention needed.

Image not showing on the Shopify product+

First sync uploads up to 10 images per product as originalSourceURLs from Back-mund's Vercel Blob storage. Shopify pulls the bytes from there. If a URL 404s (rare), Shopify keeps the row but with no image — re-running the sync after Back-mund's image mirror has caught up usually fixes it.

What about Shopify apps for the storefront?

The integration does not require any Shopify app on the storefront side. You can build the store with whichever theme and apps the merchant prefers. Common picks for this type of business:

NeedCommon app(s)
ReviewsLoox, Yotpo, Judge.me
TranslationTranslate & Adapt (built-in), Weglot
Email + SMSKlaviyo, Omnisend
SEOSearch & Discovery (built-in), JSON-LD for SEO
Currency / marketMarkets (built-in), Geolocation
Cookies / GDPRPandectes, Customer Privacy (built-in)

These are independent of Back-mund and can be added/removed at any time.

Open questions to align on before launch

These don't block setup but should be agreed with the merchant:

  1. Stale-product policy — when a SKU disappears from the supplier feed for ≥ N days, should the Shopify product be archived/unpublished, or left with stock 0? Current default: stock zeroes after 2 days, Shopify status untouched.
  2. Manual price overrides— Back-mund's daily delta sync intentionally doesn't overwrite Shopify-side price edits. A full re-sync (manual trigger from /admin/api → Sync products) WILL overwrite. Decide internal policy on when to allow that.
  3. First-time bulk sync — for a store with no products, the first run creates ~600 products at once. Designed for it (rate-limited 4-way concurrency, abort on 429) but expect ~5–10 minutes for the initial population.

Reference