Skip to main content

Image object

Every query that returns images includes these fields.
_id
Id<'images'>
required
Unique Convex document ID for the image.
title
string
required
Display title of the image.
imageUrl
string
required
Public URL of the full-resolution original image.
tags
string[]
required
Array of descriptive tags. Uploads always include "original".
category
string
required
Visual category (e.g. "Cinematic", "Film", "Landscape").
uploadedBy
Id<'users'>
required
ID of the user who uploaded or imported the image.
likes
number
required
Total like count.
views
number
required
Total view count.
isLiked
boolean
required
Whether the authenticated caller has liked this image. Always false for unauthenticated requests.
description
string
AI-generated or user-provided description.
previewUrl
string
URL of the preview-sized image (640×360 WebP).
storageId
Id<'_storage'>
Temporary Convex storage ID. Present only during upload before NextCloud finalization.
source
string
Original source attribution string (e.g. "AI Generation").
sref
string
Style reference string passed to generation models.
colors
string[]
Array of five hex color codes extracted by VLM analysis.
status
string
Lifecycle status. One of draft, pending, or active.
aiStatus
string
AI processing status. One of queued, processing, completed, or failed.
group
string
Project type group. One of: Commercial, Film, Moodboard, Spec Commercial, Spec Music Video, Music Video, TV Series, Web Series, Video Game Cinematic.
projectName
string
Name of the production project this image belongs to.
moodboardName
string
Name of the moodboard this image belongs to (reference images only).
parentImageId
Id<'images'>
ID of the source image this was generated from (AI variations only).
sourceType
string
Origin of the image. One of: upload, discord, pinterest, ai.
nextcloudPersistStatus
string
NextCloud upload status. One of pending, succeeded, or failed.
derivativeUrls
object
Public URLs for resized derivative images.

Queries

api.images.list

Returns a page of active images, optionally filtered by category and/or group.
category
string
Filter to images whose category exactly matches this value.
group
string
Filter to images whose group exactly matches this value.
limit
number
default:"50"
Maximum number of images to return. Defaults to 50.
Returns Image[] — array of image objects with isLiked populated for the authenticated user.
Full-text search across image titles, with optional category and group filters.
searchTerm
string
required
Text to search for in image titles.
category
string
Restrict results to this category.
group
string
Restrict results to this group.
Returns Image[] — up to 50 matching images with isLiked populated. Only active images are returned.

api.images.getById

Fetch a single image by its ID.
id
Id<'images'>
required
The Convex document ID of the image.
Returns Image | null — the image with isLiked populated, or null if not found.

api.images.getGroups

Returns the list of valid group values. No arguments. Returns string[] — the following values in order:
[
  "Commercial",
  "Film",
  "Moodboard",
  "Spec Commercial",
  "Spec Music Video",
  "Music Video",
  "TV Series",
  "Web Series",
  "Video Game Cinematic",
]

api.images.getCategories

Returns all known categories, combining built-in defaults with any categories already used in the database. No arguments. Returns string[] — sorted array of category strings. Built-in defaults include Abstract, Architecture, Art, Blockbuster Film, Character Design, Cinematic, Commercial, Design, Environment, Fashion, Film, Gaming, Headshot, Indy Film, Illustration, Interior, Landscape, Photography, Sci-Fi, Streetwear, Technology, Texture, UI/UX, Vintage.

api.images.getDraftImages

Returns draft images owned by the authenticated user. No arguments. Requires authentication. Returns Image[] — images with status: "draft", newest first.

api.images.getProcessingImages

Returns images with aiStatus: "processing" that were uploaded within the last 18 hours. No arguments. Requires authentication.
Images older than 18 hours are excluded from the active processing queue even if their aiStatus has not been updated. Use api.images.clearMyStaleProcessingImages to mark stale records as failed.
Returns Image[] — processing images from the last 18 hours.

api.images.getPendingImages

Returns images with status: "pending" (awaiting approval) owned by the authenticated user. No arguments. Requires authentication. Returns Image[] — pending images, newest first.

Mutations

api.images.create

Create a new image record directly from a URL. Use this for simple imports where you already have a hosted URL.
title
string
required
Display title for the image.
imageUrl
string
required
Publicly accessible URL of the image.
tags
string[]
required
Tags describing the image. The tag "original" is appended automatically.
category
string
required
Visual category for the image.
description
string
Optional description.
source
string
Source attribution string.
sref
string
Style reference string.
Returns Id<'images'> — the ID of the created image.

api.images.createExternal

Create an image record from an external import (Discord, Pinterest, or AI) with full metadata and deduplication. If a record with the same externalId already exists, the existing ID is returned immediately. If a record with the same imageUrl already exists for the current user, that ID is returned instead.
title
string
required
Display title. Defaults to "Untitled" if empty.
imageUrl
string
required
Publicly accessible URL of the full image.
description
string
Optional description.
previewUrl
string
URL of a smaller preview version.
tags
string[]
Tags. Defaults to ["original"].
category
string
Visual category. Defaults to "General".
source
string
Source attribution.
sref
string
Style reference string.
storagePath
string
Relative NextCloud WebDAV path of the stored original (e.g. pindeck/media-uploads/2024/12_01/original/image.jpg). Path traversal sequences are rejected.
previewStoragePath
string
NextCloud path of the preview file.
derivativeUrls
object
Pre-computed public URLs for derivatives.
derivativeStoragePaths
object
NextCloud paths for derivative files.
externalId
string
External platform ID for deduplication (e.g. a Discord message attachment ID).
sourceType
string
Origin of the image. One of: upload, discord, pinterest, ai.
sourceUrl
string
Original source URL before any processing.
importBatchId
Id<'importBatches'>
ID of the import batch this image belongs to.
Returns Id<'images'> — the ID of the created or existing image.
Discord imports (sourceType: "discord") are created with status: "pending" and aiStatus: "queued". All other source types are created as status: "active" with aiStatus: "processing", and VLM analysis is scheduled immediately.

api.images.generateUploadUrl

Generates a pre-signed Convex storage upload URL. Use this before calling api.images.uploadMultiple. No arguments. Requires authentication. Returns string — a short-lived upload URL. Upload your image file to this URL with a PUT request.
// 1. Get the upload URL
const uploadUrl = await convex.mutation(api.images.generateUploadUrl, {});

// 2. Upload the file
const result = await fetch(uploadUrl, {
  method: "PUT",
  headers: { "Content-Type": file.type },
  body: file,
});
const { storageId } = await result.json();

// 3. Create the image record
const [imageId] = await convex.mutation(api.images.uploadMultiple, {
  uploads: [{ storageId, title: "My image", category: "Film", tags: [] }],
});

api.images.uploadMultiple

Create image records from one or more Convex storage uploads. Each image is created as a draft and the system schedules NextCloud finalization and VLM analysis automatically.
uploads
object[]
required
Array of upload descriptors.
Returns Id<'images'>[] — array of created image IDs, in the same order as the input uploads array.

api.images.finalizeUploads

Promote draft images to active status. Call this after the user confirms their upload batch is complete.
imageIds
Id<'images'>[]
required
IDs of the draft images to activate. Only images owned by the authenticated user are updated.
Returns null

api.images.toggleLike

Toggle the authenticated user’s like on an image.
imageId
Id<'images'>
required
ID of the image to like or unlike.
Returns booleantrue if the image is now liked, false if it is now unliked.

api.images.incrementViews

Increment the view counter for an image. Call this when an image is displayed to a user.
imageId
Id<'images'>
required
ID of the image that was viewed.
Returns null

api.images.remove

Permanently delete an image and its associated storage files. Only the image owner can delete it.
id
Id<'images'>
required
ID of the image to delete.
Returns
success
boolean
required
true when the image was deleted.
This is irreversible. Both the Convex storage file and all NextCloud storage paths (original, preview, and derivatives) are deleted.

api.images.approveImage

Approve a pending or draft image. For Discord-sourced images, this transitions the image to draft and triggers VLM analysis. For all other sources, the image transitions directly to active.
imageId
Id<'images'>
required
ID of the image to approve.
Returns null

api.images.rejectImage

Reject and permanently delete an image. Only the image owner can reject it.
imageId
Id<'images'>
required
ID of the image to reject.
Returns null
Rejection permanently deletes the image record and all associated storage files.

api.images.clearMyStaleProcessingImages

Mark stale processing images as failed. Useful for cleaning up stuck AI jobs.
olderThanHours
number
default:"18"
Images with uploadedAt older than this many hours are marked as failed. Minimum is 1 hour.
Returns number — count of images updated from processing to failed.

api.images.backfillGenerationsFromAiImages

Backfill generations records for AI-generated images that predate the generations table. Scans the authenticated user’s images for those tagged "generated" or sourced as "AI Generation" and inserts missing records.
limit
number
default:"400"
Maximum number of images to scan. Capped at 2000.
Returns
scanned
number
required
Number of AI images found in the scan.
inserted
number
required
Number of new generation records created.
skippedExisting
number
required
Number of images skipped because a generation record already existed.

api.images.updateImageMetadata

Update editable metadata fields on an existing image. Only fields that are provided are changed — omitted fields are left unchanged. Any authenticated user can update metadata on any image (curation tool behavior).
imageId
Id<'images'>
required
ID of the image to update.
title
string
New display title.
description
string
New description.
tags
string[]
Replacement tag array.
category
string
New category value.
source
string
New source attribution.
sref
string
New style reference string.
colors
string[]
Replacement color palette (hex codes).
group
string
New project type group.
projectName
string
New project name.
moodboardName
string
New moodboard name.
uniqueId
string
New unique identifier.
Returns
success
boolean
required
true when the update was applied.

api.images.setAiStatus

Manually set an image’s aiStatus to completed or failed. Use this to unstick images that are stuck in processing.
imageId
Id<'images'>
required
ID of the image to update. Must be owned by the authenticated user.
status
string
required
One of "completed" or "failed".
Returns null

api.images.setProjectRowOrder

Reorder images within a project row and optionally move images to a different project. Called by the gallery’s drag-and-drop project row view.
projectName
string
required
The project name to assign all images to.
imageIds
Id<'images'>[]
required
Ordered list of image IDs. Each image’s projectOrder is set to its index in this array, and its projectName is set to the provided value.
Returns null

api.images.backfillNextcloudFailedUploads

Reschedule NextCloud persistence for images still in Convex storage. Targets images where sourceType = "upload", storageProvider = "convex", and storageId is still present.
limit
number
default:"50"
Maximum number of images to reschedule. Capped at 200.
Returns
scheduled
number
required
Number of images for which NextCloud finalization was rescheduled.
bunx convex run images:backfillNextcloudFailedUploads '{"limit":50}'

Build docs developers (and LLMs) love