Publishing artifacts
import { Aside } from ‘@astrojs/starlight/components’;
An artifact is a versioned bundle of files served at a live URL. Publishing the
same slug again creates a new version — the old ones stay reachable.
Publish
Section titled “Publish”POST /v1/publish with your files:
{ "name": "My App", "slug": "my-app", "entrypoint": "index.html", "visibility": "public", "files": [ { "path": "index.html", "content": "<!DOCTYPE html>…", "mime": "text/html", "encoding": "utf8" } ]}Omit slug and ShareOut generates one. See the full schema in the
API reference.
Share URLs
Section titled “Share URLs”The publish response includes a deployment object with live URLs:
| Field | Use |
|---|---|
deployment.subdomain_url |
Share link for workspace artifacts — https://{workspace}.shareout.site/{slug}/ |
deployment.url |
Share link for personal artifacts (https://shareout.site/a/{slug}/); also the internal routing key for workspace artifacts |
deployment.slug |
Globally unique routing slug (may differ from the human slug you sent) |
deployment.mobile_url |
Mobile entrypoint when mobile_html is set |
For workspace artifacts, present deployment.subdomain_url to users — not the apex
/a/{routing-slug}/ URL. The apex slug is an internal routing key that may be
hash-suffixed on cross-workspace collision; subdomain and namespaced URLs keep the clean
human slug. Use deployment.url only for machine links (embeds, manifests, KV).
Editor readiness
Section titled “Editor readiness”HTML publishes return an advisory editor_readiness profile — how much the visual
editor can do with the artifact. Publishing is never blocked by gaps; the page is live
regardless.
{ "editor_readiness": { "manifest": "valid", "outline": true, "counts": { "pages": 3, "bindings": 12, "templates": 1 }, "summary": { "errors": 0, "warnings": 1, "infos": 0 }, "findings": [ { "rule": "binding-undeclared", "level": "warning", "message": "Binding \"json:revenue\" references undeclared json \"revenue\"", "suggestion": "Declare \"revenue\" in the manifest sources", "disables": "inline editing and formatting of this value" } ] }}Each finding’s disables field names which studio feature that gap costs. Absent for
non-HTML artifacts. Findings may include a category — e.g. provenance warns when
a live source has no query/description or when charts lack
data-shareout-source / manifest feeds links. See Data provenance.
See the artifact spec overview and visual editor for the full checklist.
Visibility
Section titled “Visibility”| Value | Who can view |
|---|---|
private |
Only collaborators with viewer+ |
workspace |
Any member of the artifact’s workspace |
public |
Anyone on the internet with the link; discoverable |
(unlisted is a retired legacy alias, still accepted on the API and treated as public.)
Public artifacts
Section titled “Public artifacts”Public visibility triggers additional platform rules:
Safety review. The first time you publish or switch to open visibility, ShareOut
runs an automated safety check on the HTML. If it cannot approve instantly, the
artifact stays private with moderation_status: "pending" and a moderation
object on publish (or code: "MODERATION_HELD" + reason on PATCH) — but ShareOut
re-checks pending holds automatically (hourly) and restores the requested public
visibility once cleared, so most cases resolve within an hour with no action needed.
Blocked artifacts return HTTP 451 and are not served.
Owners see Under review / Blocked badges on Home cards and an inspector banner while held. Visitors who open a held public URL see a dedicated under-review page (not the artifact content). When a hold clears, the owner gets a bell notification and email.
External scripts & CDNs. On public artifacts the sandbox
Content-Security-Policy allows scripts, styles and fonts from a broad allowlist of
reputable CDNs — jsDelivr, unpkg, cdnjs, esm.sh, Skypack, Google-hosted libraries,
the Tailwind Play CDN (cdn.tailwindcss.com), jQuery, D3, Plotly, Highcharts,
DataTables, Bootstrap and more — which covers most libraries. A CDN outside the
allowlist is blocked, and its <script> will fail to load. If your artifact loads a
non-allowlisted CDN, trying to make it public is refused — it stays
private and you get a message naming the offending host.
Private artifacts have no CDN restriction. A private artifact can load
scripts, styles and fonts from any HTTPS source. So for a niche or self-hosted
CDN, keep the artifact private and add collaborators individually
(Settings → Sharing): they get full access and you keep unrestricted CDN use.
Alternatively, self-host the library as a file inside the artifact, or switch to an
allowlisted CDN.
Anonymous visitors are read-only by default. On public artifacts, anonymous viewers cannot write to json/tables/blobs/datasets, send email, use the visitor AI chat, or join realtime collaboration unless the owner opts in per capability:
| PATCH field | Allows anonymous visitors to… |
|---|---|
allow_anon_write |
Mutate json, tables, blobs, datasets |
allow_anon_email |
Send contact-form email |
allow_anon_agent |
Use the in-artifact AI chat agent |
allow_anon_collab |
Join realtime/Y.js collaboration |
All default to false. Authenticated collaborators keep their normal roles.
Badge. Off by default. Set ARTIFACT_BADGE=1 on the Worker to add a small
“Made with ShareOut” badge with a Report link to public artifacts.
Storage quota. Publishing checks the owner’s total stored bytes against
STORAGE_QUOTA_BYTES; exceeding it returns 413 STORAGE_LIMIT_EXCEEDED. Unset
or 0 means unlimited, the default.
Workspace publish governance
Section titled “Workspace publish governance”Workspace owners and admins can gate open visibility with a per-workspace policy
(allow / prohibit / require_approval). Default is allow — no change from
today unless configured. See Public artifacts policy
for the full policy context.
Configure (admin/owner):
GET /v1/workspaces/{id}/publish-policyPATCH /v1/workspaces/{id}/publish-policy{ "policy": "require_approval", "approvals_required": 2 }approvals_required is 1–10 when policy is require_approval.
When a member publishes or PATCHes visibility to open, the gate runs before platform moderation:
| Policy | API behaviour |
|---|---|
prohibit |
Visibility forced to workspace; response includes a notice. |
require_approval |
Visibility forced to workspace; response includes notice and approval_required. |
{ "deployment": { "url": "…" }, "notice": "Your workspace requires approval to publish publicly. Kept visible to your workspace — request approval from 2 teammate(s).", "approval_required": { "required": 2, "artifact_id": "art_abc123" }}Request approval (requester nominates exactly N workspace members, not self):
POST /v1/artifacts/{id}/publish-approval{ "visibility": "public", "approver_ids": ["usr_a", "usr_b"] }Approve or reject (each nominated approver):
POST /v1/artifacts/{id}/publish-approval/{requestId}/decision{ "decision": "approve" }List pending requests (any workspace member):
GET /v1/workspaces/{id}/publish-approvals?status=pendingWhen all nominated approvers approve, visibility flips to the requested level and the automated safety review runs. Any rejection cancels the request. Approval is per content hash — unchanged re-publishes stay approved.
Collaborators
Section titled “Collaborators”Add people by email with a role:
curl -X POST https://shareout.site/v1/artifacts/art_abc123/collaborators \ -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \ -d '{ "emails": ["teammate@example.com"], "role": "editor" }'| Action | Owner | Editor | Viewer |
|---|---|---|---|
| View | ✓ | ✓ | ✓ |
| Edit & publish | ✓ | ✓ | ✗ |
| Manage collaborators | ✓ | ✓ | ✗ |
| Delete | ✓ | ✗ | ✗ |
| Transfer ownership | ✓ | ✗ | ✗ |
Link previews
Section titled “Link previews”Set og:title, og:description, and og:image in your entrypoint <head> and
ShareOut serves them for Slack, WhatsApp, and iMessage unfurls. Override per
artifact with PATCH /v1/artifacts/{id} (social_title, social_description,
social_image_url).
Serving
Section titled “Serving”| URL | Serves |
|---|---|
/a/{slug}/ |
Entrypoint (auto mobile detection) |
/a/{slug}/{path} |
A specific asset |
/a/{slug}/{path}?_raw |
Raw content for iframe embedding |
Auto-summary & tags
Section titled “Auto-summary & tags”After each successful HTML publish, ShareOut runs a background AI pass over the
production entrypoint. It writes a 1–2 sentence description (only when you left
the field empty) and 3–6 tags into the existing artifact_tags table. Publish
never waits on this job — if AI is unavailable, the page still goes live.
Auto-summaries power Home card subtitles, ⌘K search hits, the weekly workspace digest, and Knowledge learner input. Older pages published before this feature shipped are backfilled on an hourly drip.
Set your own description or tags any time with PATCH /v1/artifacts/{id} — your
values are kept; auto-summary only fills gaps.
Versions & change notes
Section titled “Versions & change notes”Every publish to an existing artifact adds a version; nothing is overwritten. Send an
optional message with the publish to say what changed:
{ "slug": "my-app", "message": "Add the Q3 column", "files": [ … ] }When message is omitted, ShareOut writes a one-line AI note from the diff with the
previous version (flag ai.version_summaries, on by default). Each version records who
published it and how (api, agent, editor or restore).
To bring an old version back, restore it: that publishes a new version with the old
one’s files and keeps the full history. POST /v1/artifacts/{id}/rollback still works
but is deprecated in favour of restore. The UI, diffs and previews are covered in
Version history & restore; the endpoints are in the
API reference.
To publish several HTML pages as one artifact, see Multi-page artifacts.
Deleting & restoring
Section titled “Deleting & restoring”Deleting an artifact is a soft delete with a 30-day recovery window — not an immediate purge:
curl -X DELETE https://shareout.site/v1/artifacts/art_abc123 \ -H "Authorization: Bearer $TOKEN"# → { "recoverable_until": "...", "retention_days": 30, "restore_url": "..." }The artifact stops serving and disappears from your listings, and its slug is freed so you can re-publish the same slug — but its files, versions, and data store are kept intact. Within 30 days you can bring it back:
curl https://shareout.site/v1/artifacts/deleted -H "Authorization: Bearer $TOKEN" # trashcurl -X POST https://shareout.site/v1/artifacts/art_abc123/restore \ -H "Authorization: Bearer $TOKEN" # restoreIn the home UI, the same lives under the account menu → Recently deleted. Restoring re-derives a fresh slug if the original was reclaimed in the meantime.
Unused-page janitor
Section titled “Unused-page janitor”Once a month (per workspace or personal account), ShareOut flags published pages
with zero views in 90+ days when there are at least three of them. Starred pages
are always kept. The bell shows an Unused pages card with sample titles and
Archive all — a one-click soft-delete into the same 30-day trash (batches of
100 per click). Workspace admins use POST /v1/workspaces/{id}/unused/archive;
personal accounts use POST /v1/artifacts/unused/archive.
