# Overview

Upload files, store them public or private, and read back their URLs and dimensions.

Assets are stored files — images embedded in [content](/content/overview),
downloads, attachments. Upload is multipart, and whether the object is publicly
readable is decided at upload time.

```bash
curl -X POST https://api.console.buildbase.app/api/assets \
  -H "Authorization: $BUILDBASE_TOKEN" \
  -F "file=@diagram.png" \
  -F "public=true"
```

> **Note:**
  Send the file under the field name `file`, one per request. `public` is read
  as the **string** `"true"` — a JSON boolean in a multipart form will not
  register, and the asset lands private.


## Limits

| Constraint        | Value                   |
| ----------------- | ----------------------- |
| Maximum file size | **5 MB**                |
| Files per request | 1                       |
| Accepted types    | Any — no MIME allowlist |

A file over 5 MB is rejected by the upload middleware before the handler runs.

## What is stored

| Field        | Contents                                       |
| ------------ | ---------------------------------------------- |
| `name`       | The original filename                          |
| `uniqueName` | The generated storage name                     |
| `mimeType`   | Detected content type                          |
| `size`       | Bytes                                          |
| `encoding`   | Transfer encoding                              |
| `bucket`     | `{ name, url, path }` — where the object lives |
| `public`     | Whether the object URL is publicly readable    |
| `image`      | `{ width, height }`                            |
| `metadata`   | Empty object, reserved                         |
| `creator`    | The uploading user                             |

`image` dimensions are read from the file for `image/*` uploads only. For any
other type both values stay `0` — a `0 × 0` asset is a non-image, not a failed
upload.

> **Note:**
  **Files are stored as uploaded.** There is no resizing, format conversion, or
  thumbnail generation, and the URL is a plain object-storage URL with no
  transform parameters. Requesting a smaller version by appending query
  parameters does nothing.

If you need responsive images, generate the variants before uploading and
store them as separate assets.



## Public and private

Visibility is set at upload and can be changed afterwards:

| Method  | Path                      | Effect                            |
| ------- | ------------------------- | --------------------------------- |
| `PATCH` | `/api/assets/:id/public`  | Make the object publicly readable |
| `PATCH` | `/api/assets/:id/private` | Restrict it again                 |

The two states write to different storage paths, so the URL changes when
visibility changes. **Anything already referencing the old URL breaks** — update
the references, or decide visibility before you publish the link.

Public means public: the object URL is unguessable but unauthenticated. Do not
use it for anything you would gate behind a permission.

## Reading

| Method | Path              | Purpose                |
| ------ | ----------------- | ---------------------- |
| `GET`  | `/api/assets`     | List assets, paginated |
| `GET`  | `/api/assets/:id` | One asset              |

Filter with the standard parameters — by MIME type, for example:

```bash
curl -G https://api.console.buildbase.app/api/assets \
  -H "Authorization: $BUILDBASE_TOKEN" \
  --data-urlencode 'filter={"public":true}' \
  --data-urlencode 'sort={"createdAt":-1}'
```

## Using an asset in content

Content stores the asset's URL, not the asset record. The two are linked only by
that reference, so deleting an asset leaves a broken link in any post embedding
it — nothing checks for inbound references first.

Check usage before deleting, or prefer making an asset private over removing it.

## Next Steps

- [Content](/content/overview) — where assets get embedded.
- [Admin API](/reference/admin-api) — tokens and list-query parameters.
