curl --request POST \
--url https://www.closient.com/products/api/v1/app-links \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"gtin": "00850012345671",
"name": "Acme Home",
"platform": "ios",
"url": "https://apps.apple.com/app/acme-home/id1234567890"
}
'import requests
url = "https://www.closient.com/products/api/v1/app-links"
payload = {
"gtin": "00850012345671",
"name": "Acme Home",
"platform": "ios",
"url": "https://apps.apple.com/app/acme-home/id1234567890"
}
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({
gtin: '00850012345671',
name: 'Acme Home',
platform: 'ios',
url: 'https://apps.apple.com/app/acme-home/id1234567890'
})
};
fetch('https://www.closient.com/products/api/v1/app-links', 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/app-links",
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([
'gtin' => '00850012345671',
'name' => 'Acme Home',
'platform' => 'ios',
'url' => 'https://apps.apple.com/app/acme-home/id1234567890'
]),
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/app-links"
payload := strings.NewReader("{\n \"gtin\": \"00850012345671\",\n \"name\": \"Acme Home\",\n \"platform\": \"ios\",\n \"url\": \"https://apps.apple.com/app/acme-home/id1234567890\"\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/app-links")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"gtin\": \"00850012345671\",\n \"name\": \"Acme Home\",\n \"platform\": \"ios\",\n \"url\": \"https://apps.apple.com/app/acme-home/id1234567890\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://www.closient.com/products/api/v1/app-links")
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 \"gtin\": \"00850012345671\",\n \"name\": \"Acme Home\",\n \"platform\": \"ios\",\n \"url\": \"https://apps.apple.com/app/acme-home/id1234567890\"\n}"
response = http.request(request)
puts response.read_body{
"created": "2026-09-30T09:00:00Z",
"description": "Control your Acme kettle from your phone.",
"gtin": "00850012345671",
"id": "F5n5NdW6dTbvPYkgnLNjte",
"is_required": false,
"minimum_version": "2.1",
"modified": "2026-09-30T09:00:00Z",
"name": "Acme Home",
"platform": "ios",
"priority": 0,
"product_id": "SBjSX6xUJPPHQKUXBpYX2C",
"url": "https://apps.apple.com/app/acme-home/id1234567890"
}{
"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"
}Create app link
Create an app link on a product. Requires CONTRIBUTE on the organization that owns the product; 404 if the GTIN isn’t a product the caller can see.
curl --request POST \
--url https://www.closient.com/products/api/v1/app-links \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"gtin": "00850012345671",
"name": "Acme Home",
"platform": "ios",
"url": "https://apps.apple.com/app/acme-home/id1234567890"
}
'import requests
url = "https://www.closient.com/products/api/v1/app-links"
payload = {
"gtin": "00850012345671",
"name": "Acme Home",
"platform": "ios",
"url": "https://apps.apple.com/app/acme-home/id1234567890"
}
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({
gtin: '00850012345671',
name: 'Acme Home',
platform: 'ios',
url: 'https://apps.apple.com/app/acme-home/id1234567890'
})
};
fetch('https://www.closient.com/products/api/v1/app-links', 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/app-links",
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([
'gtin' => '00850012345671',
'name' => 'Acme Home',
'platform' => 'ios',
'url' => 'https://apps.apple.com/app/acme-home/id1234567890'
]),
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/app-links"
payload := strings.NewReader("{\n \"gtin\": \"00850012345671\",\n \"name\": \"Acme Home\",\n \"platform\": \"ios\",\n \"url\": \"https://apps.apple.com/app/acme-home/id1234567890\"\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/app-links")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"gtin\": \"00850012345671\",\n \"name\": \"Acme Home\",\n \"platform\": \"ios\",\n \"url\": \"https://apps.apple.com/app/acme-home/id1234567890\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://www.closient.com/products/api/v1/app-links")
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 \"gtin\": \"00850012345671\",\n \"name\": \"Acme Home\",\n \"platform\": \"ios\",\n \"url\": \"https://apps.apple.com/app/acme-home/id1234567890\"\n}"
response = http.request(request)
puts response.read_body{
"created": "2026-09-30T09:00:00Z",
"description": "Control your Acme kettle from your phone.",
"gtin": "00850012345671",
"id": "F5n5NdW6dTbvPYkgnLNjte",
"is_required": false,
"minimum_version": "2.1",
"modified": "2026-09-30T09:00:00Z",
"name": "Acme Home",
"platform": "ios",
"priority": 0,
"product_id": "SBjSX6xUJPPHQKUXBpYX2C",
"url": "https://apps.apple.com/app/acme-home/id1234567890"
}{
"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
Payload for POST /app-links.
GTIN of the product to show the link on (8, 12, 13 or 14 digits). Must be a product the caller's organization owns, else 404.
8 - 14App name.
1 - 255^[^\x00]{1,255}$Store listing or web app URL. Must start with https://.
9 - 500^[Hh][Tt][Tt][Pp][Ss]://[^\x00-\x20\x7f/?#][^\x00-\x20\x7f]{0,491}$Where the app runs.
ios, android, macos, windows, linux, amazon, huawei, samsung, web, other Short description.
500^[^\x00]{0,500}$Minimum app version the product needs.
50^[^\x00]{0,50}$Whether the product needs the app to work.
Display order on the hosted page (ascending).
0 <= x <= 32767Response
Created
An app link as read from the API. Mirrors :class:apps.products.models.AppLink.
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 link is shown on.
22^[23456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{22}$The product's GTIN, normalized to GTIN-14.
Where the app runs.
ios, android, macos, windows, linux, amazon, huawei, samsung, web, other App name.
Store listing or web app URL (https).
Short description. Empty string when unset.
Minimum app version the product needs. Empty string when unset.
Whether the product needs the app to work.
Display order on the hosted page (ascending).
Server-side ISO 8601 timestamp of creation (UTC).
Server-side ISO 8601 timestamp of last modification (UTC).