/apps/pod/* proxy path.
These endpoints exist to let the storefront runtime do things that a pure-client-side widget can’t: stage customer uploads to durable storage, look up fee variant IDs, geocode customer addresses, and a few other storefront-specific needs.
How Shopify app proxies work in 60 seconds
Shopify exposes a magic URL prefix on every store:/apps/pod/<path> is forwarded by Shopify to Customei with:
- The shop domain in a header (so Customei knows which tenant to serve).
- An HMAC signature computed by Shopify over the request — Customei verifies it to ensure the request actually came through a real Shopify storefront.
You don’t usually call these endpoints yourself — the Customei storefront widget does. They’re documented here so you understand what’s happening, and so you can call them directly if you’re building custom storefront tooling.
Available endpoints
| Endpoint | Purpose |
|---|---|
POST /apps/pod/upload-stage | Get a presigned URL to upload a customer file to S3. |
GET /apps/pod/fee-variant | Look up the fee-product variant ID for a given price add-on. |
POST /apps/pod/image-process | Run server-side image processing (e.g. background removal). |
GET /apps/pod/geocode | Reverse-geocode a lat/lng pair. |
GET /apps/pod/mapbox/* | Proxy requests to Mapbox (tiles, geocoding) using a server-side token. |
Upload stage
POST /apps/pod/upload-stage
Called by the storefront runtime when a customer picks a file in an image upload option. It takes the file’s name and type, asks Customei for a presigned S3 URL, and returns it — the client then uploads the file directly to S3 in a second step.
Request
- Filename — sanitized to remove path separators and unsafe characters.
- Extension — must be in an allowlist of accepted types: images (
png,jpg,jpeg,webp,gif,bmp,tiff,svg), documents (txt,doc,docx,pdf,xlsx,csv), audio (mp3,wav,wma), video (mp4,mov,qt,avi,rmvb), and archives (zip,rar). - Content type — must match the extension’s expected MIME type.
- Size — capped per option-set configuration.
Response
uploadUrlis a presigned PUT URL valid for a few minutes. Upload the file directly to this URL with a PUT request and the raw file bytes as the body.assetKeyis the Customei reference for the staged asset — use it in subsequent API calls (e.g. setting the upload on a line item).
Why two-step?
Two-step uploads keep Customei’s servers off the hot path for file bytes. The file never touches Customei — it goes client → S3 — which keeps upload latency low and our origin bandwidth bounded.Fee variant lookup
GET /apps/pod/fee-variant?amount=500¤cy=USD
Used on non-Plus stores where Customei uses the Fee Variant pricing strategy. The storefront widget calls this to find the variant ID of the hidden fee product that matches a specific add-on amount, so it can add that variant to the cart alongside the real product.
Request
Query parameters:amount— the add-on amount in the shop’s smallest currency unit (e.g. cents for USD).currency— the currency code (USD,EUR, etc.).
Response
Image processing
POST /apps/pod/image-process
Runs server-side image operations on a staged asset. Currently supports:
- Background removal (for customer photo uploads).
- Auto-crop to a target aspect ratio.
- Color-space normalization.
Geocode
GET /apps/pod/geocode?lat=37.7749&lng=-122.4194
Reverse-geocodes a lat/lng pair to a human-readable address. Used by the Map and Star map option field types when a customer picks a location from a map.
Returns a standard geocoding response (formatted address, administrative divisions, country code). Backed by Customei’s server-side geocoding provider, which is why this can’t be called directly from the browser without the signed proxy path.
Mapbox proxy
GET /apps/pod/mapbox/<path>
A thin pass-through to the Mapbox API using Customei’s server-side Mapbox token. Used by option fields that render map tiles or call Mapbox geocoding directly.
The storefront widget constructs these URLs; you generally don’t need to call them yourself.
Verifying the Shopify signature
Customei verifies Shopify’s HMAC signature on every app-proxy request automatically. You don’t need to sign anything in the caller — Shopify adds the signature as it forwards the request. What you do need to handle if you’re building a custom storefront integration:- Always use URLs starting with
/apps/pod/on the customer’s shop domain — never hit Customei’s origin directly from storefront JS. The origin is not reachable without the signature. - Don’t try to forge the signature yourself. Go through Shopify’s proxy.
When to call these yourself vs use the widget
- Use the widget for 99% of storefront personalization needs. It handles upload staging, fee variant lookups, and mapping out of the box.
- Call directly only if you’re building a custom widget or a non-widget integration — e.g. a quote form that collects a file upload without the full personalization UI. In those cases, use
upload-stageto get a presigned URL, upload the file to S3, and then reference theassetKeyin your GraphQL mutations.
Next
- Authentication — for admin-facing (non-proxy) calls.
- GraphQL quickstart
- Errors and rate limits