api

package
v0.0.0-...-f6a5dc8 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 15, 2026 License: AGPL-3.0 Imports: 87 Imported by: 0

README

API Package Guide

Overview

The API package exposes PhotoPrism’s HTTP endpoints via Gin handlers. Each file under internal/api contains the handlers, request/response DTOs, and Swagger annotations for a specific feature area. Handlers remain thin: they validate input, enforce security or ACL checks, and delegate domain work to services in internal/photoprism, internal/service, or other internal packages. Keep exported types aligned with the REST schema and avoid embedding business logic directly in handlers.

Routing & Wiring

  • Register handlers in internal/server/routes.go by attaching them to the proper router group (for example, APIv1 := router.Group(conf.BaseUri("/api/v1"), Api(conf))).
  • Group endpoints by resource to match existing patterns: sessions, cluster, photos, labels, files, downloads, metadata, and technical routes.
  • Apply middleware stacks (Api, AuthRequired, limiter.Auth, etc.) at the router level to keep handlers focused on request handling.
  • Use conf.BaseUri() when constructing route prefixes so configuration overrides propagate consistently.
  • When new endpoints require feature toggles, gate them in the router rather than inside the handler so disabled routes remain undiscoverable.

Handler Implementation Patterns

  • Accept and return JSON using the shared response helpers. Set header.ContentTypeJSON and ensure responses include proper cache headers (no-store for sensitive payloads).
  • Parse parameters with Gin binding and validate inputs before delegating work. For complex payloads, define dedicated request structs with validation tags.
  • Use the shared download helpers (safe.Download, avatar.SafeDownload) when calling outward HTTP APIs to inherit timeout, size, and SSRF protections.
  • Query and persist data through the corresponding services or repositories; avoid ad-hoc SQL or GORM usage in handlers when dedicated functions exist elsewhere.
  • Surface pagination consistently with count, offset, and limit following the defaults (100 max 1000). Validate offset >= 0 and clamp count to the allowed range.
  • When responses need role-specific fields, build DTOs that redact sensitive data for non-admin roles so the handler stays deterministic.

Security & Middleware

  • Authenticate requests using the standard middleware (AuthRequired) and check roles via helpers in internal/auth/acl (acl.ParseRole, acl.ScopePermits, acl.ScopeAttrPermits).
  • Bound request bodies before parsing JSON or multipart payloads. Use LimitRequestBodyBytes(...) with a route-appropriate cap before BindJSON(...) / ShouldBindJSON(...), detect IsRequestBodyTooLarge(err), and return 413 Request Entity Too Large via AbortRequestTooLarge(...).
  • Keep new JSON binding sites on the shared request-limit path by running make check-api-request-limits (also included in make lint) after adding or refactoring API handlers in the root repo or private overlays.
  • Never log secrets or tokens. Prefer structured logging through event.Log and redact sensitive values before logging.
  • Enforce rate limiting with the shared limiters (limiter.Auth, limiter.Login) and respond with limiter.AbortJSON to maintain consistent 429 JSON payloads.
  • Derive client IPs through api.ClientIP and extract bearer tokens with header.BearerToken or the helper setters. Use constant-time comparison for tokens and secrets.
  • For downloads or proxy endpoints, validate URLs against allowed schemes (http, https) and reject private or loopback addresses unless explicitly required.

Audit Logging

  • Emit security events via event.Audit* (AuditInfo, AuditWarn, AuditErr, AuditDebug) and always build the slice as Who → What → Outcome.
    • Who: ClientIP(c) followed by the most specific actor context ("session %s", "client %s", "user %s").
    • What: Resource constant plus action segments (for example, string(acl.ResourceCluster), "node", "%s"). Place extra context such as counts or error placeholders in separate segments before the outcome.
    • Outcome: End with a single token such as status.Succeeded, status.Failed, status.Denied, or status.Error(err) when the sanitized error message should be the outcome; nothing comes after it.
  • Prefer existing helpers (ClientIP, clean.Log, clean.LogQuote, clean.Error) instead of formatting values manually, and avoid inline = expressions.
  • Example patterns:
    event.AuditInfo([]string{
        ClientIP(c),
        "session %s",
        string(acl.ResourceCluster),
        "node", "%s",
        status.Deleted,
    }, s.RefID, uuid)
    
    event.AuditErr([]string{
        clientIp,
        "session %s",
        string(acl.ResourceCluster),
        "download theme",
        status.Error(err),
    }, refID)
    

Swagger Documentation

  • Annotate handlers with Swagger comments that include full /api/v1/... paths, request/response schemas, and security definitions. Only annotate routes that are externally accessible.
  • Regenerate docs after adding or updating handlers: make fmt-go swag-fmt swag. This formats Go files, normalizes annotations, and updates internal/api/swagger.json. Do not edit the generated JSON manually.
  • When adding new DTOs, keep field names aligned with the JSON schema and update client documentation if serialized names change.
  • Use enum annotations sparingly and ensure they reflect actual runtime constraints to avoid misleading generated clients.

Testing Strategy

  • Build tests around the API harness (NewApiTest) to obtain a configured Gin router, config, and dependencies. This isolates filesystem paths and avoids polluting global state.
  • Wrap requests with helper functions (for example, PerformRequestJSON, PerformAuthenticatedRequest) to capture status codes, headers, and payloads. Assert headers using constants from pkg/http/header.
  • When handlers interact with the database, initialize fixtures through config helpers such as config.NewTestConfig("api") or config.NewMinimalTestConfigWithDb("api", t.TempDir()) depending on fixture needs.
  • Stub external dependencies (httptest.Server) for remote calls and set AllowPrivate=true explicitly when the test server binds to loopback addresses.
  • Structure tests with table-driven subtests (t.Run("CaseName", ...)) and use PascalCase names. Provide cleanup functions (t.Cleanup) to remove temporary files or databases created during tests.
  • Do not run internal/api tests in parallel. These suites share fixture files, temporary assets, and database state, so parallel go test invocations can cause false failures and readonly/fixture-conflict errors.

Focused Test Runs

  • Fast iteration: go test ./internal/api -run '<Package|HandlerName>' -count=1
  • Cluster endpoints: go test ./internal/api -run 'Cluster' -count=1
  • Downloads and zip streaming: go test ./internal/api -run 'Download|Archive' -count=1
  • Combined CLI and API validation: pair go test ./internal/commands -run 'Cluster' -count=1 with the matching API suite to ensure DTOs remain compatible.
  • Keep focused internal/api runs sequential. Do not launch multiple go test ./internal/api ... commands at the same time.

Preflight Checklist

  • Format and regenerate documentation: make fmt-go swag-fmt swag
  • Compile backend: go build ./...
  • Execute targeted API suites: go test ./internal/api -run '<Name>' -count=1
  • Run integration-heavy checks before release: go test ./internal/service/cluster/registry -count=1 alongside relevant API routes to confirm cluster DTOs stay aligned.
  • Verify that photoprism show commands --json reflects any new API-driven flags or outputs when CLI exposure changes.

Documentation

Overview

Package api provides REST-API authentication and request handlers.

Copyright (c) 2018 - 2025 PhotoPrism UG. All rights reserved.

This program is free software: you can redistribute it and/or modify
it under Version 3 of the GNU Affero General Public License (the "AGPL"):
<https://docs.photoprism.app/license/agpl>

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.

The AGPL is supplemented by our Trademark and Brand Guidelines,
which describe how our Brand Assets may be used:
<https://www.photoprism.app/trademark>

Feel free to send an email to hello@photoprism.app if you have questions, want to support our work, or just want to say hello.

Additional information can be found in our Developer Guide: <https://docs.photoprism.app/developer-guide/>

Index

Constants

View Source
const (
	// MaxAuthRequestBytes bounds small authentication and credential-change payloads.
	MaxAuthRequestBytes int64 = 64 * 1024
	// MaxMutationRequestBytes bounds general JSON mutation payloads.
	MaxMutationRequestBytes int64 = 256 * 1024
	// MaxSelectionRequestBytes bounds selection-heavy batch mutation payloads.
	MaxSelectionRequestBytes int64 = 1024 * 1024
	// MaxVisionRequestBytes bounds Vision API payloads while still allowing supported data URLs.
	MaxVisionRequestBytes int64 = 32 * 1024 * 1024
	// MaxSessionRequestBytes bounds login request payloads.
	MaxSessionRequestBytes int64 = MaxAuthRequestBytes
	// MaxAlbumRequestBytes bounds album create and update payloads.
	MaxAlbumRequestBytes int64 = MaxMutationRequestBytes
	// MaxSettingsRequestBytes bounds settings and config option payloads.
	MaxSettingsRequestBytes int64 = MaxMutationRequestBytes
	// MaxClusterRegisterBytes bounds cluster registration and patch payloads.
	MaxClusterRegisterBytes int64 = MaxMutationRequestBytes
	// MaxUploadOptionsRequestBytes bounds upload-processing payloads.
	MaxUploadOptionsRequestBytes int64 = MaxMutationRequestBytes
	// MaxBatchPhotosEditBytes bounds batch photo edit payloads.
	MaxBatchPhotosEditBytes int64 = MaxSelectionRequestBytes
	// MaxMultipartOverheadBytes reserves room for multipart framing overhead.
	MaxMultipartOverheadBytes int64 = 1024 * 1024
	// MaxAvatarUploadBytes bounds avatar uploads including multipart overhead.
	MaxAvatarUploadBytes int64 = 20000000 + MaxMultipartOverheadBytes
	// MaxMCPRequestBytes bounds Model Context Protocol (MCP) JSON-RPC payloads.
	// The upstream SDK reads the full POST body into memory via io.ReadAll, so
	// this cap must be enforced at the handler boundary before dispatch.
	MaxMCPRequestBytes int64 = MaxMutationRequestBytes
)
View Source
const (
	UploadPath = "/upload"
)

UploadPath is the root directory underneath which user uploads are staged.

Variables

View Source
var AbortNotFound = func(c *gin.Context) {
	conf := get.Config()

	switch c.NegotiateFormat(gin.MIMEHTML, gin.MIMEJSON) {
	case gin.MIMEJSON:
		c.JSON(http.StatusNotFound, gin.H{"error": i18n.Msg(i18n.ErrNotFound)})
	default:
		var redirect string

		if root, path := conf.BaseUri("/"), c.Request.URL.Path; path != "" && path != root {
			redirect = root
		}

		values := gin.H{
			"signUp":   config.SignUp,
			"config":   conf.ClientPublic(),
			"error":    i18n.Msg(i18n.ErrNotFound),
			"code":     http.StatusNotFound,
			"redirect": redirect,
		}

		c.HTML(http.StatusNotFound, "404.gohtml", values)
	}

	c.Abort()
}

AbortNotFound renders a "404 Not Found" error page or JSON response.

View Source
var McpSessionTimeout = 5 * time.Minute

McpSessionTimeout configures the idle lifetime of MCP Streamable HTTP sessions. It is shorter than a typical IDE editing window so that sessions abandoned without a DELETE tear-down do not accumulate SDK-side bookkeeping for long periods; active clients renew the idle timer on every request, so interactive use is unaffected.

View Source
var MethodsPutPost = []string{http.MethodPut, http.MethodPost}

MethodsPutPost defines a string slice that contains the PUT and POST request methods.

View Source
var WebsocketTopics = []string{
	"user.*.*.*",
	"session.*.*.*",
	"log.fatal",
	"log.error",
	"log.warning",
	"log.warn",
	"log.info",
	"notify.*",
	"index.*",
	"upload.*",
	"import.*",
	"config.*",
	"count.*",
	"photos.*",
	"cameras.*",
	"lenses.*",
	"countries.*",
	"albums.*",
	"labels.*",
	"subjects.*",
	"people.*",
	"sync.*",
}

WebsocketTopics lists the event topics that are forwarded to connected websocket clients. Extensions may append additional topics during package initialization so they are subscribed as soon as the server starts accepting websocket connections.

Functions

func Abort

func Abort(c *gin.Context, code int, id i18n.Message, params ...any)

Abort writes a localized error response and stops further handler processing.

func AbortAlbumNotFound

func AbortAlbumNotFound(c *gin.Context)

AbortAlbumNotFound aborts with status code 404.

func AbortBadRequest

func AbortBadRequest(c *gin.Context, errs ...error)

AbortBadRequest attaches validation details and responds with status 400.

func AbortBusy

func AbortBusy(c *gin.Context)

AbortBusy responds with HTTP 429 to signal temporary overload.

func AbortDeleteFailed

func AbortDeleteFailed(c *gin.Context)

AbortDeleteFailed aborts with a generic 500 "delete failed" error.

func AbortEntityNotFound

func AbortEntityNotFound(c *gin.Context)

AbortEntityNotFound aborts with status code 404.

func AbortFeatureDisabled

func AbortFeatureDisabled(c *gin.Context)

AbortFeatureDisabled aborts with a forbidden response when a feature is disabled.

func AbortForbidden

func AbortForbidden(c *gin.Context)

AbortForbidden aborts with status code 403.

func AbortInvalidCredentials

func AbortInvalidCredentials(c *gin.Context)

AbortInvalidCredentials responds with HTTP 401 for failed authentication attempts.

func AbortInvalidName

func AbortInvalidName(c *gin.Context)

AbortInvalidName aborts with HTTP 400 when a name fails validation.

func AbortNotImplemented

func AbortNotImplemented(c *gin.Context)

AbortNotImplemented aborts with status 501 when a feature is unavailable.

func AbortPaymentRequired

func AbortPaymentRequired(c *gin.Context)

AbortPaymentRequired aborts with status code 402.

func AbortQuotaExceeded

func AbortQuotaExceeded(c *gin.Context)

AbortQuotaExceeded aborts with a forbidden response when quotas are exhausted.

func AbortRequestTooLarge

func AbortRequestTooLarge(c *gin.Context, id i18n.Message)

AbortRequestTooLarge writes a localized 413 response and stops the current request.

func AbortSaveFailed

func AbortSaveFailed(c *gin.Context)

AbortSaveFailed aborts with a generic 500 "save failed" error.

func AbortUnauthorized

func AbortUnauthorized(c *gin.Context)

AbortUnauthorized aborts with status code 401.

func AbortUnexpectedError

func AbortUnexpectedError(c *gin.Context)

AbortUnexpectedError aborts with a generic 500 error.

func AbortVideo

func AbortVideo(c *gin.Context)

AbortVideo writes a placeholder MP4 response for video errors.

func AbortVideoWithStatus

func AbortVideoWithStatus(c *gin.Context, code int)

AbortVideoWithStatus writes the placeholder MP4 response using the provided status code.

func ActivateUserPasscode

func ActivateUserPasscode(router *gin.RouterGroup)

ActivateUserPasscode activates 2FA after a passcode has been created and verified.

@Summary	activate 2FA with a verified passcode
@Id			ActivateUserPasscode
@Tags		Users
@Produce	json
@Param		uid				path		string	true	"user uid"
@Success	200				{object}	entity.Passcode
@Failure	401,403,404,429	{object}	i18n.Response
@Router		/api/v1/users/{uid}/passcode/activate [post]

func AddCacheHeader

func AddCacheHeader(c *gin.Context, duration ttl.Duration, public bool)

AddCacheHeader adds a cache control header to the response.

func AddContentTypeHeader

func AddContentTypeHeader(c *gin.Context, contentType string)

AddContentTypeHeader adds a "Content-Type" header to the response.

func AddCountHeader

func AddCountHeader(c *gin.Context, count int)

AddCountHeader adds the actual result count to the response.

func AddCoverCacheHeader

func AddCoverCacheHeader(c *gin.Context)

AddCoverCacheHeader adds cover image cache control headers to the response.

func AddDownloadHeader

func AddDownloadHeader(c *gin.Context, fileName string)

AddDownloadHeader adds a header indicating the response is expected to be downloaded.

func AddFileCountHeaders

func AddFileCountHeaders(c *gin.Context, filesCount, foldersCount int)

AddFileCountHeaders adds file and folder counts to the response.

func AddImmutableCacheHeader

func AddImmutableCacheHeader(c *gin.Context)

AddImmutableCacheHeader adds cache control headers to the response for immutable content like thumbnails.

func AddLimitHeader

func AddLimitHeader(c *gin.Context, limit int)

AddLimitHeader adds the max result count to the response.

func AddOffsetHeader

func AddOffsetHeader(c *gin.Context, offset int)

AddOffsetHeader adds the result offset to the response.

func AddPhotoLabel

func AddPhotoLabel(router *gin.RouterGroup)

AddPhotoLabel adds a label to a photo.

@Summary	adds a label to a photo
@Id			AddPhotoLabel
@Tags		Labels, Photos
@Accept		json
@Produce	json
@Success	200						{object}	entity.Photo
@Failure	400,401,403,404,429,500	{object}	i18n.Response
@Param		label					body		form.Label	true	"label properties"
@Param		uid						path		string		true	"photo uid"
@Router		/api/v1/photos/{uid}/label [post]

func AddPhotosToAlbum

func AddPhotosToAlbum(router *gin.RouterGroup)

AddPhotosToAlbum adds photos to an album.

@Summary	adds photos to an album
@Id			AddPhotosToAlbum
@Tags		Albums
@Accept		json
@Produce	json
@Success	200					{object}	gin.H
@Failure	400,401,403,404,429	{object}	i18n.Response
@Param		photos				body		form.Selection	true	"Photo Selection"
@Param		uid					path		string			true	"Album UID"
@Router		/api/v1/albums/{uid}/photos [post]

func AddService

func AddService(router *gin.RouterGroup)

AddService creates a new remote account configuration.

@Summary	creates a new remote service account configuration
@Id			AddService
@Tags		Services
@Accept		json
@Produce	json
@Success	201				{object}	entity.Service
@Failure	400,401,403,429	{object}	i18n.Response
@Param		service			body		form.Service	true	"properties of the service to be created"
@Router		/api/v1/services [post]

func AddTokenHeaders

func AddTokenHeaders(c *gin.Context, s *entity.Session)

AddTokenHeaders adds preview token headers to the response.

func AddVideoCacheHeader

func AddVideoCacheHeader(c *gin.Context, cdn bool)

AddVideoCacheHeader adds video cache control headers to the response.

func AlbumCover

func AlbumCover(router *gin.RouterGroup)

AlbumCover returns an album cover image.

@Summary	returns an album cover image
@Id			AlbumCover
@Produce	image/jpeg
@Produce	image/svg+xml
@Tags		Images, Albums
@Failure	403		{file}	image/svg+xml
@Failure	200		{file}	image/svg+xml
@Success	200		{file}	image/jpg
@Param		uid		path	string	true	"Album UID"
@Param		token	path	string	true	"user-specific security token provided with session or 'public' when running PhotoPrism in public mode"
@Param		size	path	string	true	"thumbnail size"	Enums(tile_50, tile_100, left_224, right_224, tile_224, tile_500, fit_720, tile_1080, fit_1280, fit_1600, fit_1920, fit_2048, fit_2560, fit_3840, fit_4096, fit_7680)
@Router		/api/v1/albums/{uid}/t/{token}/{size} [get]

func AlbumDownloadName

func AlbumDownloadName(c *gin.Context) customize.DownloadName

AlbumDownloadName returns the album download file name type.

func AppendWebsocketTopics

func AppendWebsocketTopics(topics ...string)

AppendWebsocketTopics adds the provided topics to the global websocket topic list.

func ApprovePhoto

func ApprovePhoto(router *gin.RouterGroup)

ApprovePhoto marks a photo in review as approved.

@Summary	marks a photo in review as approved
@Id			ApprovePhoto
@Tags		Photos
@Accept		json
@Produce	json
@Success	200					{object}	gin.H
@Failure	401,403,404,429,500	{object}	i18n.Response
@Param		uid					path		string	true	"photo uid"
@Router		/api/v1/photos/{uid}/approve [post]

func Auth

func Auth(c *gin.Context, resource acl.Resource, perm acl.Permission) *entity.Session

Auth checks if the user is authorized to access a resource with the given permission and returns the session or nil otherwise.

func AuthAny

func AuthAny(c *gin.Context, resource acl.Resource, perms acl.Permissions) (s *entity.Session)

AuthAny checks if the user is authorized to access a resource with any of the specified permissions and returns the session or nil otherwise.

func AuthToken

func AuthToken(c *gin.Context) string

AuthToken returns the client authentication token from the request context if one was found, or an empty string if no supported request header value was provided.

func BatchAlbumsDelete

func BatchAlbumsDelete(router *gin.RouterGroup)

BatchAlbumsDelete permanently removes multiple albums.

@Summary	permanently removes multiple albums
@Id			BatchAlbumsDelete
@Tags		Albums
@Accept		json
@Produce	json
@Success	200					{object}	i18n.Response
@Failure	400,401,403,404,429	{object}	i18n.Response
@Param		albums				body		form.Selection	true	"Album Selection"
@Router		/api/v1/batch/albums/delete [post]

func BatchLabelsDelete

func BatchLabelsDelete(router *gin.RouterGroup)

BatchLabelsDelete deletes multiple labels.

@Summary	deletes multiple labels
@Id			BatchLabelsDelete
@Tags		Labels
@Accept		json
@Produce	json
@Success	200					{object}	i18n.Response
@Failure	400,401,403,429,500	{object}	i18n.Response
@Param		labels				body		form.Selection	true	"Label Selection"
@Router		/api/v1/batch/labels/delete [post]

func BatchPhotosApprove

func BatchPhotosApprove(router *gin.RouterGroup)

BatchPhotosApprove approves multiple photos that are currently under review.

@Summary	approves multiple photos that are currently under review
@Id			BatchPhotosApprove
@Tags		Photos
@Accept		json
@Produce	json
@Success	200					{object}	i18n.Response
@Failure	400,401,403,404,429	{object}	i18n.Response
@Param		photos				body		form.Selection	true	"Photo Selection"
@Router		/api/v1/batch/photos/approve [post]

func BatchPhotosArchive

func BatchPhotosArchive(router *gin.RouterGroup)

BatchPhotosArchive moves multiple photos to the archive.

@Summary	moves multiple photos to the archive
@Id			BatchPhotosArchive
@Tags		Photos
@Accept		json
@Produce	json
@Success	200						{object}	i18n.Response
@Failure	400,401,403,404,429,500	{object}	i18n.Response
@Param		photos					body		form.Selection	true	"Photo Selection"
@Router		/api/v1/batch/photos/archive [post]

func BatchPhotosDelete

func BatchPhotosDelete(router *gin.RouterGroup)

BatchPhotosDelete permanently removes multiple photos from the archive.

@Summary	permanently removes multiple or all photos from the archive
@Id			BatchPhotosDelete
@Tags		Photos
@Accept		json
@Produce	json
@Success	200				{object}	i18n.Response
@Failure	400,401,403,429	{object}	i18n.Response
@Param		photos			body		form.Selection	true	"All or Photo Selection"
@Router		/api/v1/batch/photos/delete [post]

func BatchPhotosEdit

func BatchPhotosEdit(router *gin.RouterGroup)

BatchPhotosEdit returns and updates the metadata of multiple photos.

@Summary	returns and updates the metadata of multiple photos
@Id			BatchPhotosEdit
@Tags		Photos
@Accept		json
@Produce	json
@Success	200						{object}	batch.PhotosResponse
@Failure	400,401,403,404,429,500	{object}	i18n.Response
@Param		Request					body		batch.PhotosRequest	true	"photos selection and values"
@Router		/api/v1/batch/photos/edit [post]

func BatchPhotosPrivate

func BatchPhotosPrivate(router *gin.RouterGroup)

BatchPhotosPrivate toggles private state of multiple photos.

@Summary	toggles private state of multiple photos
@Id			BatchPhotosPrivate
@Tags		Photos
@Accept		json
@Produce	json
@Success	200						{object}	i18n.Response
@Failure	400,401,403,404,429,500	{object}	i18n.Response
@Param		photos					body		form.Selection	true	"Photo Selection"
@Router		/api/v1/batch/photos/private [post]

func BatchPhotosRestore

func BatchPhotosRestore(router *gin.RouterGroup)

BatchPhotosRestore restores multiple photos from the archive.

@Summary	restores multiple photos from the archive
@Id			BatchPhotosRestore
@Tags		Photos
@Accept		json
@Produce	json
@Success	200						{object}	i18n.Response
@Failure	400,401,403,404,429,500	{object}	i18n.Response
@Param		photos					body		form.Selection	true	"Photo Selection"
@Router		/api/v1/batch/photos/restore [post]

func CacheKey

func CacheKey(ns, uid, name string) string

CacheKey returns a cache key string based on namespace, uid and name.

func CancelImport

func CancelImport(router *gin.RouterGroup)

CancelImport stops the current import operation.

@Summary	cancels the active import job
@Id			CancelImport
@Tags		Library
@Produce	json
@Success	200				{object}	i18n.Response
@Failure	401,403,404,429	{object}	i18n.Response
@Router		/api/v1/import [delete]

func CancelIndexing

func CancelIndexing(router *gin.RouterGroup)

CancelIndexing stops indexing media files in the "originals" folder.

@Summary	cancels the active indexing job
@Id			CancelIndexing
@Tags		Library
@Produce	json
@Success	200				{object}	i18n.Response
@Failure	401,403,404,429	{object}	i18n.Response
@Router		/api/v1/index [delete]

func ChangeFileOrientation

func ChangeFileOrientation(router *gin.RouterGroup)

ChangeFileOrientation changes the orientation of a file.

@Summary	changes the orientation of a file
@Id			ChangeFileOrientation
@Tags		Files
@Accept		json
@Produce	json
@Success	200						{object}	entity.Photo
@Failure	400,401,403,404,429,500	{object}	i18n.Response
@Param		uid						path		string		true	"photo uid"
@Param		fileuid					path		string		true	"file uid"
@Param		file					body		form.File	true	"file orientation"
@Router		/api/v1/photos/{uid}/files/{fileuid}/orientation [put]

func ClearMarkerSubject

func ClearMarkerSubject(router *gin.RouterGroup)

ClearMarkerSubject removes the subject association from a marker.

@Summary	clear the subject of a marker
@Id			ClearMarkerSubject
@Tags		Files
@Produce	json
@Param		marker_uid			path		string	true	"marker uid"
@Success	200					{object}	entity.Marker
@Failure	400,401,403,404,429	{object}	i18n.Response
@Router		/api/v1/markers/{marker_uid}/subject [delete]

func ClientIP

func ClientIP(c *gin.Context) (ip string)

ClientIP returns the client IP address from the request context or a placeholder if it is unknown.

func CloneAlbums

func CloneAlbums(router *gin.RouterGroup)

CloneAlbums creates a new album containing pictures from other albums.

@Summary	creates a new album containing pictures from other albums
@Id			CloneAlbums
@Tags		Albums
@Accept		json
@Produce	json
@Success	200					{object}	gin.H
@Failure	400,401,403,404,429	{object}	i18n.Response
@Param		albums				body		form.Selection	true	"Album Selection"
@Param		uid					path		string			true	"UID of the album to which the pictures are to be added"
@Router		/api/v1/albums/{uid}/clone [post]

func ClusterDeleteNode

func ClusterDeleteNode(router *gin.RouterGroup)

ClusterDeleteNode removes a node entry from the registry.

@Summary	delete node by uuid
@Id			ClusterDeleteNode
@Tags		Cluster
@Produce	json
@Param		uuid			path		string	true	"node uuid"
@Success	200				{object}	cluster.StatusResponse
@Failure	401,403,404,429	{object}	i18n.Response
@Router		/api/v1/cluster/nodes/{uuid} [delete]

func ClusterGetNode

func ClusterGetNode(router *gin.RouterGroup)

ClusterGetNode returns a single node by uuid.

@Summary	get node by uuid
@Id			ClusterGetNode
@Tags		Cluster
@Produce	json
@Param		uuid			path		string	true	"node uuid"
@Success	200				{object}	cluster.Node
@Failure	401,403,404,429	{object}	i18n.Response
@Router		/api/v1/cluster/nodes/{uuid} [get]

func ClusterGetTheme

func ClusterGetTheme(router *gin.RouterGroup)

ClusterGetTheme returns custom theme files as zip, if available.

@Summary	returns custom theme files as zip, if available
@Id			ClusterGetTheme
@Tags		Cluster
@Produce	application/zip
@Success	200				{file}		application/zip
@Failure	401,403,404,429	{object}	i18n.Response
@Router		/api/v1/cluster/theme [get]

func ClusterHealth

func ClusterHealth(router *gin.RouterGroup)

ClusterHealth returns minimal health information.

@Summary	cluster health
@Id			ClusterHealth
@Tags		Cluster
@Produce	json
@Success	200			{object}	HealthResponse
@Failure	401,403,429	{object}	i18n.Response
@Router		/api/v1/cluster/health [get]

func ClusterListNodes

func ClusterListNodes(router *gin.RouterGroup)

ClusterListNodes lists registered nodes from the file-backed registry.

@Summary	lists registered nodes
@Id			ClusterListNodes
@Tags		Cluster
@Produce	json
@Param		count		query		int	false	"maximum number of results (default 100, max 1000)"	minimum(1)	maximum(1000)
@Param		offset		query		int	false	"result offset"										minimum(0)
@Success	200			{array}		cluster.Node
@Failure	401,403,429	{object}	i18n.Response
@Router		/api/v1/cluster/nodes [get]

func ClusterMetrics

func ClusterMetrics(router *gin.RouterGroup)

ClusterMetrics returns lightweight metrics about the cluster.

@Summary	temporary cluster metrics (counts only)
@Id			ClusterMetrics
@Tags		Cluster
@Produce	json
@Success	200			{object}	cluster.MetricsResponse
@Failure	401,403,429	{object}	i18n.Response
@Router		/api/v1/cluster/metrics [get]

func ClusterNodesRegister

func ClusterNodesRegister(router *gin.RouterGroup)

ClusterNodesRegister registers the Portal-only node registration endpoint.

@Summary	registers a node, provisions DB credentials, and issues ClientSecret
@Id			ClusterNodesRegister
@Tags		Cluster
@Accept		json
@Produce	json
@Param		request				body		object	true	"registration payload (NodeName required; optional: NodeRole, Labels, AdvertiseUrl, SiteUrl, AppName, AppVersion, Theme, NodeUUID, RotateDatabase, RotateSecret). New-node joins require the Bearer join token. Existing-node mutations require a Bearer OAuth access token that belongs to the same node client."
@Success	200,201				{object}	cluster.RegisterResponse
@Failure	400,401,403,409,429	{object}	i18n.Response
@Router		/api/v1/cluster/nodes/register [post]

func ClusterSummary

func ClusterSummary(router *gin.RouterGroup)

ClusterSummary returns a minimal overview of the cluster/portal.

@Summary	cluster summary
@Id			ClusterSummary
@Tags		Cluster
@Produce	json
@Success	200			{object}	cluster.SummaryResponse
@Failure	401,403,429	{object}	i18n.Response
@Router		/api/v1/cluster [get]

func ClusterUpdateNode

func ClusterUpdateNode(router *gin.RouterGroup)

ClusterUpdateNode updates mutable fields: role, labels, AdvertiseUrl.

@Summary	update node fields
@Id			ClusterUpdateNode
@Tags		Cluster
@Accept		json
@Produce	json
@Param		uuid				path		string	true	"node uuid"
@Param		node				body		object	true	"properties to update (Role, Labels, AdvertiseUrl, SiteUrl)"
@Success	200					{object}	cluster.StatusResponse
@Failure	400,401,403,404,429	{object}	i18n.Response
@Router		/api/v1/cluster/nodes/{uuid} [patch]

func ConfirmUserPasscode

func ConfirmUserPasscode(router *gin.RouterGroup)

ConfirmUserPasscode verifies a newly created passcode so that it can be activated.

@Summary	verify a new 2FA passcode
@Id			ConfirmUserPasscode
@Tags		Users
@Accept		json
@Produce	json
@Param		uid				path		string			true	"user uid"
@Param		request			body		form.Passcode	true	"verification code"
@Success	200				{object}	entity.Passcode
@Failure	400,401,403,429	{object}	i18n.Response
@Router		/api/v1/users/{uid}/passcode/confirm [post]

func Connect

func Connect(router *gin.RouterGroup)

Connect confirms external service accounts using a token.

@Summary	confirm external service accounts using a token
@Id			ConnectService
@Tags		Config
@Accept		json
@Produce	json
@Param		name		path		string			true	"service name (e.g., hub)"
@Param		connect		body		form.Connect	true	"connection token"
@Success	200			{object}	gin.H
@Failure	400,401,403	{object}	i18n.Response
@Router		/api/v1/connect/{name} [put]

func CreateAlbum

func CreateAlbum(router *gin.RouterGroup)

CreateAlbum creates a new album.

@Summary		creates a new album
@Description	Posting a title that matches a soft-deleted manual album restores it (including existing photo assignments). Use DELETE with `force=true` to purge an album before recreating it from scratch.
@Id				CreateAlbum
@Tags			Albums
@Accept			json
@Produce		json
@Success		200					{object}	entity.Album
@Success		201					{object}	entity.Album
@Failure		400,401,403,429,500	{object}	i18n.Response
@Param			album				body		form.Album	true	"properties of the album to be created (currently supports Title and Favorite)"
@Router			/api/v1/albums [post]
func CreateAlbumLink(router *gin.RouterGroup)

CreateAlbumLink adds a new album share link and return it as JSON.

@Summary	adds a new album share link and return it as JSON
@Id			CreateAlbumLink
@Tags		Links, Albums
@Accept		json
@Produce	json
@Success	200						{object}	entity.Link
@Failure	400,401,403,404,409,429	{object}	i18n.Response
@Param		uid						path		string		true	"album uid"
@Param		link					body		form.Link	true	"link properties (currently supported: slug, expires)"
@Router		/api/v1/albums/{uid}/links [post]
func CreateLink(c *gin.Context)

CreateLink adds a new share link and returns it as JSON. Note: Internal helper used by resource-specific endpoints (e.g., albums, photos). Swagger annotations are defined on those public handlers to avoid generating undocumented generic paths like "/api/v1/{entity}/{uid}/links".

func CreateMarker

func CreateMarker(router *gin.RouterGroup)

CreateMarker adds a new file area marker to assign faces or other subjects.

See internal/form/marker.go for the values required to create a new marker.

@Tags		Files
@Produce	json
@Success	201	{object}	entity.Marker
@Router		/api/v1/markers [post]

func CreateSession

func CreateSession(router *gin.RouterGroup)

CreateSession creates a new client session (login) and returns session data.

@Summary	create a session (login)
@Tags		Authentication
@Accept		json
@Produce	json
@Param		credentials	body		form.Login	true	"login credentials"
@Success	200			{object}	gin.H
@Failure	400,401,429	{object}	i18n.Response
@Router		/api/v1/session [post]
@Router		/api/v1/sessions [post]

func CreateSessionError

func CreateSessionError(code int, err error) gin.H

CreateSessionError returns an authentication error response.

func CreateSessionResponse

func CreateSessionResponse(authToken string, sess *entity.Session, conf *config.ClientConfig) gin.H

CreateSessionResponse returns the authentication response data for POST requests based on the session and configuration.

func CreateUserPasscode

func CreateUserPasscode(router *gin.RouterGroup)

CreateUserPasscode sets up a new two-factor authentication passcode for a user.

@Summary	create a new 2FA passcode for a user
@Id			CreateUserPasscode
@Tags		Users
@Accept		json
@Produce	json
@Param		uid				path		string			true	"user uid"
@Param		request			body		form.Passcode	true	"passcode setup (password required)"
@Success	201				{object}	entity.Passcode
@Failure	400,401,403,429	{object}	i18n.Response
@Router		/api/v1/users/{uid}/passcode [post]

func DeactivateUserPasscode

func DeactivateUserPasscode(router *gin.RouterGroup)

DeactivateUserPasscode removes a passcode key to disable two-factor authentication.

@Summary	deactivate 2FA and remove the passcode
@Id			DeactivateUserPasscode
@Tags		Users
@Accept		json
@Produce	json
@Param		uid					path		string			true	"user uid"
@Param		request				body		form.Passcode	true	"password for confirmation"
@Success	200					{object}	i18n.Response
@Failure	400,401,403,404,429	{object}	i18n.Response
@Router		/api/v1/users/{uid}/passcode/deactivate [post]

func DeleteAlbum

func DeleteAlbum(router *gin.RouterGroup)

DeleteAlbum deletes an existing album.

@Summary	deletes an existing album
@Id			DeleteAlbum
@Tags		Albums
@Accept		json
@Produce	json
@Failure	401,403,404,429,500	{object}	i18n.Response
@Param		uid					path		string	true	"Album UID"
@Param		force				query		boolean	false	"Set to true to permanently delete a manual album instead of archiving it."
@Router		/api/v1/albums/{uid} [delete]
func DeleteAlbumLink(router *gin.RouterGroup)

DeleteAlbumLink deletes an album share link.

@Summary	deletes an album share link
@Id			DeleteAlbumLink
@Tags		Links, Albums
@Accept		json
@Produce	json
@Success	200				{object}	entity.Link
@Failure	401,403,429,409	{object}	i18n.Response
@Param		uid				path		string	true	"album"
@Param		linkuid			path		string	true	"link uid"
@Router		/api/v1/albums/{uid}/links/{linkuid} [delete]

func DeleteAlbumYaml

func DeleteAlbumYaml(album entity.Album)

DeleteAlbumYaml removes the YAML backup file for the provided album if it exists.

func DeleteErrors

func DeleteErrors(router *gin.RouterGroup)

DeleteErrors removes all entries from the error logs.

@Summary	removes all entries from the error logs
@Id			DeleteErrors
@Tags		Logs
@Accept		json
@Produce	json
@Failure	401,403,429,500	{object}	i18n.Response
@Router		/api/v1/errors [delete]

func DeleteFile

func DeleteFile(router *gin.RouterGroup)

DeleteFile removes a file from storage.

@Summary	removes a file from storage
@Id			DeleteFile
@Tags		Files
@Accept		json
@Produce	json
@Success	200					{object}	entity.Photo
@Failure	401,403,404,429,500	{object}	i18n.Response
@Param		uid					path		string	true	"photo uid"
@Param		fileuid				path		string	true	"file uid"
@Router		/api/v1/photos/{uid}/files/{fileuid} [delete]
func DeleteLink(c *gin.Context)

DeleteLink deletes a share link.

DELETE /api/v1/:entity/:uid/links/:link

func DeleteService

func DeleteService(router *gin.RouterGroup)

DeleteService removes a remote account configuration.

@Summary	removes a remote service account configuration
@Id			DeleteService
@Tags		Services
@Accept		json
@Produce	json
@Success	200				{object}	entity.Service
@Failure	401,403,404,429	{object}	i18n.Response
@Param		id				path		string	true	"service id"
@Router		/api/v1/services/{id} [delete]

func DeleteSession

func DeleteSession(router *gin.RouterGroup)

DeleteSession deletes an existing client session (logout).

@Summary	delete a session (logout)
@Tags		Authentication
@Produce	json
@Param		id				path		string	false	"session id or ref id"
@Success	200				{object}	gin.H
@Failure	401,403,404,429	{object}	i18n.Response
@Router		/api/v1/session [delete]
@Router		/api/v1/session/{id} [delete]
@Router		/api/v1/sessions/{id} [delete]

func DeleteSessionResponse

func DeleteSessionResponse(id string) gin.H

DeleteSessionResponse returns a confirmation response for DELETE requests.

func DislikeAlbum

func DislikeAlbum(router *gin.RouterGroup)

DislikeAlbum removes the favorite flag from an album.

@Summary	removes the favorite flag from an album
@Id			DislikeAlbum
@Tags		Albums
@Accept		json
@Produce	json
@Failure	401,403,404,429,500	{object}	i18n.Response
@Param		uid					path		string	true	"Album UID"
@Router		/api/v1/albums/{uid}/like [delete]

func DislikeLabel

func DislikeLabel(router *gin.RouterGroup)

DislikeLabel removes the favorite flag from a label.

@Summary	removes favorite flag from a label
@Id			DislikeLabel
@Tags		Labels
@Accept		json
@Produce	json
@Failure	401,403,404,429	{object}	i18n.Response
@Param		uid				path		string	true	"Label UID"
@Router		/api/v1/labels/{uid}/like [delete]

func DislikePhoto

func DislikePhoto(router *gin.RouterGroup)

DislikePhoto removes the favorite flags from a photo.

@Summary	removes the favorite flags from a photo
@Id			DislikePhoto
@Tags		Photos
@Accept		json
@Produce	json
@Success	200				{object}	gin.H
@Failure	401,403,404,500	{object}	i18n.Response
@Param		uid				path		string	true	"photo uid"
@Router		/api/v1/photos/{uid}/like [delete]

func DislikeSubject

func DislikeSubject(router *gin.RouterGroup)

DislikeSubject removes the favorite flag from a subject.

@Summary	removes the favorite flag from a subject
@Id			DislikeSubject
@Tags		Subjects
@Accept		json
@Produce	json
@Failure	401,403,404,429,500	{object}	i18n.Response
@Param		uid					path		string	true	"subject uid"
@Router		/api/v1/subjects/{uid}/like [delete]

func DownloadAlbum

func DownloadAlbum(router *gin.RouterGroup)

DownloadAlbum streams the album contents as zip archive.

@Summary	streams the album contents as zip archive
@Id			DownloadAlbum
@Tags		Albums, Download
@Produce	application/zip
@Failure	403,404,500	{object}	i18n.Response
@Success	200			{file}		application/zip
@Param		uid			path		string	true	"Album UID"
@Router		/api/v1/albums/{uid}/dl [get]

func DownloadName

func DownloadName(c *gin.Context) customize.DownloadName

DownloadName returns the download file name type.

func Echo

func Echo(router *gin.RouterGroup)

Echo returns the request and response headers as JSON if debug mode is enabled.

@Summary	returns the request and response headers as JSON if debug mode is enabled
@Id			Echo
@Tags		Debug
@Success	200
@Router		/api/v1/echo [get]

func Error

func Error(c *gin.Context, code int, err error, id i18n.Message, params ...any)

Error aborts the request while attaching error details to the response payload.

func FindUserSessions

func FindUserSessions(router *gin.RouterGroup)

FindUserSessions finds user sessions and returns them as JSON.

@Summary	list sessions for a user
@Id			FindUserSessions
@Tags		Users, Authentication
@Produce	json
@Param		uid			path		string	true	"user uid"
@Param		count		query		int		true	"maximum number of results"	minimum(1)	maximum(100000)
@Param		offset		query		int		false	"result offset"				minimum(0)
@Param		q			query		string	false	"filter by username or client name"
@Success	200			{object}	entity.Sessions
@Failure	401,403,429	{object}	i18n.Response
@Router		/api/v1/users/{uid}/sessions [get]

func FlushCoverCache

func FlushCoverCache()

FlushCoverCache clears the complete cover cache.

func FolderCover

func FolderCover(router *gin.RouterGroup)

FolderCover returns a folder cover image.

@Summary	returns a folder cover image
@Id			FolderCover
@Produce	image/jpeg
@Produce	image/svg+xml
@Tags		Images, Folders
@Failure	403		{file}	image/svg+xml
@Failure	200		{file}	image/svg+xml
@Success	200		{file}	image/jpg
@Param		uid		path	string	true	"folder uid"
@Param		token	path	string	true	"user-specific security token provided with session or 'public' when running PhotoPrism in public mode"
@Param		size	path	string	true	"thumbnail size"	Enums(tile_50, tile_100, left_224, right_224, tile_224, tile_500, fit_720, tile_1080, fit_1280, fit_1600, fit_1920, fit_2048, fit_2560, fit_3840, fit_4096, fit_7680)
@Router		/api/v1/folders/t/{uid}/{token}/{size} [get]

func GetAlbum

func GetAlbum(router *gin.RouterGroup)

GetAlbum returns album details as JSON.

@Summary	returns album details as JSON
@Id			GetAlbum
@Tags		Albums
@Produce	json
@Success	200				{object}	entity.Album
@Failure	401,403,404,429	{object}	i18n.Response
@Param		uid				path		string	true	"Album UID"
@Router		/api/v1/albums/{uid} [get]
func GetAlbumLinks(router *gin.RouterGroup)

GetAlbumLinks returns all share links for the given UID as JSON.

@Summary	returns all share links for the given UID as JSON
@Id			GetAlbumLinks
@Tags		Links, Albums
@Produce	json
@Success	200				{array}		entity.Link
@Failure	401,403,404,429	{object}	i18n.Response
@Param		uid				path		string	true	"album uid"
@Router		/api/v1/albums/{uid}/links [get]

func GetClientConfig

func GetClientConfig(router *gin.RouterGroup)

GetClientConfig returns the client configuration values as JSON.

@Summary	get client configuration
@Id			GetClientConfig
@Tags		Config
@Produce	json
@Success	200	{object}	gin.H
@Failure	401	{object}	i18n.Response
@Router		/api/v1/config [get]

func GetConfigOptions

func GetConfigOptions(router *gin.RouterGroup)

GetConfigOptions returns backend config options.

@Summary	returns backend config options
@Id			GetConfigOptions
@Tags		Config, Settings
@Produce	json
@Success	200			{object}	config.Options
@Failure	401,403,429	{object}	i18n.Response
@Router		/api/v1/config/options [get]

func GetDownload

func GetDownload(router *gin.RouterGroup)

GetDownload returns the raw file data.

@Summary	returns the raw file data
@Id			GetDownload
@Tags		Images, Files
@Produce	application/octet-stream
@Failure	403,404	{file}	image/svg+xml
@Success	200		{file}	application/octet-stream
@Param		file	path	string	true	"file hash or unique download id"
@Router		/api/v1/dl/{file} [get]

func GetErrors

func GetErrors(router *gin.RouterGroup)

GetErrors searches the error logs and returns the results as JSON.

@Summary	searches the error logs and returns the results as JSON
@Id			GetErrors
@Tags		Logs
@Produce	json
@Success	200				{object}	entity.Error
@Failure	401,403,429,400	{object}	i18n.Response
@Param		count			query		int		true	"maximum number of results"	minimum(1)	maximum(100000)
@Param		offset			query		int		false	"search result offset"		minimum(0)	maximum(100000)
@Param		q				query		string	false	"search query"
@Router		/api/v1/errors [get]

func GetFace

func GetFace(router *gin.RouterGroup)

GetFace returns a face as JSON.

@Summary	returns a face as JSON
@Id			GetFace
@Tags		Faces
@Produce	json
@Success	200				{object}	entity.Face
@Failure	401,403,404,429	{object}	i18n.Response
@Param		id				path		string	true	"face id"
@Router		/api/v1/faces/{id} [get]

func GetFile

func GetFile(router *gin.RouterGroup)

GetFile returns file details as JSON.

@Summary	returns file details as JSON
@Id			GetFile
@Tags		Files
@Produce	json
@Success	200				{object}	entity.File
@Failure	401,403,404,429	{object}	i18n.Response
@Param		hash			path		string	true	"hash (string) SHA-1 hash of the file"
@Router		/api/v1/files/{hash} [get]

func GetMetrics

func GetMetrics(router *gin.RouterGroup)

GetMetrics provides a Prometheus-compatible metrics endpoint for monitoring the instance, including usage details and portal cluster metrics.

@Summary	a prometheus-compatible metrics endpoint for monitoring this instance
@Id			GetMetrics
@Tags		Metrics
@Produce	plain
@Success	200		{object}	[]dto.MetricFamily
@Failure	401,403	{object}	i18n.Response
@Router		/api/v1/metrics [get]

func GetMomentsTime

func GetMomentsTime(router *gin.RouterGroup)

GetMomentsTime returns monthly albums as JSON.

@Summary	returns monthly albums as JSON
@Id			GetMomentsTime
@Tags		Albums
@Produce	json
@Success	200				{array}		query.Moment
@Failure	401,403,429,500	{object}	i18n.Response
@Router		/api/v1/moments/time [get]

func GetPhoto

func GetPhoto(router *gin.RouterGroup)

GetPhoto returns picture details as JSON.

@Summary	returns picture details as JSON
@Id			GetPhoto
@Tags		Photos
@Produce	json
@Success	200				{object}	entity.Photo
@Failure	401,403,404,429	{object}	i18n.Response
@Param		uid				path		string	true	"Photo UID"
@Router		/api/v1/photos/{uid} [get]

func GetPhotoDownload

func GetPhotoDownload(router *gin.RouterGroup)

GetPhotoDownload returns the primary file matching that belongs to the photo.

@Summary	returns the primary file matching that belongs to the photo
@Id			GetPhotoDownload
@Tags		Images, Files
@Produce	application/octet-stream
@Failure	403,404	{file}	image/svg+xml
@Success	200		{file}	application/octet-stream
@Param		uid		path	string	true	"photo uid"
@Router		/api/v1/photos/{uid}/dl [get]

func GetPhotoYaml

func GetPhotoYaml(router *gin.RouterGroup)

GetPhotoYaml returns picture details as YAML.

@Summary	returns picture details as YAML
@Id			GetPhotoYaml
@Tags		Photos
@Produce	text/x-yaml
@Failure	401,403,404,429,500	{object}	i18n.Response
@Success	200					{file}		text/x-yaml
@Param		uid					path		string	true	"photo uid"
@Router		/api/v1/photos/{uid}/yaml [get]

func GetPlacesReverse

func GetPlacesReverse(router *gin.RouterGroup)

GetPlacesReverse returns location details for the specified coordinates.

GET /api/v1/places/reverse?lat=12.444526469291622&lng=-69.94435584903263

@Summary	returns location details for the specified coordinates
@Id			GetPlacesReverse
@Tags		Places
@Produce	json
@Param		lat		query		string	true	"Latitude"
@Param		lng		query		string	true	"Longitude"
@Param		locale	query		string	false	"Locale"
@Success	200		{object}	places.Location
@Failure	400		{object}	gin.H	"Missing latitude or longitude"
@Failure	401		{object}	i18n.Response
@Failure	500		{object}	gin.H	"Geocoding service error"
@Router		/api/v1/places/reverse [get]

func GetPlacesSearch

func GetPlacesSearch(router *gin.RouterGroup)

GetPlacesSearch returns locations that match the specified search query.

GET /api/v1/places/search?q=query&locale=en&count=10

@Summary	returns locations that match the specified search query
@Id			GetPlacesSearch
@Tags		Places
@Produce	json
@Param		q		query		string	true	"Search query"
@Param		locale	query		string	false	"Locale for results (default: en)"
@Param		count	query		int		false	"Maximum number of results (default: 10, max: 50)"
@Success	200		{object}	places.SearchResults
@Failure	400		{object}	gin.H	"Missing search query"
@Failure	401		{object}	i18n.Response
@Failure	500		{object}	gin.H	"Search service error"
@Router		/api/v1/places/search [get]

func GetService

func GetService(router *gin.RouterGroup)

GetService returns an account as JSON.

@Summary	returns the specified remote service account configuration as JSON
@Id			GetService
@Tags		Services
@Produce	json
@Success	200				{object}	entity.Service
@Failure	401,403,404,429	{object}	i18n.Response
@Param		id				path		string	true	"service id"
@Router		/api/v1/services/{id} [get]

func GetServiceFolders

func GetServiceFolders(router *gin.RouterGroup)

GetServiceFolders returns folders that belong to an account.

@Summary	returns folders that belong to a remote service account
@Id			GetServiceFolders
@Tags		Services
@Produce	json
@Success	200					{array}		object
@Failure	400,401,403,404,429	{object}	i18n.Response
@Param		id					path		string	true	"service id"
@Router		/api/v1/services/{id}/folders [get]

func GetSession

func GetSession(router *gin.RouterGroup)

GetSession returns session data for the current or specified session.

@Summary	get the current session or a session by id
@Tags		Authentication
@Produce	json
@Param		id				path		string	false	"session id"
@Success	200				{object}	gin.H
@Failure	401,403,404,429	{object}	i18n.Response
@Router		/api/v1/session [get]
@Router		/api/v1/session/{id} [get]
@Router		/api/v1/sessions/{id} [get]

func GetSessionResponse

func GetSessionResponse(authToken string, sess *entity.Session, conf *config.ClientConfig) gin.H

GetSessionResponse returns the authentication response data for GET requests based on the session and configuration.

func GetSettings

func GetSettings(router *gin.RouterGroup)

GetSettings returns the user app settings as JSON.

@Summary	returns the user app settings as JSON
@Id			GetSettings
@Tags		Settings
@Produce	json
@Success	200			{object}	customize.Settings
@Failure	401,403,404	{object}	i18n.Response
@Router		/api/v1/settings [get]

func GetStatus

func GetStatus(router *gin.RouterGroup)

GetStatus responds with status code 200 if the server is operational.

@Summary	responds with status code 200 if the server is operational
@Id			GetStatus
@Tags		Debug
@Produce	json
@Success	200	{object}	gin.H
@Router		/api/v1/status [get]

func GetSubject

func GetSubject(router *gin.RouterGroup)

GetSubject returns a subject as JSON.

@Summary	returns a subject as JSON
@Id			GetSubject
@Tags		Subjects
@Produce	json
@Success	200				{object}	entity.Subject
@Failure	401,403,404,429	{object}	i18n.Response
@Param		uid				path		string	true	"subject uid"
@Router		/api/v1/subjects/{uid} [get]

func GetSvg

func GetSvg(router *gin.RouterGroup)

GetSvg returns SVG placeholder symbols.

@Summary	returns SVG placeholder symbols for UI fallbacks
@Id			GetSvg
@Tags		Assets
@Produce	image/svg+xml
@Param		icon	path		string	true	"SVG icon name"	Enums(user,face,camera,photo,raw,file,video,label,portrait,folder,album,broken,uncached)
@Success	200		{string}	string	"SVG icon"
@Failure	404		{object}	gin.H	"Icon not found"
@Router		/api/v1/svg/{icon} [get]

func GetThumb

func GetThumb(router *gin.RouterGroup)

GetThumb returns a thumbnail image matching the file hash, crop area, and type.

@Summary		returns a thumbnail image with the requested size
@Description	For more information see:
@Description	- https://docs.photoprism.app/developer-guide/api/thumbnails/#image-endpoint-uri
@Id				GetThumb
@Produce		image/jpeg, image/svg+xml
@Tags			Images, Files
@Failure		403		{file}	image/svg+xml
@Success		200		{file}	image/svg+xml
@Success		200		{file}	image/jpg
@Param			thumb	path	string	true	"SHA1 file hash, optionally with a crop area suffixed, e.g. '-016014058037'"
@Param			token	path	string	true	"user-specific security token provided with session or 'public' when running PhotoPrism in public mode"
@Param			size	path	string	true	"thumbnail size"	Enums(tile_50, tile_100, left_224, right_224, tile_224, tile_500, fit_720, tile_1080, fit_1280, fit_1600, fit_1920, fit_2048, fit_2560, fit_3840, fit_4096, fit_7680)
@Router			/api/v1/t/{thumb}/{token}/{size} [get]

func GetVideo

func GetVideo(router *gin.RouterGroup)

GetVideo returns a video, optionally limited to a byte range for streaming.

@Summary		returns a video, optionally limited to a byte range for streaming
@Description	For more information see:
@Description	- https://docs.photoprism.app/developer-guide/api/thumbnails/#video-endpoint-uri
@Id				GetVideo
@Produce		video/mp4
@Tags			Files, Videos
@Failure		403		{object}	i18n.Response
@Param			thumb	path		string	true	"SHA1 video file hash"
@Param			token	path		string	true	"user-specific security token provided with session"
@Param			format	path		string	true	"video format, e.g. mp4"
@Router			/api/v1/videos/{hash}/{token}/{format} [get]

func InvalidDownloadToken

func InvalidDownloadToken(c *gin.Context) bool

InvalidDownloadToken checks if the token found in the request is valid for file downloads.

func InvalidPreviewToken

func InvalidPreviewToken(c *gin.Context) bool

InvalidPreviewToken checks if the token found in the request is valid for image thumbnails and video streams.

func IsRequestBodyTooLarge

func IsRequestBodyTooLarge(err error) bool

IsRequestBodyTooLarge reports whether the parsing error was caused by a body-size limit.

func LabelCover

func LabelCover(router *gin.RouterGroup)

LabelCover returns a label cover image.

@Summary	returns a label cover image
@Id			LabelCover
@Produce	image/jpeg
@Produce	image/svg+xml
@Tags		Images, Labels
@Failure	403		{file}	image/svg+xml
@Failure	200		{file}	image/svg+xml
@Success	200		{file}	image/jpg
@Param		uid		path	string	true	"Label UID"
@Param		token	path	string	true	"user-specific security token provided with session or 'public' when running PhotoPrism in public mode"
@Param		size	path	string	true	"thumbnail size"	Enums(tile_50, tile_100, left_224, right_224, tile_224, tile_500, fit_720, tile_1080, fit_1280, fit_1600, fit_1920, fit_2048, fit_2560, fit_3840, fit_4096, fit_7680)
@Router		/api/v1/labels/{uid}/t/{token}/{size} [get]

func LikeAlbum

func LikeAlbum(router *gin.RouterGroup)

LikeAlbum sets the favorite flag for an album.

@Summary	sets the favorite flag for an album
@Id			LikeAlbum
@Tags		Albums
@Accept		json
@Produce	json
@Failure	401,403,404,429,500	{object}	i18n.Response
@Param		uid					path		string	true	"Album UID"
@Router		/api/v1/albums/{uid}/like [post]

func LikeLabel

func LikeLabel(router *gin.RouterGroup)

LikeLabel flags a label as favorite.

@Summary	sets favorite flag for a label
@Id			LikeLabel
@Tags		Labels
@Accept		json
@Produce	json
@Failure	401,403,404,429	{object}	i18n.Response
@Param		uid				path		string	true	"Label UID"
@Router		/api/v1/labels/{uid}/like [post]

func LikePhoto

func LikePhoto(router *gin.RouterGroup)

LikePhoto flags a photo as favorite.

@Summary	flags a photo as favorite
@Id			LikePhoto
@Tags		Photos
@Accept		json
@Produce	json
@Success	200				{object}	gin.H
@Failure	401,403,404,500	{object}	i18n.Response
@Param		uid				path		string	true	"photo uid"
@Router		/api/v1/photos/{uid}/like [post]

func LikeSubject

func LikeSubject(router *gin.RouterGroup)

LikeSubject flags a subject as favorite.

@Summary	flags a subject as favorite
@Id			LikeSubject
@Tags		Subjects
@Accept		json
@Produce	json
@Failure	401,403,404,429,500	{object}	i18n.Response
@Param		uid					path		string	true	"subject uid"
@Router		/api/v1/subjects/{uid}/like [post]

func LimitRequestBodyBytes

func LimitRequestBodyBytes(c *gin.Context, limit int64)

LimitRequestBodyBytes caps the readable request body size for the current handler.

func OAuthAuthorize

func OAuthAuthorize(router *gin.RouterGroup)

OAuthAuthorize (placeholder) for Authorization Code Grant consent.

@Summary	OAuth2 authorization endpoint (not implemented)
@Id			OAuthAuthorize
@Tags		Authentication
@Produce	json
@Failure	405	{object}	i18n.Response
@Router		/api/v1/oauth/authorize [get]

func OAuthRevoke

func OAuthRevoke(router *gin.RouterGroup)

OAuthRevoke revokes an access token or session. A client may only revoke its own tokens.

@Summary	revoke an OAuth2 access token or session
@Id			OAuthRevoke
@Tags		Authentication
@Accept		json
@Produce	json
@Param		request				body		form.OAuthRevokeToken	true	"revoke request"
@Success	200					{object}	gin.H
@Failure	400,401,403,404,429	{object}	i18n.Response
@Router		/api/v1/oauth/revoke [post]

func OAuthToken

func OAuthToken(router *gin.RouterGroup)

OAuthToken creates a new access token for clients using OAuth2 grant types.

@Summary	create an OAuth2 access token
@Id			OAuthToken
@Tags		Authentication
@Accept		json
@Produce	json
@Param		request		body		form.OAuthCreateToken	true	"token request (supports client_credentials, password, or session grant)"
@Success	200			{object}	gin.H
@Failure	400,401,429	{object}	i18n.Response
@Router		/api/v1/oauth/token [post]

func OAuthUserinfo

func OAuthUserinfo(router *gin.RouterGroup)

OAuthUserinfo should return information about the authenticated user, see https://github.com/photoprism/photoprism/issues/4369.

@Summary	OAuth2 userinfo endpoint (not implemented)
@Id			OAuthUserinfo
@Tags		Authentication
@Produce	json
@Failure	405	{object}	i18n.Response
@Router		/api/v1/oauth/userinfo [get]

func OIDCLogin

func OIDCLogin(router *gin.RouterGroup)

OIDCLogin redirects a browser to the login page of the configured OpenID Connect provider.

@Summary	start OpenID Connect login (browser redirect)
@Id			OIDCLogin
@Tags		Authentication
@Produce	html
@Success	307			{string}	string	"redirect to provider login page"
@Failure	401,403,429	{object}	i18n.Response
@Router		/api/v1/oidc/login [get]

func OIDCRedirect

func OIDCRedirect(router *gin.RouterGroup)

OIDCRedirect completes the OIDC flow, creates a session, and renders a page that stores the token client-side.

@Summary	complete OIDC login (callback)
@Id			OIDCRedirect
@Tags		Authentication
@Produce	html
@Param		state		query		string	true	"opaque OAuth2 state value"
@Param		code		query		string	true	"authorization code"
@Success	200			{string}	string	"HTML page bootstrapping token storage"
@Failure	401,403,429	{string}	string	"rendered error page"
@Router		/api/v1/oidc/redirect [get]

func Options

func Options(router *gin.RouterGroup)

Options returns CORS headers with an empty response body.

@Summary		returns CORS headers with an empty response body
@Description	A preflight request is automatically issued by a browser and in normal cases, front-end developers don't need to craft such requests themselves. It appears when request is qualified as "to be preflighted" and omitted for simple requests.
@Id				Options
@Tags			CORS
@Success		204
@Router			/api/v1/{any} [options]

func PhotoPrimary

func PhotoPrimary(router *gin.RouterGroup)

PhotoPrimary sets the primary file for a photo.

@Summary	sets the primary file for a photo
@Id			PhotoPrimary
@Tags		Photos, Stacks
@Accept		json
@Produce	json
@Success	200					{object}	entity.Photo
@Failure	401,403,404,429,500	{object}	i18n.Response
@Param		uid					path		string	true	"photo uid"
@Param		fileuid				path		string	true	"file uid"
@Router		/api/v1/photos/{uid}/files/{fileuid}/primary [post]

func PhotoUnstack

func PhotoUnstack(router *gin.RouterGroup)

PhotoUnstack removes a file from an existing photo stack.

@Summary	removes a file from an existing photo stack
@Id			PhotoUnstack
@Tags		Photos, Stacks
@Accept		json
@Produce	json
@Success	200						{object}	entity.Photo
@Failure	400,401,403,404,429,500	{object}	i18n.Response
@Param		uid						path		string	true	"photo uid"
@Param		fileuid					path		string	true	"file uid"
@Router		/api/v1/photos/{uid}/files/{fileuid}/unstack [post]

func PostVisionCaption

func PostVisionCaption(router *gin.RouterGroup)

PostVisionCaption returns a suitable caption for an image.

@Summary	returns a suitable caption for an image
@Id			PostVisionCaption
@Tags		Vision
@Produce	json
@Success	200					{object}	vision.ApiResponse
@Failure	401,403,404,429,501	{object}	i18n.Response
@Param		images				body		vision.ApiRequest	true	"list of image file urls"
@Router		/api/v1/vision/caption [post]

func PostVisionFace

func PostVisionFace(router *gin.RouterGroup)

PostVisionFace returns the embeddings of a face.

@Summary	returns the embeddings of a face image
@Id			PostVisionFace
@Tags		Vision
@Produce	json
@Success	200				{object}	vision.ApiResponse
@Failure	401,403,429,501	{object}	i18n.Response
@Param		images			body		vision.ApiRequest	true	"list of image file urls"
@Router		/api/v1/vision/face [post]

func PostVisionLabels

func PostVisionLabels(router *gin.RouterGroup)

PostVisionLabels returns suitable labels for an image.

@Summary	returns suitable labels for an image
@Id			PostVisionLabels
@Tags		Vision
@Accept		json
@Produce	json
@Success	200			{object}	vision.ApiResponse
@Failure	401,403,429	{object}	i18n.Response
@Param		images		body		vision.ApiRequest	true	"list of image file urls"
@Router		/api/v1/vision/labels [post]

func PostVisionNsfw

func PostVisionNsfw(router *gin.RouterGroup)

PostVisionNsfw checks the specified images for inappropriate content.

@Summary	checks the specified images for inappropriate content
@Id			PostVisionNsfw
@Tags		Vision
@Accept		json
@Produce	json
@Success	200			{object}	vision.ApiResponse
@Failure	401,403,429	{object}	i18n.Response
@Param		images		body		vision.ApiRequest	true	"list of image file urls"
@Router		/api/v1/vision/nsfw [post]

func ProcessUserUpload

func ProcessUserUpload(router *gin.RouterGroup)

ProcessUserUpload triggers processing and import of previously uploaded files.

@Summary	process previously uploaded files for a user
@Id			ProcessUserUpload
@Tags		Users, Files
@Accept		json
@Produce	json
@Param		uid						path		string				true	"user uid"
@Param		token					path		string				true	"upload token"
@Param		options					body		form.UploadOptions	true	"processing options"
@Success	200						{object}	i18n.Response
@Failure	400,401,403,404,409,429	{object}	i18n.Response
@Router		/api/v1/users/{uid}/upload/{token} [put]

func PublishAlbumEvent

func PublishAlbumEvent(ev Event, uid string, c *gin.Context)

PublishAlbumEvent publishes updated album data after changes have been made.

func PublishLabelEvent

func PublishLabelEvent(ev Event, uid string, c *gin.Context)

PublishLabelEvent publishes updated label data after changes have been made.

func PublishPhotoEvent

func PublishPhotoEvent(ev Event, uid string, c *gin.Context)

PublishPhotoEvent publishes updated photo data after changes have been made.

func PublishSubjectEvent

func PublishSubjectEvent(ev Event, uid string, c *gin.Context)

PublishSubjectEvent publishes updated subject data after changes have been made.

func RemoveFromAlbumCoverCache

func RemoveFromAlbumCoverCache(uid string)

RemoveFromAlbumCoverCache removes covers by album UID e.g. after adding or removing photos.

func RemoveFromFolderCache

func RemoveFromFolderCache(rootName string)

RemoveFromFolderCache removes an item from the folder cache e.g. after indexing.

func RemoveFromLabelCoverCache

func RemoveFromLabelCoverCache(uid string)

RemoveFromLabelCoverCache removes covers by label UID e.g. after updates.

func RemovePhotoLabel

func RemovePhotoLabel(router *gin.RouterGroup)

RemovePhotoLabel removes a label from a photo.

@Summary	removes a label from a photo
@Id			RemovePhotoLabel
@Tags		Labels, Photos
@Accept		json
@Produce	json
@Success	200						{object}	entity.Photo
@Failure	400,401,403,404,429,500	{object}	i18n.Response
@Param		uid						path		string	true	"photo uid"
@Param		id						path		string	true	"label id"
@Router		/api/v1/photos/{uid}/label/{id} [delete]

func RemovePhotosFromAlbum

func RemovePhotosFromAlbum(router *gin.RouterGroup)

RemovePhotosFromAlbum removes photos from an album.

@Summary	removes photos from an album
@Id			RemovePhotosFromAlbum
@Tags		Albums
@Accept		json
@Produce	json
@Success	200					{object}	gin.H
@Failure	400,401,403,404,429	{object}	i18n.Response
@Param		photos				body		form.Selection	true	"Photo Selection"
@Param		uid					path		string			true	"Album UID"
@Router		/api/v1/albums/{uid}/photos [delete]

func SaveAlbumYaml

func SaveAlbumYaml(album *entity.Album)

SaveAlbumYaml saves the album metadata to a YAML backup file.

func SaveConfigOptions

func SaveConfigOptions(router *gin.RouterGroup)

SaveConfigOptions updates backend config options.

@Summary	updates backend config options
@Id			SaveConfigOptions
@Tags		Config, Settings
@Accept		json
@Produce	json
@Success	200					{object}	config.Options
@Failure	400,401,403,429,500	{object}	i18n.Response
@Param		options				body		config.Options	true	"properties to be updated (only submit values that should be changed)"
@Router		/api/v1/config/options [post]

func SaveSettings

func SaveSettings(router *gin.RouterGroup)

SaveSettings saves the user app settings.

@Summary	saves the user app settings
@Id			SaveSettings
@Tags		Settings
@Accept		json
@Produce	json
@Success	200					{object}	customize.Settings
@Failure	400,401,403,404,500	{object}	i18n.Response
@Param		settings			body		customize.Settings	true	"user settings"
@Router		/api/v1/settings [post]

func SaveSidecarYaml

func SaveSidecarYaml(photo *entity.Photo)

SaveSidecarYaml saves the photo metadata to a YAML sidecar file.

func SearchAlbums

func SearchAlbums(router *gin.RouterGroup)

SearchAlbums finds albums and returns them as JSON.

@Summary	finds albums and returns them as JSON
@Id			SearchAlbums
@Tags		Albums
@Produce	json
@Success	200		{object}	search.AlbumResults
@Failure	400,404	{object}	i18n.Response
@Param		count	query		int		true	"maximum number of results"	minimum(1)	maximum(100000)
@Param		offset	query		int		false	"search result offset"		minimum(0)	maximum(100000)
@Param		order	query		string	false	"sort order"				Enums(favorites, name, title, added, edited)
@Param		q		query		string	false	"search query"
@Router		/api/v1/albums [get]

func SearchFaces

func SearchFaces(router *gin.RouterGroup)

SearchFaces finds and returns faces as JSON.

@Summary	finds and returns faces as JSON
@Id			SearchFaces
@Tags		Faces
@Produce	json
@Success	200					{object}	search.FaceResults
@Failure	400,401,403,429,404	{object}	i18n.Response
@Param		count				query		int		true	"maximum number of results"	minimum(1)	maximum(100000)
@Param		offset				query		int		false	"search result offset"		minimum(0)	maximum(100000)
@Param		order				query		string	false	"sort order"				Enums(subject, added, samples)
@Param		hidden				query		string	false	"show hidden"				Enums(yes, no)
@Param		unknown				query		string	false	"show unknown"				Enums(yes, no)
@Router		/api/v1/faces [get]

func SearchFolders

func SearchFolders(router *gin.RouterGroup, urlPath, rootName, rootPath string)

SearchFolders is a reusable request handler for directory listings (GET /api/v1/folders/*).

func SearchFoldersImport

func SearchFoldersImport(router *gin.RouterGroup)

SearchFoldersImport returns import folders as JSON.

@Summary	list folders in import
@Id			SearchFoldersImport
@Tags		Folders
@Produce	json
@Success	200		{object}	api.FoldersResponse
@Failure	401,403	{object}	i18n.Response
@Router		/api/v1/folders/import [get]

func SearchFoldersOriginals

func SearchFoldersOriginals(router *gin.RouterGroup)

SearchFoldersOriginals returns folders in originals as JSON.

@Summary	list folders in originals
@Id			SearchFoldersOriginals
@Tags		Folders
@Produce	json
@Success	200		{object}	api.FoldersResponse
@Failure	401,403	{object}	i18n.Response
@Router		/api/v1/folders/originals [get]

func SearchGeo

func SearchGeo(router *gin.RouterGroup)

SearchGeo finds photos and returns results as JSON, so they can be displayed on a map or in a viewer. See form.SearchPhotosGeo for supported search params and data types.

@Summary	finds photos and returns results as JSON, so they can be displayed on a map or in a viewer
@Id			SearchGeo
@Tags		Photos
@Produce	json
@Success	200				{object}	search.GeoResults
@Failure	400,401,403,404	{object}	i18n.Response
@Param		count			query		int		true	"maximum number of files"	minimum(1)	maximum(100000)
@Param		offset			query		int		false	"file offset"				minimum(0)	maximum(100000)
@Param		public			query		bool	false	"excludes private pictures"
@Param		quality			query		int		true	"minimum quality score (1-7)"	Enums(0, 1, 2, 3, 4, 5, 6, 7)
@Param		q				query		string	false	"search query"
@Param		s				query		string	false	"album uid"
@Param		path			query		string	false	"photo path"
@Param		video			query		bool	false	"is type video"
@Router		/api/v1/geo [get]

func SearchLabels

func SearchLabels(router *gin.RouterGroup)

SearchLabels finds and returns labels as JSON.

@Summary	finds and returns labels as JSON
@Id			SearchLabels
@Tags		Labels
@Produce	json
@Success	200				{array}		search.Label
@Failure	401,429,403,400	{object}	i18n.Response
@Param		count			query		int		true	"maximum number of results"	minimum(1)	maximum(100000)
@Param		offset			query		int		false	"search result offset"		minimum(0)	maximum(100000)
@Param		all				query		bool	false	"show all"
@Param		q				query		string	false	"search query"
@Router		/api/v1/labels [get]

func SearchPhotos

func SearchPhotos(router *gin.RouterGroup)

SearchPhotos finds pictures and returns them as JSON.

@Summary		finds pictures and returns them as JSON
@Description	For more information see:
@Description	- https://docs.photoprism.app/developer-guide/api/search/#get-apiv1photos
@Id				SearchPhotos
@Tags			Photos
@Produce		json
@Success		200				{object}	search.PhotoResults
@Failure		400,401,403,404	{object}	i18n.Response
@Param			count			query		int		true	"maximum number of files"	minimum(1)	maximum(100000)
@Param			offset			query		int		false	"file offset"				minimum(0)	maximum(100000)
@Param			order			query		string	false	"sort order"				Enums(name, title, added, edited, newest, oldest, size, random, duration, relevance)
@Param			merged			query		bool	false	"groups consecutive files that belong to the same photo"
@Param			public			query		bool	false	"excludes private pictures"
@Param			quality			query		int		false	"minimum quality score (1-7)"	Enums(0, 1, 2, 3, 4, 5, 6, 7)
@Param			q				query		string	false	"search query"
@Param			s				query		string	false	"album uid"
@Param			path			query		string	false	"photo path"
@Param			video			query		bool	false	"is type video"
@Router			/api/v1/photos [get]

func SearchPhotosView

func SearchPhotosView(router *gin.RouterGroup)

SearchPhotosView finds pictures and returns a viewer-formatted JSON result for the lightbox.

@Summary		finds pictures and returns a viewer-formatted JSON result for the lightbox
@Description	Returns search results formatted for the photo viewer (lightbox) in the web UI,
@Description	including resolved content URLs and preview/download tokens.
@Description	For more information see:
@Description	- https://docs.photoprism.app/developer-guide/api/search/#get-apiv1photos
@Id				SearchPhotosView
@Tags			Photos
@Produce		json
@Success		200				{object}	viewer.Results
@Failure		400,401,403,404	{object}	i18n.Response
@Param			count			query		int		true	"maximum number of files"	minimum(1)	maximum(100000)
@Param			offset			query		int		false	"file offset"				minimum(0)	maximum(100000)
@Param			order			query		string	false	"sort order"				Enums(name, title, added, edited, newest, oldest, size, random, duration, relevance)
@Param			merged			query		bool	false	"groups consecutive files that belong to the same photo"
@Param			public			query		bool	false	"excludes private pictures"
@Param			quality			query		int		false	"minimum quality score (1-7)"	Enums(0, 1, 2, 3, 4, 5, 6, 7)
@Param			q				query		string	false	"search query"
@Param			s				query		string	false	"album uid"
@Param			path			query		string	false	"photo path"
@Param			video			query		bool	false	"is type video"
@Router			/api/v1/photos/view [get]

func SearchServices

func SearchServices(router *gin.RouterGroup)

SearchServices finds account settings and returns them as JSON.

@Summary	finds services and returns them as JSON
@Id			SearchServices
@Tags		Services
@Produce	json
@Success	200				{object}	entity.Services
@Failure	401,403,404,429	{object}	i18n.Response
@Param		count			query		int	true	"maximum number of results"	minimum(1)	maximum(100000)
@Router		/api/v1/services [get]

func SearchSubjects

func SearchSubjects(router *gin.RouterGroup)

SearchSubjects finds and returns subjects as JSON.

@Summary	finds and returns subjects as JSON
@Id			SearchSubjects
@Tags		Subjects
@Produce	json
@Success	200				{object}	search.SubjectResults
@Failure	401,429,403,400	{object}	i18n.Response
@Param		count			query		int		true	"maximum number of results"	minimum(1)	maximum(100000)
@Param		offset			query		int		false	"search result offset"		minimum(0)	maximum(100000)
@Param		order			query		string	false	"sort order"				Enums(name, count, added, relevance)
@Param		hidden			query		string	false	"show hidden"				Enums(yes, no)
@Param		files			query		int		false	"minimum number of files"
@Param		q				query		string	false	"search query"
@Router		/api/v1/subjects [get]

func ServeMCP

func ServeMCP(router *gin.RouterGroup)

ServeMCP registers the Model Context Protocol (MCP) Streamable HTTP endpoint at /api/v1/mcp.

@Summary	model context protocol endpoint
@Id			ServeMCP
@Tags		MCP
@Accept		json
@Produce	json
@Success	200					{string}	string	"JSON-RPC 2.0 response"
@Failure	401,403,404,413,429	{object}	i18n.Response
@Router		/api/v1/mcp [post]

func Session

func Session(clientIp, authToken string) (sess *entity.Session)

Session finds the client session for the specified auth token, or returns nil if not found.

func SessionRefID

func SessionRefID(c *gin.Context) string

SessionRefID returns the current session ref ID for audit logs, or "unknown" if unavailable.

func SharePreview

func SharePreview(router *gin.RouterGroup)

SharePreview returns a preview image for the given share uid if the token is valid.

@Summary	returns a share preview image when the token is valid
@Id			SharePreview
@Tags		Sharing
@Produce	image/jpeg
@Param		token	path		string	true	"Share token"
@Param		shared	path		string	true	"Shared resource UID"
@Success	200		{file}		file	"Preview image"
@Failure	302		{string}	string	"Redirect to the default preview page"
@Router		/s/{token}/{shared}/preview [get]

func ShareToken

func ShareToken(router *gin.RouterGroup)

ShareToken creates a session using the specified share token and renders the generic sharing bootstrap page.

@Summary	creates a session using the specified share token and renders the generic sharing bootstrap page
@Id			ShareToken
@Tags		Sharing
@Produce	text/html
@Param		token	path		string	true	"Share token"
@Success	200		{string}	string	"Rendered HTML page"
@Failure	302		{string}	string	"Redirect to the base site when the token is invalid"
@Router		/s/{token} [get]

func ShareTokenShared

func ShareTokenShared(router *gin.RouterGroup)

ShareTokenShared creates a session with the specified share token and redirects to the shared content.

@Summary	creates a session with the specified share token and redirects to the shared content
@Id			ShareTokenShared
@Tags		Sharing
@Produce	text/html
@Param		token	path		string	true	"Share token"
@Param		shared	path		string	true	"Shared resource UID"
@Success	200		{string}	string	"Rendered HTML page"
@Failure	302		{string}	string	"Redirect to the base site when the token is invalid"
@Router		/s/{token}/{shared} [get]

func StartImport

func StartImport(router *gin.RouterGroup)

StartImport imports media files from a directory and converts/indexes them as needed.

@Summary	start import
@Id			StartImport
@Tags		Library
@Accept		json
@Produce	json
@Success	200			{object}	i18n.Response
@Failure	400,401,403	{object}	i18n.Response
@Param		options		body		form.ImportOptions	true	"import options"
@Router		/api/v1/import/ [post]

func StartIndexing

func StartIndexing(router *gin.RouterGroup)

StartIndexing indexes media files in the "originals" folder.

@Summary	start indexing
@Id			StartIndexing
@Tags		Library
@Accept		json
@Produce	json
@Success	200					{object}	i18n.Response
@Failure	400,401,403,429,500	{object}	i18n.Response
@Param		options				body		form.IndexOptions	true	"index options"
@Router		/api/v1/index [post]

func StopServer

func StopServer(router *gin.RouterGroup)

StopServer allows authorized admins to restart the server.

@Summary	allows authorized admins to restart the server
@Id			StopServer
@Tags		Internal
@Produce	json
@Success	200		{object}	config.Options
@Failure	401,403	{object}	i18n.Response
@Router		/api/v1/server/stop [post]

func UpdateAlbum

func UpdateAlbum(router *gin.RouterGroup)

UpdateAlbum updates album metadata like title and description.

@Summary	updates album metadata like title and description
@Id			UpdateAlbum
@Tags		Albums
@Accept		json
@Produce	json
@Success	200						{object}	entity.Album
@Failure	400,401,403,404,429,500	{object}	i18n.Response
@Param		uid						path		string		true	"Album UID"
@Param		album					body		form.Album	true	"properties to be updated"
@Router		/api/v1/albums/{uid} [put]
func UpdateAlbumLink(router *gin.RouterGroup)

UpdateAlbumLink updates an album share link and return it as JSON.

@Summary	updates an album share link and return it as JSON
@Id			UpdateAlbumLink
@Tags		Links, Albums
@Accept		json
@Produce	json
@Success	200						{object}	entity.Link
@Failure	400,401,403,429,409,500	{object}	i18n.Response
@Param		uid						path		string		true	"album uid"
@Param		linkuid					path		string		true	"link uid"
@Param		link					body		form.Link	true	"properties to be updated (currently supported: slug, expires, token)"
@Router		/api/v1/albums/{uid}/links/{linkuid} [put]

func UpdateClientConfig

func UpdateClientConfig()

UpdateClientConfig publishes updated client configuration values over the websocket connections.

func UpdateFace

func UpdateFace(router *gin.RouterGroup)

UpdateFace updates face properties.

@Summary	updates face properties
@Id			UpdateFace
@Tags		Faces
@Accept		json
@Produce	json
@Success	200						{object}	entity.Face
@Failure	400,401,403,404,429,500	{object}	i18n.Response
@Param		id						path		string		true	"face id"
@Param		face					body		form.Face	true	"properties to be updated"
@Router		/api/v1/faces/{id} [put]

func UpdateLabel

func UpdateLabel(router *gin.RouterGroup)

UpdateLabel updates label properties.

PUT /api/v1/labels/:uid

@Summary	updates label name
@Id			UpdateLabel
@Tags		Labels
@Accept		json
@Produce	json
@Success	200				{object}	entity.Label
@Failure	401,403,404,429	{object}	i18n.Response
@Param		uid				path		string		true	"Label UID"
@Param		label			body		form.Label	true	"Label Name"
@Router		/api/v1/labels/{uid} [put]
func UpdateLink(c *gin.Context)

UpdateLink updates a share link and return it as JSON.

PUT /api/v1/:entity/:uid/links/:link

func UpdateMarker

func UpdateMarker(router *gin.RouterGroup)

UpdateMarker updates an existing file area marker to assign faces or other subjects.

@Summary	update a marker (face/subject region)
@Id			UpdateMarker
@Tags		Files
@Accept		json
@Produce	json
@Param		marker_uid			path		string		true	"marker uid"
@Param		marker				body		form.Marker	true	"marker properties"
@Success	200					{object}	entity.Marker
@Failure	400,401,403,404,429	{object}	i18n.Response
@Router		/api/v1/markers/{marker_uid} [put]

func UpdatePhoto

func UpdatePhoto(router *gin.RouterGroup)

UpdatePhoto updates picture details and returns them as JSON.

@Summary	updates picture details and returns them as JSON
@Id			UpdatePhoto
@Tags		Photos
@Accept		json
@Produce	json
@Success	200						{object}	entity.Photo
@Failure	400,401,403,404,429,500	{object}	i18n.Response
@Param		uid						path		string		true	"Photo UID"
@Param		photo					body		form.Photo	true	"properties to be updated (only submit values that should be changed)"
@Router		/api/v1/photos/{uid} [put]

func UpdatePhotoLabel

func UpdatePhotoLabel(router *gin.RouterGroup)

UpdatePhotoLabel changes a photo label.

@Summary	changes a photo label
@Id			UpdatePhotoLabel
@Tags		Labels, Photos
@Accept		json
@Produce	json
@Success	200						{object}	entity.Photo
@Failure	400,401,403,404,429,500	{object}	i18n.Response
@Param		uid						path		string		true	"photo uid"
@Param		id						path		string		true	"label id"
@Param		label					body		form.Label	true	"properties to be updated (currently supports: uncertainty)"
@Router		/api/v1/photos/{uid}/label/{id} [put]

func UpdateService

func UpdateService(router *gin.RouterGroup)

UpdateService updates a remote account configuration.

@Summary	updates a remote account configuration
@Id			UpdateService
@Tags		Services
@Accept		json
@Produce	json
@Success	200						{object}	entity.Service
@Failure	400,401,403,404,429,500	{object}	i18n.Response
@Param		id						path		string			true	"service id"
@Param		service					body		form.Service	true	"properties to be updated (only submit values that should be changed)"
@Router		/api/v1/services/{id} [put]

func UpdateSubject

func UpdateSubject(router *gin.RouterGroup)

UpdateSubject updates subject properties.

@Summary	updates subject properties
@Id			UpdateSubject
@Tags		Subjects
@Accept		json
@Produce	json
@Success	200						{object}	entity.Subject
@Failure	400,401,403,404,429,500	{object}	i18n.Response
@Param		uid						path		string			true	"subject uid"
@Param		subject					body		form.Subject	true	"properties to be updated (only submit values that should be changed)"
@Router		/api/v1/subjects/{uid} [put]

func UpdateUser

func UpdateUser(router *gin.RouterGroup)

UpdateUser updates profile information for the specified user.

@Summary	update user profile information
@Id			UpdateUser
@Tags		Users
@Accept		json
@Produce	json
@Param		uid						path		string		true	"user uid"
@Param		user					body		form.User	true	"properties to be updated"
@Success	200						{object}	entity.User
@Failure	400,401,403,404,409,429	{object}	i18n.Response
@Router		/api/v1/users/{uid} [put]

func UpdateUserPassword

func UpdateUserPassword(router *gin.RouterGroup)

UpdateUserPassword changes the password of the specified user.

@Summary	change a user's password
@Id			UpdateUserPassword
@Tags		Users, Authentication
@Accept		json
@Produce	json
@Param		uid					path		string				true	"user uid"
@Param		request				body		form.ChangePassword	true	"old and new password"
@Success	200					{object}	i18n.Response
@Failure	400,401,403,404,429	{object}	i18n.Response
@Router		/api/v1/users/{uid}/password [put]

func UploadCheckFile

func UploadCheckFile(destName string, rejectRaw bool, totalSizeLimit int64) (remainingSizeLimit int64, err error)

UploadCheckFile checks if the file is supported and has the correct extension.

func UploadToService

func UploadToService(router *gin.RouterGroup)

UploadToService uploads files to the selected service account.

@Summary	uploads files to the selected service account
@Id			UploadToService
@Tags		Services
@Accept		json
@Produce	json
@Param		id				path		string	true	"service id"
@Success	200				{object}	entity.Files
@Failure	401,403,404,429	{object}	i18n.Response
@Router		/api/v1/services/{id}/upload [post]

func UploadUserAvatar

func UploadUserAvatar(router *gin.RouterGroup)

UploadUserAvatar updates the avatar image of the specified user.

@Summary		upload a new avatar image for a user
@Description	Accepts a single PNG or JPEG file (max 20 MB) in a multipart form field named "files" and sets it as the user's avatar.
@Id				UploadUserAvatar
@Tags			Users
@Accept			multipart/form-data
@Produce		json
@Param			uid					path		string	true	"user uid"
@Param			files				formData	file	true	"avatar image (png or jpeg, <= 20 MB)"
@Success		200					{object}	entity.User
@Failure		400,401,403,404,429	{object}	i18n.Response
@Router			/api/v1/users/{uid}/avatar [post]

func UploadUserFiles

func UploadUserFiles(router *gin.RouterGroup)

UploadUserFiles adds files to the user's upload folder from where they can be processed and indexed.

@Summary	upload files to a user's upload folder
@Id			UploadUserFiles
@Tags		Users, Files
@Accept		multipart/form-data
@Produce	json
@Param		uid						path		string	true	"user uid"
@Param		token					path		string	true	"upload token"
@Param		files					formData	file	true	"one or more files to upload (repeat the field for multiple files)"
@Success	200						{object}	i18n.Response
@Failure	400,401,403,413,429,507	{object}	i18n.Response
@Router		/api/v1/users/{uid}/upload/{token} [post]

func UserAgent

func UserAgent(c *gin.Context) string

UserAgent returns the user agent from the request context or an empty string if it is unknown.

func WebSocket

func WebSocket(router *gin.RouterGroup)

WebSocket registers the /ws endpoint for establishing websocket connections.

@Summary	opens a WebSocket connection for real-time events
@Id			WebSocket
@Tags		WebSocket
@Success	101	{string}	string	"Switching Protocols"
@Failure	403	{string}	string	"Forbidden"
@Router		/ws [get]

func ZipCreate

func ZipCreate(router *gin.RouterGroup)

ZipCreate creates a zip file archive for download.

@Summary	creates a zip file archive for download
@Id			ZipCreate
@Tags		Download
@Produce	json
@Failure	400,403,404	{object}	i18n.Response
@Success	200			{file}		application/zip
@Router		/api/v1/zip [post]

func ZipDownload

func ZipDownload(router *gin.RouterGroup)

ZipDownload returns a zip file archive after it has been created.

@Summary	returns a zip file archive after it has been created
@Id			ZipDownload
@Tags		Download
@Produce	application/zip
@Failure	403,404,500	{object}	i18n.Response
@Success	200			{file}		application/zip
@Param		filename	path		string	true	"zip archive filename returned by the POST /api/v1/zip endpoint"
@Router		/api/v1/zip/{filename} [get]

Types

type ByteCache

type ByteCache struct {
	Data []byte
}

ByteCache wraps in-memory cached byte slices for fast responses.

type Event

type Event string

Event represents an api event type.

const (
	StatusCreated Event = "created"
	StatusUpdated Event = "updated"
	StatusDeleted Event = "deleted"
	StatusSuccess Event = "success"
	StatusFailed  Event = "failed"
)

Canonical event payload status strings used by the API layer.

func (Event) String

func (ev Event) String() string

String returns the event type as string.

type FoldersResponse

type FoldersResponse struct {
	Root      string          `json:"root,omitempty"`
	Folders   []entity.Folder `json:"folders"`
	Files     []entity.File   `json:"files,omitempty"`
	Recursive bool            `json:"recursive,omitempty"`
	Cached    bool            `json:"cached,omitempty"`
}

FoldersResponse represents the folders API response.

type HealthResponse

type HealthResponse struct {
	Status string `json:"status"`
	Time   string `json:"time"`
}

HealthResponse is the response type for GET /api/v1/cluster/health. swagger:model HealthResponse

func NewHealthResponse

func NewHealthResponse(status string) *HealthResponse

NewHealthResponse returns a standard health response with a status and RFC 3339 UTC timestamp.

type Response

type Response struct {
	Code    int    `json:"code"`
	Err     string `json:"error,omitempty"`
	Msg     string `json:"message,omitempty"`
	Details string `json:"details,omitempty"`
}

Response represents a server status response.

func NewResponse

func NewResponse(code int, err error, details string) Response

NewResponse creates a new server status response.

type SwaggerTimeDuration

type SwaggerTimeDuration = time.Duration

SwaggerTimeDuration overrides the generated schema for time.Duration to avoid unstable enums from the standard library constants (Nanosecond, Minute, etc.). Using a simple integer schema is accurate (nanoseconds) and deterministic.

@name			time.Duration
@description	Duration in nanoseconds (int64). Examples: 1000000000 (1s), 60000000000 (1m).

type ThumbCache

type ThumbCache struct {
	FileName  string
	ShareName string
}

ThumbCache describes files persisted on disk for cached thumbnails and share images.

Directories

Path Synopsis
Package download allows to register files so that they can be temporarily made available for download.
Package download allows to register files so that they can be temporarily made available for download.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL