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
GET
https://api.lunargroup.dev/admin/s3/testAuth requiredSmoke 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)
bucketExistsstringoptional
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
POST
https://api.lunargroup.dev/admin/s3/uploadAuth requiredUpload 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
bucketNamestringrequired
Target bucket, e.g.
lunar-api.objectNamestringrequired
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
DELETE
https://api.lunargroup.dev/admin/s3/deleteAuth requiredDelete an object by name (preferred) or by etag. Requires admin or owner.
Body
bucketNamestringrequired
The bucket to delete from.
objectNamestringoptional
Object key to delete. Preferred over
etag.etagstringoptional
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" }