# Manage shares

> List every preview link you have minted, reconcile the local record with the platform, and revoke a link for good.

Canonical: https://docs.extension.dev/share/manage-shares
This page as Markdown: https://docs.extension.dev/share/manage-shares.md
Section: Share and preview
Siblings: [Build links and channel links](https://docs.extension.dev/share/build-and-channel-links.md) · [Share an unpublished extension build for review](https://docs.extension.dev/share/unpublished-build-for-review.md) · [Public project pages](https://docs.extension.dev/share/public-pages.md)
Map of every page: https://docs.extension.dev/llms.txt · Whole corpus: https://docs.extension.dev/llms-full.txt

---

# Manage shares

Share management is the lifecycle of a preview link after you mint it: the
list of links that are alive, the record each project keeps, and the revoke
that kills one. Reach for it when a link you sent needs to die, or when you
need to know which links still resolve.

## Quick start

Ask the agent, with the [MCP server](/tools/mcp) configured:

```
Revoke the preview link https://preview.extension.dev/?preview=gen_...
```

The agent calls `extension_shares` with `action: "revoke"`. The link stops
resolving for everyone, the stored build is deleted, and re-sharing the same
build mints a different address.


## How it works

Every share minted from a project is added to
`.extension.dev/shared-previews.json` inside that project. The file exists
because the `revokeUrl` is the only handle that pulls a link back, and losing
a chat transcript should not mean losing the ability to revoke. Rows are only
ever added. When the old file cannot be read, it is renamed beside the new
one instead of being replaced. The tool adds `.extension.dev/` to the
project's `.gitignore`, and tells you to add it yourself when it cannot.

`extension_shares` lists every share the token can see, live and dead, with
each `previewUrl`, `zipUrl`, `revokeUrl`, `createdAt`, `expiresAt` and
`revokedAt`. A revoked link is still listed, which is what makes "why does
this link not work" answerable. Its `previewUrl` and `zipUrl` come back
`null`, because neither resolves for anyone any more, and `revokeUrl` stays
on every row. An expired row disappears once the sweep deletes it.

Shares come in three groups. A project share is owned by a project, and any
token scoped to that project may revoke it. A personal share is owned by one
person, and only that person may revoke it. An unknown share is visible to
the token but attributable to neither.

Pass `projectPath` and the listing reconciles the platform's answer with the
project's own record. A `remoteOnly` row is a live link this checkout never
minted, shared from another machine or another checkout. A `localOnly` row
is recorded here with nothing behind it on the platform. A `localOnly` row
is not proof that the link is dead: read its status line, never the group.

The console lists a project's shares in the **Share links** section of its
project settings, at
`console.extension.dev/<workspace>/<project>/project-settings/share-links`.
That list holds the shares the project owns. A personal share names no
project and is not listed there. The old
[/shares](https://console.extension.dev/shares) address only redirects to the
workspace home.

Revoke by `artifactId` or by any URL of the share: the `previewUrl`, the
`zipUrl`, the `viewUrl` or the `revokeUrl`. The link you sent someone is
enough. Equivalently, `DELETE` the `revokeUrl` with the same token, or press
**Revoke** on the row in the console and confirm with **Revoke permanently**.

::: warning
Revocation burns the link. The id is never recycled, the link cannot be
restored or pointed at a different build, and re-sharing mints a new address.
Revocation limits future access. It does not recall copies already
downloaded, so treat any build that shipped in a link as disclosed.
:::

## Reference

| `extension_shares` input | Values |
| --- | --- |
| `action` | `list` (default) or `revoke` |
| `artifactId` | The share id, `gen_` followed by 64 lowercase hex characters |
| `url` | Any URL of the share, for `revoke` |
| `projectPath` | Reconcile the listing with that project's record |
| `status` | `all` (default) or `live` |
| `limit` | 1 to 200, platform default 100 |

| Group | Who may revoke |
| --- | --- |
| Project | Any token scoped to the owning project |
| Personal | Only the person who minted it |
| Unknown | Cannot be stated |

| A `localOnly` status line starts with | What it means |
| --- | --- |
| `unknown` | The platform's list was cut short, or it did not say whether the list was whole. The share may sit past the window that came back |
| `expired` | Its own `expiresAt` has passed and the platform no longer lists it |
| `not in this live-only listing` | You asked for live shares only. Rerun with `status: "all"` to tell revoked from gone |
| `not owned by this token` | Expired and swept, revoked long ago, or shared while logged in to a different project |

## When it fails

- **The link you want dead is in no listing**: it was minted by a token you do not hold. Find the checkout that shared it and read its `shared-previews.json`.
- **Revoke refuses on a personal share**: only the person who minted it may revoke it. Project shares are the ones any project token can kill.
- **Revoke answers `403` with a share link token**: a `?share=` token can read a project but cannot revoke its shares. Use a project token.
- **The listing shows `localOnly` for a link someone says still works**: read that row's status line. A status that starts with `unknown` settles nothing. Rerun with `status: "all"`, raise the `limit`, and open the link yourself.

## Next

- [Share an unpublished build for review](/share/unpublished-build-for-review) for minting the links this page manages
- [Access tokens](/tools/access-tokens) for what a token can see and revoke
