Galleries
Gallery management endpoints. Galleries are ordered collections of media items, typically images. Unlike posts and pages, the primary content of a gallery is media rather than text.
Base path: /api/v1/galleries
List Galleries
Required permission: galleries:read
Query parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
skip |
int | 0 |
Pagination offset |
limit |
int | 100 |
Pagination limit |
status |
string | — | Filter by status: draft, published, archived |
Response 200 OK
Create Gallery
Required permission: galleries:create
Request body
{
"slug": "summer-2026",
"status": "draft",
"cover_image_id": "uuid",
"author_id": "uuid",
"translations": [
{
"language_id": "uuid",
"title": "Summer 2026",
"description": "Photos from our summer event.",
"meta_title": "Summer 2026 Gallery",
"meta_description": "Browse our summer 2026 photo gallery."
}
]
}
| Field | Type | Required | Constraints |
|---|---|---|---|
slug |
string | ✅ | 2–255 characters, unique |
status |
string | ❌ | draft, published, archived. Default: draft |
cover_image_id |
UUID | ❌ | Must exist in media |
author_id |
UUID | ❌ | Defaults to current user |
translations |
array | ❌ | List of translations |
Response 201 Created — full GalleryResponse object.
Errors
| Status | Description |
|---|---|
404 |
Cover image not found |
409 |
Gallery slug already exists |
Get Gallery
Required permission: galleries:read
Response 200 OK
{
"id": "uuid",
"slug": "summer-2026",
"status": "published",
"cover_image_id": "uuid",
"author_id": "uuid",
"created_by": "uuid",
"translations": [
{
"id": "uuid",
"gallery_id": "uuid",
"language_id": "uuid",
"title": "Summer 2026",
"description": "Photos from our summer event.",
"meta_title": "Summer 2026 Gallery",
"meta_description": "Browse our summer 2026 photo gallery.",
"created_at": "2026-01-01T00:00:00Z",
"updated_at": null
}
],
"gallery_media": [
{
"gallery_id": "uuid",
"media_id": "uuid",
"order": 0,
"caption": "Opening ceremony",
"created_at": "2026-01-01T00:00:00Z",
"media": {
"id": "uuid",
"filename": "550e8400.jpg",
"original_filename": "photo1.jpg",
"mime_type": "image/jpeg",
"size": 204800,
"path": "uploads/media/550e8400.jpg",
"alt_text": "Opening ceremony photo"
}
}
],
"cover_image": {
"id": "uuid",
"filename": "cover.jpg",
"original_filename": "cover.jpg",
"mime_type": "image/jpeg",
"size": 102400,
"path": "uploads/media/cover.jpg",
"alt_text": "Gallery cover"
},
"created_at": "2026-01-01T00:00:00Z",
"updated_at": null
}
Errors
| Status | Description |
|---|---|
404 |
Gallery not found |
Update Gallery
Required permission: galleries:update
Request body — all fields optional
{
"slug": "summer-2026-updated",
"status": "published",
"cover_image_id": "uuid",
"author_id": "uuid"
}
Response 200 OK — updated GalleryResponse object.
Errors
| Status | Description |
|---|---|
404 |
Gallery not found |
404 |
Cover image not found |
409 |
Gallery slug already exists |
Delete Gallery
Soft-deletes a gallery. Associated media items are not deleted from the media library.
Required permission: galleries:delete
Response 204 No Content
Errors
| Status | Description |
|---|---|
404 |
Gallery not found |
Upsert Translation
Creates or updates a translation for a specific language.
Required permission: galleries:update
Request body
{
"language_id": "uuid",
"title": "Summer 2026",
"description": "Photos from our summer event.",
"meta_title": "Summer 2026 Gallery",
"meta_description": "Browse our summer 2026 photo gallery."
}
| Field | Type | Required | Description |
|---|---|---|---|
language_id |
UUID | ✅ | Must exist in DB |
title |
string | ✅ | Gallery title |
description |
string | ❌ | Gallery description |
meta_title |
string | ❌ | SEO title |
meta_description |
string | ❌ | SEO description |
Response 200 OK — updated GalleryResponse object.
Errors
| Status | Description |
|---|---|
404 |
Gallery not found |
404 |
Language not found |
Delete Translation
Required permission: galleries:update
Response 200 OK — updated GalleryResponse object.
Errors
| Status | Description |
|---|---|
404 |
Gallery not found |
404 |
Translation not found |
Add Media
Adds a media item to the gallery.
Required permission: galleries:update
Request body
| Field | Type | Required | Constraints |
|---|---|---|---|
media_id |
UUID | ✅ | Must exist in media |
order |
int | ❌ | Default: auto-increment |
caption |
string | ❌ | Max 500 characters |
Response 201 Created — updated GalleryResponse object.
Auto-increment order
If order is 0 or not provided, the item is appended at the end of the gallery automatically.
Errors
| Status | Description |
|---|---|
400 |
Media is already in this gallery |
404 |
Gallery not found |
404 |
Media not found |
Update Media Item
Updates the order or caption of a media item within the gallery.
Required permission: galleries:update
Request body — all fields optional
Response 200 OK — updated GalleryResponse object.
Errors
| Status | Description |
|---|---|
404 |
Gallery not found |
404 |
Media not found in this gallery |
Remove Media
Removes a media item from the gallery. The media file itself is not deleted from the media library.
Required permission: galleries:update
Response 200 OK — updated GalleryResponse object.
Errors
| Status | Description |
|---|---|
404 |
Gallery not found |
404 |
Media not found in this gallery |
Reorder Media
Sets a new order for all media items in the gallery in a single operation. Pass all media IDs in the desired order.
Required permission: galleries:update
Request body
| Field | Type | Required | Constraints |
|---|---|---|---|
media_ids |
UUID array | ✅ | Must include ALL media items in gallery |
Response 200 OK — updated GalleryResponse object.
All items required
The media_ids array must contain all media items currently in the gallery.
Partial reordering is not supported — if any item is missing, the request will fail.
Errors
| Status | Description |
|---|---|
400 |
Not all media items included in reorder request |
404 |
Gallery not found |
404 |
One or more media IDs not found in gallery |