Skip to main content

Publishing & sharing

Once you've built something worth showing — a notebook, a dataset — you share it two ways: outward to anyone with a link or browsing the marketplace, and inward to your own organization. This page covers both.

note

This page combines outward publishing and inward collaboration. As each half grows it may split into separate Publishing and Collaborating pages. For now it's one walkthrough.

The Notebooks tutorial owns the publish loop — the part where a notebook is rendered into a shareable snapshot. This page picks up from there: Notebooks builds and renders → Publishing shares it with the world. We cross-link rather than repeat that step.

The permission model in one paragraph

Two access paths exist and they are separate by design. Interactive access — opening, re-running, and editing a notebook — keys off organization membership: if you're a member of the org that owns a resource, you can work with it live. Public link sharing is a separate grant on the resource itself (resource_permissions), and it is READ-only by design — a public link gives a static view, never edit or re-run. Granting any permission requires admin on the resource.

Publishing is two steps, and they live in two places.

Step 1 — render (owned by the Notebooks tutorial). publishNotebook renders a static HTML snapshot of the notebook to R2 storage. It requires admin on the notebook and produces a versioned published record. See the publish loop in Notebooks for how to trigger and monitor it.

Step 2 — make it public (here). Rendering does not make the snapshot reachable. To expose it, grant a public READ permission with grantResourcePermission:

mutation {
grantResourcePermission(
input: {
id: "<notebook-id>"
resourceType: NOTEBOOK
permissionLevel: READ
# no targetUserId, no targetOrgId, no targetUserEmail => public
}
) {
success
message
}
}

A grant with no targetUserId, targetOrgId, or targetUserEmail is a public link. Public links only accept READ (or NONE to revoke) — the backend rejects WRITE/ADMIN on a public grant with a clear error. This is the READ-only, static-view guarantee: a public viewer sees the rendered snapshot and cannot re-run or edit it.

To take the link down, grant NONE (revokes the permission) — or call unpublishNotebook to also delete the rendered snapshot from storage.

mutation {
grantResourcePermission(
input: {
id: "<notebook-id>"
resourceType: NOTEBOOK
permissionLevel: NONE
}
) {
success
message
}
}

Share a dataset on the marketplace

The quickest way to see the consumer side — subscribe to a dataset and query it — is in the app:

  • 0:00 — open the Marketplace and subscribe (here, OSS Directory).
  • 0:31 — preview the dataset to find its table names.
  • 0:44 — open Scratchpad and query a table with COUNT(*).
  • 1:06 — run further checks, then reuse the table name in notebooks.

The data marketplace is how orgs publish and consume each other's datasets. Three operations:

Browse. marketplaceDatasets(orgId, search, datasetType) lists public datasets owned by other orgs (it excludes your own). It's paginated and supports a text search across dataset and org names.

Subscribe / unsubscribe. subscribeToDataset(datasetId, orgId) grants your org READ access to a public dataset — it first checks the dataset actually has a public READ grant, then records the subscription. unsubscribeFromDataset reverses it.

mutation {
subscribeToDataset(input: { datasetId: "<id>", orgId: "<your-org>" }) {
success
}
}

Publish your own dataset. There is no single "publish to marketplace" call. You stitch two steps: createDataset to create it in your org, then a public grant to list it — the same public-READ grant used for notebooks, with resourceType: DATASET.

mutation {
createDataset(
input: {
orgId: "<your-org>"
name: "my_dataset"
displayName: "My Dataset"
type: USER_MODEL
}
) {
dataset {
id
}
success
}
}
# then, with the returned dataset id:
mutation {
grantResourcePermission(
input: { id: "<dataset-id>", resourceType: DATASET, permissionLevel: READ }
) {
success
}
}
Known gap

There is currently no end-to-end "publish to marketplace" skill or single mutation. The flow works — createDataset then a public grant — but you wire the two steps together yourself, and there's no guided UI path that does it for you end to end. Expect rough edges until this is consolidated.

One structural rule to know: a resource cannot be public-linked and organization-shared at the same time. If a dataset already has an org-wide grant, revoke it before enabling the public link, and vice versa — the backend enforces this and returns an explanatory error.

Share inward: organizations & membership

Membership is the unit of inward collaboration. A member of an org gets interactive access to that org's resources — open, re-run, edit — without any per-resource grant. That's why sharing with a teammate means adding them to the org.

Invite a teammate. createInvitation(orgId, email) creates an invitation and emails a join link. The recipient calls acceptInvitation(invitationId) to become a member.

mutation {
createInvitation(input: { orgId: "<org>", email: "[email protected]" }) {
success
}
}
Caveat: invites currently grant admin

Accepting an invitation currently creates the membership with the admin role — there is no member/viewer tier yet. Invite only people you're comfortable giving full control of the org's resources. Scope this deliberately until finer roles land.

Safe editing: don't break downstream viewers

Because interactive editing and public viewing are different paths, editing a notebook can quietly change what the public sees. Two behaviors to keep straight:

  • Saving creates a revision. updateNotebook writes a new notebook revision each time content changes, so history is preserved.
  • Saving can auto-republish. If the editor has admin on the notebook, a content save also re-runs the publish loop and bumps the published version. Whoever holds the public link sees the new snapshot on their next load.

So before you edit a published notebook, know whether it has a live public link. If you want to iterate without disturbing viewers, fork it (forkNotebook) into a working copy, change that, and republish deliberately when ready. To stop sharing entirely, revoke with a NONE grant or unpublishNotebook.

Where to go next

  • Notebooks — build and render the notebook you're publishing.
  • Querying OSO — the data those notebooks and datasets are built on.
  • Connect over MCP — drive all of these mutations from your own agent.