---
title: "Set a file public or private"
method: PUT
path: "/v1/files/{uuid}/visibility"
tags: ["Files"]
---

# Set a file public or private

`PUT /v1/files/{uuid}/visibility`

## Request

- Base URL: `https://contentmaschine.ai/api`
- URL: `https://contentmaschine.ai/api/v1/files/{uuid}/visibility`
- Auth: one of:
  - HTTP bearer
  - OAuth 2 (authorization code, authorization URL `https://contentmaschine.ai/api/oauth/authorize`, token URL `https://contentmaschine.ai/api/oauth/token`)

An idempotent SET, not a toggle. `public` is REQUIRED and must be a real JSON
boolean: a missing key, the string "yes", the integer 1 and null are all 400s. An
idempotent set has no defensible default, and guessing one is how a caller publishes
a file it did not mean to publish.

Repeating the call is safe: `changed` reports whether this call was an actual
transition, and side effects (the social preview image, the `made_public_at` stamp)
run only on a real transition.

**Setting a file public publishes it at a permanent, unauthenticated URL** - see
GET /v1/files/{uuid}/share.

**Setting a file private is NOT an access control, and must not be described as one.**
It removes the public file page. It does NOT revoke access to the bytes: the legacy
`GET /api/files/serve/{uuid}` and `GET /api/files/thumbnail/{uuid}?original=true`
routes serve the same bytes to a caller with NO credentials at all, by deliberate
design - those routes exist so browser <img> tags can load without credentials, and
they treat the uuid itself as the capability. Anyone who kept the uuid keeps the
bytes. Nothing already fetched or cached is retroactively unpublished either. Treat
a file uuid you have ever made public as public forever.

## Path parameters

- `uuid` string, uuid, required

## Request body

- object
  - `public` boolean, required: true publishes the file, false unpublishes the page. Must be a real boolean.

## Response `200`

The resulting state.

- object
  - `success` boolean
  - `data` object
    - `file_uuid` string, uuid
    - `public` boolean: The state after this call.
    - `made_public_at` string, date-time, nullable: Stamped on the FIRST transition to public only, so a repeat call leaves it unchanged.
    - `changed` boolean: false when the file was already in the requested state.
  - `timestamp` string, date-time

## Other responses

- `400`: `public` missing, or not a real boolean.
- `401`: Missing or invalid API key.
- `404`: Unknown file, or not yours.
- `default`: Any other error. Every failure this API emits uses the same envelope; branch on `error.type`, never on `error.message`, and quote `error.correlation_id` to support.

---

[API](https://skmtc.dev/contentmaschine/apis/contentmaschine-ai-api.md) · [All operations](https://skmtc.dev/contentmaschine/apis/contentmaschine-ai-api/llms.txt) · [OpenAPI document](https://skmtc.dev/contentmaschine/apis/contentmaschine-ai-api/revisions/28c74f46051c?raw)
