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. |
| 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.