Share an app
You have a working web app — a dashboard, a demo, an internal tool — running behind a sandbox preview URL, and you want to give that URL to someone else. This guide takes it from a preview that expires to an App Link that does not, and then shows how to ship an update to the same address.
The short version: a preview URL is for you, now; an App Link is for someone else, later.
Before you start
Section titled “Before you start”- A web app that starts with one command and listens on one port.
- Its files as UTF-8 text — HTML, CSS, JS, JSON, TypeScript. Bundles reject binaries, so inline small images as SVG or data URLs.
- A signed-in Sapiom account, or a
SAPIOM_API_KEYfor the REST path.
-
Check the app actually runs
Section titled “Check the app actually runs”Get it serving in a sandbox first, with
sapiom_dev_sandbox_previewor however you have been iterating. Publishing does not run your app, so a bundle that does not start locally will fail at its first wake instead — where the failure surfaces to whoever opened the link.Note the exact start command and port. Publishing from a project on disk reuses whatever
sapiom.jsonalready records; publishing by file map takes them verbatim. -
Publish it to a slug
Section titled “Publish it to a slug”The slug is the last segment of the URL, so pick one a person can read:
quarterly-dashboard, notdash-v3-final.Ask Claude Code or Codex:
Publish this app as a Sapiom App Link on the slug
quarterly-dashboard. Return the live URL.From a project on disk the agent uses
sapiom_dev_app_publishon the localsapiom-devMCP, which reads the source directory, start command and port straight out of thesapiom.jsonresource you previewed with in step 1 — you do not repeat them. If the app only exists in the conversation, the hostedsapiom_app_publishtakes the files inline instead. See Connect and authenticate for the two aliases and which one carries which tools.Create the app, upload the bundle, then activate it:
Terminal window APP_ID=$(curl -s -X POST https://api.sapiom.ai/v1/app-links \-H "x-api-key: $SAPIOM_API_KEY" -H 'content-type: application/json' \-d '{"slug":"quarterly-dashboard","name":"Quarterly dashboard"}' | jq -r .id)curl -X PUT https://api.sapiom.ai/v1/app-links/$APP_ID/bundle \-H "x-api-key: $SAPIOM_API_KEY" -H 'content-type: application/json' \-d '{"files":{"index.html":"<!doctype html>…","server.js":"…"},"start":"node server.js","port":3000}'curl -X POST https://api.sapiom.ai/v1/app-links/$APP_ID/publish \-H "x-api-key: $SAPIOM_API_KEY"You get back a URL shaped like
https://apps.sapiom.ai/{your-org}/quarterly-dashboard. That is the durable address. -
Open the link yourself first
Section titled “Open the link yourself first”The first visit after any publish is a cold start: you will see a “Starting …” page for tens of seconds while Sapiom creates a sandbox and deploys the bundle, and it redirects itself when the app answers.
Opening it yourself is the real test of the bundle — it is the first time the
startcommand runs in a fresh sandbox. If the app is broken, you find out instead of your audience. -
Send the canonical link
Section titled “Send the canonical link”Share the
apps.sapiom.aiURL, not whatever ends up in your address bar after the redirect. The redirect target is a per-session sandbox address that dies with its sandbox; theapps.sapiom.ailink is the part that keeps working.By default only signed-in members of your organization can open it. If the person you are sending it to is outside the org, you need a public link — read who can open it first, because your org pays for every wake a public visitor causes and going public requires an explicit confirmation and a daily spend cap.
-
Republish to ship an update
Section titled “Republish to ship an update”Publish again to the same slug. The bundle is replaced in place: the link you already sent keeps working and serves the new version from its next wake. Nothing else republishes as a side effect, so a link only ever changes when you deliberately publish to it.
Keeping a link current automatically
Section titled “Keeping a link current automatically”If the app renders data that goes stale, a scheduled workflow can republish it on a cadence, so the link someone bookmarked keeps showing fresh numbers without anyone opening a terminal. A run’s default credential already carries the narrow publish permission — see the Workflow tab on the capability page.
If something goes wrong
Section titled “If something goes wrong”- “Starting …” never finishes. The bundle’s
startcommand failed in a fresh sandbox. Most often it depends on something you installed by hand while iterating — add abuildcommand (for examplenpm install) so the dependency is there on every wake, and keep it quick, because it runs on every wake. - Publish rejected the files. Bundles are UTF-8 text only. A binary image or font is refused at publish rather than silently corrupted.
- Your changes are not showing. Publishing to a slug requires an actual publish call; uploading a bundle alone does not activate it.
- State disappears between visits. Every wake is a fresh sandbox from the bundle, so nothing written to its filesystem survives. Move anything that must persist into a database.
© 2026 Sapiom, Inc.