# Nightcord Storage

> Version **2.0.0** · API index for agents and humans

Object storage proxy with SEKAI v2 resource facade. Legacy upload paths remain; new clients should prefer /v2/upload and typed resolve URLs.

## Hosts

| Role | URL |
|------|-----|
| Storage (upload + legacy) | `https://storage.nightcord.de5.net` |
| R2 facade (public media) | `https://r2.nightcord.de5.net` |

Both hosts hit this Worker when bound. Prefer the media host for public SEKAI GETs; uploads may use either host.

## SEKAI v2 (prefer this)

### Upload

```http
PUT /v2/upload
X-Filename: <percent-encoded filename>
Content-Type: <mime>
Content-Length: <bytes>
X-Sekai-Kind: image | file | sticker   # optional
X-Image-Width: <int>                 # optional
X-Image-Height: <int>                # optional

<raw file bytes>
```

**Response fields:** `uuid`, `key` (=uuid), `type`, `size` (kB), `size_bytes`, `name`, `kind`, `url`, optional `w`/`h`.

**Example:**

```bash
curl -X PUT https://r2.nightcord.de5.net/v2/upload -H "X-Filename: photo.jpg" -H "Content-Type: image/jpeg" --data-binary @photo.jpg
```

### Resolve

- `GET|HEAD /images/{uuid}`
- `GET|HEAD /files/{uuid}`
- `GET|HEAD /stickers/{uuid}`
- `GET /v2/meta/{uuid}` — JSON metadata written at upload time (best-effort).

- UUID is a standard UUID v4 string.
- Objects are stored under AttachFiles/sekai/{uuid}{ext} on OSS.
- Public Cache-Control: immutable (long TTL) for successful GETs.

### SEKAI message payload examples

```text
<$SEKAI:Image:w=…;h=…;name=…:{uuid}>
<$SEKAI:Files:type=…;size=…;name=…:{uuid}>
<$SEKAI:Stamp:custom=true:{uuid}>
```

## Legacy (still supported)

- `PUT /` → `{ key, url, size }` where `key` is `{uid}/{fileUuid}.ext`
- `GET|HEAD|DELETE /{key}`
- Chunked: `/chunked/…`

Use for older clients and historical messages. New Nightcord builds use v2.

## Caching

Public media (images/files/stickers, legacy keys). Exclude / and /v2/* from cache eligibility.

See: Cloudflare Cache Rules on storage.* and r2.*

## Alternate formats

| Format | How |
|--------|-----|
| HTML (default) | `https://r2.nightcord.de5.net/` |
| JSON | `https://r2.nightcord.de5.net/?format=json` or `Accept: application/json` |
| Markdown | `https://r2.nightcord.de5.net/?format=md` or `Accept: text/markdown` |

Markdown responses use `Content-Type: text/markdown` and `x-markdown-tokens`.

---

*Nightcord storage worker · SEKAI resource facade · same Worker on `storage.*` and `r2.*`*
