curl --request PATCH \
--url https://www.closient.com/scanner/api/v1/sessions/{session_id}/photos/{photo_id} \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"metadata": {
"order_id": "6735"
},
"photo_type": "nutrition"
}
'import requests
url = "https://www.closient.com/scanner/api/v1/sessions/{session_id}/photos/{photo_id}"
payload = {
"metadata": { "order_id": "6735" },
"photo_type": "nutrition"
}
headers = {
"X-API-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {'X-API-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({metadata: {order_id: '6735'}, photo_type: 'nutrition'})
};
fetch('https://www.closient.com/scanner/api/v1/sessions/{session_id}/photos/{photo_id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://www.closient.com/scanner/api/v1/sessions/{session_id}/photos/{photo_id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'metadata' => [
'order_id' => '6735'
],
'photo_type' => 'nutrition'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://www.closient.com/scanner/api/v1/sessions/{session_id}/photos/{photo_id}"
payload := strings.NewReader("{\n \"metadata\": {\n \"order_id\": \"6735\"\n },\n \"photo_type\": \"nutrition\"\n}")
req, _ := http.NewRequest("PATCH", url, payload)
req.Header.Add("X-API-Key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.patch("https://www.closient.com/scanner/api/v1/sessions/{session_id}/photos/{photo_id}")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"metadata\": {\n \"order_id\": \"6735\"\n },\n \"photo_type\": \"nutrition\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://www.closient.com/scanner/api/v1/sessions/{session_id}/photos/{photo_id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["X-API-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"metadata\": {\n \"order_id\": \"6735\"\n },\n \"photo_type\": \"nutrition\"\n}"
response = http.request(request)
puts response.read_body{
"capture_short_id": "cap-a1b2c3",
"created": "2025-08-15T14:30:00Z",
"file_size": 245760,
"metadata": {
"order_id": "6735"
},
"original_filename": "IMG_1234.jpg",
"photo_type": "front",
"s3_key": "scans/2025/08/photo-x1y2z3.jpg",
"sort_order": 1
}{
"detail": "The requested resource was not found.",
"error_code": "not_found",
"retryable": false,
"status": 404,
"timestamp": "2026-03-31T12:00:00+00:00",
"title": "Not Found",
"type": "https://closient.com/docs/errors/not_found"
}{
"detail": "The requested resource was not found.",
"error_code": "not_found",
"retryable": false,
"status": 404,
"timestamp": "2026-03-31T12:00:00+00:00",
"title": "Not Found",
"type": "https://closient.com/docs/errors/not_found"
}{
"detail": "The requested resource was not found.",
"error_code": "not_found",
"retryable": false,
"status": 404,
"timestamp": "2026-03-31T12:00:00+00:00",
"title": "Not Found",
"type": "https://closient.com/docs/errors/not_found"
}{
"detail": "The requested resource was not found.",
"error_code": "not_found",
"retryable": false,
"status": 404,
"timestamp": "2026-03-31T12:00:00+00:00",
"title": "Not Found",
"type": "https://closient.com/docs/errors/not_found"
}{
"detail": "The requested resource was not found.",
"error_code": "not_found",
"retryable": false,
"status": 404,
"timestamp": "2026-03-31T12:00:00+00:00",
"title": "Not Found",
"type": "https://closient.com/docs/errors/not_found"
}{
"detail": "The requested resource was not found.",
"error_code": "not_found",
"retryable": false,
"status": 404,
"timestamp": "2026-03-31T12:00:00+00:00",
"title": "Not Found",
"type": "https://closient.com/docs/errors/not_found"
}{
"detail": "The requested resource was not found.",
"error_code": "not_found",
"retryable": false,
"status": 404,
"timestamp": "2026-03-31T12:00:00+00:00",
"title": "Not Found",
"type": "https://closient.com/docs/errors/not_found"
}Update photo classification
Update the classification label of a product photo.
curl --request PATCH \
--url https://www.closient.com/scanner/api/v1/sessions/{session_id}/photos/{photo_id} \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"metadata": {
"order_id": "6735"
},
"photo_type": "nutrition"
}
'import requests
url = "https://www.closient.com/scanner/api/v1/sessions/{session_id}/photos/{photo_id}"
payload = {
"metadata": { "order_id": "6735" },
"photo_type": "nutrition"
}
headers = {
"X-API-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {'X-API-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({metadata: {order_id: '6735'}, photo_type: 'nutrition'})
};
fetch('https://www.closient.com/scanner/api/v1/sessions/{session_id}/photos/{photo_id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://www.closient.com/scanner/api/v1/sessions/{session_id}/photos/{photo_id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'metadata' => [
'order_id' => '6735'
],
'photo_type' => 'nutrition'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://www.closient.com/scanner/api/v1/sessions/{session_id}/photos/{photo_id}"
payload := strings.NewReader("{\n \"metadata\": {\n \"order_id\": \"6735\"\n },\n \"photo_type\": \"nutrition\"\n}")
req, _ := http.NewRequest("PATCH", url, payload)
req.Header.Add("X-API-Key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.patch("https://www.closient.com/scanner/api/v1/sessions/{session_id}/photos/{photo_id}")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"metadata\": {\n \"order_id\": \"6735\"\n },\n \"photo_type\": \"nutrition\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://www.closient.com/scanner/api/v1/sessions/{session_id}/photos/{photo_id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["X-API-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"metadata\": {\n \"order_id\": \"6735\"\n },\n \"photo_type\": \"nutrition\"\n}"
response = http.request(request)
puts response.read_body{
"capture_short_id": "cap-a1b2c3",
"created": "2025-08-15T14:30:00Z",
"file_size": 245760,
"metadata": {
"order_id": "6735"
},
"original_filename": "IMG_1234.jpg",
"photo_type": "front",
"s3_key": "scans/2025/08/photo-x1y2z3.jpg",
"sort_order": 1
}{
"detail": "The requested resource was not found.",
"error_code": "not_found",
"retryable": false,
"status": 404,
"timestamp": "2026-03-31T12:00:00+00:00",
"title": "Not Found",
"type": "https://closient.com/docs/errors/not_found"
}{
"detail": "The requested resource was not found.",
"error_code": "not_found",
"retryable": false,
"status": 404,
"timestamp": "2026-03-31T12:00:00+00:00",
"title": "Not Found",
"type": "https://closient.com/docs/errors/not_found"
}{
"detail": "The requested resource was not found.",
"error_code": "not_found",
"retryable": false,
"status": 404,
"timestamp": "2026-03-31T12:00:00+00:00",
"title": "Not Found",
"type": "https://closient.com/docs/errors/not_found"
}{
"detail": "The requested resource was not found.",
"error_code": "not_found",
"retryable": false,
"status": 404,
"timestamp": "2026-03-31T12:00:00+00:00",
"title": "Not Found",
"type": "https://closient.com/docs/errors/not_found"
}{
"detail": "The requested resource was not found.",
"error_code": "not_found",
"retryable": false,
"status": 404,
"timestamp": "2026-03-31T12:00:00+00:00",
"title": "Not Found",
"type": "https://closient.com/docs/errors/not_found"
}{
"detail": "The requested resource was not found.",
"error_code": "not_found",
"retryable": false,
"status": 404,
"timestamp": "2026-03-31T12:00:00+00:00",
"title": "Not Found",
"type": "https://closient.com/docs/errors/not_found"
}{
"detail": "The requested resource was not found.",
"error_code": "not_found",
"retryable": false,
"status": 404,
"timestamp": "2026-03-31T12:00:00+00:00",
"title": "Not Found",
"type": "https://closient.com/docs/errors/not_found"
}Authorizations
Path Parameters
Unique session short_id identifier.
Unique photo short_id identifier.
Body
Request body for updating photo classification.
New classification label for the photo. Same value set as on registration — see PhotoTypeEnum.
front, back, left, right, top, bottom, nutrition, ingredients, barcode, recycling, certification, other Developer-attached key/value data. Send {} or null to clear. Empty-string values delete that key. Omitted keys are preserved.
Show child attributes
Show child attributes
Response
OK
A single product photo in a scan session gallery.
Classification label — which side or aspect of the product this photo shows. Drives routing through the vision pipeline (e.g. nutrition photos go to the nutrition-facts extractor).
front, back, left, right, top, bottom, nutrition, ingredients, barcode, recycling, certification, other S3 object key for the photo file.
Original filename.
Display position.
Timestamp when the photo was registered.
Developer-attached key/value data attached to this object. Up to 50 keys; key max 40 chars, value max 500 chars.
Show child attributes
Show child attributes
File size in bytes.
Slug of the linked barcode capture.