List products
curl --request GET \
--url https://api.closedloop.sh/v1/products \
--header 'X-API-Key: <api-key>'import requests
url = "https://api.closedloop.sh/v1/products"
headers = {"X-API-Key": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'X-API-Key': '<api-key>'}};
fetch('https://api.closedloop.sh/v1/products', 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://api.closedloop.sh/v1/products",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"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"
"net/http"
"io"
)
func main() {
url := "https://api.closedloop.sh/v1/products"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-API-Key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.closedloop.sh/v1/products")
.header("X-API-Key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.closedloop.sh/v1/products")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["X-API-Key"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"data": [
{
"id": "123e4567-e89b-42d3-a456-426614174000",
"name": "Core Platform",
"description": "Shared platform capabilities",
"aliases": [
"Platform"
],
"key_features": [
"Permissions",
"Exports"
],
"url": "https://example.com/products/core",
"status": "active",
"source": "manual",
"sort_order": 0,
"created_at": "2026-04-02T00:00:00Z",
"updated_at": "2026-05-01T00:00:00Z"
}
]
}Products
List products
Current product vocabulary for the authenticated team. Draft and active products
are returned by default. Use these immutable IDs with product_id filters.
GET
/
products
List products
curl --request GET \
--url https://api.closedloop.sh/v1/products \
--header 'X-API-Key: <api-key>'import requests
url = "https://api.closedloop.sh/v1/products"
headers = {"X-API-Key": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'X-API-Key': '<api-key>'}};
fetch('https://api.closedloop.sh/v1/products', 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://api.closedloop.sh/v1/products",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"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"
"net/http"
"io"
)
func main() {
url := "https://api.closedloop.sh/v1/products"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-API-Key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.closedloop.sh/v1/products")
.header("X-API-Key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.closedloop.sh/v1/products")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["X-API-Key"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"data": [
{
"id": "123e4567-e89b-42d3-a456-426614174000",
"name": "Core Platform",
"description": "Shared platform capabilities",
"aliases": [
"Platform"
],
"key_features": [
"Permissions",
"Exports"
],
"url": "https://example.com/products/core",
"status": "active",
"source": "manual",
"sort_order": 0,
"created_at": "2026-04-02T00:00:00Z",
"updated_at": "2026-05-01T00:00:00Z"
}
]
}Authorizations
Team-scoped API key created in the app (Settings → API Keys).
Sent as X-API-Key: <key> on every request. The header name apikey
is also accepted as an alias.
Query Parameters
Include retired products as well as draft and active products.
Response
Product vocabulary
Show child attributes
Show child attributes
⌘I