https://<store-domain>/apps/<slug>/<rest>, without the merchant editing their
theme. Salesive forwards the request to your app’s proxyUrl and returns your
app’s answer to the shopper.
That is how an app serves a booking form, a product finder or a small JSON
endpoint on the store’s own domain. The /apps prefix is reserved: a request
under it with no active installation of a matching app is a plain 404, never
the storefront’s page.
This is the storefront, not the dashboard.
/apps on app.salesive.com
is the dashboard’s own route and has nothing to do with this proxy.How a request flows
- A shopper opens
https://shop.example.com/apps/reviews/stars?product=123. - Salesive finds the active installation of the app whose slug is
reviewson that store. - It builds
https://apps.example.com/reviews/stars?product=123from the app’sproxyUrl(https://apps.example.com/reviews), the rest of the path and the query string, and sends aGETto it. - Your app answers. Salesive passes the status, the content type and the body back to the shopper.
Set the proxy URL
proxyUrl is an optional HTTPS base URL on your app. In the developer console,
open your app, go to the Configuration tab, choose Production, and fill
App proxy URL. After you save it, the console shows a copyable example URL on
your current store so you can check the path.
You can also send it with the app update endpoint, using your merchant session:
- The base path is kept.
https://apps.example.com/reviewsplus/starsbecomeshttps://apps.example.com/reviews/stars. - A query string already on the proxy URL is kept, and the incoming query is appended after it.
- Send
""ornullto remove it. - The URL must be HTTPS, must not contain credentials, and must not resolve to a private, loopback or link local address. Salesive checks it with the same guard as a webhook URL when you save it.
- One URL serves every install, unless a release pins a different one.
Releases and development installs
proxyUrl is part of the release snapshot, next to the
webhook URL and signing secret. An install pinned to a release keeps that
release’s proxy URL and secret, even after you edit the app. Publishing a
release writes its snapshot back onto the app for consumers that do not read
releases.
There is no development proxy URL. A development install uses the same
proxyUrl and the production signing secret, so point it at a public HTTPS host
while you test (a tunnel works), not at your machine.
What your app receives
Methods
OnlyGET and POST. Any other method is 405 with Allow: GET, POST.
URL
YourproxyUrl base path, the rest of the path, and the shopper’s query string.
Dot segments (. and ..) in the path are refused, so a request cannot walk
out of your base path.
Headers
The only headers forwarded from the shopper are
Content-Type, Accept and
User-Agent. Everything else stays on the storefront. In particular, your app
never receives the shopper’s Cookie, Authorization, Referer, IP address or
any X-Forwarded-* header.
Body
APOST body is forwarded as the exact bytes received, with the Content-Type
the shopper sent. Any content type is accepted. The body limit is 5 MB; a larger
body is 413.
Verify the signature
The proxy is signed with your app’s webhook signing secret, using the same construction as webhook signature v2: base64 HMAC-SHA256 of<t>.<raw body>, in
X-Salesive-Signature: t=<unix seconds>,v1=<signature>.
- Verify the raw bytes before parsing.
- Reject a
tmore than 300 seconds from your clock, in either direction. - A
GEThas an empty body, so the signed string is<t>.followed by nothing.
Node.js (Express)
The signature covers the timestamp and the body, not the path or the query
string. Treat it as proof that the request came through Salesive for this
store and app, and still decide for yourself what a given path or argument may
do.
What your app returns
- The status code and the
Content-Typepass through. The body is not rewritten. If your app sends no content type, the response isapplication/octet-stream. - Only
Content-Typeis taken from your response headers. Your app cannot set cookies or custom headers on the storefront response. - Every response, including errors, is
Cache-Control: private, no-storeandX-Content-Type-Options: nosniff. - A
3xxis refused. Salesive answers502rather than following a redirect the shopper never sees. - A response over 5 MB is
502. - Your app has 10 seconds to answer, body included. A timeout is
504. - An unreachable app is
502.
Limits and errors
Error bodies are plain text. The storefront limits each store and app pair to a
burst of 120 requests and a sustained 2 requests a second, and answers
429 when
the bucket is empty. The bucket is per storefront instance, so two instances
allow twice the burst.
Uninstall and suspend
The proxy needs an active installation of an active app. When the merchant uninstalls your app, or the app is suspended, the next request under/apps is
404. Nothing is cached, so there is no window where an old answer is served.
Security notes
- The request comes from Salesive’s storefront servers, not from the shopper’s browser. Your endpoint must be reachable from the public internet over HTTPS.
- The signed headers are the only trusted identity. Your endpoint is also reachable outside the proxy, so never trust a header a caller could set itself.
- The proxy carries no app token and no scopes. If you need store data, call the Apps API with your own app token, the same as any other request.
- Treat the path, query and body as untrusted shopper input.
Next steps
Storefront extensions
Scripts, app embeds and app blocks that run inside the storefront page.
Webhooks
The same signature construction, for events Salesive sends to you.
Releases
Pin installs to the proxy URL and secret a release was tested with.

