# Build links and channel links

> Share one build with a build link, or the newest build of a channel with a channel link, and choose who can open each one.

Canonical: https://docs.extension.dev/share/build-and-channel-links
This page as Markdown: https://docs.extension.dev/share/build-and-channel-links.md
Section: Share and preview
Siblings: [Share an unpublished extension build for review](https://docs.extension.dev/share/unpublished-build-for-review.md) · [Manage shares](https://docs.extension.dev/share/manage-shares.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

---

# Build links and channel links

extension.dev gives you two links to share an extension. A build link opens
one build. A channel link opens the newest build of a channel. Read this page
when you send a build to someone and need to know which link to send, who can
open it, and how long it works.

## Quick start

Start the [MCP server](/tools/mcp) with `--features=local,platform`, log in,
and ask the agent:

```
Publish my latest build and give me the link to send
```

The agent calls [`extension_publish`](/tools/mcp/publish). The answer carries
`link`, the link to send, and `tellThem`, one sentence to send with it.


## How it works

### Public and private projects

A project is public or private. Visibility is a setting of the extension.dev
project, not of its GitHub repository. A workspace owner or admin changes it
under **Visibility** in project settings. See
[Public project pages](/share/public-pages).

### Build links

A build link opens the page of one build:

```
https://<workspace>.extension.dev/<project>/builds/<sha>
```

It always shows that one build, even after newer builds land. On a public
project the link has no token and no end date.

On a private project the link carries a signed `?share=` token. The token
lasts 7 days by default. You can ask for more, up to your plan's share
window: 30 days on Free and 365 days on Pro. After that, the link stops
working. Publish again to get a new one.

### Channel links

A channel link opens a channel:

```
https://<workspace>.extension.dev/<project>/channels/<channel>
```

It always opens the newest build on that channel, and it never expires. Send
it when testers should get every update without a new link. A channel link
exists on a public project. It also exists on a public channel of a private
project.

### Channel audience

Every channel has an audience, public or private. On a public project, every
channel is public. On a private project, a new channel is private unless you
ask for public when you create it.

Only a workspace owner or admin, signed in, can make a channel public. They
choose it when they create the channel, or later on the **Releases** page. A
project token, which is what the agent uses, can create a private channel
only. Changing the project's visibility sets every channel's audience to
match.

A public channel shows its page, the build it serves now, and every build it
served before. It never shows a build that no public channel served. Build
logs stay private in every case. Nothing recalls a file someone already
downloaded.

### The live channel

The project's landing page, `https://<workspace>.extension.dev/<project>`,
opens the live channel. Choose it under **Opens on** in the project's
**General** settings. **Automatic** chooses the first channel the project has,
in this order: production, stable, latest, release, development, preview.

### Share links open only what they name

Publishing a build of a private project gives a link that opens that one
build and nothing else in the project. A link that opens the whole project is
for members of the workspace, not for testers.

Named tester lists are not available yet. Send a build link or a channel link.

### What the agent answers

On a private project, `extension_publish` answers a build link:

```json
{
  "link": {
    "kind": "build",
    "url": "https://acme.extension.dev/notes/builds/a1b2c3d4e5f6?share=…",
    "expiresAt": "2026-10-09T12:00:00.000Z",
    "pointsAt": "this build",
    "audience": "anyone with the link"
  },
  "tellThem": "Here is the build link for version 1.2.0. Anyone who has it can open it until October 9, 2026 at 12:00 UTC, and it always shows this build."
}
```

On a public project whose build a channel serves, it answers the channel
link, with `"pointsAt": "latest in stable"` and the sentence "Here is the
channel link. It always opens the newest stable build."

Store submission is a separate path, and these links do not change it. See
[Publishing](/publish/overview).

## Reference

| Link | Opens | Token | Ends |
| --- | --- | --- | --- |
| Build link, public project | One build | None | Never |
| Build link, private project | One build | `?share=` | After 7 days by default, at most the plan's share window |
| Channel link | The channel's newest build | None | Never |

| `link` field | Meaning |
| --- | --- |
| `kind` | `build` or `channel` |
| `url` | The address to send |
| `expiresAt` | When the link stops working, as an ISO date, or `null` when it never does |
| `pointsAt` | `this build` for a build link, `latest in <channel>` for a channel link |
| `audience` | `public`, or `anyone with the link` for a private project's build link |

| Setting | Who changes it | HTTP call, signed in |
| --- | --- | --- |
| Project visibility | Workspace owner or admin | `PUT /api/projects/{id}/visibility` |
| Channel audience at creation | Workspace owner or admin for `public`, any member or project token for `private` | `POST /api/projects/{id}/channels` with `audience` set to `public` or `private`. Without it, the channel takes the project's visibility |
| Channel audience later | Workspace owner or admin | `PUT /api/projects/{id}/channels/{channel}/audience` with `audience` set to `public` or `private` |
| Live channel | Workspace owner or admin | `PATCH /api/projects/{id}/settings/general` with `liveChannel` set to a channel name, or `null` for Automatic |

| Plan | Default build link life | Longest build link life |
| --- | --- | --- |
| Free | 7 days | 30 days |
| Pro | 7 days | 365 days |

## When it fails

- **A tester's build link stopped working**: the token reached its end date. Publish again for a new link, or send a channel link, which never expires.
- **The link shows an older build than you expected**: a build link always shows one build. Send the channel link to follow the newest build.
- **A private project has no channel link**: none of its channels is public. A workspace owner or admin makes one channel public, or makes the project public.
- **Changing or creating a channel answers `400` with `PROJECT_IS_PUBLIC`**: on a public project, every channel is public. Make the project private first.
- **Creating a public channel answers `403` with `TOKEN_CANNOT_OPEN_CHANNEL`**: a project token cannot open a channel on a private project. Create it private, then a workspace owner or admin makes it public on the **Releases** page.
- **Changing a channel's audience answers `403` with `TOKEN_CANNOT_CHANGE_AUDIENCE`**: a project token cannot change who can download a channel. Sign in to extension.dev as a workspace owner or admin.
- **The link ends sooner than you asked**: the platform cut the request to your plan's share window. Read `expiresAt` for the date it set.
- **The landing page opens the wrong channel**: choose the channel under **Opens on** in General settings.

## Next

- [Share an unpublished build for review](/share/unpublished-build-for-review) to send a build before it lands on a channel
- [Public project pages](/share/public-pages) for what a public project shows
- [Releases](/builds/releases) for how a build reaches a channel
- [Publishing](/publish/overview) for the store path
