Admin S3 routes

S3/MinIO object storage admin: test the connection, upload raw image bytes, and delete objects.

Admin S3 routes

All /admin/s3/* routes require admin or owner. Object storage is backed by MinIO.

Test the connection

GEThttps://api.lunargroup.dev/admin/s3/testAuth required
Smoke test. Optionally checks whether a bucket exists.

With no body it confirms the route is wired. If the body contains bucketExists, the API calls MinIO bucketExists for that name.

Body (optional)
bucketExists
stringoptional
A bucket name to check for existence.

Request body (optional):

{ "bucketExists": "lunar-api" }

Response 200 (default):

{ "status": 200, "message": "S3 test endpoint is working!" }

Response 200 (with bucketExists provided):

{ "status": 200, "bucketExists": true }

Upload an image

POSThttps://api.lunargroup.dev/admin/s3/uploadAuth required
Upload raw image bytes to a bucket. Requires admin or owner.

The request body must be raw image bytes, and Content-Type must start with image/. The bucket and object name are passed as query params.

Query
bucketName
stringrequired
Target bucket, e.g. lunar-api.
objectName
stringrequired
Object key, e.g. fox/example.png.
POST /admin/s3/upload?bucketName=lunar-api&objectName=fox/example.png
Content-Type: image/png
Authorization: Bearer <token>

<binary image bytes>

Response 200:

{
  "status": 200,
  "message": "Image uploaded successfully",
  "bucketName": "lunar-api",
  "objectName": "fox/example.png",
  "etag": "etag-value",
  "versionId": "version-id"
}

Errors:

{ "status": 400, "message": "bucketName, objectName and path query params are required" }
{ "status": 400, "message": "Content-Type must be an image/* mime type" }
{ "status": 400, "message": "Request body must contain image bytes" }

Delete an object

DELETEhttps://api.lunargroup.dev/admin/s3/deleteAuth required
Delete an object by name (preferred) or by etag. Requires admin or owner.
Body
bucketName
stringrequired
The bucket to delete from.
objectName
stringoptional
Object key to delete. Preferred over etag.
etag
stringoptional
Delete by etag instead of object name.

Request (by object name):

{
  "bucketName": "lunar-api",
  "objectName": "fox/example.png"
}

Request (by etag):

{
  "bucketName": "lunar-api",
  "etag": "etag-value"
}

Response 200:

{
  "status": 200,
  "message": "Object deleted successfully",
  "bucketName": "lunar-api",
  "object": "fox/example.png"
}

Errors:

{ "status": 400, "message": "bucketName and either objectName or etag are required" }
{ "status": 500, "message": "Error deleting object" }