> ## Documentation Index
> Fetch the complete documentation index at: https://docs.artifacta.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Publish Artifact

> Publish an artifact as a public shareable page.

## `POST /v1/artifacts/{id}/publish`

Publishes an artifact as a page at `https://artifacta.io/a/{slug}`. The slug is minted on the first publish and stays stable across re-publishes. Calling this endpoint again on the same artifact upserts the existing page and keeps the same URL — it is safe to call repeatedly.

Publishing is a lifecycle transition and does not increment the monthly request counter.

## Authentication

Requires a Bearer token. See [Authentication](/authentication).

## Path parameters

| Parameter | Type | Description |
| - | - | - |
| `id` | string | Artifact ID (`art_...`) |

## Request body

```json theme={null}
{
  "visibility": "unlisted",
  "access": "none",
  "title": "Q2 Report"
}
```

| Field | Type | Required | Description |
| - | - | - | - |
| `visibility` | string | Yes | `"unlisted"` — accessible by URL only. `"public"` — discoverable. |
| `access` | string | No | `"none"` (default) — open. `"password"` — password-protected (Pro plan). |
| `title` | string | No | Page title shown in the viewer header. |
| `password` | string | Conditional | Required when `access="password"`. Argon2id-hashed server-side. Pro plan only. Not available for HTML content types. |

## Response

```json theme={null}
{
  "page_id": "pg_aB3xK9mP1qR5sT2u",
  "public_url": "https://artifacta.io/a/pg_aB3xK9mP1qR5sT2u",
  "visibility": "unlisted",
  "access": "none"
}
```

| Field | Type | Description |
| - | - | - |
| `page_id` | string | Page slug (`pg_...`). Stable across re-publishes. |
| `public_url` | string | Full viewer URL. Anyone with this URL can view the artifact. |
| `visibility` | string | Echo of the requested visibility. |
| `access` | string | Echo of the requested access mode. |

## Error codes

| Code | Status | When |
| - | - | - |
| `artifact_not_found` | 404 | Artifact ID does not exist or belongs to another tenant. |
| `artifact_already_deleted` | 410 | Artifact has been soft-deleted. |
| `artifact_expired` | 410 | Artifact has passed its TTL. |
| `quota_exceeded` | 403 | `access="password"` on a Free-tier account, or monthly request quota reached. |
| `invalid_request` | 400 | Missing `visibility`, invalid field value, or `access="password"` for HTML content type. |

## Notes

* **HTML and passwords**: `access="password"` is rejected for `text/html` or `application/xhtml+xml` artifacts — there is no safe gated render path for HTML in the current viewer.
* **Re-publish**: Calling publish again on the same artifact updates the page title, visibility, and access, keeping the existing `page_id` and URL.
* **`page` field on artifacts**: After a successful publish, `GET /v1/artifacts/{id}` returns a `page` sub-object on the artifact — see [the artifact response page field](/api/overview#the-page-field-on-artifact-responses).

## Example

```bash theme={null}
curl -X POST https://api.artifacta.io/v1/artifacts/art_abc123/publish \
  -H "Authorization: Bearer ak_live_..." \
  -H "Content-Type: application/json" \
  -d '{"visibility": "unlisted", "title": "Q2 Analysis"}'
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.