> ## 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"}'
```
