Asset Types
| Type | Description | Stored in DB |
|---|---|---|
face | Face reference images for persons | Yes |
template | Style reference templates | Yes |
bucket | Temporary file upload (no DB entry) | No |
The
bucket type uploads files to temporary storage without creating a database entry. Useful for transient images needed during generation workflows.List Assets
Lists your owned or organization-shared stored images, including unpublished uploads.GET /api/assets
Query Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
type | string | No | - | Filter by type: face, template, bucket |
page | number | No | 1 | Page number |
limit | number | No | 20 | Items per page (max 100) |
bash
# List all assets
curl https://youthumb.ai/api/assets \
-H "x-api-key: your_api_key"
# List only face assets
curl "https://youthumb.ai/api/assets?type=face" \
-H "x-api-key: your_api_key"
# Paginated
curl "https://youthumb.ai/api/assets?page=2&limit=10" \
-H "x-api-key: your_api_key"List Response
json
{
"success": true,
"data": {
"assets": [
{
"id": "asset-uuid",
"type": "face",
"url": "https://...",
"name": "photo.jpg",
"description": "Front face photo",
"mimeType": "image/jpeg",
"size": 245000,
"width": 1920,
"height": 1080,
"createdAt": "2024-01-15T10:30:00.000Z"
}
],
"pagination": {
"page": 1,
"limit": 20
}
}
}Upload Asset
Upload an image. Supports two modes: multipart/form-data and JSON (base64).POST /api/assets
Mode 1: Multipart (FormData)
| Field | Type | Required | Description |
|---|---|---|---|
file | File | Yes | Image file (MIME must start with image/) |
type | string | Yes | face, template, or bucket |
description | string | No | Description |
bash
curl -X POST https://youthumb.ai/api/assets \
-H "x-api-key: your_api_key" \
-F "file=@face-photo.jpg" \
-F "type=face" \
-F "description=Front face photo"Mode 2: Base64 (JSON)
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
base64 | string | Yes | - | Base64-encoded image (with or without data: prefix) |
type | string | Yes | - | face, template, or bucket |
filename | string | No | auto-generated | Filename |
mimeType | string | No | image/jpeg | image/jpeg, image/png, image/webp, image/gif |
description | string | No | - | Description (max 500 chars) |
bash
curl -X POST https://youthumb.ai/api/assets \
-H "x-api-key: your_api_key" \
-H "Content-Type: application/json" \
-d '{
"base64": "data:image/jpeg;base64,/9j/4AAQ...",
"type": "face",
"filename": "my-face.jpg",
"mimeType": "image/jpeg",
"description": "Front face photo"
}'Upload Response
json
{
"success": true,
"data": {
"id": "new-asset-uuid",
"type": "face",
"url": "https://...",
"name": "my-face.jpg",
"description": "Front face photo",
"mimeType": "image/jpeg",
"size": 245000,
"width": 1920,
"height": 1080,
"createdAt": "2024-01-15T10:30:00.000Z"
}
}For
bucket uploads, the response will have an empty id and null for width/height, since the file is stored temporarily without a database record.Get Asset
Retrieve a specific asset by ID.GET /api/assets/{id}
| Parameter | Type | Description |
|---|---|---|
id | string (UUID) | Asset ID |
bash
curl https://youthumb.ai/api/assets/asset-uuid \
-H "x-api-key: your_api_key"Get Response
json
{
"success": true,
"data": {
"id": "asset-uuid",
"type": "face",
"url": "https://...",
"name": "photo.jpg",
"description": "Front face photo",
"mimeType": "image/jpeg",
"size": 245000,
"width": 1920,
"height": 1080,
"createdAt": "2024-01-15T10:30:00.000Z"
}
}Delete Asset
Delete an asset by ID.DELETE /api/assets/{id}
| Parameter | Type | Description |
|---|---|---|
id | string (UUID) | Asset ID |
bash
curl -X DELETE https://youthumb.ai/api/assets/asset-uuid \
-H "x-api-key: your_api_key"Delete Response
json
{
"success": true,
"data": {
"message": "Asset deleted"
}
}Complete Example: JavaScript
javascript
const API = 'https://youthumb.ai/api';
const headers = {
'x-api-key': process.env.YOUTHUMB_API_KEY,
'Content-Type': 'application/json',
};
// Upload a face image (base64)
async function uploadFaceImage(base64Data, filename) {
const response = await fetch(`${API}/assets`, {
method: 'POST',
headers,
body: JSON.stringify({
base64: base64Data,
type: 'face',
filename,
mimeType: 'image/jpeg',
}),
});
return response.json();
}
// List all face assets
async function listFaceAssets() {
const response = await fetch(`${API}/assets?type=face`, { headers });
return response.json();
}
// Upload face then create person
async function setupPerson(name, faceImages) {
// 1. Upload all face images
const uploadResults = await Promise.all(
faceImages.map((img) => uploadFaceImage(img.base64, img.filename))
);
const imageIds = uploadResults.map((r) => r.data.id);
// 2. Create person with uploaded images
const person = await fetch(`${API}/persons`, {
method: 'POST',
headers,
body: JSON.stringify({ name, imageIds }),
});
return person.json();
}Assets are the prerequisite for the Persons API. Upload face images as assets first, then pass their IDs when creating or updating a person.
Resources: persons, uploads and catalog
All resource operations use the connected identity. Stored assets must belong to the selected organization and be owned by you or shared with it. Imports stay unpublished and are still discoverable. Unknown or inaccessible IDs return 404; permission refusals return 403; invalid inputs return 400. MCP errors useisError: true. Management operations consume no credits.
| REST | MCP | Input / effect |
|---|---|---|
PATCH /api/persons/:id | update_person | name? (1–100), description? (max 500); null clears description; at least one field |
DELETE /api/persons/:id | delete_person | Deletes profile and photo associations; stored images remain |
DELETE /api/persons/:id/images/:imageId | remove_person_image | Detaches only this existing association, without deleting the asset |
PUT /api/persons/:id/default | set_default_person | Idempotent organization default; existing owner permissions apply |
GET /api/assets/:id | get_asset | Authorized stored asset UUID |
GET /api/templates/:id | get_template | Published catalog template or your own private template |
mcp:assets and active Images and persons access. Reads require mcp:read and active Read access. Tool arguments use personId, imageId, assetId or templateId instead of URL path parameters. Person reads/updates return the profile with images and imageCount; delete returns {"deleted":true}. Existing create/add-photo calls also validate every referenced image before writing.
Asset discovery
GET /api/assets / list_assets accepts type (face, template, bucket), search, isPublished, page (default 1), limit (default 20, max 100). Without type, stored face and template images are listed. Search matches name/description, and visibility/publication filters apply before pagination and count. Stored results include isPublished, ownerScope: "organization"; pagination returns page, limit, total, totalPages, hasMore.
type=bucket lists the caller's personal temporary folder across organizations. Results include ownerScope: "user", id: "", stable fileKey, url and isFavorite. Use contentImages: [{"url": "RETURNED_URL"}] for generation; get_asset and userImageId require a persisted asset UUID, never a bucket file key. favorite=true selects starred files, favorite=false excludes them; omission includes both. search matches file names. Bucket-only sortBy=name|createdAt and sortOrder=asc|desc default to createdAt descending. Unknown or invalid dates remain createdAt: null and sort last in either direction; ties use fileKey ascending. These three bucket filters are rejected for other asset types; isPublished is invalid for bucket files.
The service enumerates matching storage files in batches of 100, deduplicates by path and excludes non-images/placeholders before favorite filtering, sorting and public pagination. total is the filtered image count, totalPages = ceil(total / limit) and hasMore signals another page. Empty results have totals of 0; an out-of-range page is empty. Orphan favorites do not create assets. Every request enumerates the matching folder, so large folders cost more storage requests; concurrent changes are not an atomic snapshot. Any provider page failure fails the request rather than returning partial success. Temporary files cannot be deleted through /api/assets/:id.
Example: GET /api/assets?type=bucket&search=logo&favorite=true&sortBy=createdAt&sortOrder=desc&page=1&limit=20 or MCP list_assets({"type":"bucket","search":"logo","favorite":true,"sortBy":"createdAt","sortOrder":"desc","page":1,"limit":20}).
Three reference namespaces
GET /api/templates / list_templates searches catalog title, description and tags with search. scope=public (default) lists published catalog templates; scope=mine lists only templates you created, published or private. isPublished=false requires scope=mine. Existing category, isFeatured, page, limit filters remain. Responses contain templates and pagination (page, limit, total, totalPages).
A catalog UUID goes in templateId. An uploaded personal reference is found through list_assets(type="template"): use its URL as styleReferenceUrl, or its UUID as a content userImageId / prompt-assistance assetId. A temporary file uses its URL. Never interchange catalog IDs, asset IDs and file keys.
bash
curl "$BASE/api/assets?type=template&search=studio&page=1&limit=20" -H "x-api-key: $YOUTHUMB_API_KEY"
curl "$BASE/api/templates?scope=mine&isPublished=false&search=studio" -H "x-api-key: $YOUTHUMB_API_KEY"
curl -X PATCH "$BASE/api/persons/$PERSON_ID" -H "x-api-key: $YOUTHUMB_API_KEY" -H "Content-Type: application/json" -d '{"description":null}'