Share and Version Pipelines Across a Team#
This guide shows how to fork, diff, share, and import pipelines through the web API — the collaboration primitives for working across users and teams.
Overview#
| Operation | Description | Endpoint |
|---|---|---|
| Fork | Copy a pipeline to your workspace | POST /api/pipelines/{id}/fork |
| Diff | Compare two pipelines | POST /api/pipelines/diff |
| Share | Create a shareable link | POST /api/pipelines/{id}/share |
| Import | Import from share link | POST /api/pipelines/import |
Fork#
Create an independent copy of a pipeline in your workspace. The fork is a full copy — changes to the original do not affect the fork, and vice versa.
# API — ownership comes from your session, so no user id is sent
curl -X POST http://localhost:8080/api/pipelines/pipeline-abc/fork
# Response
{
"forked_id": "pipeline-def",
"name": "my-analysis (fork)"
}
Forks record their lineage — the forked_from field tracks the source pipeline.
Diff#
Compare two pipelines and see what changed:
curl -X POST http://localhost:8080/api/pipelines/diff \
-H "Content-Type: application/json" \
-d '{"toml_a": "<workflow-a TOML>", "toml_b": "<workflow-b TOML>"}'
# Response
{
"diffs": [
{
"path": "rules",
"category": "rules",
"description": "rule \"align\": shell command changed",
"severity": "info"
}
]
}
Share#
Create a shareable link for a pipeline:
curl -X POST http://localhost:8080/api/pipelines/pipeline-abc/share \
-H "Content-Type: application/json" \
-d '{"visibility": "link", "expires_in_days": 30}'
# Response
{
"share_url": "oxo+https://lab.example.com:8080/share/abc123",
"access_token": "abc123",
"expires_at": "2024-02-12T00:00:00+00:00"
}
Visibility levels (link / public — public is an alias of link)
are stored on the share record; other values (e.g. workspace) are
rejected with UNSUPPORTED_VISIBILITY.
The share URL opens a public read-only landing page (see
Share Landing Pages below); programmatic consumption
goes through the import API below.
Import#
Import a pipeline from an oxo+https:// share link (oxo+http:// is
accepted too — the token, not the scheme, is what the import validates):
curl -X POST http://localhost:8080/api/pipelines/import \
-H "Content-Type: application/json" \
-d '{"url": "oxo+https://lab.example.com:8080/share/abc123"}'
# Response
{
"pipeline_id": "pipeline-xyz"
}
The oxo+https:// protocol prefix makes share links explicit and unambiguous —
you can paste them into any tool and the intent is clear.
Import behavior:
- Creates a full copy of the shared pipeline
- Records the source via
forked_from - Sets visibility to
privateby default - Checks share expiration before allowing import
Permissions Model#
A simple three-state visibility model:
| Level | Access |
|---|---|
| Private | Only the owner can view/edit (the default for imported pipelines) |
Shared (link / workspace) |
Read-only access via share/import |
| Admin | Can view all, manage users |
No nested RBAC. No group hierarchies. Simple and transparent.
Share Landing Pages#
A share link (oxo+https://host:port/share/<token>) opens a public
read-only landing page — pipeline name/version, DAG shape, the full TOML,
the owner, expiry, and the most recent terminal run as provenance. No
session is required to view it (the token is the authorization). The
Import into my workspace action copies the pipeline to the acting user's
account (login required — the API enforces it).
Visibility is now enforced server-side: private pipelines are
owner/admin-only, workspace pipelines are readable (not writable) by
every authenticated user, link pipelines are reachable only through
their share token.
Version History#
Every save/update snapshots the previous pipeline content (up to 50 revisions). In the editor's History tab you can load any snapshot into the editor or roll back — rollback preserves the current version as a new revision, so nothing is ever lost.
Audit Trail#
Every state-changing API call (fork, share, import, run, …) is recorded by
the audit middleware — any non-GET request lands in audit_logs with the
acting user, method+path, and result. View audit logs via
GET /api/audit?days=7.