---
title: sherserve
description: The v1 reference for uploading and managing files.
---

# sherserve

Base path `/api/sherserve/v1`. See [API reference](/api) for
authentication and the `api.shebang.pro` rewrite.

Every route requires an `shb_...` key or bearer with `serve` in scope
(master keys always qualify). `project` behaves exactly as described in
[platform](/api/platform#projects). An object's access level, password,
expiry, and view budget live on its [sherlink](/api/sherlink) short link
— see [access modes](/concepts/access-modes).

The **Object** returned by metadata routes:

```json
{
  "id": "uuid",
  "public_id": "string",
  "url": "string",
  "shortUrl": "string | null",
  "slug": "string",
  "title": "string",
  "originalFilename": "string",
  "contentType": "string",
  "sizeBytes": "number",
  "access": "private | password | allow_list | public",
  "status": "active | archived",
  "expiresAt": "ISO 8601 | null",
  "maxViews": "number | null",
  "viewCount": "number",
  "createdAt": "ISO 8601",
  "updatedAt": "ISO 8601",
  "archivedAt": "ISO 8601 | null"
}
```

### GET /api/sherserve/v1/objects

Lists objects.

- **Auth** — `serve` scope.
- **Query params** — `status` (`"active"` or `"archived"`, defaults to
  `"active"`), `project` (slug, optional).
- **Response** — `200 { "objects": [Object, ...], "project": "slug" }`.
- **Errors** — `400 invalid status filter`, `403 insufficient_scope`.

### POST /api/sherserve/v1/objects

Uploads a file — creates the resource row, stores the bytes, and mints
its short link in one call. Rolls back everything already created if a
later step fails. Body is `multipart/form-data`, not JSON.

- **Auth** — `serve` scope, write access to the target project.
- **Request body** (form fields) — `file` (required, ≤ 500 MB), `title`
  (optional, defaults to the filename), `slug` (optional — derived from
  `title` if omitted, auto-suffixed on collision only when omitted),
  `access` (default `"private"`), `password` (required if `access` is
  `"password"`), `expiresAt` (ISO 8601, optional), `maxViews` (positive
  integer, optional), `alias` (optional), `allow` (repeated field and/or
  comma-separated, optional), `project` (slug, optional).
- **Response** — `201 { "object": Object, "url", "shortUrl", "project" }`.
- **Errors** — `400` (missing/invalid `file`, `title`, `slug`, `access`,
  `password`, `expiresAt`, `maxViews`, `alias`, `allow` entry, or a
  malformed multipart body), `400 password_required`, `409
  slug_conflict`, `409 alias_conflict`, `413 file too large`, `415`
  (unsupported file type — no extension or content type to infer one
  from), `403 insufficient_scope`, `500 public_id_exhausted`.

### GET /api/sherserve/v1/objects/{id}

Fetches one object.

- **Auth** — `serve` scope, read access to the object's project.
- **Path params** — `id` (uuid).
- **Response** — `200 Object`.
- **Errors** — `404 not_found`, `403 insufficient_scope`.

### GET /api/sherserve/v1/objects/{id}/content

Downloads an owner's original file bytes. Uses the same bearer credentials
as metadata, including for private objects. Visitor link passwords, expiry,
archive status, and view budgets do not restrict this owner operation.

- **Auth** — `serve` scope, object ownership, read access to its project.
- **Path params** — `id` (uuid).
- **Response** — `200` streamed file bytes with the stored content type,
  an attachment filename, and `Cache-Control: private, no-store`.
  Always returns the complete original file; ranges and image transforms
  are not applied.
- **Errors** — `401` (invalid credentials), `403 insufficient_scope`,
  `404 not_found` (invalid ID, wrong owner, or missing row/bytes),
  `500 internal_error` (storage unavailable).

### PATCH /api/sherserve/v1/objects/{id}

Updates an object's content fields and/or its link's policy fields. The
row commits first; if the link update then fails, the row is reverted.

- **Auth** — `serve` scope, write access to the object's project.
- **Path params** — `id` (uuid).
- **Request body** — any of `title`, `slug`, `access`, `password`
  (string or `null`), `expiresAt` (string or `null`), `maxViews` (number
  or `null`), `alias` (string or `null`), `status` (`"active"` or
  `"archived"`) — all optional.
- **Response** — `200 Object`.
- **Errors** — `400` (invalid field value), `404 not_found`, `409
  slug_taken`, `409 alias_conflict`, `400 password_required`, `403
  insufficient_scope`.

### DELETE /api/sherserve/v1/objects/{id}

Deletes an object — its stored bytes, its short link, then the row.

- **Auth** — `serve` scope, write access to the object's project.
- **Path params** — `id` (uuid).
- **Response** — `204` (empty body).
- **Errors** — `404 not_found`, `403 insufficient_scope`, `500
  storage_cleanup_failed`, `500 link_cleanup_failed`.

## Next

[sherlink](/api/sherlink) — short links and access.
