---
title: Custom share URL name (custom slug + short link)
---

# Custom share URL name (custom slug + short link)

## What it is

Paid users (Pro or above) can replace the random 64-hex token in a share link with a memorable name, so the public page reads `https://shares.omniscio.com/s/<name>` instead of `https://shares.omniscio.com/s/<token>`. An optional **short link** (`omnisc.io/<code>`) can be minted for the same share at publish time.

This applies to any share that goes through the standard publish pipeline — session / message shares ([artifact-sharing.md](artifact-sharing.md)), file and pasted-content artifacts ([share-artifacts.md](share-artifacts.md)), and CLI publishes ([share-cli.md](share-cli.md)). The feature is toggled by the `customShareUrlEnabled` setting (Settings → Sharing), default off.

## Where to find it

Both controls are on the publishing path rather than in a page of their own. The public **name** is offered in the share publish dialog, where you type the name you want; the switch that turns the whole feature on is **Settings → Sharing**. The agent-facing short-link default has its own switch in the same settings section, under the wording about defaulting to short share links.

## How it behaves

### Custom slug (the `/s/<name>` link)

- **Eligibility.** Setting a custom name requires a paid account (Pro or above, any managed tier); a non-paid caller is refused at the relay and the share simply keeps its random token URL.
- **How it's set.** The publish payload accepts a `customSlug` field (1–80 chars). After the share is uploaded, the slug is **claimed** through the share relay's `claim-slug` op. If the name is already taken the claim fails gracefully and the publish falls back to the token URL — publishing is never blocked by a name collision.
- **Re-using your own name (re-publish).** Publishing new content under a name you already own **moves** the name to the newest share: the relay re-points it globally and the local record transfers it in one atomic step (`setShareSlug` releases the name off the prior live share before setting it on the new one), so the older share reverts to its token URL and `/s/<name>` always resolves to your latest publish. This holds for a re-publish or two near-simultaneous publishes of the same name — it never fails with a `UNIQUE constraint failed: shared_links.slug` error (the fix for that Sentry crash; see [custom-share-url-contract.md](../../.claude/memory/contracts/custom-share-url-contract.md) `local-slug-is-UX-only`).
- **Name rules** (`share-slug-rules.ts`, the single source of truth, mirrored byte-for-byte in the relay):
  - 4–80 characters; lowercase alphanumerics plus interior hyphens; must start and end alphanumeric (no leading/trailing hyphen).
  - A name shaped like a 16- or 64-hex share token is rejected — the share router's hex fast-path resolves tokens first, so such a slug would be unreachable.
  - Structural route words are reserved and always blocked: `s`, `run`, `video`, `unlock`, `png`, `inner`.
  - A small anti-squatting denylist (`demo`, `home`, `apps`, `pricing`, `login`, `admin`, `support`, …) stops any single user from locking away generic or premium words globally.
  - The publish UI pre-validates a name against these rules before the round-trip, showing the same message the relay would; the relay remains the authoritative validator.

### Short link (the `omnisc.io/<code>` opt-in)

- **System-minted.** At publish time (when no custom slug is set and the short-link opt-in is on), the service generates a code — 7 characters from an unambiguous 31-symbol alphabet that omits `0`, `1`, `i`, `l`, `o` so a link read aloud or hand-typed can't be mis-keyed — and claims it as a system-minted slug through the same `claim-slug` op.
- **Collision-safe.** A rare collision is retried by regenerating (up to 3 attempts); only a genuinely "taken" code is worth retrying. Any other failure (not paid / invalid / error) leaves the share with its token URL.
- **Never fatal.** A short link is optional: every failure path degrades to "keep the token URL" rather than breaking the publish.
- **Stable across republishes (fixed 2026-08-29).** A share keeps the SAME short code every time it is republished — the publish REUSES the code already saved on the row instead of minting a new one. This fixes a bug where each republish minted a FRESH code whose claim released the previous one, so every short link handed out earlier began 404ing and only the newest worked. Re-claiming the same code for the same share is idempotent server-side, so a republish also revives the current link if an earlier one had already broken it. Codes overwritten before this fix are not locally recoverable and are not revived.
- **A custom name wins over a short link.** A share has ONE pretty-URL slot (a short code and a custom name are both claimed there), so when the share already carries a custom name the short-link request is REFUSED — the publish returns a `shortLinkError` saying so — rather than silently replacing the name. To switch a share to a short link, clear its custom name first.
- **Persisted + opens in-app (2026-08-19).** A claimed code is saved on the local share row (`short_code`), so a received `omnisc.io/<code>` link opens in the in-app floating viewer — on the canonical `shares.omniscio.com/s/<code>` page, never `omnisc.io` — and is background-warmed for an instant open, exactly like a full `/s/<token>` link. Short links minted before this column still open in-app but aren't inbox-preloaded or shown with the owner's label (their code wasn't saved and isn't locally recoverable).

### Behaviour with in-app shares

When `sharesOpenInApp` is on, a share link opens in the in-app floating viewer instead of the browser. The viewer builds the canonical `shares.omniscio.com/s/<…>` URL from the link's validated token OR short code — never the raw href, and never `omnisc.io` (a redirect alias that is deliberately never loaded in the webview). The custom slug / short-link variants resolve through the same `serveShare` path — a slug or short code is just a claimable alias into the one share-index, not a parallel system. A short link is also background-warmed (and inbox-preloaded when it is your own share), so it opens instantly like a long `/s/<token>` link.

## For agents

### Agents (AMC-spawned sessions)

AMC-spawned agents publish shares over the CLI (`POST /share/publish`, `shortLink: true` → `data.shortUrl`). They are TOLD about the short-link option **only when the signed-in account is entitled** (`custom_share_url`, any paid tier) — the short-link guidance is a distinct system-prompt fragment (`SHARE_SHORTLINK_SHIM`) added to the engine prompt bundle right after the publish shim, gated on `EnginePromptContext.canMintShortLink`.

- **User toggle (default ON).** `canMintShortLink` is computed at spawn by `agentShortLinkEnabled(settings)` = **paid entitlement AND the user's `agentShortLinkDefault` setting** (Settings → Sharing → "Default to short share links"). Default ON, so paid accounts get it out of the box; turning it OFF stops agents defaulting to short links even on a paid plan. It does NOT affect the user's own in-app publish (that stays governed by the publish modal / `customShareUrlEnabled`). Free accounts are unaffected — the toggle is inert, since the relay still requires a paid tier.
- **Entitlement is resolved at spawn**, synchronously and fail-closed, via `currentUserCanUseCustomShareUrl()` (cached auth tier + the `can(…, 'custom_share_url')` policy). A free / signed-out / unresolved-tier account gets NO short-link guidance and the base publish shim stays byte-identical.
- **Not the operator bypass.** The check deliberately does NOT use `can(null) === true`; a machine owner with no cloud sign-in cannot mint a slug (the relay needs a real paid token), so advertising it would be a false promise.
- **Relay stays authoritative.** The shim only decides whether the agent is *told*; a stale local entitlement still falls back to the token URL because the relay enforces the real tier, and the shim tells the agent to use `data.publicUrl` when no `data.shortUrl` returns.
- **Scope.** Only the short link is advertised to agents; `customSlug` (a memorable custom *name*) is intentionally not — agents should not auto-invent globally-claimed names.

## Related

Which kinds of share go through the pipeline this page describes — session and message shares, file and pasted-content artifacts, and agent publishes over the command line — is on the [artifact sharing](artifact-sharing.md), [share artifacts](share-artifacts.md) and [share CLI](share-cli.md) pages respectively. If a link of yours is not opening where you expect, the [shares view](shares-view.md) covers the in-app list and viewer that a received link is resolved into.
