---
title: "OpenVibe.Vision API · OpenVibe.Services"
canonical: "https://openvibe.services/docs/api/vision"
updated: null
---

# OpenVibe.Vision API · OpenVibe.Services

HTML: [OpenVibe.Vision API · OpenVibe.Services](https://openvibe.services/docs/api/vision)

# OpenVibe.Vision API

Generated at 2026-11-13 06:25:48 UTC from [`openvibe-contracts v0.419.0`](https://github.com/OpenVibers/OpenVibe.Contracts/tree/v0.419.0) and [`openvibe-sdk v0.161.0`](https://github.com/OpenVibers/OpenVibe.SDK/tree/v0.161.0).

Server `https://openvibe.vision`. 38 routes performing 23 capabilities. [OpenAPI 3.1 document](/docs/api/vision.json).

  only routes apps can be granted (public, partner)  

### POST `/api/v1/alt`

Write editable alt text for an image on OpenVibe.Vision: POST /api/v1/alt returns one short sentence about the scene, objects and action, never about a person.

- Capabilities: [vision.alt.write](/docs/capabilities/vision.alt.write)
- Visibility: first-party
- Request body: `application/json` [vision.image-request@1](/docs/contracts/vision.image-request)
- Response: `application/json` [vision.alt-result@1](/docs/contracts/vision.alt-result)
- Errors: [errors.problem@1](/docs/contracts/errors.problem) (application/problem+json)

 Description<p><strong>vision.alt.write</strong> (first-party): Write editable alt text for an image on OpenVibe.Vision: POST /api/v1/alt returns one short sentence about the scene, objects and action, never about a person. The answer has passed noLooks; the receipt names the engine, cost and latency. Rooms use it for Pics, Media and Chat uploads.</p>

### POST `/api/v1/ask`

Ask or describe an image on OpenVibe.Vision: POST /api/v1/ask and /api/v1/describe take an image (multipart, data URL or public URL), a question, a task (ask, describe, identify, count, translate, ocr

- Capabilities: [vision.image.ask](/docs/capabilities/vision.image.ask)
- Visibility: first-party
- Request body: `application/json` [vision.ask-request@1](/docs/contracts/vision.ask-request)
- Response: `application/json` [vision.answer-result@1](/docs/contracts/vision.answer-result)
- Errors: [errors.problem@1](/docs/contracts/errors.problem) (application/problem+json)

 Description<p><strong>vision.image.ask</strong> (first-party): Ask or describe an image on OpenVibe.Vision: POST /api/v1/ask and /api/v1/describe take an image (multipart, data URL or public URL), a question, a task (ask, describe, identify, count, translate, ocr) and a mode (auto, local, ai). A read question is answered by the local OCR reader first; everything else goes through OpenVibe.AI, whose provenance the answer reports. In auto mode a read question also works anonymously; any other task needs a signed-in person or this capability.</p>

### GET `/api/v1/benchmarks`

Read OpenVibe.Vision's aggregate comparison results: GET /api/v1/benchmarks groups compare samples by task, engine, provider and model with sample counts, mean latency and mean cost, with no subject, 

- Capabilities: [vision.benchmarks.read](/docs/capabilities/vision.benchmarks.read)
- Visibility: first-party
- Response: `application/json` [vision.benchmarks@1](/docs/contracts/vision.benchmarks)
- Errors: [errors.problem@1](/docs/contracts/errors.problem) (application/problem+json)

 Description<p><strong>vision.benchmarks.read</strong> (first-party): Read OpenVibe.Vision&#39;s aggregate comparison results: GET /api/v1/benchmarks groups compare samples by task, engine, provider and model with sample counts, mean latency and mean cost, with no subject, image or answer text. Public.</p>

### POST `/api/v1/compare`

Run OpenVibe.Vision's side-by-side comparison: POST /api/v1/compare runs the local reader and up to three AI model hints on the same image and returns each row with its success, text, cost and latency.

- Capabilities: [vision.model.compare](/docs/capabilities/vision.model.compare)
- Visibility: first-party
- Request body: `application/json` [vision.compare-request@1](/docs/contracts/vision.compare-request)
- Response: `application/json` [vision.answer-result@1](/docs/contracts/vision.answer-result)
- Errors: [errors.problem@1](/docs/contracts/errors.problem) (application/problem+json)

 Description<p><strong>vision.model.compare</strong> (first-party): Run OpenVibe.Vision&#39;s side-by-side comparison: POST /api/v1/compare runs the local reader and up to three AI model hints on the same image and returns each row with its success, text, cost and latency. The requested model is a hint; OpenVibe.AI&#39;s own provenance is what each row reports.</p>

### POST `/api/v1/describe`

Ask or describe an image on OpenVibe.Vision: POST /api/v1/ask and /api/v1/describe take an image (multipart, data URL or public URL), a question, a task (ask, describe, identify, count, translate, ocr

- Capabilities: [vision.image.ask](/docs/capabilities/vision.image.ask)
- Visibility: first-party
- Request body: `application/json` [vision.ask-request@1](/docs/contracts/vision.ask-request)
- Response: `application/json` [vision.answer-result@1](/docs/contracts/vision.answer-result)
- Errors: [errors.problem@1](/docs/contracts/errors.problem) (application/problem+json)

 Description<p><strong>vision.image.ask</strong> (first-party): Ask or describe an image on OpenVibe.Vision: POST /api/v1/ask and /api/v1/describe take an image (multipart, data URL or public URL), a question, a task (ask, describe, identify, count, translate, ocr) and a mode (auto, local, ai). A read question is answered by the local OCR reader first; everything else goes through OpenVibe.AI, whose provenance the answer reports. In auto mode a read question also works anonymously; any other task needs a signed-in person or this capability.</p>

### POST `/api/v1/faces/blur`

Identity-free face blurring on OpenVibe.Vision: POST /api/v1/faces/blur returns a redacted PNG derivative and the blurred count in X-Faces-Blur.

- Capabilities: [vision.face.blur](/docs/capabilities/vision.face.blur)
- Visibility: first-party
- Request body: `application/json` [vision.image-request@1](/docs/contracts/vision.image-request)
- Response: `application/json` [vision.face-blur@1](/docs/contracts/vision.face-blur)
- Errors: [errors.problem@1](/docs/contracts/errors.problem) (application/problem+json)

 Description<p><strong>vision.face.blur</strong> (first-party): Identity-free face blurring on OpenVibe.Vision: POST /api/v1/faces/blur returns a redacted PNG derivative and the blurred count in X-Faces-Blur. No template is stored and the original is discarded; anyone may use it.</p>

### POST `/api/v1/faces/cast/match`

Match faces against one channel's opted-in adult cast roster for OpenVibe.Live: POST /api/v1/faces/cast/match.

- Capabilities: [vision.face.cast.match](/docs/capabilities/vision.face.cast.match)
- Visibility: first-party
- Request body: `application/json` [vision.face-cast-match-request@1](/docs/contracts/vision.face-cast-match-request)
- Response: `application/json` [vision.face-cast-match@1](/docs/contracts/vision.face-cast-match)
- Errors: [errors.problem@1](/docs/contracts/errors.problem) (application/problem+json)

 Description<p><strong>vision.face.cast.match</strong> (first-party): Match faces against one channel&#39;s opted-in adult cast roster for OpenVibe.Live: POST /api/v1/faces/cast/match. The caller is the Live service token scoped to that channel (its channel\_id claim must equal the body&#39;s channel) and must hold this capability. A non-consented person is never matched and the answer does not say whether they exist.</p>

### GET `/api/v1/faces/cast/tags`

Read your own cast tags on OpenVibe.Vision: GET /api/v1/faces/cast/tags lists the named channel and media reference for each tag the person's own cast consent produced.

- Capabilities: [vision.face.cast.read](/docs/capabilities/vision.face.cast.read)
- Visibility: first-party
- Response: `application/json` [vision.face-tag-list@1](/docs/contracts/vision.face-tag-list)
- Errors: [errors.problem@1](/docs/contracts/errors.problem) (application/problem+json)

 Description<p><strong>vision.face.cast.read</strong> (first-party): Read your own cast tags on OpenVibe.Vision: GET /api/v1/faces/cast/tags lists the named channel and media reference for each tag the person&#39;s own cast consent produced. Revoking the consent removes them.</p>

### GET `/api/v1/faces/consents`

Read, grant and revoke purpose-scoped face or voice consent on OpenVibe.Vision: GET /api/v1/faces/consents and /consents/text, POST /consents/:feature with the signed current text, and DELETE /consent

- Capabilities: [vision.face.consent.manage](/docs/capabilities/vision.face.consent.manage)
- Visibility: first-party
- Parameters: - `signed_name` (query, required)
- `text_version` (query, required)
- `modality` (query)
- `feature` (query) — Echo of the :feature path segment.
- `channel` (query)
- `adult` (query)
- `region` (query)
- Input: [vision.consent-request@1](/docs/contracts/vision.consent-request)
- Response: `application/json` [vision.consent@1](/docs/contracts/vision.consent)
- Errors: [errors.problem@1](/docs/contracts/errors.problem) (application/problem+json)

 Description<p><strong>vision.face.consent.manage</strong> (first-party): Read, grant and revoke purpose-scoped face or voice consent on OpenVibe.Vision: GET /api/v1/faces/consents and /consents/text, POST /consents/:feature with the signed current text, and DELETE /consents/:feature, which revokes and erases the template and derived data in one transaction. A person manages only their own record; the record says whose face or voice, the scope, expiry and how it was revoked (vision.consent@1).</p>

### POST `/api/v1/faces/consents/{feature}`

Read, grant and revoke purpose-scoped face or voice consent on OpenVibe.Vision: GET /api/v1/faces/consents and /consents/text, POST /consents/:feature with the signed current text, and DELETE /consent

- Capabilities: [vision.face.consent.manage](/docs/capabilities/vision.face.consent.manage)
- Visibility: first-party
- Parameters: - `feature` (path, required)
- Request body: `application/json` [vision.consent-request@1](/docs/contracts/vision.consent-request)
- Response: `application/json` [vision.consent@1](/docs/contracts/vision.consent)
- Errors: [errors.problem@1](/docs/contracts/errors.problem) (application/problem+json)

 Description<p><strong>vision.face.consent.manage</strong> (first-party): Read, grant and revoke purpose-scoped face or voice consent on OpenVibe.Vision: GET /api/v1/faces/consents and /consents/text, POST /consents/:feature with the signed current text, and DELETE /consents/:feature, which revokes and erases the template and derived data in one transaction. A person manages only their own record; the record says whose face or voice, the scope, expiry and how it was revoked (vision.consent@1).</p>

### DELETE `/api/v1/faces/consents/{feature}`

Read, grant and revoke purpose-scoped face or voice consent on OpenVibe.Vision: GET /api/v1/faces/consents and /consents/text, POST /consents/:feature with the signed current text, and DELETE /consent

- Capabilities: [vision.face.consent.manage](/docs/capabilities/vision.face.consent.manage)
- Visibility: first-party
- Parameters: - `feature` (path, required)
- `signed_name` (query, required)
- `text_version` (query, required)
- `modality` (query)
- `channel` (query)
- `adult` (query)
- `region` (query)
- Input: [vision.consent-request@1](/docs/contracts/vision.consent-request)
- Response: `application/json` [vision.consent@1](/docs/contracts/vision.consent)
- Errors: [errors.problem@1](/docs/contracts/errors.problem) (application/problem+json)

 Description<p><strong>vision.face.consent.manage</strong> (first-party): Read, grant and revoke purpose-scoped face or voice consent on OpenVibe.Vision: GET /api/v1/faces/consents and /consents/text, POST /consents/:feature with the signed current text, and DELETE /consents/:feature, which revokes and erases the template and derived data in one transaction. A person manages only their own record; the record says whose face or voice, the scope, expiry and how it was revoked (vision.consent@1).</p>

### GET `/api/v1/faces/consents/text`

Read, grant and revoke purpose-scoped face or voice consent on OpenVibe.Vision: GET /api/v1/faces/consents and /consents/text, POST /consents/:feature with the signed current text, and DELETE /consent

- Capabilities: [vision.face.consent.manage](/docs/capabilities/vision.face.consent.manage)
- Visibility: first-party
- Parameters: - `signed_name` (query, required)
- `text_version` (query, required)
- `modality` (query)
- `feature` (query) — Echo of the :feature path segment.
- `channel` (query)
- `adult` (query)
- `region` (query)
- Input: [vision.consent-request@1](/docs/contracts/vision.consent-request)
- Response: `application/json` [vision.consent@1](/docs/contracts/vision.consent)
- Errors: [errors.problem@1](/docs/contracts/errors.problem) (application/problem+json)

 Description<p><strong>vision.face.consent.manage</strong> (first-party): Read, grant and revoke purpose-scoped face or voice consent on OpenVibe.Vision: GET /api/v1/faces/consents and /consents/text, POST /consents/:feature with the signed current text, and DELETE /consents/:feature, which revokes and erases the template and derived data in one transaction. A person manages only their own record; the record says whose face or voice, the scope, expiry and how it was revoked (vision.consent@1).</p>

### POST `/api/v1/faces/detect`

Identity-free face detection on OpenVibe.Vision: POST /api/v1/faces/detect counts faces and returns their boxes and scores with local YuNet.

- Capabilities: [vision.face.detect](/docs/capabilities/vision.face.detect)
- Visibility: first-party
- Request body: `application/json` [vision.image-request@1](/docs/contracts/vision.image-request)
- Response: `application/json` [vision.face-detection@1](/docs/contracts/vision.face-detection)
- Errors: [errors.problem@1](/docs/contracts/errors.problem) (application/problem+json)

 Description<p><strong>vision.face.detect</strong> (first-party): Identity-free face detection on OpenVibe.Vision: POST /api/v1/faces/detect counts faces and returns their boxes and scores with local YuNet. It stores no template, names no one and needs no consent; anyone may use it.</p>

### POST `/api/v1/faces/enrol/{feature}`

Verify yourself against your own enrolled template on OpenVibe.Vision: POST /api/v1/faces/enrol/verify and /api/v1/faces/verify.

- Capabilities: [vision.face.verify.self](/docs/capabilities/vision.face.verify.self)
- Visibility: first-party
- Parameters: - `feature` (path, required)
- Request body: `application/json` [vision.face-enrol-request@1](/docs/contracts/vision.face-enrol-request)
- Response: `application/json` [vision.face-verify@1](/docs/contracts/vision.face-verify)
- Errors: [errors.problem@1](/docs/contracts/errors.problem) (application/problem+json)

 Description<p><strong>vision.face.verify.self</strong> (first-party): Verify yourself against your own enrolled template on OpenVibe.Vision: POST /api/v1/faces/enrol/verify and /api/v1/faces/verify. Refused with faces.consent\_required without that person&#39;s verify consent, the same answer whether or not a template exists; a match alone unlocks nothing.</p>

### POST `/api/v1/faces/find`

Find yourself in your own private uploads on OpenVibe.Vision: POST /api/v1/faces/media, GET /api/v1/faces/media/:id and POST /api/v1/faces/find.

- Capabilities: [vision.face.find.self](/docs/capabilities/vision.face.find.self)
- Visibility: first-party
- Request body: `application/json` [vision.find-request@1](/docs/contracts/vision.find-request)
- Response: `application/json` [vision.face-find-result@1](/docs/contracts/vision.face-find-result)
- Errors: [errors.problem@1](/docs/contracts/errors.problem) (application/problem+json)

 Description<p><strong>vision.face.find.self</strong> (first-party): Find yourself in your own private uploads on OpenVibe.Vision: POST /api/v1/faces/media, GET /api/v1/faces/media/:id and POST /api/v1/faces/find. Refused with faces.consent\_required without find consent, the same answer whether or not any media exists; results are private links to the caller&#39;s own rows.</p>

### POST `/api/v1/faces/library/cluster`

Group faces in your own Vision library: POST /api/v1/faces/library/cluster (region-gated), GET /api/v1/faces/library/groups and POST /api/v1/faces/library/correct (exclude, merge, split).

- Capabilities: [vision.face.library](/docs/capabilities/vision.face.library)
- Visibility: first-party
- Request body: `application/json` [vision.face-library-request@1](/docs/contracts/vision.face-library-request)
- Response: `application/json` [vision.face-library-result@1](/docs/contracts/vision.face-library-result)
- Errors: [errors.problem@1](/docs/contracts/errors.problem) (application/problem+json)

 Description<p><strong>vision.face.library</strong> (first-party): Group faces in your own Vision library: POST /api/v1/faces/library/cluster (region-gated), GET /api/v1/faces/library/groups and POST /api/v1/faces/library/correct (exclude, merge, split). Requires library consent; unknown faces stay unlabelled and nothing leaves that person&#39;s library.</p>

### POST `/api/v1/faces/library/correct`

Group faces in your own Vision library: POST /api/v1/faces/library/cluster (region-gated), GET /api/v1/faces/library/groups and POST /api/v1/faces/library/correct (exclude, merge, split).

- Capabilities: [vision.face.library](/docs/capabilities/vision.face.library)
- Visibility: first-party
- Request body: `application/json` [vision.face-library-request@1](/docs/contracts/vision.face-library-request)
- Response: `application/json` [vision.face-library-result@1](/docs/contracts/vision.face-library-result)
- Errors: [errors.problem@1](/docs/contracts/errors.problem) (application/problem+json)

 Description<p><strong>vision.face.library</strong> (first-party): Group faces in your own Vision library: POST /api/v1/faces/library/cluster (region-gated), GET /api/v1/faces/library/groups and POST /api/v1/faces/library/correct (exclude, merge, split). Requires library consent; unknown faces stay unlabelled and nothing leaves that person&#39;s library.</p>

### GET `/api/v1/faces/library/groups`

Group faces in your own Vision library: POST /api/v1/faces/library/cluster (region-gated), GET /api/v1/faces/library/groups and POST /api/v1/faces/library/correct (exclude, merge, split).

- Capabilities: [vision.face.library](/docs/capabilities/vision.face.library)
- Visibility: first-party
- Parameters: - `action` (query, required)
- `region` (query)
- `ids` (query)
- Input: [vision.face-library-request@1](/docs/contracts/vision.face-library-request)
- Response: `application/json` [vision.face-library-result@1](/docs/contracts/vision.face-library-result)
- Errors: [errors.problem@1](/docs/contracts/errors.problem) (application/problem+json)

 Description<p><strong>vision.face.library</strong> (first-party): Group faces in your own Vision library: POST /api/v1/faces/library/cluster (region-gated), GET /api/v1/faces/library/groups and POST /api/v1/faces/library/correct (exclude, merge, split). Requires library consent; unknown faces stay unlabelled and nothing leaves that person&#39;s library.</p>

### POST `/api/v1/faces/media`

Find yourself in your own private uploads on OpenVibe.Vision: POST /api/v1/faces/media, GET /api/v1/faces/media/:id and POST /api/v1/faces/find.

- Capabilities: [vision.face.find.self](/docs/capabilities/vision.face.find.self)
- Visibility: first-party
- Request body: `application/json` [vision.find-request@1](/docs/contracts/vision.find-request)
- Response: `application/json` [vision.face-find-result@1](/docs/contracts/vision.face-find-result)
- Errors: [errors.problem@1](/docs/contracts/errors.problem) (application/problem+json)

 Description<p><strong>vision.face.find.self</strong> (first-party): Find yourself in your own private uploads on OpenVibe.Vision: POST /api/v1/faces/media, GET /api/v1/faces/media/:id and POST /api/v1/faces/find. Refused with faces.consent\_required without find consent, the same answer whether or not any media exists; results are private links to the caller&#39;s own rows.</p>

### GET `/api/v1/faces/media/{id}`

Find yourself in your own private uploads on OpenVibe.Vision: POST /api/v1/faces/media, GET /api/v1/faces/media/:id and POST /api/v1/faces/find.

- Capabilities: [vision.face.find.self](/docs/capabilities/vision.face.find.self)
- Visibility: first-party
- Parameters: - `id` (path, required)
- Input: [vision.find-request@1](/docs/contracts/vision.find-request)
- Response: `application/json` [vision.face-find-result@1](/docs/contracts/vision.face-find-result)
- Errors: [errors.problem@1](/docs/contracts/errors.problem) (application/problem+json)

 Description<p><strong>vision.face.find.self</strong> (first-party): Find yourself in your own private uploads on OpenVibe.Vision: POST /api/v1/faces/media, GET /api/v1/faces/media/:id and POST /api/v1/faces/find. Refused with faces.consent\_required without find consent, the same answer whether or not any media exists; results are private links to the caller&#39;s own rows.</p>

### POST `/api/v1/faces/verify`

Verify yourself against your own enrolled template on OpenVibe.Vision: POST /api/v1/faces/enrol/verify and /api/v1/faces/verify.

- Capabilities: [vision.face.verify.self](/docs/capabilities/vision.face.verify.self)
- Visibility: first-party
- Request body: `application/json` [vision.face-enrol-request@1](/docs/contracts/vision.face-enrol-request)
- Response: `application/json` [vision.face-verify@1](/docs/contracts/vision.face-verify)
- Errors: [errors.problem@1](/docs/contracts/errors.problem) (application/problem+json)

 Description<p><strong>vision.face.verify.self</strong> (first-party): Verify yourself against your own enrolled template on OpenVibe.Vision: POST /api/v1/faces/enrol/verify and /api/v1/faces/verify. Refused with faces.consent\_required without that person&#39;s verify consent, the same answer whether or not a template exists; a match alone unlocks nothing.</p>

### GET `/api/v1/find`

Index and search a person's own images by CLIP embedding on OpenVibe.Vision: POST /api/v1/index stores one scoped embedding per item and GET/POST /api/v1/find searches only that person's own private i

- Capabilities: [vision.media.find](/docs/capabilities/vision.media.find)
- Visibility: first-party
- Input: [vision.find-request@1](/docs/contracts/vision.find-request)
- Response: `application/json` [vision.find-result@1](/docs/contracts/vision.find-result)
- Errors: [errors.problem@1](/docs/contracts/errors.problem) (application/problem+json)

 Description<p><strong>vision.media.find</strong> (first-party): Index and search a person&#39;s own images by CLIP embedding on OpenVibe.Vision: POST /api/v1/index stores one scoped embedding per item and GET/POST /api/v1/find searches only that person&#39;s own private index, by words or by an example image. No public image index is made; every read is owner-checked.</p>

### POST `/api/v1/find`

Index and search a person's own images by CLIP embedding on OpenVibe.Vision: POST /api/v1/index stores one scoped embedding per item and GET/POST /api/v1/find searches only that person's own private i

- Capabilities: [vision.media.find](/docs/capabilities/vision.media.find)
- Visibility: first-party
- Request body: `application/json` [vision.find-request@1](/docs/contracts/vision.find-request)
- Response: `application/json` [vision.find-result@1](/docs/contracts/vision.find-result)
- Errors: [errors.problem@1](/docs/contracts/errors.problem) (application/problem+json)

 Description<p><strong>vision.media.find</strong> (first-party): Index and search a person&#39;s own images by CLIP embedding on OpenVibe.Vision: POST /api/v1/index stores one scoped embedding per item and GET/POST /api/v1/find searches only that person&#39;s own private index, by words or by an example image. No public image index is made; every read is owner-checked.</p>

### POST `/api/v1/index`

Index and search a person's own images by CLIP embedding on OpenVibe.Vision: POST /api/v1/index stores one scoped embedding per item and GET/POST /api/v1/find searches only that person's own private i

- Capabilities: [vision.media.find](/docs/capabilities/vision.media.find)
- Visibility: first-party
- Request body: `application/json` [vision.find-request@1](/docs/contracts/vision.find-request)
- Response: `application/json` [vision.find-result@1](/docs/contracts/vision.find-result)
- Errors: [errors.problem@1](/docs/contracts/errors.problem) (application/problem+json)

 Description<p><strong>vision.media.find</strong> (first-party): Index and search a person&#39;s own images by CLIP embedding on OpenVibe.Vision: POST /api/v1/index stores one scoped embedding per item and GET/POST /api/v1/find searches only that person&#39;s own private index, by words or by an example image. No public image index is made; every read is owner-checked.</p>

### GET `/api/v1/models`

Read OpenVibe.Vision's model menu: GET /api/v1/models returns the AI route's offered provider:model hints, the configured hints and the local engines present, with no subject data.

- Capabilities: [vision.models.read](/docs/capabilities/vision.models.read)
- Visibility: first-party
- Response: `application/json` [vision.models@1](/docs/contracts/vision.models)
- Errors: [errors.problem@1](/docs/contracts/errors.problem) (application/problem+json)

 Description<p><strong>vision.models.read</strong> (first-party): Read OpenVibe.Vision&#39;s model menu: GET /api/v1/models returns the AI route&#39;s offered provider:model hints, the configured hints and the local engines present, with no subject data. Public; OpenVibe.AI&#39;s router is still the authority.</p>

### POST `/api/v1/moments`

Find moments in a stream or VOD on OpenVibe.Vision: POST /api/v1/moments compares up to 30 timestamped frames with CLIP prompt embeddings and a histogram scene-change pass, returning scene changes and

- Capabilities: [vision.video.moments](/docs/capabilities/vision.video.moments)
- Visibility: first-party
- Request body: `application/json` [vision.moments-request@1](/docs/contracts/vision.moments-request)
- Response: `application/json` [vision.moments-result@1](/docs/contracts/vision.moments-result)
- Errors: [errors.problem@1](/docs/contracts/errors.problem) (application/problem+json)

 Description<p><strong>vision.video.moments</strong> (first-party): Find moments in a stream or VOD on OpenVibe.Vision: POST /api/v1/moments compares up to 30 timestamped frames with CLIP prompt embeddings and a histogram scene-change pass, returning scene changes and candidate moments. A candidate is a suggestion for Live or Media to accept.</p>

### POST `/api/v1/ocr`

Read text from an image with OpenVibe.Vision's local Tesseract 5 reader: POST /api/v1/ocr returns the text, mean confidence and word boxes at zero cost, anonymously.

- Capabilities: [vision.text.read](/docs/capabilities/vision.text.read)
- Visibility: first-party
- Request body: `application/json` [vision.ocr-request@1](/docs/contracts/vision.ocr-request)
- Response: `application/json` [vision.answer-result@1](/docs/contracts/vision.answer-result)
- Errors: [errors.problem@1](/docs/contracts/errors.problem) (application/problem+json)

 Description<p><strong>vision.text.read</strong> (first-party): Read text from an image with OpenVibe.Vision&#39;s local Tesseract 5 reader: POST /api/v1/ocr returns the text, mean confidence and word boxes at zero cost, anonymously. <code>fallback</code> asks OpenVibe.AI only when the local pass found no usable text, and that fallback needs a signed-in person or this capability.</p>

### POST `/api/v1/product`

Match a product photo to offers on OpenVibe.Vision: POST /api/v1/product describes the product only (never a person), embeds it with CLIP and returns candidate offers from OpenVibe.Deals and open.shoe

- Capabilities: [vision.product.match](/docs/capabilities/vision.product.match)
- Visibility: first-party
- Request body: `application/json` [vision.product-request@1](/docs/contracts/vision.product-request)
- Response: `application/json` [vision.product-result@1](/docs/contracts/vision.product-result)
- Errors: [errors.problem@1](/docs/contracts/errors.problem) (application/problem+json)

 Description<p><strong>vision.product.match</strong> (first-party): Match a product photo to offers on OpenVibe.Vision: POST /api/v1/product describes the product only (never a person), embeds it with CLIP and returns candidate offers from OpenVibe.Deals and open.shoes with their score and URL. A candidate is not a verified price.</p>

### POST `/api/v1/receipt`

Read a receipt on OpenVibe.Vision: POST /api/v1/receipt returns the store, line items and total the local OCR reader extracted; \`fallback\` asks OpenVibe.AI only when the local pass could not produce b

- Capabilities: [vision.receipt.read](/docs/capabilities/vision.receipt.read)
- Visibility: first-party
- Request body: `application/json` [vision.receipt-request@1](/docs/contracts/vision.receipt-request)
- Response: `application/json` [vision.receipt-result@1](/docs/contracts/vision.receipt-result)
- Errors: [errors.problem@1](/docs/contracts/errors.problem) (application/problem+json)

 Description<p><strong>vision.receipt.read</strong> (first-party): Read a receipt on OpenVibe.Vision: POST /api/v1/receipt returns the store, line items and total the local OCR reader extracted; <code>fallback</code> asks OpenVibe.AI only when the local pass could not produce both. OpenVibe.Food decides what enters a pantry.</p>

### GET `/api/v1/review`

Read OpenVibe.Vision's unsafe-image review queue and one review, including its operator report and the logged operator views.

- Capabilities: [vision.review.read](/docs/capabilities/vision.review.read)
- Visibility: first-party
- Response: —
- Errors: [errors.problem@1](/docs/contracts/errors.problem) (application/problem+json)

 Description<p><strong>vision.review.read</strong> (first-party): Read OpenVibe.Vision&#39;s unsafe-image review queue and one review, including its operator report and the logged operator views. Staff use it through the review pages; a service token holding this capability can read the queue. POST /api/v1/review/:id/reveal opens one 60-second Media evidence view and logs it.</p>

### POST `/api/v1/review`

Sort one image (or one AI text) into OpenVibe.Vision's unsafe-image review: exactly fine (nudity allowed), sex\_acts (never public; kept for its owner) or minor\_sexual (always blocked, quarantined and 

- Capabilities: [vision.image.review](/docs/capabilities/vision.image.review)
- Visibility: first-party
- Response: —
- Errors: [errors.problem@1](/docs/contracts/errors.problem) (application/problem+json)

 Description<p><strong>vision.image.review</strong> (first-party): Sort one image (or one AI text) into OpenVibe.Vision&#39;s unsafe-image review: exactly fine (nudity allowed), sex\_acts (never public; kept for its owner) or minor\_sexual (always blocked, quarantined and reported to the operator). POST /api/v1/review accepts a multipart image, a data URL, a public https image URL or text, plus the caller&#39;s object reference; the answer carries the category, plain words, the action and the operator report for category 3. Media, Community and Live call it with their own service token. No image bytes are stored.</p>

### GET `/api/v1/review/{id}`

Read OpenVibe.Vision's unsafe-image review queue and one review, including its operator report and the logged operator views.

- Capabilities: [vision.review.read](/docs/capabilities/vision.review.read)
- Visibility: first-party
- Parameters: - `id` (path, required)
- Response: —
- Errors: [errors.problem@1](/docs/contracts/errors.problem) (application/problem+json)

 Description<p><strong>vision.review.read</strong> (first-party): Read OpenVibe.Vision&#39;s unsafe-image review queue and one review, including its operator report and the logged operator views. Staff use it through the review pages; a service token holding this capability can read the queue. POST /api/v1/review/:id/reveal opens one 60-second Media evidence view and logs it.</p>

### POST `/api/v1/review/{id}/decide`

Set one OpenVibe.Vision unsafe-image review to exactly fine, sex\_acts or minor\_sexual.

- Capabilities: [vision.review.decide](/docs/capabilities/vision.review.decide)
- Visibility: first-party
- Parameters: - `id` (path, required)
- Response: —
- Errors: [errors.problem@1](/docs/contracts/errors.problem) (application/problem+json)

 Description<p><strong>vision.review.decide</strong> (first-party): Set one OpenVibe.Vision unsafe-image review to exactly fine, sex\_acts or minor\_sexual. POST /api/v1/review/:id/decide records who decided and when, and an overruling category releases Media&#39;s evidence hold. Staff use it through the review page; a service token holding this capability can make the same decision.</p>

### POST `/api/v1/review/{id}/reveal`

Read OpenVibe.Vision's unsafe-image review queue and one review, including its operator report and the logged operator views.

- Capabilities: [vision.review.read](/docs/capabilities/vision.review.read)
- Visibility: first-party
- Parameters: - `id` (path, required)
- Response: —
- Errors: [errors.problem@1](/docs/contracts/errors.problem) (application/problem+json)

 Description<p><strong>vision.review.read</strong> (first-party): Read OpenVibe.Vision&#39;s unsafe-image review queue and one review, including its operator report and the logged operator views. Staff use it through the review pages; a service token holding this capability can read the queue. POST /api/v1/review/:id/reveal opens one 60-second Media evidence view and logs it.</p>

### GET `/api/v1/review/reports`

Read OpenVibe.Vision's unsafe-image review queue and one review, including its operator report and the logged operator views.

- Capabilities: [vision.review.read](/docs/capabilities/vision.review.read)
- Visibility: first-party
- Response: —
- Errors: [errors.problem@1](/docs/contracts/errors.problem) (application/problem+json)

 Description<p><strong>vision.review.read</strong> (first-party): Read OpenVibe.Vision&#39;s unsafe-image review queue and one review, including its operator report and the logged operator views. Staff use it through the review pages; a service token holding this capability can read the queue. POST /api/v1/review/:id/reveal opens one 60-second Media evidence view and logs it.</p>

### POST `/api/v1/ui-check`

Run OpenVibe.Vision's UI check: POST /api/v1/ui-check takes HTML, a public URL or a screenshot plus an optional viewport and returns overflow, cut-off text, low contrast, overlap and layering findings

- Capabilities: [vision.ui.check](/docs/capabilities/vision.ui.check)
- Visibility: first-party
- Request body: `application/json` [vision.ui-check-request@1](/docs/contracts/vision.ui-check-request)
- Response: `application/json` [vision.ui-check-result@1](/docs/contracts/vision.ui-check-result)
- Errors: [errors.problem@1](/docs/contracts/errors.problem) (application/problem+json)

 Description<p><strong>vision.ui.check</strong> (first-party): Run OpenVibe.Vision&#39;s UI check: POST /api/v1/ui-check takes HTML, a public URL or a screenshot plus an optional viewport and returns overflow, cut-off text, low contrast, overlap and layering findings with counts and severity; GET /api/v1/ui-checks/:id reads a saved check. OpenVibe.Design&#39;s Arena is the caller today; a signed-in person may also use it. The check runs entirely on Vision&#39;s host (static HTML/CSS parsing, or OCR boxes and pixel sampling for a screenshot): it executes no JavaScript and fetches only a public URL through the SSRF guard.</p>

### GET `/api/v1/ui-checks/{id}`

Run OpenVibe.Vision's UI check: POST /api/v1/ui-check takes HTML, a public URL or a screenshot plus an optional viewport and returns overflow, cut-off text, low contrast, overlap and layering findings

- Capabilities: [vision.ui.check](/docs/capabilities/vision.ui.check)
- Visibility: first-party
- Parameters: - `id` (path, required)
- Input: [vision.ui-check-request@1](/docs/contracts/vision.ui-check-request)
- Response: `application/json` [vision.ui-check-result@1](/docs/contracts/vision.ui-check-result)
- Errors: [errors.problem@1](/docs/contracts/errors.problem) (application/problem+json)

 Description<p><strong>vision.ui.check</strong> (first-party): Run OpenVibe.Vision&#39;s UI check: POST /api/v1/ui-check takes HTML, a public URL or a screenshot plus an optional viewport and returns overflow, cut-off text, low contrast, overlap and layering findings with counts and severity; GET /api/v1/ui-checks/:id reads a saved check. OpenVibe.Design&#39;s Arena is the caller today; a signed-in person may also use it. The check runs entirely on Vision&#39;s host (static HTML/CSS parsing, or OCR boxes and pixel sampling for a screenshot): it executes no JavaScript and fetches only a public URL through the SSRF guard.</p>

### POST `/api/v1/watch`

Watch a camera still on OpenVibe.Vision: POST /api/v1/watch finds the requested classes (DETR labels, snow, delivery, package through CLIP, or a histogram scene change against previous\_image) and retu

- Capabilities: [vision.camera.watch](/docs/capabilities/vision.camera.watch)
- Visibility: first-party
- Request body: `application/json` [vision.watch-request@1](/docs/contracts/vision.watch-request)
- Response: `application/json` [vision.watch-result@1](/docs/contracts/vision.watch-result)
- Errors: [errors.problem@1](/docs/contracts/errors.problem) (application/problem+json)

 Description<p><strong>vision.camera.watch</strong> (first-party): Watch a camera still on OpenVibe.Vision: POST /api/v1/watch finds the requested classes (DETR labels, snow, delivery, package through CLIP, or a histogram scene change against previous\_image) and returns detections with confidence and boxes. Owner-granted camera alerting only; a watched class can raise vision.alert.</p>
