curl --request POST \
--url https://www.closient.com/products/api/v1/product-links/reorder \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"links": [
{
"id": "keATfB8VP2gSjcnTbsMNQL",
"order": 0
},
{
"id": "F5n5NdW6dTbvPYkgnLNjte",
"order": 1
}
],
"product_id": "SBjSX6xUJPPHQKUXBpYX2C"
}
'import requests
url = "https://www.closient.com/products/api/v1/product-links/reorder"
payload = {
"links": [
{
"id": "keATfB8VP2gSjcnTbsMNQL",
"order": 0
},
{
"id": "F5n5NdW6dTbvPYkgnLNjte",
"order": 1
}
],
"product_id": "SBjSX6xUJPPHQKUXBpYX2C"
}
headers = {
"X-API-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
links: [
{id: 'keATfB8VP2gSjcnTbsMNQL', order: 0},
{id: 'F5n5NdW6dTbvPYkgnLNjte', order: 1}
],
product_id: 'SBjSX6xUJPPHQKUXBpYX2C'
})
};
fetch('https://www.closient.com/products/api/v1/product-links/reorder', 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/product-links/reorder",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'links' => [
[
'id' => 'keATfB8VP2gSjcnTbsMNQL',
'order' => 0
],
[
'id' => 'F5n5NdW6dTbvPYkgnLNjte',
'order' => 1
]
],
'product_id' => 'SBjSX6xUJPPHQKUXBpYX2C'
]),
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/product-links/reorder"
payload := strings.NewReader("{\n \"links\": [\n {\n \"id\": \"keATfB8VP2gSjcnTbsMNQL\",\n \"order\": 0\n },\n {\n \"id\": \"F5n5NdW6dTbvPYkgnLNjte\",\n \"order\": 1\n }\n ],\n \"product_id\": \"SBjSX6xUJPPHQKUXBpYX2C\"\n}")
req, _ := http.NewRequest("POST", 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.post("https://www.closient.com/products/api/v1/product-links/reorder")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"links\": [\n {\n \"id\": \"keATfB8VP2gSjcnTbsMNQL\",\n \"order\": 0\n },\n {\n \"id\": \"F5n5NdW6dTbvPYkgnLNjte\",\n \"order\": 1\n }\n ],\n \"product_id\": \"SBjSX6xUJPPHQKUXBpYX2C\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://www.closient.com/products/api/v1/product-links/reorder")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"links\": [\n {\n \"id\": \"keATfB8VP2gSjcnTbsMNQL\",\n \"order\": 0\n },\n {\n \"id\": \"F5n5NdW6dTbvPYkgnLNjte\",\n \"order\": 1\n }\n ],\n \"product_id\": \"SBjSX6xUJPPHQKUXBpYX2C\"\n}"
response = http.request(request)
puts response.read_body[
{
"anchor": "review",
"created": "2026-09-01T09:00:00Z",
"description": "",
"display_label": "Rate it on Untappd",
"id": "keATfB8VP2gSjcnTbsMNQL",
"label": "Rate it on Untappd",
"link_type": "gs1:review",
"modified": "2026-09-01T09:00:00Z",
"order": 0,
"product_id": "SBjSX6xUJPPHQKUXBpYX2C",
"url": "https://untappd.com/b/container-brewing-seawise-giant/3533900",
"use_ai_substitution": false
}
]{
"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"
}Reorder product links
Atomically set order on every link belonging to one product or brand. Every link id referenced must belong to that product/brand, otherwise the whole call aborts with 404 and nothing is changed.
curl --request POST \
--url https://www.closient.com/products/api/v1/product-links/reorder \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"links": [
{
"id": "keATfB8VP2gSjcnTbsMNQL",
"order": 0
},
{
"id": "F5n5NdW6dTbvPYkgnLNjte",
"order": 1
}
],
"product_id": "SBjSX6xUJPPHQKUXBpYX2C"
}
'import requests
url = "https://www.closient.com/products/api/v1/product-links/reorder"
payload = {
"links": [
{
"id": "keATfB8VP2gSjcnTbsMNQL",
"order": 0
},
{
"id": "F5n5NdW6dTbvPYkgnLNjte",
"order": 1
}
],
"product_id": "SBjSX6xUJPPHQKUXBpYX2C"
}
headers = {
"X-API-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
links: [
{id: 'keATfB8VP2gSjcnTbsMNQL', order: 0},
{id: 'F5n5NdW6dTbvPYkgnLNjte', order: 1}
],
product_id: 'SBjSX6xUJPPHQKUXBpYX2C'
})
};
fetch('https://www.closient.com/products/api/v1/product-links/reorder', 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/product-links/reorder",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'links' => [
[
'id' => 'keATfB8VP2gSjcnTbsMNQL',
'order' => 0
],
[
'id' => 'F5n5NdW6dTbvPYkgnLNjte',
'order' => 1
]
],
'product_id' => 'SBjSX6xUJPPHQKUXBpYX2C'
]),
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/product-links/reorder"
payload := strings.NewReader("{\n \"links\": [\n {\n \"id\": \"keATfB8VP2gSjcnTbsMNQL\",\n \"order\": 0\n },\n {\n \"id\": \"F5n5NdW6dTbvPYkgnLNjte\",\n \"order\": 1\n }\n ],\n \"product_id\": \"SBjSX6xUJPPHQKUXBpYX2C\"\n}")
req, _ := http.NewRequest("POST", 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.post("https://www.closient.com/products/api/v1/product-links/reorder")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"links\": [\n {\n \"id\": \"keATfB8VP2gSjcnTbsMNQL\",\n \"order\": 0\n },\n {\n \"id\": \"F5n5NdW6dTbvPYkgnLNjte\",\n \"order\": 1\n }\n ],\n \"product_id\": \"SBjSX6xUJPPHQKUXBpYX2C\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://www.closient.com/products/api/v1/product-links/reorder")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"links\": [\n {\n \"id\": \"keATfB8VP2gSjcnTbsMNQL\",\n \"order\": 0\n },\n {\n \"id\": \"F5n5NdW6dTbvPYkgnLNjte\",\n \"order\": 1\n }\n ],\n \"product_id\": \"SBjSX6xUJPPHQKUXBpYX2C\"\n}"
response = http.request(request)
puts response.read_body[
{
"anchor": "review",
"created": "2026-09-01T09:00:00Z",
"description": "",
"display_label": "Rate it on Untappd",
"id": "keATfB8VP2gSjcnTbsMNQL",
"label": "Rate it on Untappd",
"link_type": "gs1:review",
"modified": "2026-09-01T09:00:00Z",
"order": 0,
"product_id": "SBjSX6xUJPPHQKUXBpYX2C",
"url": "https://untappd.com/b/container-brewing-seawise-giant/3533900",
"use_ai_substitution": false
}
]{
"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
Body
- ProductLinkReorderInput
- ProductLinkReorderInput
Body for the bulk reorder endpoint — new ordering for one product's or brand's links.
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}$Complete new ordering for every link under the given product/brand. Applied in a single transaction; a link id outside that owner's scope aborts the whole reorder with 404 and nothing is changed.
Show child attributes
Show child attributes
Reorder the links belonging to this brand. Exactly one of product_id/brand_id.
Response
OK
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}$GS1 Web Vocabulary link-type CURIE, e.g. gs1:promotion, gs1:loyaltyProgram, gs1:homepage. Validated against the live GS1 Web Vocabulary link-type set — an unknown or resolver-only CURIE (gs1:defaultLink, gs1:handledBy, …) is rejected with 422.
64Destination URL. May include {gtin}/{lot}/{serial} substitution tokens to prefill the brand's page from the scan context when use_ai_substitution is set.
2048Display order within the link type's group on the hosted page (ascending).
x >= 0When set, treat url as a template and inject the scanned GS1 AIs (GTIN/lot/serial) at render time.
Hosted-page fragment anchor this link's group renders under.
Label to render — the explicit label, else the link type's title.
Server-side ISO 8601 timestamp of creation (UTC).
Server-side ISO 8601 timestamp of last modification (UTC).
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}$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}$Link label shown on the hosted page. Defaults to the GS1 link type's title when blank.
120Optional longer description shown alongside the link.