curl --request PATCH \
--url https://www.closient.com/products/api/v1/products/{gtin}/lots/{lot_id} \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"expiration_date": "2027-10-01"
}
'import requests
url = "https://www.closient.com/products/api/v1/products/{gtin}/lots/{lot_id}"
payload = { "expiration_date": "2027-10-01" }
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({expiration_date: '2027-10-01'})
};
fetch('https://www.closient.com/products/api/v1/products/{gtin}/lots/{lot_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/products/api/v1/products/{gtin}/lots/{lot_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([
'expiration_date' => '2027-10-01'
]),
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/products/api/v1/products/{gtin}/lots/{lot_id}"
payload := strings.NewReader("{\n \"expiration_date\": \"2027-10-01\"\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/products/api/v1/products/{gtin}/lots/{lot_id}")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"expiration_date\": \"2027-10-01\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://www.closient.com/products/api/v1/products/{gtin}/lots/{lot_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 \"expiration_date\": \"2027-10-01\"\n}"
response = http.request(request)
puts response.read_body{
"created": "2026-09-01T09:00:00Z",
"expiration_date": "2027-09-01",
"gtin": "00850012345671",
"id": "keATfB8VP2gSjcnTbsMNQL",
"lot_identifier": "L2026-14",
"modified": "2026-09-01T09:00:00Z",
"product_id": "SBjSX6xUJPPHQKUXBpYX2C",
"production_date": "2026-09-01T08:00:00Z",
"quantity": 1200,
"unit_of_measure": "CS"
}{
"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"
}{
"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 a lot
Partial update: only the keys in the body are applied. A null clears a nullable field; an empty body is a 422. Once a traceability event references the lot, its identifier is locked. Requires CONTRIBUTE on the owning organization.
curl --request PATCH \
--url https://www.closient.com/products/api/v1/products/{gtin}/lots/{lot_id} \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"expiration_date": "2027-10-01"
}
'import requests
url = "https://www.closient.com/products/api/v1/products/{gtin}/lots/{lot_id}"
payload = { "expiration_date": "2027-10-01" }
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({expiration_date: '2027-10-01'})
};
fetch('https://www.closient.com/products/api/v1/products/{gtin}/lots/{lot_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/products/api/v1/products/{gtin}/lots/{lot_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([
'expiration_date' => '2027-10-01'
]),
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/products/api/v1/products/{gtin}/lots/{lot_id}"
payload := strings.NewReader("{\n \"expiration_date\": \"2027-10-01\"\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/products/api/v1/products/{gtin}/lots/{lot_id}")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"expiration_date\": \"2027-10-01\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://www.closient.com/products/api/v1/products/{gtin}/lots/{lot_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 \"expiration_date\": \"2027-10-01\"\n}"
response = http.request(request)
puts response.read_body{
"created": "2026-09-01T09:00:00Z",
"expiration_date": "2027-09-01",
"gtin": "00850012345671",
"id": "keATfB8VP2gSjcnTbsMNQL",
"lot_identifier": "L2026-14",
"modified": "2026-09-01T09:00:00Z",
"product_id": "SBjSX6xUJPPHQKUXBpYX2C",
"production_date": "2026-09-01T08:00:00Z",
"quantity": 1200,
"unit_of_measure": "CS"
}{
"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"
}{
"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
GTIN barcode (8, 12, 13 or 14 digits), normalized to GTIN-14 for lookup.
^[0-9]{8,14}$Id of the lot.
22^[23456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{22}$Body
Payload for PATCH /products/{gtin}/lots/{lot_id}. Only the keys present are applied.
GS1 AI(10) batch or lot number. Locked once a traceability event references the lot: changing it then is a 422.
1 - 20^[!-~]{1,20}$When the lot was produced. Null clears it.
Expiration date (GS1 AI 17). Null clears it.
Best-before date (GS1 AI 15). Null clears it.
Total quantity in the lot. Null clears it.
0 <= x <= 999999999.999Unit of the lot's quantity. Null clears it.
EA, DZN, CS, PLT, GRM, KGM, LBR, OZA, MLT, LTR, GLL, FOZ Response
OK
A lot as read from the API. Mirrors ProductLot.
URL-safe 22-character shortuuid encoding of the row's UUID primary key. Stable across the row's lifetime; suitable for sharing in URLs, log lines, and external SDK clients. Accepted on input as either the shortuuid form or the canonical UUID form (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx).
22^[23456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{22}$The product this lot belongs to.
22^[23456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{22}$The product's GTIN, normalized to GTIN-14.
GS1 AI(10) batch or lot number.
Server-side ISO 8601 timestamp of creation (UTC).
Server-side ISO 8601 timestamp of last modification (UTC).
When the lot was produced. Null when unset.
Expiration date (GS1 AI 17). Null when unset.
Best-before date (GS1 AI 15). Null when unset.
Total quantity in the lot. Null when unset.
Unit of the lot's quantity. Null when unset.
EA, DZN, CS, PLT, GRM, KGM, LBR, OZA, MLT, LTR, GLL, FOZ