A self-hosted image hosting and resizing API. Upload images from any app, get back unique URLs that serve optimized, resized versions on the fly.
Base URL: https://imgs.modscape.com
Upload and delete endpoints require a Bearer token in the Authorization header. Image serving (GET) is public with no auth required.
Authorization: Bearer YOUR_API_KEY
| Method | Route | Auth | Description |
|---|---|---|---|
| POST | /upload | Yes | Upload an image |
| GET | /:id | No | Serve original image (max 2400px wide) |
| GET | /:id/:width | No | Serve image at a specific pixel width |
| DELETE | /:id | Yes | Delete an image and all its resized versions |
Send a multipart/form-data POST with the image in a field named file. Max file size depends on the server's PHP configuration (typically 2–50 MB).
curl -X POST https://imgs.modscape.com/upload \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "file=@/path/to/photo.jpg"
const form = new FormData();
form.append('file', fs.createReadStream('/path/to/photo.jpg'));
const res = await fetch('https://imgs.modscape.com/upload', {
method: 'POST',
headers: { 'Authorization': 'Bearer YOUR_API_KEY' },
body: form
});
const data = await res.json();
// Given an <input type="file"> element:
const file = inputElement.files[0];
const form = new FormData();
form.append('file', file);
const res = await fetch('https://imgs.modscape.com/upload', {
method: 'POST',
headers: { 'Authorization': 'Bearer YOUR_API_KEY' },
body: form
});
const data = await res.json();
// data.id → "a7xK9mPq2w"
// data.original → "https://imgs.modscape.com/a7xK9mPq2w"
// data.sizes → { 200: "https://...200", 400: "https://...400", ... }
{
"id": "a7xK9mPq2w",
"original": "https://imgs.modscape.com/a7xK9mPq2w",
"sizes": {
"200": "https://imgs.modscape.com/a7xK9mPq2w/200",
"400": "https://imgs.modscape.com/a7xK9mPq2w/400",
"800": "https://imgs.modscape.com/a7xK9mPq2w/800",
"1200": "https://imgs.modscape.com/a7xK9mPq2w/1200",
"1600": "https://imgs.modscape.com/a7xK9mPq2w/1600"
}
}
sizes object only includes widths smaller than the uploaded image. If you upload a 600px wide image, you will only get 200 and 400 in sizes.
Images are served publicly. No authentication needed. Use the image ID and an optional width.
https://imgs.modscape.com/a7xK9mPq2w
https://imgs.modscape.com/a7xK9mPq2w/400
Width must be between 1 and 2400 pixels. The aspect ratio is always preserved. If the requested width hasn't been generated before, it is created on the first request and cached for all future requests.
<!-- Simple usage -->
<img src="https://imgs.modscape.com/a7xK9mPq2w/800" alt="My image">
<!-- Responsive with srcset -->
<img
src="https://imgs.modscape.com/a7xK9mPq2w/800"
srcset="
https://imgs.modscape.com/a7xK9mPq2w/400 400w,
https://imgs.modscape.com/a7xK9mPq2w/800 800w,
https://imgs.modscape.com/a7xK9mPq2w/1200 1200w,
https://imgs.modscape.com/a7xK9mPq2w/1600 1600w
"
sizes="(max-width: 600px) 400px, 800px"
alt="My image"
>
<!-- As a CSS background -->
<div style="background-image: url('https://imgs.modscape.com/a7xK9mPq2w/1200')"></div>
Removes the image and all generated sizes from disk.
curl -X DELETE https://imgs.modscape.com/a7xK9mPq2w \
-H "Authorization: Bearer YOUR_API_KEY"
{ "deleted": "a7xK9mPq2w" }
| Status | Body | Cause |
|---|---|---|
| 400 | { "error": "No file uploaded" } | Upload request missing the file field |
| 400 | { "error": "Width must be between 1 and 2400" } | Invalid width parameter |
| 401 | { "error": "Unauthorized" } | Missing or invalid API key |
| 404 | { "error": "Image not found" } | Image ID does not exist |
Cache-Control: public, max-age=31536000, immutable (1 year).a7xK9mPq2w.When building an app with an admin panel that manages image uploads:
POST /upload and receives the image ID.a7xK9mPq2w) in your database alongside the related record.https://imgs.modscape.com/{id}/{width}.DELETE /:id when the record is removed from your app.// Example: save the image ID to your database
const uploadRes = await fetch('https://imgs.modscape.com/upload', {
method: 'POST',
headers: { 'Authorization': 'Bearer YOUR_API_KEY' },
body: form
});
const { id } = await uploadRes.json();
// Save `id` to your database record
await db.query('UPDATE products SET image_id = $1 WHERE id = $2', [id, productId]);
// Later, on the frontend, render it at whatever size you need:
// <img src={`https://imgs.modscape.com/${product.image_id}/800`} />