PhotoPrism Vision API
The Vision API from PhotoPrism — 4 operation(s) for vision.
The Vision API from PhotoPrism — 4 operation(s) for vision.
Every API here is available over the APIs.io API and to AI agents over MCP.
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
find_apisBrowse and filter every API in the catalog.get_api_artifactsOne API's artifacts, grouped by type.get_openapiThe primary OpenAPI for this API.find_similar_apisAPIs that look like this one.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.curl "https://apis.io/api/v1/apis/photoprism:photoprism-vision-api"
curl "https://apis.io/api/v1/apis?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
contact: {}
description: 'API request bodies and responses are usually JSON-encoded, except for binary data and some of the OAuth2 endpoints. Note that the `Content-Type` header must be set to `application/json` for this, as the request may otherwise fail with error 400.
When clients have a valid access token, e.g. obtained through the `POST /api/v1/session` or `POST /api/v1/oauth/token` endpoint, they can use a standard Bearer Authorization header to authenticate their requests. Submitting the access token with a custom `X-Auth-Token` header is supported as well.'
title: PhotoPrism Vision API
version: v1
servers:
- url: https://demo.photoprism.app
security:
- BearerAuth: []
tags:
- name: Vision
paths:
/api/v1/vision/caption:
post:
operationId: PostVisionCaption
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/vision.ApiResponse'
'400':
description: Bad Request
content:
application/json:
schema:
$ref: '#/components/schemas/vision.ApiResponse'
'401':
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/i18n.Response'
'403':
description: Vision API disabled; permission errors return i18n.Response
content:
application/json:
schema:
$ref: '#/components/schemas/vision.ApiResponse'
'413':
description: Request Entity Too Large
content:
application/json:
schema:
$ref: '#/components/schemas/vision.ApiResponse'
'429':
description: Too Many Requests
content:
application/json:
schema:
$ref: '#/components/schemas/i18n.Response'
'500':
description: Internal Server Error
content:
application/json:
schema:
$ref: '#/components/schemas/vision.ApiResponse'
summary: returns a suitable caption for an image
tags:
- Vision
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/vision.ApiRequest'
description: list of image file urls
required: true
/api/v1/vision/face:
post:
operationId: PostVisionFace
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/vision.ApiResponse'
'400':
description: Bad Request
content:
application/json:
schema:
$ref: '#/components/schemas/vision.ApiResponse'
'401':
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/i18n.Response'
'403':
description: Vision API disabled; permission errors return i18n.Response
content:
application/json:
schema:
$ref: '#/components/schemas/vision.ApiResponse'
'413':
description: Request Entity Too Large
content:
application/json:
schema:
$ref: '#/components/schemas/vision.ApiResponse'
'429':
description: Too Many Requests
content:
application/json:
schema:
$ref: '#/components/schemas/i18n.Response'
summary: returns the embeddings of a face image
tags:
- Vision
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/vision.ApiRequest'
description: list of image file urls
required: true
/api/v1/vision/labels:
post:
operationId: PostVisionLabels
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/vision.ApiResponse'
'400':
description: Bad Request
content:
application/json:
schema:
$ref: '#/components/schemas/vision.ApiResponse'
'401':
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/i18n.Response'
'403':
description: Vision API disabled; permission errors return i18n.Response
content:
application/json:
schema:
$ref: '#/components/schemas/vision.ApiResponse'
'413':
description: Request Entity Too Large
content:
application/json:
schema:
$ref: '#/components/schemas/vision.ApiResponse'
'429':
description: Too Many Requests
content:
application/json:
schema:
$ref: '#/components/schemas/i18n.Response'
summary: returns suitable labels for an image
tags:
- Vision
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/vision.ApiRequest'
description: list of image file urls
required: true
/api/v1/vision/nsfw:
post:
operationId: PostVisionNsfw
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/vision.ApiResponse'
'400':
description: Bad Request
content:
application/json:
schema:
$ref: '#/components/schemas/vision.ApiResponse'
'401':
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/i18n.Response'
'403':
description: Vision API disabled; permission errors return i18n.Response
content:
application/json:
schema:
$ref: '#/components/schemas/vision.ApiResponse'
'413':
description: Request Entity Too Large
content:
application/json:
schema:
$ref: '#/components/schemas/vision.ApiResponse'
'429':
description: Too Many Requests
content:
application/json:
schema:
$ref: '#/components/schemas/i18n.Response'
summary: checks the specified images for inappropriate content
tags:
- Vision
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/vision.ApiRequest'
description: list of image file urls
required: true
components:
schemas:
vision.ApiFormat:
enum:
- url
- images
- vision
- ollama
- openai
type: string
x-enum-varnames:
- ApiFormatUrl
- ApiFormatImages
- ApiFormatVision
- ApiFormatOllama
- ApiFormatOpenAI
tensorflow.PhotoInput:
properties:
height:
type: integer
index:
type: integer
inputOrder:
$ref: '#/components/schemas/tensorflow.ColorChannelOrder'
intervals:
items:
$ref: '#/components/schemas/tensorflow.Interval'
type: array
name:
type: string
resizeOperation:
$ref: '#/components/schemas/tensorflow.ResizeOperation'
shape:
items:
$ref: '#/components/schemas/tensorflow.ShapeComponent'
type: array
width:
type: integer
type: object
vision.CaptionResult:
properties:
confidence:
type: number
source:
type: string
text:
type: string
type: object
vision.ModelType:
enum:
- labels
- nsfw
- face
- caption
- generate
type: string
x-enum-varnames:
- ModelTypeLabels
- ModelTypeNsfw
- ModelTypeFace
- ModelTypeCaption
- ModelTypeGenerate
onnx.ModelInfo:
properties:
file:
type: string
input:
$ref: '#/components/schemas/onnx.Input'
license:
type: string
output:
$ref: '#/components/schemas/onnx.Output'
quantization:
type: string
sha256:
type: string
source:
type: string
type: object
vision.ModelOptions:
properties:
combine_outputs:
description: OpenAI
type: string
detail:
description: OpenAI
type: string
force_json:
description: Ollama, OpenAI
type: boolean
frequency_penalty:
description: OpenAI
type: number
low_vram:
description: Ollama
type: boolean
main_gpu:
description: Ollama
type: integer
max_output_tokens:
description: Ollama, OpenAI
type: integer
min_p:
description: Ollama
type: number
mirostat:
description: Ollama
type: integer
mirostat_eta:
description: Ollama
type: number
mirostat_tau:
description: Ollama
type: number
num_batch:
description: Ollama
type: integer
num_ctx:
description: Ollama, OpenAI
type: integer
num_gpu:
description: Ollama
type: integer
num_keep:
description: Ollama
type: integer
num_predict:
description: Ollama
type: integer
num_thread:
description: Ollama
type: integer
numa:
description: Ollama
type: boolean
penalize_newline:
description: Ollama
type: boolean
presence_penalty:
description: OpenAI
type: number
repeat_last_n:
description: Ollama
type: integer
repeat_penalty:
description: Ollama
type: number
schema_version:
description: Ollama, OpenAI
type: string
seed:
description: Ollama
type: integer
stop:
description: Ollama, OpenAI
items:
type: string
type: array
temperature:
description: Ollama, OpenAI
type: number
tfs_z:
description: Ollama
type: number
top_k:
description: Ollama
type: integer
top_p:
description: Ollama, OpenAI
type: number
typical_p:
description: Ollama
type: number
use_mlock:
description: Ollama
type: boolean
use_mmap:
description: Ollama
type: boolean
vocab_only:
description: Ollama
type: boolean
type: object
tensorflow.ResizeOperation:
enum:
- 0
- 1
- 2
- 3
type: integer
x-enum-varnames:
- UndefinedResizeOperation
- ResizeBreakAspectRatio
- CenterCrop
- Padding
onnx.Interpolation:
enum:
- ''
- nearest
- linear
- bicubic
- lanczos
type: string
x-enum-varnames:
- InterpolationUndefined
- InterpolationNearest
- InterpolationLinear
- InterpolationBicubic
- InterpolationLanczos
tensorflow.ModelOutput:
properties:
index:
type: integer
logits:
type: boolean
name:
type: string
outputs:
type: integer
type: object
i18n.Response:
properties:
code:
type: integer
details:
type: string
error:
type: string
message:
type: string
messageId:
type: string
messageParams:
items: {}
type: array
type: object
onnx.ResizeMode:
enum:
- ''
- stretch
- center-crop
- pad
type: string
x-enum-varnames:
- ResizeUndefined
- ResizeStretch
- ResizeCenterCrop
- ResizePad
vision.LabelResult:
properties:
categories:
items:
type: string
type: array
confidence:
type: number
name:
type: string
nsfw:
type: boolean
nsfw_confidence:
type: number
priority:
type: integer
source:
type: string
topicality:
type: number
type: object
vision.Model:
properties:
Run:
allOf:
- $ref: '#/components/schemas/vision.RunType'
description: '"auto", "never", "manual", "always", "newly-indexed", "on-schedule"'
canonicalOrder:
type: boolean
default:
type: boolean
defaultThreshold:
type: number
disabled:
type: boolean
engine:
$ref: '#/components/schemas/vision.ModelEngine'
format:
type: string
labelFile:
type: string
model:
type: string
name:
type: string
neutralClassIndex:
type: integer
normalize:
allOf:
- $ref: '#/components/schemas/vision.NormalizeType'
description: '"single-word", "phrase", or "false"'
onnx:
$ref: '#/components/schemas/onnx.ModelInfo'
options:
$ref: '#/components/schemas/vision.ModelOptions'
prompt:
type: string
reduction:
$ref: '#/components/schemas/nsfw.Reduction'
resolution:
type: integer
schema:
type: string
schemaFile:
type: string
service:
$ref: '#/components/schemas/vision.Service'
system:
type: string
tensorflow:
$ref: '#/components/schemas/tensorflow.ModelInfo'
type:
$ref: '#/components/schemas/vision.ModelType'
unsafeClassIndex:
type: integer
version:
type: string
type: object
tensorflow.ShapeComponent:
enum:
- Batch
type: string
x-enum-varnames:
- ShapeBatch
tensorflow.ModelInfo:
properties:
input:
$ref: '#/components/schemas/tensorflow.PhotoInput'
output:
$ref: '#/components/schemas/tensorflow.ModelOutput'
tags:
items:
type: string
type: array
type: object
vision.Service:
properties:
disabled:
type: boolean
fileScheme:
type: string
method:
type: string
model:
description: Optional endpoint-specific model override.
type: string
org:
description: Optional organization header (e.g. OpenAI).
type: string
project:
description: Optional project header (e.g. OpenAI).
type: string
requestFormat:
$ref: '#/components/schemas/vision.ApiFormat'
responseFormat:
$ref: '#/components/schemas/vision.ApiFormat'
think:
description: Optional reasoning hint for compatible engines (e.g. Ollama, GPT-OSS); defaults to "false" for the Ollama engine.
type: string
tier:
description: Optional service tier sent as service_tier in the request body (OpenAI, e.g. "flex").
type: string
uri:
type: string
type: object
nsfw.Result:
properties:
Drawing:
description: 'Class probabilities used by legacy and remote models. Detectors with a binary taxonomy
leave these zero, so a client must read Status. The JSON names are capitalized because
that is what this endpoint has always emitted for these untagged fields.'
type: number
Hentai:
type: number
Neutral:
type: number
Porn:
type: number
Sexy:
type: number
reason:
description: Reason names why no decision was made, and is empty otherwise.
type: string
score:
description: Score is the probability that the image is unsafe, from 0 to 1.
type: number
status:
description: 'Status is the decision, and the only field a caller may act on. The tag spells the wire
values out because the zero value serializes as "unavailable" rather than as itself.'
enum:
- safe
- unsafe
- unavailable
type: string
threshold:
description: 'Threshold is the value Score was compared against, recorded so a decision can be
explained, or re-derived by a caller, without running inference again.'
type: number
type: object
tensorflow.Interval:
properties:
end:
type: number
mean:
type: number
start:
type: number
stdDev:
type: number
type: object
onnx.Resize:
properties:
cropRatio:
type: number
interpolation:
$ref: '#/components/schemas/onnx.Interpolation'
mode:
$ref: '#/components/schemas/onnx.ResizeMode'
shortEdge:
type: integer
type: object
vision.ApiRequest:
properties:
context:
items:
type: integer
type: array
format:
type: string
id:
type: string
images:
items:
type: string
type: array
model:
type: string
options:
$ref: '#/components/schemas/vision.ModelOptions'
org:
type: string
project:
type: string
prompt:
type: string
schema:
items:
type: integer
type: array
stream:
type: boolean
suffix:
type: string
system:
type: string
think:
type: string
tier:
type: string
url:
type: string
version:
type: string
type: object
vision.ModelEngine:
enum:
- vision
- tensorflow
- onnx
- local
type: string
x-enum-varnames:
- EngineVision
- EngineTensorFlow
- EngineONNX
- EngineLocal
nsfw.Reduction:
enum:
- softmax-unsafe
- sigmoid-unsafe
- neutral-complement
type: string
x-enum-varnames:
- ReductionSoftmaxUnsafe
- ReductionSigmoidUnsafe
- ReductionNeutralComplement
onnx.ColorOrder:
enum:
- ''
- RGB
- BGR
type: string
x-enum-varnames:
- OrderUndefined
- RGB
- BGR
onnx.Normalization:
properties:
mean:
items:
type: number
type: array
stdDev:
items:
type: number
type: array
type: object
onnx.Input:
properties:
colorOrder:
$ref: '#/components/schemas/onnx.ColorOrder'
height:
type: integer
layout:
$ref: '#/components/schemas/onnx.Layout'
name:
type: string
normalization:
$ref: '#/components/schemas/onnx.Normalization'
resize:
$ref: '#/components/schemas/onnx.Resize'
width:
type: integer
type: object
vision.ApiResponse:
properties:
code:
type: integer
error:
type: string
id:
type: string
model:
$ref: '#/components/schemas/vision.Model'
result:
$ref: '#/components/schemas/vision.ApiResult'
type: object
tensorflow.ColorChannelOrder:
enum:
- 0
type: integer
x-enum-varnames:
- UndefinedOrder
vision.ApiResult:
properties:
caption:
$ref: '#/components/schemas/vision.CaptionResult'
embeddings:
items:
items:
items:
format: float64
type: number
type: array
type: array
type: array
labels:
items:
$ref: '#/components/schemas/vision.LabelResult'
type: array
nsfw:
items:
$ref: '#/components/schemas/nsfw.Result'
type: array
type: object
vision.RunType:
enum:
- ''
- never
- manual
- always
- newly-indexed
- on-demand
- on-schedule
- on-index
type: string
x-enum-varnames:
- RunAuto
- RunNever
- RunManual
- RunAlways
- RunNewlyIndexed
- RunOnDemand
- RunOnSchedule
- RunOnIndex
vision.NormalizeType:
enum:
- ''
- single-word
- phrase
- 'false'
type: string
x-enum-varnames:
- NormalizeAuto
- NormalizeWord
- NormalizePhrase
- NormalizeFalse
onnx.Output:
properties:
count:
type: integer
logits:
type: boolean
name:
type: string
width:
type: integer
type: object
onnx.Layout:
enum:
- ''
- NCHW
- NHWC
type: string
x-enum-varnames:
- LayoutUndefined
- LayoutNCHW
- LayoutNHWC
securitySchemes:
BearerAuth:
in: header
name: Authorization
type: apiKey
externalDocs:
description: Learn more ›
url: https://docs.photoprism.app/developer-guide/api/