Validate a product feed (no writes)
Parse and validate a product feed without writing anything to your store, and get
back the same summary and errors you would receive from a real import — plus a
normalized_preview of how Galactic Core interpreted your rows. No API key
required, so you can perfect your feed format before integrating. Accepts JSON, XML,
or CSV like the real endpoint. Rate-limited to 60 requests/hour per IP.
curl --request POST \
--url https://api.tybritelabs.com/v1/ingest/test \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"products": [
{
"sku": "TEE-BLK-S",
"name": "Classic Cotton Tee",
"category": "Apparel",
"price": 22,
"product_group": "TEE-CLASSIC",
"variant_name": "Black / S",
"description": "<string>",
"subcategory": "T-Shirts",
"brand": "<string>",
"image": "<string>",
"cost_price": 8.4,
"stock": 30,
"threshold": 5,
"barcode": "<string>",
"barcode_type": "EAN13"
}
]
}
'import requests
url = "https://api.tybritelabs.com/v1/ingest/test"
payload = { "products": [
{
"sku": "TEE-BLK-S",
"name": "Classic Cotton Tee",
"category": "Apparel",
"price": 22,
"product_group": "TEE-CLASSIC",
"variant_name": "Black / S",
"description": "<string>",
"subcategory": "T-Shirts",
"brand": "<string>",
"image": "<string>",
"cost_price": 8.4,
"stock": 30,
"threshold": 5,
"barcode": "<string>",
"barcode_type": "EAN13"
}
] }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
products: [
{
sku: 'TEE-BLK-S',
name: 'Classic Cotton Tee',
category: 'Apparel',
price: 22,
product_group: 'TEE-CLASSIC',
variant_name: 'Black / S',
description: '<string>',
subcategory: 'T-Shirts',
brand: '<string>',
image: '<string>',
cost_price: 8.4,
stock: 30,
threshold: 5,
barcode: '<string>',
barcode_type: 'EAN13'
}
]
})
};
fetch('https://api.tybritelabs.com/v1/ingest/test', 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.tybritelabs.com/v1/ingest/test",
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([
'products' => [
[
'sku' => 'TEE-BLK-S',
'name' => 'Classic Cotton Tee',
'category' => 'Apparel',
'price' => 22,
'product_group' => 'TEE-CLASSIC',
'variant_name' => 'Black / S',
'description' => '<string>',
'subcategory' => 'T-Shirts',
'brand' => '<string>',
'image' => '<string>',
'cost_price' => 8.4,
'stock' => 30,
'threshold' => 5,
'barcode' => '<string>',
'barcode_type' => 'EAN13'
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$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://api.tybritelabs.com/v1/ingest/test"
payload := strings.NewReader("{\n \"products\": [\n {\n \"sku\": \"TEE-BLK-S\",\n \"name\": \"Classic Cotton Tee\",\n \"category\": \"Apparel\",\n \"price\": 22,\n \"product_group\": \"TEE-CLASSIC\",\n \"variant_name\": \"Black / S\",\n \"description\": \"<string>\",\n \"subcategory\": \"T-Shirts\",\n \"brand\": \"<string>\",\n \"image\": \"<string>\",\n \"cost_price\": 8.4,\n \"stock\": 30,\n \"threshold\": 5,\n \"barcode\": \"<string>\",\n \"barcode_type\": \"EAN13\"\n }\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
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://api.tybritelabs.com/v1/ingest/test")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"products\": [\n {\n \"sku\": \"TEE-BLK-S\",\n \"name\": \"Classic Cotton Tee\",\n \"category\": \"Apparel\",\n \"price\": 22,\n \"product_group\": \"TEE-CLASSIC\",\n \"variant_name\": \"Black / S\",\n \"description\": \"<string>\",\n \"subcategory\": \"T-Shirts\",\n \"brand\": \"<string>\",\n \"image\": \"<string>\",\n \"cost_price\": 8.4,\n \"stock\": 30,\n \"threshold\": 5,\n \"barcode\": \"<string>\",\n \"barcode_type\": \"EAN13\"\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.tybritelabs.com/v1/ingest/test")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"products\": [\n {\n \"sku\": \"TEE-BLK-S\",\n \"name\": \"Classic Cotton Tee\",\n \"category\": \"Apparel\",\n \"price\": 22,\n \"product_group\": \"TEE-CLASSIC\",\n \"variant_name\": \"Black / S\",\n \"description\": \"<string>\",\n \"subcategory\": \"T-Shirts\",\n \"brand\": \"<string>\",\n \"image\": \"<string>\",\n \"cost_price\": 8.4,\n \"stock\": 30,\n \"threshold\": 5,\n \"barcode\": \"<string>\",\n \"barcode_type\": \"EAN13\"\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"status": "partial",
"format": "json",
"validate_only": true,
"summary": {
"rows_total": 2,
"rows_created": 1,
"rows_updated": 0,
"rows_skipped": 0,
"rows_failed": 1
},
"errors": [
{
"row": 2,
"sku": "DEMO-BAD",
"field": "price",
"reason": "price must be a positive number"
}
],
"normalized_preview": [
{
"sku": "DEMO-1",
"name": "Demo Widget",
"category": "General",
"price": 19.99,
"stock": 10
},
{
"sku": "DEMO-BAD",
"name": "No Price",
"category": "General",
"price": -5,
"stock": 3
}
]
}{
"error": {
"code": "invalid_request",
"message": "Invalid request parameters",
"details": "The 'email' field is required"
}
}{
"error": {
"code": "rate_limited",
"message": "Too many requests for this API key. Please slow down and try again shortly.",
"remaining": 0,
"reset": 1706198400
}
}Authorizations
API Key Authentication
Use your API key in the Authorization header:
Authorization: Bearer tybrite_sk_live_YOUR_KEY
Key Types:
Secret Keys (Server-Side Only):
- Format:
tybrite_sk_live_*(production) ortybrite_sk_test_*(sandbox) - Full read/write access to all endpoints
- ⚠️ NEVER expose in client-side code or public repositories
- Required for: write operations, authentication, payment verification, AI recommendations
Publishable Keys (Client-Safe):
- Format:
tybrite_pk_live_*(production) ortybrite_pk_test_*(sandbox) - Read-only access (GET requests only, plus POST semantic search)
- ✅ Safe for client-side JavaScript, mobile apps, and public code
- Allowed for: browsing products, search, CMS content, pricing queries
Endpoint-Specific Requirements:
- Authentication endpoints (
/v1/auth/*): Secret key required - Payment verification (
POST /v1/payments/verify): Secret key required - AI Recommendations (
POST /v1/recommendations): Secret key required - Semantic Search (
POST /v1/search): Both key types allowed (read-only operation) - All write operations: Secret key required
- All read operations: Both key types allowed
Using a publishable key for restricted operations returns 403 Forbidden.
Body
Show child attributes
Show child attributes
Response
Validation result. status is valid (no failures), partial (some rows failed),
or invalid (all rows failed).
curl --request POST \
--url https://api.tybritelabs.com/v1/ingest/test \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"products": [
{
"sku": "TEE-BLK-S",
"name": "Classic Cotton Tee",
"category": "Apparel",
"price": 22,
"product_group": "TEE-CLASSIC",
"variant_name": "Black / S",
"description": "<string>",
"subcategory": "T-Shirts",
"brand": "<string>",
"image": "<string>",
"cost_price": 8.4,
"stock": 30,
"threshold": 5,
"barcode": "<string>",
"barcode_type": "EAN13"
}
]
}
'import requests
url = "https://api.tybritelabs.com/v1/ingest/test"
payload = { "products": [
{
"sku": "TEE-BLK-S",
"name": "Classic Cotton Tee",
"category": "Apparel",
"price": 22,
"product_group": "TEE-CLASSIC",
"variant_name": "Black / S",
"description": "<string>",
"subcategory": "T-Shirts",
"brand": "<string>",
"image": "<string>",
"cost_price": 8.4,
"stock": 30,
"threshold": 5,
"barcode": "<string>",
"barcode_type": "EAN13"
}
] }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
products: [
{
sku: 'TEE-BLK-S',
name: 'Classic Cotton Tee',
category: 'Apparel',
price: 22,
product_group: 'TEE-CLASSIC',
variant_name: 'Black / S',
description: '<string>',
subcategory: 'T-Shirts',
brand: '<string>',
image: '<string>',
cost_price: 8.4,
stock: 30,
threshold: 5,
barcode: '<string>',
barcode_type: 'EAN13'
}
]
})
};
fetch('https://api.tybritelabs.com/v1/ingest/test', 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.tybritelabs.com/v1/ingest/test",
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([
'products' => [
[
'sku' => 'TEE-BLK-S',
'name' => 'Classic Cotton Tee',
'category' => 'Apparel',
'price' => 22,
'product_group' => 'TEE-CLASSIC',
'variant_name' => 'Black / S',
'description' => '<string>',
'subcategory' => 'T-Shirts',
'brand' => '<string>',
'image' => '<string>',
'cost_price' => 8.4,
'stock' => 30,
'threshold' => 5,
'barcode' => '<string>',
'barcode_type' => 'EAN13'
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$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://api.tybritelabs.com/v1/ingest/test"
payload := strings.NewReader("{\n \"products\": [\n {\n \"sku\": \"TEE-BLK-S\",\n \"name\": \"Classic Cotton Tee\",\n \"category\": \"Apparel\",\n \"price\": 22,\n \"product_group\": \"TEE-CLASSIC\",\n \"variant_name\": \"Black / S\",\n \"description\": \"<string>\",\n \"subcategory\": \"T-Shirts\",\n \"brand\": \"<string>\",\n \"image\": \"<string>\",\n \"cost_price\": 8.4,\n \"stock\": 30,\n \"threshold\": 5,\n \"barcode\": \"<string>\",\n \"barcode_type\": \"EAN13\"\n }\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
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://api.tybritelabs.com/v1/ingest/test")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"products\": [\n {\n \"sku\": \"TEE-BLK-S\",\n \"name\": \"Classic Cotton Tee\",\n \"category\": \"Apparel\",\n \"price\": 22,\n \"product_group\": \"TEE-CLASSIC\",\n \"variant_name\": \"Black / S\",\n \"description\": \"<string>\",\n \"subcategory\": \"T-Shirts\",\n \"brand\": \"<string>\",\n \"image\": \"<string>\",\n \"cost_price\": 8.4,\n \"stock\": 30,\n \"threshold\": 5,\n \"barcode\": \"<string>\",\n \"barcode_type\": \"EAN13\"\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.tybritelabs.com/v1/ingest/test")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"products\": [\n {\n \"sku\": \"TEE-BLK-S\",\n \"name\": \"Classic Cotton Tee\",\n \"category\": \"Apparel\",\n \"price\": 22,\n \"product_group\": \"TEE-CLASSIC\",\n \"variant_name\": \"Black / S\",\n \"description\": \"<string>\",\n \"subcategory\": \"T-Shirts\",\n \"brand\": \"<string>\",\n \"image\": \"<string>\",\n \"cost_price\": 8.4,\n \"stock\": 30,\n \"threshold\": 5,\n \"barcode\": \"<string>\",\n \"barcode_type\": \"EAN13\"\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"status": "partial",
"format": "json",
"validate_only": true,
"summary": {
"rows_total": 2,
"rows_created": 1,
"rows_updated": 0,
"rows_skipped": 0,
"rows_failed": 1
},
"errors": [
{
"row": 2,
"sku": "DEMO-BAD",
"field": "price",
"reason": "price must be a positive number"
}
],
"normalized_preview": [
{
"sku": "DEMO-1",
"name": "Demo Widget",
"category": "General",
"price": 19.99,
"stock": 10
},
{
"sku": "DEMO-BAD",
"name": "No Price",
"category": "General",
"price": -5,
"stock": 3
}
]
}{
"error": {
"code": "invalid_request",
"message": "Invalid request parameters",
"details": "The 'email' field is required"
}
}{
"error": {
"code": "rate_limited",
"message": "Too many requests for this API key. Please slow down and try again shortly.",
"remaining": 0,
"reset": 1706198400
}
}
