curl --request GET \
--url https://app.solya.app/api/stock-ledger \
--header 'Authorization: Bearer <token>'import requests
url = "https://app.solya.app/api/stock-ledger"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://app.solya.app/api/stock-ledger', 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://app.solya.app/api/stock-ledger",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$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://app.solya.app/api/stock-ledger"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://app.solya.app/api/stock-ledger")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.solya.app/api/stock-ledger")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"data": [
{
"averageCostOfIndividualInventoryItem": 51.92000000000004,
"brandCity": "Paris",
"brandCode": "jonak",
"brandCreatedAt": "2026-06-22T10:39:14.241Z",
"brandDeactivatedAt": null,
"brandDescription": "Chausseur parisien alliant tendance et savoir-faire cuir.",
"brandId": "demo-brand-1933d9b5",
"brandImageUrl": null,
"brandIsActive": true,
"brandMainBrandTypeTaxonomyFullPath": null,
"brandMainBrandTypeTaxonomyId": null,
"brandName": "Jonak",
"brandStyle": "classique",
"brandUpdatedAt": "2026-06-22T13:30:19.661Z",
"costOfStock": 51.92000000000004,
"createdAt": "2026-06-22T13:33:37.680Z",
"movementCategory": "Stock Out",
"movementCode": null,
"movementId": null,
"movementTime": "2026-06-22T00:00:00.000Z",
"movementType": "Sale",
"movementTypeId": null,
"organizationId": "demo",
"polarisFlagType": null,
"productClassificationCode": "chaussures",
"productClassificationName": "Chaussures",
"productCode": "baskets-retro-en-cuir-et-suede",
"productCreatedAt": "2026-06-22T10:39:23.372Z",
"productDeactivatedAt": null,
"productExtraInformation": null,
"productFamilyCode": "chaussures",
"productFamilyMainTaxonomyFullPath": "Chaussures/Autres catégories unisexes/Chaussures techniques/Chaussures de marche (trail, trekking)",
"productFamilyMainTaxonomyId": "solya_family_fr_01fc3185",
"productFamilyName": "Chaussures",
"productGenderTaxonomyFullPath": "Femme",
"productGenderTaxonomyId": "solya_gender_fr_43c65bcc",
"productId": "demo-product-f3aaf2c6",
"productImageUrl": null,
"productIsActive": true,
"productLongDescription": null,
"productName": "Baskets rétro en cuir et suède",
"productShortDescription": "Baskets d'inspiration vintage mêlant cuir et suède avec semelle gomme. Un confort décontracté au look nostalgique.",
"productUpdatedAt": "2026-06-22T13:30:24.709Z",
"quantityChange": -1,
"saleCode": "S-00018731",
"saleDate": "2026-06-22",
"saleId": "e835b9c2-c530-4d7e-8d38-6488bb7447a0",
"shopAddress": "3 Passage Pommeraye, 44000 Nantes",
"shopCity": "Nantes",
"shopCode": "boutique-nantes-passage-pommeraye",
"shopCountry": "bcbbd48b-f69c-4e02-85f5-90b919b1270b",
"shopCountryId": "bcbbd48b-f69c-4e02-85f5-90b919b1270b",
"shopCreatedAt": "2026-06-22T10:39:04.345Z",
"shopDeactivatedAt": null,
"shopDescription": "Boutique Nantes",
"shopId": "demo-shop-6fde3675",
"shopIsActive": true,
"shopKind": "STORE",
"shopLat": "47.2184",
"shopLng": "-1.5536",
"shopName": "Boutique Nantes - Passage Pommeraye",
"shopRegion": "Pays de la Loire",
"shopStatus": "ACTIVE",
"shopSystem": "demo",
"shopUpdatedAt": "2026-06-22T13:30:14.027Z",
"sizeTaxonomyFullPath": "38",
"sizeTaxonomyId": "solya_size_fr_73bc6288",
"sizeTaxonomyLanguage": "fr",
"stockAfter": 0,
"updatedAt": "2026-06-22T13:33:37.680Z",
"variantCode": "baskets-retro-en-cuir-et-suede-marine",
"variantCollectionId": "demo-collection-787b0177",
"variantColorFullPath1": "Couleurs Froides/Primaires/Bleu/Marine",
"variantColorFullPath2": null,
"variantColorFullPath3": null,
"variantColorId1": "solya_color_fr_31058a6a",
"variantColorId2": null,
"variantColorId3": null,
"variantCreatedAt": "2026-06-22T10:39:35.359Z",
"variantDeactivatedAt": null,
"variantDescription": null,
"variantDisplayName": "Marine",
"variantFullName": "Baskets rétro en cuir et suède - Marine",
"variantId": "demo-variant-00df093a",
"variantIsActive": true,
"variantName": "Baskets rétro en cuir et suède - Marine",
"variantUpdatedAt": "2026-06-22T13:30:30.155Z"
}
],
"meta": {
"page": 1,
"pageSize": 20,
"total": 98417
}
}List stock ledger entries (inventory transaction history)
Returns a paginated list of stock ledger entries — the chronological ledger of inventory transactions (receipts, sales, transfers, returns, adjustments) that explain how stock levels changed over time. Filter by shop, variant, movement category, movement type, and date range. Use this for an audit trail of stock movements. No get-by-ID endpoint as the table has no single primary key.
curl --request GET \
--url https://app.solya.app/api/stock-ledger \
--header 'Authorization: Bearer <token>'import requests
url = "https://app.solya.app/api/stock-ledger"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://app.solya.app/api/stock-ledger', 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://app.solya.app/api/stock-ledger",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$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://app.solya.app/api/stock-ledger"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://app.solya.app/api/stock-ledger")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.solya.app/api/stock-ledger")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"data": [
{
"averageCostOfIndividualInventoryItem": 51.92000000000004,
"brandCity": "Paris",
"brandCode": "jonak",
"brandCreatedAt": "2026-06-22T10:39:14.241Z",
"brandDeactivatedAt": null,
"brandDescription": "Chausseur parisien alliant tendance et savoir-faire cuir.",
"brandId": "demo-brand-1933d9b5",
"brandImageUrl": null,
"brandIsActive": true,
"brandMainBrandTypeTaxonomyFullPath": null,
"brandMainBrandTypeTaxonomyId": null,
"brandName": "Jonak",
"brandStyle": "classique",
"brandUpdatedAt": "2026-06-22T13:30:19.661Z",
"costOfStock": 51.92000000000004,
"createdAt": "2026-06-22T13:33:37.680Z",
"movementCategory": "Stock Out",
"movementCode": null,
"movementId": null,
"movementTime": "2026-06-22T00:00:00.000Z",
"movementType": "Sale",
"movementTypeId": null,
"organizationId": "demo",
"polarisFlagType": null,
"productClassificationCode": "chaussures",
"productClassificationName": "Chaussures",
"productCode": "baskets-retro-en-cuir-et-suede",
"productCreatedAt": "2026-06-22T10:39:23.372Z",
"productDeactivatedAt": null,
"productExtraInformation": null,
"productFamilyCode": "chaussures",
"productFamilyMainTaxonomyFullPath": "Chaussures/Autres catégories unisexes/Chaussures techniques/Chaussures de marche (trail, trekking)",
"productFamilyMainTaxonomyId": "solya_family_fr_01fc3185",
"productFamilyName": "Chaussures",
"productGenderTaxonomyFullPath": "Femme",
"productGenderTaxonomyId": "solya_gender_fr_43c65bcc",
"productId": "demo-product-f3aaf2c6",
"productImageUrl": null,
"productIsActive": true,
"productLongDescription": null,
"productName": "Baskets rétro en cuir et suède",
"productShortDescription": "Baskets d'inspiration vintage mêlant cuir et suède avec semelle gomme. Un confort décontracté au look nostalgique.",
"productUpdatedAt": "2026-06-22T13:30:24.709Z",
"quantityChange": -1,
"saleCode": "S-00018731",
"saleDate": "2026-06-22",
"saleId": "e835b9c2-c530-4d7e-8d38-6488bb7447a0",
"shopAddress": "3 Passage Pommeraye, 44000 Nantes",
"shopCity": "Nantes",
"shopCode": "boutique-nantes-passage-pommeraye",
"shopCountry": "bcbbd48b-f69c-4e02-85f5-90b919b1270b",
"shopCountryId": "bcbbd48b-f69c-4e02-85f5-90b919b1270b",
"shopCreatedAt": "2026-06-22T10:39:04.345Z",
"shopDeactivatedAt": null,
"shopDescription": "Boutique Nantes",
"shopId": "demo-shop-6fde3675",
"shopIsActive": true,
"shopKind": "STORE",
"shopLat": "47.2184",
"shopLng": "-1.5536",
"shopName": "Boutique Nantes - Passage Pommeraye",
"shopRegion": "Pays de la Loire",
"shopStatus": "ACTIVE",
"shopSystem": "demo",
"shopUpdatedAt": "2026-06-22T13:30:14.027Z",
"sizeTaxonomyFullPath": "38",
"sizeTaxonomyId": "solya_size_fr_73bc6288",
"sizeTaxonomyLanguage": "fr",
"stockAfter": 0,
"updatedAt": "2026-06-22T13:33:37.680Z",
"variantCode": "baskets-retro-en-cuir-et-suede-marine",
"variantCollectionId": "demo-collection-787b0177",
"variantColorFullPath1": "Couleurs Froides/Primaires/Bleu/Marine",
"variantColorFullPath2": null,
"variantColorFullPath3": null,
"variantColorId1": "solya_color_fr_31058a6a",
"variantColorId2": null,
"variantColorId3": null,
"variantCreatedAt": "2026-06-22T10:39:35.359Z",
"variantDeactivatedAt": null,
"variantDescription": null,
"variantDisplayName": "Marine",
"variantFullName": "Baskets rétro en cuir et suède - Marine",
"variantId": "demo-variant-00df093a",
"variantIsActive": true,
"variantName": "Baskets rétro en cuir et suède - Marine",
"variantUpdatedAt": "2026-06-22T13:30:30.155Z"
}
],
"meta": {
"page": 1,
"pageSize": 20,
"total": 98417
}
}Authorizations
User session token issued by NextAuth. For human users accessing Solya via the web application.
Query Parameters
Page number, 1-indexed (default: 1)
1 <= x <= 9007199254740991Number of items per page, max 100 (default: 20)
1 <= x <= 100Filter by shop UUID
Filter by variant UUID
Filter by movement category. Values are title case as stored in the gold layer (NOT uppercase). Known values: 'Stock Out', 'Stock In', 'Correction'. Example: 'Stock Out'.
Filter by movement type. Values are title case as stored in the gold layer (NOT uppercase). Known values: 'Sale', 'Receipt', 'Transfer', 'Return'. Example: 'Sale'.
Return entries where movementTime >= this value (inclusive). ISO 8601 date 'YYYY-MM-DD' (e.g. '2026-01-01') or datetime 'YYYY-MM-DDTHH:mm:ssZ' — both accepted. Filters on the movementTime ledger timestamp, NOT saleDate.
Return entries where movementTime <= this value (inclusive). ISO 8601 date 'YYYY-MM-DD' (e.g. '2026-12-31') or datetime 'YYYY-MM-DDTHH:mm:ssZ' — both accepted. Filters on the movementTime ledger timestamp, NOT saleDate.
Column to sort by. Allowed: 'movementTime', 'quantityChange', 'stockAfter'. Defaults to 'movementTime'.
Sort direction: 'asc' or 'desc'. Default order is movementTime descending (most recent first).
asc, desc 
