JSON Feed Schema
Use this schema to export your full product catalog (including unpublished or draft products) so it can be imported into AironFlow. In the app, add a data source and choose JSON Feed; then enter the URL of a JSON file that follows this format.
Schema (TypeScript)
Root must be an object with a products array. Only id and name are required per product; all other fields are optional.
// Root: feed must have a "products" array
interface JsonFeed {
products: JsonProduct[];
}
// Category entry: categoryId (external id) and full path/name
interface JsonCategoryEntry {
categoryId: number;
categoryName: string;
}
// Filter: key-value pair (e.g. for facets)
interface JsonFilter {
key: string;
value: string;
}
// Variation: aligns with product variations (size, color, price, stock)
interface JsonVariation {
sku: string;
mpn?: string;
size?: string;
color?: string;
price?: number | string;
stock?: number | string;
}
// Product: all fields optional except id and name
interface JsonProduct {
id: string; // required – external product id
name: string; // required
brand?: string;
brandId?: number; // optional – external brand id (persisted to brands table)
short_description?: string;
description?: string;
sku?: string;
mpn?: string;
price?: number | string;
old_price?: number | string;
stock?: number | string;
slug?: string;
meta_title?: string;
meta_description?: string;
meta_keywords?: string;
image?: string; // main image URL
additional_images?: string[];
categories?: JsonCategoryEntry[]; // persisted to categories + product_categories (legacy string[] not persisted)
filters?: JsonFilter[];
custom_field1?: string;
custom_field2?: string;
custom_field3?: string;
alternative_codes?: string[];
variations?: JsonVariation[];
}Example
One product with brandId, categories (object shape), filters, custom fields, alternative codes, additional images, and variations.
{
"products": [
{
"id": "prod-001",
"name": "Wireless Bluetooth Headphones",
"brand": "AudioPro",
"brandId": 16,
"short_description": "Noise-cancelling over-ear headphones.",
"description": "High-quality wireless headphones with active noise cancellation, 30h battery life, and foldable design.",
"sku": "SKU-HEAD-001",
"mpn": "AP-BT-100",
"price": 89.99,
"old_price": 119.99,
"stock": 50,
"slug": "wireless-bluetooth-headphones",
"meta_title": "Wireless Bluetooth Headphones | AudioPro",
"meta_description": "Buy AudioPro wireless headphones. Noise-cancelling, 30h battery.",
"image": "https://example.com/images/headphones-main.jpg",
"additional_images": [
"https://example.com/images/headphones-side.jpg",
"https://example.com/images/headphones-case.jpg"
],
"categories": [
{ "categoryId": 162, "categoryName": "Electronics > Audio > Headphones" },
{ "categoryId": 177, "categoryName": "Gadgets > Audio" }
],
"filters": [
{ "key": "color", "value": "Black" },
{ "key": "connectivity", "value": "Bluetooth 5.2" }
],
"custom_field1": "Premium",
"custom_field2": "2024",
"custom_field3": "Bestseller",
"alternative_codes": ["EAN-1234567890123", "UPC-012345678901"],
"variations": [
{
"sku": "SKU-HEAD-001-BLK",
"mpn": "AP-BT-100-BLK",
"size": null,
"color": "Black",
"price": 89.99,
"stock": 30
},
{
"sku": "SKU-HEAD-001-WHT",
"mpn": "AP-BT-100-WHT",
"size": null,
"color": "White",
"price": 89.99,
"stock": 20
}
]
}
]
}Filters and Specifications
The filters array allows you to define product specifications that can be used for filtering and faceted search.
How Filters Work
- Each filter key becomes a specification name (e.g., "Color", "Material", "Size")
- Each filter value becomes a specification option (e.g., "Red", "Blue", "Cotton")
- Specifications are automatically created per e-shop (not global)
- All imported filter options are set to
allowFiltering: trueby default - You can view and manage specifications in the Specifications tab on the product details page
Example
If you import a product with filters:
"filters": [
{ "key": "Color", "value": "Red" },
{ "key": "Color", "value": "Blue" },
{ "key": "Material", "value": "Cotton" }
]This will create:
- Specification: Color with options: Red, Blue
- Specification: Material with option: Cotton
Field reference
| Field | Type | Required | Description |
|---|---|---|---|
| id | string | Yes | External product ID (unique per eshop). |
| name | string | Yes | Product name. |
| brand | string | No | Brand name (used when brandId is not set). |
| brandId | number | No | External brand id. Persisted to brands table and linked to product via brand_id. |
| short_description | string | No | Brief product summary. |
| description | string | No | Full product description. |
| sku | string | No | Stock keeping unit. |
| mpn | string | No | Manufacturer part number. |
| price | number | string | No | Current price. |
| old_price | number | string | No | Previous/crossed-out price. |
| stock | number | string | No | Stock quantity. |
| slug | string | No | URL slug. |
| meta_title | string | No | SEO title. |
| meta_description | string | No | SEO meta description. |
| meta_keywords | string | No | SEO keywords. |
| image | string | No | Main product image URL. |
| additional_images | string[] | No | Extra image URLs. |
| categories | { categoryId, categoryName }[] | No | Category entries with external id and full path/name. Persisted to categories and product_categories tables. Legacy string[] is still accepted but not persisted. |
| filters | { key, value }[] | No | Key-value attributes (e.g. color, material). Not persisted to DB in current version. |
| country_of_origin | string | No | Country of origin (e.g. "Τουρκία"). Also read from a specifications entry named "Χώρα προέλευσης" or "Country of Origin". Stored as the product specification «Χώρα προέλευσης» on every sync (existing products too) and used by the AI when writing descriptions. An empty value keeps the stored one. |
| custom_field1 | string | No | Custom field 1. Not persisted to DB in current version. |
| custom_field2 | string | No | Custom field 2. Not persisted to DB in current version. |
| custom_field3 | string | No | Custom field 3. Not persisted to DB in current version. |
| alternative_codes | string[] | No | EAN, UPC, or other codes. Not persisted to DB in current version. |
| variations | JsonVariation[] | No | Product variations (sku, mpn, size, color, price, stock). |
Categories feed (Categories data source)
For a Categories data source, the JSON root may be either an object with a categories array or a bare array of category items. Each item must have id and name; other fields are optional.
{
"categories": [
{
"id": 1,
"name": "Electronics",
"parentCategoryId": null,
"path": "Electronics",
"url": "https://example.com/electronics",
"level": 0,
"description": "Electronic devices and accessories.",
"shortDescription": "Electronics",
"metaTitle": "Electronics | Shop",
"metaDescription": "Browse electronics.",
"metaKeywords": "electronics, gadgets",
"published": true
},
{
"id": 2,
"name": "Audio",
"parentCategoryId": 1,
"path": "Electronics > Audio",
"url": "https://example.com/electronics/audio",
"level": 1,
"description": "Audio equipment.",
"metaTitle": "Audio | Electronics",
"published": true
}
]
}Supported fields: id, name, parentCategoryId, path, url, slug, level, description, shortDescription, metaTitle, metaDescription, metaKeywords, published.
Recommended: include `url`. When a category carries the URL of its storefront page, generated product content can include an internal-linking section pointing at the categories the product belongs to — standard SEO practice, and something we cannot do safely without it. We never derive the URL from the category name: transliterating Greek names is not reversible, and a wrong internal link is worse than none. Absolute URLs are preferred, the value is used verbatim, and omitting `url` on a later sync never erases a URL we already have.
Brands feed (Brands data source)
For a Brands data source, the JSON root may be either an object with a brands array or a bare array of brand items. Each item must have id and name; other fields are optional.
{
"brands": [
{
"id": 1,
"name": "AudioPro",
"description": "Premium audio brand.",
"metaTitle": "AudioPro | Brand",
"metaDescription": "Shop AudioPro products.",
"metaKeywords": "audiopro, audio",
"published": true,
"displayOrder": 1,
"pictureId": "pic-123"
}
]
}Supported fields: id, name, description, metaTitle, metaDescription, metaKeywords, published, displayOrder, pictureId.
Filters feed (Filters data source)
For a Filters data source, the JSON root must be an object with a filters array. Each item must have id (product external ID) and a filters array of key-value pairs. Products are matched by external ID; unmatched products are skipped. Existing filter links for matched products are fully replaced.
{
"filters": [
{
"id": "9193",
"name": "Example Product",
"filters": [
{ "key": "Color", "value": "Black" },
{ "key": "Material", "value": "Aluminum" }
]
}
]
}Each filter entry: id (required, product external ID), name (optional, for reference), filters (array of {key, value} pairs).
In AironFlow, go to Data Sources, add a source, and choose JSON Feed (products), Categories, Brands, or Filters; then enter the URL of your JSON feed to sync.