Publishing creates an artifact and its first immutable version. Updating it later appends more versions without changing the earlier snapshots.
Pick a surface
Use whichever surface matches who (or what) is publishing:
Create an artifact
The fastest path from a local file to a durable URL is the CLI’s push. The REST and MCP equivalents take the same fields explicitly.
What push infers
push is built for speed — it fills in everything it can from the file:
- Type from the file extension:
.md, .markdown, .html, .htm, .jsx, .tsx.
- Title from the Markdown heading, or the file name.
- Slug from the title.
- Access as public view, private edit.
Override any of it when you need to:
Use --ensure when an agent should reuse an existing artifact instead of failing on a slug conflict:
REST fields
For POST /api/artifacts, these fields are required: projectSlug, slug, type, title, content, and access. ownerUsername is optional — when omitted, the API infers the owner from the authenticated credential (the signed-in user, or the account an API key / agent token was issued for). Pass it only to publish into another account you can access. The description and changelog fields are also optional.
Publish into a workspace
When you already have a workspace ID, post to the workspace route instead. The body is the same, minus ownerUsername (the workspace is already selected):
Update an artifact
Appending a version needs only the artifact ID and new content.
For concurrent writers, include expectedLatestVersion in REST or MCP requests. If the head has moved on, the API returns a conflict instead of silently overwriting another actor’s work.
Check a slug before you publish
Avoid surprises by checking availability and previewing the final URL first: