Skip to content

Media

Media management endpoints. Handles file uploads and management. Uploaded files are served as static files.

Base path: /api/v1/media


List Media

GET /api/v1/media

Required permission: media:read

Query parameters

Parameter Type Default Description
skip int 0 Pagination offset
limit int 100 Pagination limit

Response 200 OK

[
  {
    "id": "uuid",
    "filename": "550e8400-e29b-41d4-a716-446655440000.jpg",
    "original_filename": "my-photo.jpg",
    "mime_type": "image/jpeg",
    "size": 204800,
    "path": "uploads/media/550e8400-e29b-41d4-a716-446655440000.jpg",
    "alt_text": null
  }
]


List Images

Returns only image files (image/* mime types).

GET /api/v1/media/images

Required permission: media:read

Query parameters

Parameter Type Default Description
skip int 0 Pagination offset
limit int 100 Pagination limit

Response 200 OK — list of MediaSummary objects.


Upload File

Uploads a file to the server.

POST /api/v1/media/upload

Required permission: media:upload

Requestmultipart/form-data

Field Type Required Description
file file File to upload

Allowed mime types

Type Extensions
image/jpeg .jpg, .jpeg
image/png .png
image/gif .gif
image/webp .webp
image/svg+xml .svg
application/pdf .pdf
video/mp4 .mp4
video/webm .webm

File size limit

Maximum file size is 10MB. Requests exceeding this limit will be rejected.

Response 201 Created

{
  "id": "uuid",
  "filename": "550e8400-e29b-41d4-a716-446655440000.jpg",
  "original_filename": "my-photo.jpg",
  "mime_type": "image/jpeg",
  "size": 204800,
  "path": "uploads/media/550e8400-e29b-41d4-a716-446655440000.jpg",
  "alt_text": null,
  "uploaded_by": "uuid",
  "created_at": "2026-01-01T00:00:00Z",
  "updated_at": null
}

Filename

The original filename is preserved in original_filename. A unique UUID-based filename is generated and stored in filename to avoid collisions.

Errors

Status Description
400 File type not allowed
400 File size exceeds 10MB limit

Get Media

GET /api/v1/media/{id}

Required permission: media:read

Response 200 OK

{
  "id": "uuid",
  "filename": "550e8400-e29b-41d4-a716-446655440000.jpg",
  "original_filename": "my-photo.jpg",
  "mime_type": "image/jpeg",
  "size": 204800,
  "path": "uploads/media/550e8400-e29b-41d4-a716-446655440000.jpg",
  "alt_text": "A beautiful sunset over the mountains",
  "uploaded_by": "uuid",
  "created_at": "2026-01-01T00:00:00Z",
  "updated_at": "2026-01-01T01:00:00Z"
}

Errors

Status Description
404 Media not found

Update Media

Updates media metadata. Currently only alt_text can be updated.

PATCH /api/v1/media/{id}

Required permission: media:upload

Request body

{
  "alt_text": "A beautiful sunset over the mountains"
}

Field Type Required Constraints
alt_text string Max 255 characters

Response 200 OK — updated MediaResponse object.

Errors

Status Description
404 Media not found

Delete Media

Soft-deletes a media record and removes the physical file from the server.

DELETE /api/v1/media/{id}

Required permission: media:delete

Response 204 No Content

Errors

Status Description
404 Media not found

Warning

Deleting a media file that is referenced by a post, page, or gallery as a featured image will not automatically remove those references. Handle with care.


Accessing Files

Uploaded files are served as static files and publicly accessible without authentication.

GET /uploads/media/{filename}

Example

GET /uploads/media/550e8400-e29b-41d4-a716-446655440000.jpg

To construct the full URL for an uploaded file, combine the API base URL with the path field:

const fileUrl = `${API_BASE_URL}/${media.path}`;
// http://localhost:8100/uploads/media/550e8400-e29b-41d4-a716-446655440000.jpg