Thumbnail Presets
The File Storage service auto-generates thumbnail variants for every uploaded image. Modules retrieve thumbnails by preset name — no manual resize or URL construction required.
Preset Reference
| Preset | Dimensions | Auto-generated | Typical use case |
|---|---|---|---|
icon_32 | 32 × 32 px | ✅ Always | Favicons, sidebar icons, compact lists |
avatar_64 | 64 × 64 px | ☐ On-demand | User avatars in nav, comments, cards |
card_300 | 300 × 200 px | ✅ Always | File cards, grid thumbnails, table previews |
preview_600 | 600 × 400 px | ☐ On-demand | Modal previews, lightbox preview |
full_1200 | 1 200 × auto | ☐ On-demand | Full-size display, image viewer |
icon_32 and card_300 are generated automatically when any image
is uploaded. The remaining three presets are generated on the first
GET /files/:id/thumbnail/:preset request (lazy generation), or
when explicitly requested in uploadImage({ presets: [...] }).
Retrieve a Thumbnail
SDK
const url = await kernel.files().thumbnail(
'01j9paf1l000000000000000',
'avatar_64'
);
// 'https://api.septemcore.com/v1/files/01j9paf1l.../thumbnail/avatar_64'
REST
GET https://api.septemcore.com/v1/files/01j9paf1l000000000000000/thumbnail/avatar_64
Authorization: Bearer <access_token>
Response options:
Thumbnail ready — 302 Found:
HTTP/1.1 302 Found
Location: https://s3.septemcore.com/01j9p3kz.../avatars/01j9paf1l..._avatar_64.webp?X-Amz-Signature=...
Cache-Control: public, max-age=31536000
The redirect target is a presigned S3 URL valid for 1 year
(Cache-Control: max-age=31536000). CDN can cache the thumbnail
indefinitely — a new presigned URL is generated when the cache expires.
Thumbnail pending (being generated) — 202 Accepted:
{
"status": "pending",
"preset": "avatar_64",
"message": "Thumbnail is being generated. Retry in 2–5 seconds."
}
Preset not valid — 400 Bad Request:
{
"type": "https://api.septemcore.com/problems/validation-error",
"status": 400,
"detail": "Unknown preset 'banner_800'. Valid presets: icon_32, avatar_64, card_300, preview_600, full_1200.",
"code": "INVALID_PRESET"
}
Request Thumbnails at Upload Time
To avoid lazy-generation latency, specify all required presets in
uploadImage():
const result = await kernel.files().uploadImage({
file: imageBlob,
filename: 'hero.png',
bucket: 'assets',
presets: ['icon_32', 'avatar_64', 'card_300', 'preview_600', 'full_1200'],
// All 5 thumbnails generated synchronously before the response is returned
});
// result.thumbnails:
// {
// icon_32: 'https://api.septemcore.com/v1/files/01j9paf1l.../thumbnail/icon_32',
// avatar_64: 'https://api.septemcore.com/v1/files/01j9paf1l.../thumbnail/avatar_64',
// card_300: 'https://api.septemcore.com/v1/files/01j9paf1l.../thumbnail/card_300',
// preview_600: 'https://api.septemcore.com/v1/files/01j9paf1l.../thumbnail/preview_600',
// full_1200: 'https://api.septemcore.com/v1/files/01j9paf1l.../thumbnail/full_1200'
// }
All five thumbnails are generated synchronously and their URLs are included in the upload response — no separate requests needed.
Thumbnail URLs in Metadata
File metadata (GET /files/:id with Accept: application/json)
includes all generated thumbnail URLs:
{
"fileId": "01j9paf1l000000000000000",
"filename": "hero.png",
"mimeType": "image/webp",
"size": 84320,
"status": "available",
"thumbnails": {
"icon_32": "https://api.septemcore.com/v1/files/01j9paf1l.../thumbnail/icon_32",
"card_300": "https://api.septemcore.com/v1/files/01j9paf1l.../thumbnail/card_300",
"avatar_64": null,
"preview_600": null,
"full_1200": null
}
}
null means the thumbnail has not been generated yet. Request it via
GET /files/:id/thumbnail/:preset to trigger lazy generation.
Using with the ImageUpload Component
The <ImageUpload> component accepts a presets prop to control which
thumbnails are generated during upload:
import { ImageUpload } from '@platform/ui-shell';
<ImageUpload
bucket="avatars"
aspectRatio="1:1"
presets={['icon_32', 'avatar_64']}
onUploadComplete={(result) => {
const avatarUrl = result.thumbnails.avatar_64;
updateProfile({ avatarUrl });
}}
/>
Only the presets listed in presets are generated during upload.
Unspecified presets are generated lazily on first access.
Thumbnail Generation Rules
| Rule | Detail |
|---|---|
| Auto-generated presets | icon_32 and card_300 always generated on upload |
| Lazy presets | avatar_64, preview_600, full_1200 generated on first GET |
| Format | Always WebP regardless of original format (smallest size) |
| Aspect ratio | Thumbnails are center-cropped to match the preset's ratio |
| Processing timeout | 30 s (FILES_IMAGE_PROCESSING_TIMEOUT_SEC) |
| On timeout | Thumbnail status = pending; background retry queued |
| Non-image files | GET /files/:id/thumbnail/:preset → 415 Unsupported Media Type |
Error Reference
| Scenario | HTTP | Code |
|---|---|---|
| Invalid preset name | 400 | INVALID_PRESET |
| File is not an image | 415 | UNSUPPORTED_MEDIA_TYPE |
| File not found | 404 | not-found |
| File belongs to different tenant | 403 | forbidden |
| Thumbnail still generating | 202 | status: "pending" — retry in 2–5 s |