Files you upload through nostackai are stored privately and served through a CDN (cdn-{domain}.nostackai.com). Whether a browser can load a file depends on its path on the CDN.
| CDN path | Where it comes from | Who can load it |
|---|---|---|
/content/… | Free-form content uploads | Signed-in users, on pages hosted on *.nostackai.com (console, Playground) |
/data/… | Entity file / s3 fields | Signed-in users, on pages hosted on *.nostackai.com |
/org/… | Org resources | Signed-in org users, same restriction |
/public/… | Published files and AI-generated images/audio | Anyone with the URL, from any website |
/shared/… | Files with a share link | Anyone with the link, from any website |
Why a private file doesn't load on another website
Private paths are protected by a cookie that nostackai sets when you sign in. A page on a different domain — for example your own site — treats that cookie as third-party, and Safari, Firefox and Chrome (with third-party cookies off) don't send it. The CDN then answers 403 cdn_auth_required. Reading a file's bytes from another site (fetch, canvas) is also blocked.
Public files work anywhere
<audio>, <video> and <img> can load a public file from any domain, including seeking within audio and video. There is nothing special about hosting it on nostackai.com — only the cookie requirement is the problem.
Make a file public
POST {orgApiEndpoint}/app/{orgCode}/content/{contentId}/publish
→ { "publicKey": "public/{guid}.mp3", "publicUrl": "https://cdn-{domain}.nostackai.com/public/{guid}.mp3" } Only the file's owner or a content admin can publish. Use publicUrl anywhere. To take it back, call DELETE on the same path — the public copy is removed and stops working within about a minute. Publishing is idempotent: calling it again on a published file returns the same public URL.
Public means anyone with the URL
The long random name in the URL is the only protection, and a public file can't expire on its own. Don't publish anything sensitive.
Share a link
POST {orgApiEndpoint}/app/{orgCode}/content/{contentId}/share
→ { "sharing": { "link": { "enabled": true, "token": "…", "url": "https://cdn-{domain}.nostackai.com/shared/{token}/{filename}", "role": "viewer" } } } An empty body turns on an anyone-with-the-link URL; DELETE on the same path revokes it. The sharing settings also accept org, users, role and expiresAt, but only the link is enforced today — those other fields are recorded and do not restrict who can read the file, and a link expiry isn't applied (the link works until you revoke it).
What's already public, and what isn't
- Images and audio generated by an
ai_callstep are written under/public/, so their URLs already work on any website. - Entity
file/s3fields upload to the private/data/path and can't be made public in place — only free-form content can be published. To show a file on another website, upload it as content and publish it. - There is no per-file visibility switch, no expiring signed link and no custom CDN domain per tenant yet.
Rule of thumb
Showing media on a page that isn't on nostackai.com? Upload it as content (GET /app/{orgCode}/content/uploadurl), publish it, and use the publicUrl. Keep sensitive files private and view them from nostackai-hosted pages.