This is a simple image upload and management API designed to provide secure and efficient file storage for various prototype applications being built by Raymmar Tirado.
It's a sandbox API for uploading images and passing back a hosted URL to make media management simpler for different projects. You can clone this code, or copy the repl to implement this in your own projects.
- File Storage: Upload and manage images with secure API key authentication
- UI: TypeScript/React frontend for a responsive and intuitive user experience
- Security: Express backend with API key authentication and request validation
- Storage: Uses Replit Object Storage for reliable and scalable image storage
- Copy-to-Clipboard: Intelligent URL generation for sharing images in production environments
The application uses simple environment variables for URL configuration:
# .env file
VITE_PRODUCTION_DOMAIN=your-app-name.replit.app
This ensures that copied image URLs will use the correct production domain when shared.
The API is accessible at: https://file-upload.replit.app/api
Protected endpoints require an API key to be included in the request headers:
X-API-KEY: your-api-key-here
Upload a new image to the storage.
POST /api/upload
Content-Type: multipart/form-data
X-API-KEY: your-api-key
Request Body:
file: Image file (Required)- Supported formats: JPEG, JPG, PNG, WebP
- Max file size: 5MB
Example Request (zsh/bash):
# Using curl
curl -X POST \
-H "Content-Type: multipart/form-data" \
-H "X-API-KEY: your-api-key" \
-F "file=@\"./path/to/your/image.jpg\"" \
https://file-upload.replit.app/api/upload
# Using httpie (alternative)
http -f POST https://file-upload.replit.app/api/upload \
"X-API-KEY: your-api-key" \
file@"./path/to/your/image.jpg"Success Response:
{
"success": true,
"data": {
"id": 1,
"filename": "images/1234567890-image.jpg",
"url": "/api/storage/1234567890-image.jpg",
"contentType": "image/jpeg",
"size": 123456
}
}Error Response:
{
"success": false,
"error": "File too large. Maximum file size is 5MB.",
"code": "FILE_TOO_LARGE"
}Retrieve a list of all uploaded images.
GET /api/images
X-API-KEY: your-api-key (optional)
Example Request (zsh/bash):
# Using curl
curl "https://file-upload.replit.app/api/images"
# Using httpie (alternative)
http GET https://file-upload.replit.app/api/imagesSuccess Response:
{
"success": true,
"data": [
{
"id": 1,
"filename": "images/1234567890-image.jpg",
"url": "/api/storage/1234567890-image.jpg",
"contentType": "image/jpeg",
"size": 123456
}
]
}Retrieve information about a specific image by ID.
GET /api/images/:id
X-API-KEY: your-api-key (optional)
Example Request (zsh/bash):
# Using curl
curl "https://file-upload.replit.app/api/images/1"
# Using httpie (alternative)
http GET https://file-upload.replit.app/api/images/1Success Response:
{
"success": true,
"data": {
"id": 1,
"filename": "images/1234567890-image.jpg",
"url": "/api/storage/1234567890-image.jpg",
"contentType": "image/jpeg",
"size": 123456
}
}Delete a specific image by ID.
DELETE /api/images/:id
X-API-KEY: your-api-key
Example Request (zsh/bash):
# Using curl
curl -X DELETE \
-H "X-API-KEY: your-api-key" \
"https://file-upload.replit.app/api/images/1"
# Using httpie (alternative)
http DELETE https://file-upload.replit.app/api/images/1 \
"X-API-KEY: your-api-key"Success Response:
{
"success": true,
"data": {
"success": true
}
}Get the actual image file.
GET /api/storage/:filename
Example Request (zsh/bash):
# Using curl (download file)
curl -O "https://file-upload.replit.app/api/storage/1234567890-image.jpg"
# Using curl (view in browser)
curl "https://file-upload.replit.app/api/storage/1234567890-image.jpg"
# Using httpie
http GET https://file-upload.replit.app/api/storage/1234567890-image.jpgResponse:
- Returns the image file directly
- Appropriate content-type header will be set (image/jpeg, image/png, image/webp)
- Includes caching headers for better performance
All endpoints return error responses in the following format:
{
"success": false,
"error": "Error message describing what went wrong",
"code": "ERROR_CODE"
}The code field is optional and provides a machine-readable identifier for the error type.
Common Error Codes:
UNAUTHORIZED: Missing API key when requiredINVALID_API_KEY: The provided API key is invalidFILE_TOO_LARGE: The uploaded file exceeds the maximum allowed sizeINVALID_FILE_TYPE: The uploaded file is not an accepted image formatNOT_FOUND: The requested resource does not existSERVER_ERROR: An internal server error occurredUPLOAD_ERROR: A generic error occurred during upload
Common HTTP Status Codes:
- 400: Bad Request (invalid input)
- 401: Unauthorized (missing API key)
- 403: Forbidden (invalid API key)
- 404: Not Found (image or resource doesn't exist)
- 500: Internal Server Error
- Maximum file size: 5MB
- Supported image formats: JPEG, JPG, PNG, WebP
- Filenames are automatically sanitized and timestamped
The web interface provides an intuitive way to:
- Enter your API key in the secure input field (not stored in localStorage for security)
- Upload new images with drag-and-drop or file selection
- View all uploaded images in a responsive gallery
- Copy image URLs to clipboard with automatic domain correction for production environments
- Delete images with confirmation dialog
- Node.js and npm installed
- A Replit account for deployment
- Clone the repository
- Copy
.env.exampleto.envand configure the production domain - Install dependencies with
npm install - Run the application with
npm run dev
- Frontend: React, TypeScript, Shadcn UI, and TailwindCSS
- Backend: Express.js with TypeScript
- Storage: Replit Object Storage
- Authentication: API key-based with secure session management
MIT