openpx-sdk 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1888 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "https://schema.openpx.org/v0.7.0/openpx-schema.json",
4
+ "title": "OpenPX V0.7.0 Schema",
5
+ "description": "JSON Schema validation rules for Open Product Exchange V0.7.0 \u2014 open_attribute_value now carries typed_attribute_measurement (a required unit plus at least one of value/min/max/avg, superseding typed_attribute_value and typed_attribute_range) and typed_attribute_list (a flat list of 1-50 unique scalars); every string in the open-attribute area is maxLength 255. Arrays are permitted in attributes again, reversing #1535. See docs/prd-schema-enhancements-v0.7.0.md.",
6
+ "type": "object",
7
+ "required": ["openpx"],
8
+ "properties": {
9
+ "openpx": {
10
+ "type": "string",
11
+ "pattern": "^\\d+\\.\\d+\\.\\d+$",
12
+ "description": "OpenPX schema version"
13
+ },
14
+ "organization": {
15
+ "$ref": "#/definitions/organization"
16
+ },
17
+ "brand": {
18
+ "$ref": "#/definitions/brand"
19
+ },
20
+ "product": {
21
+ "$ref": "#/definitions/product"
22
+ },
23
+ "variant": {
24
+ "$ref": "#/definitions/variant"
25
+ },
26
+ "listing": {
27
+ "$ref": "#/definitions/listing"
28
+ },
29
+ "signature": {
30
+ "$ref": "#/definitions/signature"
31
+ }
32
+ },
33
+ "definitions": {
34
+ "uuid": {
35
+ "type": "string",
36
+ "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$",
37
+ "description": "UUID v7 format (RFC 9562) - time-ordered, monotonic"
38
+ },
39
+ "organization_identifiers": {
40
+ "type": "object",
41
+ "required": ["slug"],
42
+ "properties": {
43
+ "slug": {
44
+ "type": "string",
45
+ "minLength": 1,
46
+ "maxLength": 100,
47
+ "pattern": "^[a-z0-9](-?[a-z0-9])*$",
48
+ "description": "URL-safe identifier (lowercase, hyphens allowed). Cannot start or end with a hyphen, and no consecutive hyphens."
49
+ },
50
+ "duns": {
51
+ "type": ["string", "null"],
52
+ "pattern": "^\\d{9}$",
53
+ "description": "D-U-N-S Number (9 digits)"
54
+ },
55
+ "gln": {
56
+ "type": ["string", "null"],
57
+ "pattern": "^\\d{13}$",
58
+ "description": "GS1 Global Location Number (13 digits)"
59
+ }
60
+ }
61
+ },
62
+ "brand_identifiers": {
63
+ "type": "object",
64
+ "required": ["slug"],
65
+ "properties": {
66
+ "slug": {
67
+ "type": "string",
68
+ "minLength": 1,
69
+ "maxLength": 100,
70
+ "pattern": "^[a-z0-9](-?[a-z0-9])*$",
71
+ "description": "URL-safe identifier within organization (lowercase, hyphens allowed). Cannot start or end with a hyphen, and no consecutive hyphens."
72
+ }
73
+ }
74
+ },
75
+ "organization": {
76
+ "type": "object",
77
+ "required": ["id", "name", "identifiers"],
78
+ "properties": {
79
+ "id": {
80
+ "$ref": "#/definitions/uuid"
81
+ },
82
+ "name": {
83
+ "type": "string",
84
+ "minLength": 1,
85
+ "maxLength": 255
86
+ },
87
+ "identifiers": {
88
+ "$ref": "#/definitions/organization_identifiers"
89
+ },
90
+ "logo_url": {
91
+ "type": "string",
92
+ "format": "uri",
93
+ "maxLength": 2048
94
+ },
95
+ "description": {
96
+ "type": "string",
97
+ "maxLength": 10000
98
+ },
99
+ "website": {
100
+ "type": "string",
101
+ "format": "uri",
102
+ "maxLength": 2048
103
+ },
104
+ "status": {
105
+ "type": "string",
106
+ "enum": ["draft", "active", "archived"]
107
+ },
108
+ "metadata": {
109
+ "type": "object",
110
+ "additionalProperties": true
111
+ },
112
+ "signing": {
113
+ "type": "object",
114
+ "required": ["key_ref", "algorithm"],
115
+ "properties": {
116
+ "key_ref": {
117
+ "type": "string",
118
+ "pattern": "^\\.openpx/keys/[a-z0-9_-]+-\\d{4}-\\d{2}-\\d{2}\\.pub$",
119
+ "description": "Path to the organization's public signing key"
120
+ },
121
+ "algorithm": {
122
+ "type": "string",
123
+ "enum": ["Ed25519"],
124
+ "description": "Signing algorithm used by this organization"
125
+ }
126
+ }
127
+ }
128
+ }
129
+ },
130
+ "brand": {
131
+ "type": "object",
132
+ "required": ["id", "organization_id", "name", "identifiers"],
133
+ "properties": {
134
+ "id": {
135
+ "$ref": "#/definitions/uuid"
136
+ },
137
+ "organization_id": {
138
+ "$ref": "#/definitions/uuid"
139
+ },
140
+ "name": {
141
+ "type": "string",
142
+ "minLength": 1,
143
+ "maxLength": 255
144
+ },
145
+ "identifiers": {
146
+ "$ref": "#/definitions/brand_identifiers"
147
+ },
148
+ "logo_url": {
149
+ "type": "string",
150
+ "format": "uri"
151
+ },
152
+ "story": {
153
+ "type": "string",
154
+ "maxLength": 5000
155
+ },
156
+ "values": {
157
+ "type": "array",
158
+ "items": {
159
+ "type": "string",
160
+ "minLength": 1,
161
+ "maxLength": 100
162
+ },
163
+ "maxItems": 10
164
+ },
165
+ "website": {
166
+ "type": "string",
167
+ "format": "uri",
168
+ "maxLength": 2048
169
+ },
170
+ "status": {
171
+ "type": "string",
172
+ "enum": ["draft", "active", "archived"]
173
+ },
174
+ "metadata": {
175
+ "type": "object",
176
+ "additionalProperties": true
177
+ },
178
+ "access_control": {
179
+ "$ref": "#/definitions/access_control"
180
+ }
181
+ }
182
+ },
183
+ "product": {
184
+ "type": "object",
185
+ "required": ["id", "brand_id", "status", "identifiers", "classification", "content"],
186
+ "properties": {
187
+ "id": {
188
+ "$ref": "#/definitions/uuid"
189
+ },
190
+ "brand_id": {
191
+ "$ref": "#/definitions/uuid"
192
+ },
193
+ "status": {
194
+ "type": "string",
195
+ "enum": ["draft", "active", "archived"]
196
+ },
197
+ "content": {
198
+ "allOf": [
199
+ { "$ref": "#/definitions/content" },
200
+ { "required": ["locale", "name", "description_short"] }
201
+ ]
202
+ },
203
+ "condition": {
204
+ "type": "string",
205
+ "enum": ["new", "used", "refurbished"],
206
+ "description": "Product condition. Defaults to 'new' if not specified."
207
+ },
208
+ "identifiers": {
209
+ "type": "object",
210
+ "anyOf": [
211
+ {"required": ["sku"]},
212
+ {"required": ["gtin"]},
213
+ {"required": ["upc"]},
214
+ {"required": ["ean"]},
215
+ {"required": ["mpn"]},
216
+ {"required": ["model_number"]},
217
+ {"required": ["usda_fdc_id"]},
218
+ {"required": ["asin"]},
219
+ {"required": ["nsn"]}
220
+ ],
221
+ "properties": {
222
+ "sku": {
223
+ "type": "string",
224
+ "minLength": 1,
225
+ "maxLength": 100
226
+ },
227
+ "gtin": {
228
+ "type": "string",
229
+ "pattern": "^\\d{8,14}$",
230
+ "description": "Global Trade Item Number (GTIN-8/12/13/14)"
231
+ },
232
+ "upc": {
233
+ "type": "string",
234
+ "pattern": "^\\d{12}$",
235
+ "description": "Universal Product Code (12 digits)"
236
+ },
237
+ "ean": {
238
+ "type": "string",
239
+ "pattern": "^\\d{13}$",
240
+ "description": "European Article Number (13 digits)"
241
+ },
242
+ "mpn": {
243
+ "type": "string",
244
+ "maxLength": 100
245
+ },
246
+ "model_number": {
247
+ "type": "string",
248
+ "maxLength": 100
249
+ },
250
+ "usda_fdc_id": {
251
+ "type": "string",
252
+ "pattern": "^\\d+$",
253
+ "description": "USDA FoodData Central database ID"
254
+ },
255
+ "asin": {
256
+ "type": "string",
257
+ "maxLength": 10,
258
+ "pattern": "^[A-Z0-9]{10}$",
259
+ "description": "Amazon Standard Identification Number (exactly 10 uppercase alphanumeric characters)"
260
+ },
261
+ "nsn": {
262
+ "type": "string",
263
+ "maxLength": 16,
264
+ "pattern": "^[0-9A-Z]{4}-[0-9A-Z]{2}-[0-9A-Z]{3}-[0-9A-Z]{4}$|^[0-9A-Z][0-9A-Z-]{0,15}$",
265
+ "description": "NATO Stock Number — hyphenated NATO form (e.g. 1234-56-789-1234) or local/alphanumeric form (e.g. 850519-S01)"
266
+ }
267
+ }
268
+ },
269
+ "classification": {
270
+ "type": "object",
271
+ "required": ["primary_category"],
272
+ "properties": {
273
+ "primary_category_id": {
274
+ "type": ["string", "null"],
275
+ "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$",
276
+ "description": "UUID v7 FK to openpx_category.id (populated after taxonomy tables exist)"
277
+ },
278
+ "primary_category": {
279
+ "type": "string",
280
+ "minLength": 1,
281
+ "maxLength": 500,
282
+ "pattern": "^[a-z][a-z0-9_]*(\\.[a-z][a-z0-9_]*)*$",
283
+ "description": "Dot-separated ltree path (e.g., openpx.food_beverage.bakery.bread)"
284
+ },
285
+ "product_type": {
286
+ "type": "string",
287
+ "minLength": 1,
288
+ "maxLength": 255
289
+ },
290
+ "category_schema_url": {
291
+ "type": "string",
292
+ "format": "uri",
293
+ "description": "URL to category-specific attribute validation schema (optional). If provided, product.attributes will be validated against this schema in addition to base schema."
294
+ },
295
+ "tags": {
296
+ "type": "array",
297
+ "items": {
298
+ "type": "string",
299
+ "minLength": 1,
300
+ "maxLength": 50
301
+ },
302
+ "maxItems": 50
303
+ },
304
+ "external_codes": {
305
+ "type": "object",
306
+ "properties": {
307
+ "unspsc": {
308
+ "type": "string",
309
+ "pattern": "^\\d{8}$"
310
+ },
311
+ "eclass": {
312
+ "type": "string",
313
+ "pattern": "^\\d{8}$"
314
+ },
315
+ "etim": {
316
+ "type": "string",
317
+ "pattern": "^EC\\d{6}$"
318
+ }
319
+ }
320
+ }
321
+ }
322
+ },
323
+ "channel_content": {
324
+ "type": "object",
325
+ "additionalProperties": { "$ref": "#/definitions/content" },
326
+ "description": "Per-channel content variants, keyed by channel identifier (e.g. 'amazon-seller', 'walmart', 'shopify'). Each entry has the shape of `content` (all fields optional, extra keys allowed); sparse-override, deep-merged over `content` when a listing for that channel is created."
327
+ },
328
+ "attributes": { "$ref": "#/definitions/open_attributes" },
329
+ "physical": {
330
+ "$ref": "#/definitions/physical_specifications"
331
+ },
332
+ "media_assets": {
333
+ "$ref": "#/definitions/media_assets"
334
+ },
335
+ "compliance": {
336
+ "$ref": "#/definitions/compliance"
337
+ },
338
+ "assurances": {
339
+ "$ref": "#/definitions/assurances"
340
+ },
341
+ "instructions": {
342
+ "$ref": "#/definitions/instructions"
343
+ },
344
+ "pricing": {
345
+ "$ref": "#/definitions/pricing"
346
+ },
347
+ "relationships": {
348
+ "type": "array",
349
+ "items": { "$ref": "#/definitions/relationship" },
350
+ "maxItems": 100
351
+ },
352
+ "brand_groupings": {
353
+ "$ref": "#/definitions/brand_groupings"
354
+ },
355
+ "technical_data": {
356
+ "type": "object",
357
+ "description": "Measured/tested technical properties grouped by section name",
358
+ "maxProperties": 20,
359
+ "additionalProperties": {
360
+ "type": "array",
361
+ "maxItems": 100,
362
+ "items": {
363
+ "type": "object",
364
+ "minProperties": 1,
365
+ "additionalProperties": {
366
+ "oneOf": [
367
+ { "type": "string" },
368
+ { "type": "number" },
369
+ { "type": "boolean" }
370
+ ]
371
+ }
372
+ }
373
+ }
374
+ },
375
+ "metadata": {
376
+ "type": "object",
377
+ "additionalProperties": true
378
+ },
379
+ "content_hash": {
380
+ "type": ["string", "null"],
381
+ "pattern": "^[a-f0-9]{64}$",
382
+ "description": "SHA-256 hash of canonical JSON representation"
383
+ },
384
+ "variants": {
385
+ "type": "array",
386
+ "items": {
387
+ "$ref": "#/definitions/variant"
388
+ },
389
+ "description": "Embedded variants for this product. Each variant is a sparse override — only include fields that differ from the product."
390
+ },
391
+ "access_control": {
392
+ "$ref": "#/definitions/access_control"
393
+ }
394
+ }
395
+ },
396
+ "media_assets": {
397
+ "type": "object",
398
+ "properties": {
399
+ "images": {
400
+ "type": "array",
401
+ "items": {
402
+ "$ref": "#/definitions/image_asset"
403
+ },
404
+ "maxItems": 50
405
+ },
406
+ "videos": {
407
+ "type": "array",
408
+ "items": {
409
+ "$ref": "#/definitions/video_asset"
410
+ },
411
+ "maxItems": 10
412
+ },
413
+ "documents": {
414
+ "type": "array",
415
+ "items": {
416
+ "$ref": "#/definitions/document_asset"
417
+ },
418
+ "maxItems": 20
419
+ },
420
+ "ar_vr_models": {
421
+ "type": "array",
422
+ "items": {
423
+ "$ref": "#/definitions/ar_vr_asset"
424
+ },
425
+ "maxItems": 5
426
+ }
427
+ }
428
+ },
429
+ "image_asset": {
430
+ "type": "object",
431
+ "required": ["url", "type"],
432
+ "properties": {
433
+ "id": {
434
+ "$ref": "#/definitions/uuid"
435
+ },
436
+ "url": {
437
+ "type": "string",
438
+ "format": "uri"
439
+ },
440
+ "alt_text": {
441
+ "type": "string",
442
+ "maxLength": 255
443
+ },
444
+ "type": {
445
+ "type": "string",
446
+ "enum": ["primary", "alternate", "lifestyle", "detail", "size chart", "ingredient", "nutrition"]
447
+ },
448
+ "width": {
449
+ "type": "integer",
450
+ "minimum": 1
451
+ },
452
+ "height": {
453
+ "type": "integer",
454
+ "minimum": 1
455
+ },
456
+ "format": {
457
+ "type": "string",
458
+ "enum": ["jpg", "png", "webp", "gif"]
459
+ }
460
+ }
461
+ },
462
+ "video_asset": {
463
+ "type": "object",
464
+ "required": ["url", "type"],
465
+ "properties": {
466
+ "id": {
467
+ "$ref": "#/definitions/uuid"
468
+ },
469
+ "url": {
470
+ "type": "string",
471
+ "format": "uri"
472
+ },
473
+ "thumbnail_url": {
474
+ "type": "string",
475
+ "format": "uri"
476
+ },
477
+ "duration_seconds": {
478
+ "type": "integer",
479
+ "minimum": 1
480
+ },
481
+ "type": {
482
+ "type": "string",
483
+ "enum": ["demo", "unboxing", "tutorial", "lifestyle", "testimonial"]
484
+ }
485
+ }
486
+ },
487
+ "document_asset": {
488
+ "type": "object",
489
+ "required": ["url", "type", "title"],
490
+ "properties": {
491
+ "id": {
492
+ "$ref": "#/definitions/uuid"
493
+ },
494
+ "url": {
495
+ "type": "string",
496
+ "format": "uri"
497
+ },
498
+ "type": {
499
+ "type": "string",
500
+ "enum": ["manual", "spec sheet", "warranty", "installation guide", "safety sheet", "catalog"]
501
+ },
502
+ "title": {
503
+ "type": "string",
504
+ "minLength": 1,
505
+ "maxLength": 255
506
+ },
507
+ "locale": {
508
+ "type": "string",
509
+ "pattern": "^[a-z]{2}-[A-Z]{2}$"
510
+ }
511
+ }
512
+ },
513
+ "ar_vr_asset": {
514
+ "type": "object",
515
+ "required": ["url", "format"],
516
+ "properties": {
517
+ "id": {
518
+ "$ref": "#/definitions/uuid"
519
+ },
520
+ "url": {
521
+ "type": "string",
522
+ "format": "uri"
523
+ },
524
+ "format": {
525
+ "type": "string",
526
+ "enum": ["glb", "usdz", "obj", "fbx"]
527
+ },
528
+ "file_size_mb": {
529
+ "type": "number",
530
+ "minimum": 0
531
+ }
532
+ }
533
+ },
534
+ "compliance": {
535
+ "type": "object",
536
+ "properties": {
537
+ "origin": {
538
+ "$ref": "#/definitions/product_origin"
539
+ },
540
+ "certifications": {
541
+ "type": "array",
542
+ "items": {
543
+ "$ref": "#/definitions/certification"
544
+ }
545
+ },
546
+ "warnings": {
547
+ "type": "object",
548
+ "properties": {
549
+ "prop65": {
550
+ "type": "boolean"
551
+ },
552
+ "choking_hazard": {
553
+ "type": "boolean"
554
+ },
555
+ "age_restriction": {
556
+ "type": "string",
557
+ "pattern": "^\\d+\\+$"
558
+ },
559
+ "baa_taa_compliant": {
560
+ "type": "boolean",
561
+ "description": "Compliant with US Buy American Act (BAA) / Trade Agreements Act (TAA) for federal procurement"
562
+ },
563
+ "taa_compliant_country": {
564
+ "type": "string",
565
+ "pattern": "^[A-Z]{2}$",
566
+ "description": "ISO 3166-1 alpha-2 country code asserting TAA compliance (designated country of origin under Trade Agreements Act)"
567
+ }
568
+ }
569
+ },
570
+ "hazmat": {
571
+ "type": "object",
572
+ "description": "Hazardous materials compliance data (regulation, UN code, GHS, SDS URL). Sibling to warnings: warnings carries boolean attestations; hazmat carries structured regulatory data.",
573
+ "properties": {
574
+ "is_hazmat": {
575
+ "type": "boolean",
576
+ "description": "Product classified as hazardous material"
577
+ },
578
+ "regulation": {
579
+ "type": "string",
580
+ "enum": ["ghs", "storage", "transportation", "waste", "other", "not applicable"],
581
+ "description": "Dangerous-goods regulatory framework declaration (mirrors Amazon supplier_declared_dg_hz_regulation)"
582
+ },
583
+ "un_regulatory_id": {
584
+ "type": "string",
585
+ "pattern": "^UN\\d{4}[a-zA-Z]?$",
586
+ "description": "UN regulatory identifier (e.g. UN1993, UN3481b). The optional trailing letter denotes a UN sub-division — Amazon publishes UN3481b for lithium-ion cells packed with equipment (#2097)"
587
+ },
588
+ "ghs_classification": {
589
+ "type": "object",
590
+ "description": "Globally Harmonized System hazard classification",
591
+ "properties": {
592
+ "class": {
593
+ "type": "string",
594
+ "enum": [
595
+ "explosive",
596
+ "flammable",
597
+ "oxidizing",
598
+ "compressed gas",
599
+ "corrosive",
600
+ "toxic",
601
+ "harmful irritant",
602
+ "health hazard",
603
+ "environmental hazard",
604
+ "other"
605
+ ]
606
+ },
607
+ "category": { "type": "string" },
608
+ "signal_word": {
609
+ "type": "string",
610
+ "enum": ["danger", "warning"]
611
+ },
612
+ "hazard_statement": { "type": "string" },
613
+ "h_code": { "type": "string" }
614
+ },
615
+ "additionalProperties": false
616
+ },
617
+ "safety_data_sheet_url": {
618
+ "type": "string",
619
+ "format": "uri",
620
+ "maxLength": 2048,
621
+ "description": "URL to the Safety Data Sheet (SDS or MSDS) document"
622
+ }
623
+ },
624
+ "additionalProperties": false
625
+ },
626
+ "media": {
627
+ "type": "array",
628
+ "description": "URLs to compliance-related media (certificates, declarations, regulatory documents). Generic complement to safety_data_sheet_url under hazmat; used for any compliance regime requiring document attestations.",
629
+ "maxItems": 20,
630
+ "items": {
631
+ "type": "string",
632
+ "format": "uri",
633
+ "maxLength": 2048
634
+ }
635
+ },
636
+ "safety_attestation": {
637
+ "type": "boolean",
638
+ "description": "Attestation that product meets applicable safety regulations for its category and channel scope"
639
+ },
640
+ "gpsr": {
641
+ "type": "object",
642
+ "description": "EU General Product Safety Regulation (GPSR, effective 2024) compliance fields. Article 4 (Responsible Person), Article 9 (Manufacturer obligations).",
643
+ "properties": {
644
+ "manufacturer_reference": {
645
+ "type": "string",
646
+ "description": "GPSR manufacturer identifier (importer/manufacturer reference declaration)"
647
+ },
648
+ "responsible_person": {
649
+ "type": "object",
650
+ "description": "EU-resident Responsible Person contact (Article 4 of GPSR)",
651
+ "properties": {
652
+ "name": { "type": "string" },
653
+ "email": { "type": "string", "format": "email" },
654
+ "address": { "type": "string", "maxLength": 1024 },
655
+ "phone": { "type": "string" }
656
+ },
657
+ "additionalProperties": false
658
+ }
659
+ },
660
+ "additionalProperties": false
661
+ },
662
+ "sustainability": {
663
+ "$ref": "#/definitions/sustainability"
664
+ }
665
+ }
666
+ },
667
+ "sustainability": {
668
+ "type": "object",
669
+ "description": "Sustainability metrics, material claims, carbon footprint, and environmental declarations",
670
+ "properties": {
671
+ "claims": {
672
+ "type": "object",
673
+ "properties": {
674
+ "recyclable": { "type": "boolean" },
675
+ "recycled_content_percent": { "type": "number", "minimum": 0, "maximum": 100 },
676
+ "renewable_materials_percent": { "type": "number", "minimum": 0, "maximum": 100 },
677
+ "compostable": { "type": "boolean" },
678
+ "biodegradable": { "type": "boolean" },
679
+ "green_purchasing_compliant": {
680
+ "type": "boolean",
681
+ "description": "Compliant with US Federal Green Purchasing Law (FAR 23.703 — environmentally preferred products)"
682
+ }
683
+ }
684
+ },
685
+ "carbon": {
686
+ "type": "object",
687
+ "properties": {
688
+ "footprint": {
689
+ "type": "object",
690
+ "required": ["value", "unit", "scope"],
691
+ "properties": {
692
+ "value": { "type": "number", "minimum": 0 },
693
+ "unit": { "type": "string", "enum": ["kgCO2e", "tCO2e"] },
694
+ "scope": { "type": "string", "enum": ["cradle to gate", "cradle to grave", "cradle to cradle"] },
695
+ "standard": { "type": "string", "maxLength": 100 }
696
+ }
697
+ }
698
+ }
699
+ },
700
+ "environmental_declarations": {
701
+ "type": "array",
702
+ "maxItems": 20,
703
+ "items": { "$ref": "#/definitions/environmental_declaration" }
704
+ }
705
+ }
706
+ },
707
+ "environmental_declaration": {
708
+ "type": "object",
709
+ "required": ["type"],
710
+ "properties": {
711
+ "type": { "type": "string", "enum": ["epd", "hpd", "lca"] },
712
+ "standard": { "type": "string", "maxLength": 100 },
713
+ "program_operator": { "type": "string", "maxLength": 200 },
714
+ "registration_number": { "type": "string", "maxLength": 100 },
715
+ "expiry_date": { "type": "string", "format": "date", "description": "ISO 8601 date" },
716
+ "document_url": { "type": "string", "format": "uri", "maxLength": 2000 }
717
+ }
718
+ },
719
+ "product_origin": {
720
+ "type": "object",
721
+ "properties": {
722
+ "country_of_origin": {
723
+ "type": "string",
724
+ "pattern": "^[A-Z]{2}$",
725
+ "description": "ISO 3166-1 alpha-2 country code where raw materials originate"
726
+ },
727
+ "country_of_assembly": {
728
+ "type": "string",
729
+ "pattern": "^[A-Z]{2}$",
730
+ "description": "ISO 3166-1 alpha-2 country code where product is assembled"
731
+ },
732
+ "country_of_last_processing": {
733
+ "type": "string",
734
+ "pattern": "^[A-Z]{2}$",
735
+ "description": "ISO 3166-1 alpha-2 country code where last substantial transformation occurs"
736
+ },
737
+ "country_of_design": {
738
+ "type": "string",
739
+ "pattern": "^[A-Z]{2}$",
740
+ "description": "ISO 3166-1 alpha-2 country code where product is designed"
741
+ }
742
+ }
743
+ },
744
+ "assurances": {
745
+ "type": "object",
746
+ "properties": {
747
+ "warranty": {
748
+ "$ref": "#/definitions/warranty"
749
+ },
750
+ "return_policy": {
751
+ "$ref": "#/definitions/return_policy"
752
+ }
753
+ }
754
+ },
755
+ "instructions": {
756
+ "type": "object",
757
+ "description": "Human-facing operational guidance for using and caring for the product",
758
+ "properties": {
759
+ "locale": {
760
+ "type": "string",
761
+ "pattern": "^[a-z]{2}-[A-Z]{2}$",
762
+ "description": "BCP 47 locale code (e.g., en-US)"
763
+ },
764
+ "preparation": { "type": "string", "maxLength": 2000, "description": "Steps to ready the product before first use" },
765
+ "installation": { "type": "string", "maxLength": 2000, "description": "Setup or assembly instructions" },
766
+ "usage": { "type": "string", "maxLength": 2000, "description": "How to operate or use the product" },
767
+ "application": { "type": "string", "maxLength": 2000, "description": "Surface, material, or context suitability" },
768
+ "safety": { "type": "string", "maxLength": 2000, "description": "Safety warnings and precautions during use" },
769
+ "storage": { "type": "string", "maxLength": 2000, "description": "How to store the product when not in use" },
770
+ "cleaning": { "type": "string", "maxLength": 2000, "description": "How to clean or care for the product itself" },
771
+ "maintenance": { "type": "string", "maxLength": 2000, "description": "Ongoing upkeep to extend product life" },
772
+ "disposal": { "type": "string", "maxLength": 2000, "description": "End-of-life handling, recycling, or disposal guidance" },
773
+ "clean_up": { "type": "string", "maxLength": 2000, "description": "How to clean tools or work area after use" }
774
+ }
775
+ },
776
+ "warranty": {
777
+ "type": "object",
778
+ "properties": {
779
+ "type": {
780
+ "type": "string",
781
+ "enum": ["standard", "extended"]
782
+ },
783
+ "duration": {
784
+ "type": "object",
785
+ "required": ["value", "unit"],
786
+ "properties": {
787
+ "value": {
788
+ "type": "integer",
789
+ "minimum": 1
790
+ },
791
+ "unit": {
792
+ "type": "string",
793
+ "enum": ["day", "month", "year"]
794
+ }
795
+ }
796
+ },
797
+ "scope": {
798
+ "type": "string",
799
+ "enum": ["limited", "full", "replacement only"]
800
+ },
801
+ "description": {
802
+ "type": "string",
803
+ "maxLength": 5000,
804
+ "description": "Free-text warranty description, disclaimer, or legal prose"
805
+ }
806
+ }
807
+ },
808
+ "return_policy": {
809
+ "type": "object",
810
+ "properties": {
811
+ "window_days": {
812
+ "type": "integer",
813
+ "minimum": 0,
814
+ "maximum": 365
815
+ },
816
+ "free_return": {
817
+ "type": "boolean"
818
+ }
819
+ }
820
+ },
821
+ "certification": {
822
+ "type": "object",
823
+ "required": ["type"],
824
+ "properties": {
825
+ "type": {
826
+ "type": "string",
827
+ "pattern": "^[A-Za-z][A-Za-z0-9 _./()\\-]{0,99}$",
828
+ "minLength": 1,
829
+ "maxLength": 100,
830
+ "description": "Standard reference such as 'UL', 'UL Listed', 'ISO 11148-6', 'ATEX 2014/34/EU'. Accepts letters, digits, spaces, underscores, dots, slashes, parens, hyphens. Cannot contain commas or semicolons — those are list separators handled by the CSV mapper."
831
+ },
832
+ "number": {
833
+ "type": "string",
834
+ "minLength": 1,
835
+ "maxLength": 100
836
+ },
837
+ "expiry_date": {
838
+ "type": "string",
839
+ "format": "date"
840
+ },
841
+ "document_url": {
842
+ "type": "string",
843
+ "format": "uri"
844
+ }
845
+ }
846
+ },
847
+ "variant": {
848
+ "type": "object",
849
+ "description": "Variant is a sparse override of product fields. Only include fields that differ from the parent product. All product fields can be overridden except id, brand_id, and classification.",
850
+ "required": ["id", "product_id"],
851
+ "properties": {
852
+ "id": {
853
+ "$ref": "#/definitions/uuid"
854
+ },
855
+ "product_id": {
856
+ "$ref": "#/definitions/uuid",
857
+ "description": "Reference to parent product. Variant inherits all product fields unless explicitly overridden."
858
+ },
859
+ "status": {
860
+ "type": "string",
861
+ "enum": ["draft", "active", "archived"],
862
+ "description": "Optional - inherits from product if not specified"
863
+ },
864
+ "content": {
865
+ "$ref": "#/definitions/content",
866
+ "description": "Rarely overridden, but possible for variant-specific content"
867
+ },
868
+ "condition": {
869
+ "type": "string",
870
+ "enum": ["new", "used", "refurbished"],
871
+ "description": "Optional - inherits from product if not specified"
872
+ },
873
+ "identifiers": {
874
+ "type": "object",
875
+ "description": "Only include identifiers that differ from product. SKU typically overridden for each variant.",
876
+ "properties": {
877
+ "sku": {
878
+ "type": "string",
879
+ "minLength": 1,
880
+ "maxLength": 100
881
+ },
882
+ "gtin": {
883
+ "type": "string",
884
+ "pattern": "^\\d{8,14}$"
885
+ },
886
+ "upc": {
887
+ "type": "string",
888
+ "pattern": "^\\d{12}$"
889
+ },
890
+ "ean": {
891
+ "type": "string",
892
+ "pattern": "^\\d{13}$"
893
+ },
894
+ "mpn": {
895
+ "type": "string",
896
+ "maxLength": 100
897
+ },
898
+ "model_number": {
899
+ "type": "string",
900
+ "maxLength": 100
901
+ },
902
+ "usda_fdc_id": {
903
+ "type": "string",
904
+ "pattern": "^\\d+$",
905
+ "description": "USDA FoodData Central database ID"
906
+ },
907
+ "asin": {
908
+ "type": "string",
909
+ "maxLength": 10,
910
+ "pattern": "^[A-Z0-9]{10}$",
911
+ "description": "Amazon Standard Identification Number (exactly 10 uppercase alphanumeric characters)"
912
+ },
913
+ "nsn": {
914
+ "type": "string",
915
+ "maxLength": 16,
916
+ "pattern": "^[0-9A-Z]{4}-[0-9A-Z]{2}-[0-9A-Z]{3}-[0-9A-Z]{4}$|^[0-9A-Z][0-9A-Z-]{0,15}$",
917
+ "description": "NATO Stock Number — hyphenated NATO form (e.g. 1234-56-789-1234) or local/alphanumeric form (e.g. 850519-S01)"
918
+ }
919
+ }
920
+ },
921
+ "channel_content": {
922
+ "type": "object",
923
+ "additionalProperties": { "$ref": "#/definitions/content" },
924
+ "description": "Per-channel variant content variants, keyed by channel identifier. Each entry has the shape of `content` (all fields optional, extra keys allowed); sparse-override, deep-merged over variant `content` when a listing for that channel is created."
925
+ },
926
+ "attributes": { "$ref": "#/definitions/open_attributes" },
927
+ "physical": {
928
+ "$ref": "#/definitions/physical_specifications",
929
+ "description": "Only include physical specs that differ from product (e.g., weight varies by size)"
930
+ },
931
+ "media_assets": {
932
+ "$ref": "#/definitions/media_assets",
933
+ "description": "Variant can override product media. Arrays replace (not merge)."
934
+ },
935
+ "compliance": {
936
+ "$ref": "#/definitions/compliance"
937
+ },
938
+ "assurances": {
939
+ "$ref": "#/definitions/assurances"
940
+ },
941
+ "instructions": {
942
+ "$ref": "#/definitions/instructions"
943
+ },
944
+ "pricing": {
945
+ "$ref": "#/definitions/pricing"
946
+ },
947
+ "relationships": {
948
+ "type": "array",
949
+ "items": { "$ref": "#/definitions/relationship" },
950
+ "maxItems": 100
951
+ },
952
+ "brand_groupings": {
953
+ "$ref": "#/definitions/brand_groupings"
954
+ },
955
+ "technical_data": {
956
+ "type": "object",
957
+ "description": "Measured/tested technical properties grouped by section name",
958
+ "maxProperties": 20,
959
+ "additionalProperties": {
960
+ "type": "array",
961
+ "maxItems": 100,
962
+ "items": {
963
+ "type": "object",
964
+ "minProperties": 1,
965
+ "additionalProperties": {
966
+ "oneOf": [
967
+ { "type": "string" },
968
+ { "type": "number" },
969
+ { "type": "boolean" }
970
+ ]
971
+ }
972
+ }
973
+ }
974
+ },
975
+ "metadata": {
976
+ "type": "object",
977
+ "additionalProperties": true
978
+ },
979
+ "content_hash": {
980
+ "type": ["string", "null"],
981
+ "pattern": "^[a-f0-9]{64}$",
982
+ "description": "SHA-256 hash of canonical JSON representation"
983
+ }
984
+ }
985
+ },
986
+ "physical_specifications": {
987
+ "type": "object",
988
+ "properties": {
989
+ "weight": {
990
+ "$ref": "#/definitions/weight_measurement"
991
+ },
992
+ "dimensions": {
993
+ "$ref": "#/definitions/dimensions_measurement"
994
+ },
995
+ "package_weight": {
996
+ "$ref": "#/definitions/weight_measurement"
997
+ },
998
+ "package_dimensions": {
999
+ "$ref": "#/definitions/dimensions_measurement"
1000
+ }
1001
+ }
1002
+ },
1003
+ "weight_measurement": {
1004
+ "type": "object",
1005
+ "required": ["value", "unit"],
1006
+ "properties": {
1007
+ "value": {
1008
+ "type": "number",
1009
+ "minimum": 0
1010
+ },
1011
+ "unit": {
1012
+ "type": "string",
1013
+ "enum": ["lb", "kg", "g", "oz"]
1014
+ }
1015
+ }
1016
+ },
1017
+ "dimensions_measurement": {
1018
+ "type": "object",
1019
+ "required": ["length", "width", "height", "unit"],
1020
+ "properties": {
1021
+ "length": {
1022
+ "type": "number",
1023
+ "minimum": 0
1024
+ },
1025
+ "width": {
1026
+ "type": "number",
1027
+ "minimum": 0
1028
+ },
1029
+ "height": {
1030
+ "type": "number",
1031
+ "minimum": 0
1032
+ },
1033
+ "unit": {
1034
+ "type": "string",
1035
+ "enum": ["in", "cm", "mm", "ft", "m"]
1036
+ }
1037
+ }
1038
+ },
1039
+ "typed_attribute_measurement": {
1040
+ "type": "object",
1041
+ "description": "Open-attribute measurement: a required unit of measure plus at least one of value, min, max, avg. Any combination is permitted. Supersedes the former typed_attribute_value and typed_attribute_range (v0.7.0).",
1042
+ "required": ["unit"],
1043
+ "anyOf": [
1044
+ { "required": ["value"] },
1045
+ { "required": ["min"] },
1046
+ { "required": ["max"] },
1047
+ { "required": ["avg"] }
1048
+ ],
1049
+ "properties": {
1050
+ "value": { "type": "number" },
1051
+ "min": { "type": "number" },
1052
+ "max": { "type": "number" },
1053
+ "avg": { "type": "number" },
1054
+ "unit": { "type": "string", "minLength": 1, "maxLength": 255 }
1055
+ },
1056
+ "additionalProperties": false
1057
+ },
1058
+ "typed_attribute_list": {
1059
+ "type": "array",
1060
+ "description": "Open-attribute value list: several independent scalar values for one attribute. Small, flat lists only - for multi-dimensional or tabular data such as test results, use technical_data.",
1061
+ "minItems": 1,
1062
+ "maxItems": 50,
1063
+ "uniqueItems": true,
1064
+ "items": {
1065
+ "oneOf": [
1066
+ { "type": "string", "maxLength": 255 },
1067
+ { "type": "number" },
1068
+ { "type": "boolean" }
1069
+ ]
1070
+ }
1071
+ },
1072
+ "open_attribute_value": {
1073
+ "description": "Permitted value shapes for an open attribute: scalar, null, measurement {unit + any of value/min/max/avg}, or a flat list of scalars.",
1074
+ "oneOf": [
1075
+ { "type": "string", "maxLength": 255 },
1076
+ { "type": "number" },
1077
+ { "type": "boolean" },
1078
+ { "type": "null" },
1079
+ { "$ref": "#/definitions/typed_attribute_measurement" },
1080
+ { "$ref": "#/definitions/typed_attribute_list" }
1081
+ ]
1082
+ },
1083
+ "open_attributes": {
1084
+ "type": "object",
1085
+ "description": "Open attribute bag: five universal string attributes (color/size/material/finish/pattern) plus arbitrary additional attributes whose values follow open_attribute_value (scalar | null | measurement | list of scalars). e.g. processor_brand: 'intel', ram_gb: 16, weight_capacity: {value: 50, unit: 'kg'}, max_pressure: {max: 90, unit: 'psi'}, vacuum_capability: ['self-generating', 'vacuum ready'].",
1086
+ "properties": {
1087
+ "color": { "type": "string", "maxLength": 255 },
1088
+ "size": { "type": "string", "maxLength": 255 },
1089
+ "material": { "type": "string", "maxLength": 255 },
1090
+ "finish": { "type": "string", "maxLength": 255 },
1091
+ "pattern": { "type": "string", "maxLength": 255 }
1092
+ },
1093
+ "additionalProperties": { "$ref": "#/definitions/open_attribute_value" }
1094
+ },
1095
+ "listing": {
1096
+ "type": "object",
1097
+ "required": ["id", "product_id", "channel", "channel_account_id", "status", "content"],
1098
+ "properties": {
1099
+ "id": {
1100
+ "$ref": "#/definitions/uuid"
1101
+ },
1102
+ "product_id": {
1103
+ "$ref": "#/definitions/uuid",
1104
+ "description": "Reference to the product this listing is for"
1105
+ },
1106
+ "brand_id": {
1107
+ "$ref": "#/definitions/uuid",
1108
+ "description": "Relationship FK to the brand entity. Mirrors product.brand_id; consumer connectors resolve brand data via brands/{brand_id}.json at sync time. Optional."
1109
+ },
1110
+ "channel": {
1111
+ "type": "string",
1112
+ "pattern": "^[a-z][a-z0-9_]{0,49}$",
1113
+ "minLength": 1,
1114
+ "maxLength": 50,
1115
+ "description": "Channel identifier. See config/schemas/registries/channels.json for known values."
1116
+ },
1117
+ "channel_account_id": {
1118
+ "type": "string",
1119
+ "minLength": 1,
1120
+ "maxLength": 100
1121
+ },
1122
+ "status": {
1123
+ "type": "string",
1124
+ "enum": ["draft", "pending", "active", "error", "delisted", "suspended"]
1125
+ },
1126
+ "content": {
1127
+ "allOf": [
1128
+ { "$ref": "#/definitions/content" },
1129
+ { "required": ["name"] }
1130
+ ]
1131
+ },
1132
+ "condition": {
1133
+ "type": "string",
1134
+ "enum": ["new", "used", "refurbished"],
1135
+ "description": "Optional - inherits from product if not specified"
1136
+ },
1137
+ "identifiers": {
1138
+ "type": "object",
1139
+ "description": "Channel-level identifier overrides",
1140
+ "properties": {
1141
+ "sku": {
1142
+ "type": "string",
1143
+ "minLength": 1,
1144
+ "maxLength": 100
1145
+ },
1146
+ "gtin": {
1147
+ "type": "string",
1148
+ "pattern": "^\\d{8,14}$"
1149
+ },
1150
+ "upc": {
1151
+ "type": "string",
1152
+ "pattern": "^\\d{12}$"
1153
+ },
1154
+ "ean": {
1155
+ "type": "string",
1156
+ "pattern": "^\\d{13}$"
1157
+ },
1158
+ "mpn": {
1159
+ "type": "string",
1160
+ "maxLength": 100
1161
+ },
1162
+ "model_number": {
1163
+ "type": "string",
1164
+ "maxLength": 100
1165
+ },
1166
+ "usda_fdc_id": {
1167
+ "type": "string",
1168
+ "pattern": "^\\d+$"
1169
+ },
1170
+ "asin": {
1171
+ "type": "string",
1172
+ "maxLength": 10,
1173
+ "pattern": "^[A-Z0-9]{10}$",
1174
+ "description": "Amazon Standard Identification Number (exactly 10 uppercase alphanumeric characters)"
1175
+ },
1176
+ "nsn": {
1177
+ "type": "string",
1178
+ "maxLength": 16,
1179
+ "pattern": "^[0-9A-Z]{4}-[0-9A-Z]{2}-[0-9A-Z]{3}-[0-9A-Z]{4}$|^[0-9A-Z][0-9A-Z-]{0,15}$",
1180
+ "description": "NATO Stock Number — hyphenated NATO form (e.g. 1234-56-789-1234) or local/alphanumeric form (e.g. 850519-S01)"
1181
+ }
1182
+ }
1183
+ },
1184
+ "classification": {
1185
+ "type": "object",
1186
+ "description": "Channel-level classification overrides",
1187
+ "properties": {
1188
+ "primary_category": {
1189
+ "type": "string",
1190
+ "minLength": 1,
1191
+ "maxLength": 500
1192
+ },
1193
+ "product_type": {
1194
+ "type": "string",
1195
+ "minLength": 1,
1196
+ "maxLength": 255
1197
+ },
1198
+ "tags": {
1199
+ "type": "array",
1200
+ "items": {
1201
+ "type": "string",
1202
+ "minLength": 1,
1203
+ "maxLength": 50
1204
+ },
1205
+ "maxItems": 50
1206
+ },
1207
+ "external_codes": {
1208
+ "type": "object",
1209
+ "properties": {
1210
+ "unspsc": {
1211
+ "type": "string",
1212
+ "pattern": "^\\d{8}$"
1213
+ },
1214
+ "eclass": {
1215
+ "type": "string",
1216
+ "pattern": "^\\d{8}$"
1217
+ },
1218
+ "etim": {
1219
+ "type": "string",
1220
+ "pattern": "^EC\\d{6}$"
1221
+ }
1222
+ }
1223
+ }
1224
+ }
1225
+ },
1226
+ "attributes": { "$ref": "#/definitions/open_attributes" },
1227
+ "physical": {
1228
+ "$ref": "#/definitions/physical_specifications"
1229
+ },
1230
+ "media_assets": {
1231
+ "$ref": "#/definitions/media_assets"
1232
+ },
1233
+ "compliance": {
1234
+ "$ref": "#/definitions/compliance"
1235
+ },
1236
+ "assurances": {
1237
+ "$ref": "#/definitions/assurances"
1238
+ },
1239
+ "instructions": {
1240
+ "$ref": "#/definitions/instructions"
1241
+ },
1242
+ "pricing": {
1243
+ "$ref": "#/definitions/pricing"
1244
+ },
1245
+ "availability": {
1246
+ "$ref": "#/definitions/availability"
1247
+ },
1248
+ "shipping": {
1249
+ "$ref": "#/definitions/shipping"
1250
+ },
1251
+ "relationships": {
1252
+ "type": "array",
1253
+ "items": { "$ref": "#/definitions/relationship" },
1254
+ "maxItems": 50
1255
+ },
1256
+ "recommendations": {
1257
+ "type": "array",
1258
+ "items": { "$ref": "#/definitions/recommendation" },
1259
+ "maxItems": 50
1260
+ },
1261
+ "brand_groupings": {
1262
+ "$ref": "#/definitions/brand_groupings"
1263
+ },
1264
+ "technical_data": {
1265
+ "type": "object",
1266
+ "description": "Technical specifications",
1267
+ "additionalProperties": true
1268
+ },
1269
+ "metadata": {
1270
+ "type": "object",
1271
+ "additionalProperties": true
1272
+ },
1273
+ "syndication": {
1274
+ "$ref": "#/definitions/syndication_metadata"
1275
+ },
1276
+ "content_hash": {
1277
+ "type": ["string", "null"],
1278
+ "pattern": "^[a-f0-9]{64}$",
1279
+ "description": "SHA-256 hash of canonical JSON representation"
1280
+ },
1281
+ "variants": {
1282
+ "type": "array",
1283
+ "description": "Variant-level listing details. Each entry is a sparse override of listing-level defaults.",
1284
+ "items": {
1285
+ "type": "object",
1286
+ "required": ["variant_id"],
1287
+ "properties": {
1288
+ "variant_id": {
1289
+ "$ref": "#/definitions/uuid",
1290
+ "description": "Reference to the variant in the product"
1291
+ },
1292
+ "status": {
1293
+ "type": "string",
1294
+ "enum": ["draft", "pending", "active", "error", "delisted", "suspended"]
1295
+ },
1296
+ "condition": {
1297
+ "type": "string",
1298
+ "enum": ["new", "used", "refurbished"]
1299
+ },
1300
+ "identifiers": {
1301
+ "type": "object",
1302
+ "properties": {
1303
+ "sku": {
1304
+ "type": "string",
1305
+ "minLength": 1,
1306
+ "maxLength": 100
1307
+ },
1308
+ "gtin": {
1309
+ "type": "string",
1310
+ "pattern": "^\\d{8,14}$"
1311
+ },
1312
+ "upc": {
1313
+ "type": "string",
1314
+ "pattern": "^\\d{12}$"
1315
+ },
1316
+ "ean": {
1317
+ "type": "string",
1318
+ "pattern": "^\\d{13}$"
1319
+ },
1320
+ "mpn": {
1321
+ "type": "string",
1322
+ "maxLength": 100
1323
+ },
1324
+ "model_number": {
1325
+ "type": "string",
1326
+ "maxLength": 100
1327
+ },
1328
+ "usda_fdc_id": {
1329
+ "type": "string",
1330
+ "pattern": "^\\d+$"
1331
+ },
1332
+ "asin": {
1333
+ "type": "string",
1334
+ "maxLength": 10,
1335
+ "pattern": "^[A-Z0-9]{10}$",
1336
+ "description": "Amazon Standard Identification Number (exactly 10 uppercase alphanumeric characters)"
1337
+ },
1338
+ "nsn": {
1339
+ "type": "string",
1340
+ "maxLength": 16,
1341
+ "pattern": "^[0-9A-Z]{4}-[0-9A-Z]{2}-[0-9A-Z]{3}-[0-9A-Z]{4}$|^[0-9A-Z][0-9A-Z-]{0,15}$",
1342
+ "description": "NATO Stock Number — hyphenated NATO form (e.g. 1234-56-789-1234) or local/alphanumeric form (e.g. 850519-S01)"
1343
+ }
1344
+ }
1345
+ },
1346
+ "classification": {
1347
+ "type": "object",
1348
+ "properties": {
1349
+ "primary_category": {
1350
+ "type": "string",
1351
+ "minLength": 1,
1352
+ "maxLength": 500
1353
+ },
1354
+ "product_type": {
1355
+ "type": "string",
1356
+ "minLength": 1,
1357
+ "maxLength": 255
1358
+ },
1359
+ "tags": {
1360
+ "type": "array",
1361
+ "items": {
1362
+ "type": "string",
1363
+ "minLength": 1,
1364
+ "maxLength": 50
1365
+ },
1366
+ "maxItems": 50
1367
+ }
1368
+ }
1369
+ },
1370
+ "content": {
1371
+ "$ref": "#/definitions/content"
1372
+ },
1373
+ "attributes": { "$ref": "#/definitions/open_attributes" },
1374
+ "physical": {
1375
+ "$ref": "#/definitions/physical_specifications"
1376
+ },
1377
+ "media_assets": {
1378
+ "$ref": "#/definitions/media_assets"
1379
+ },
1380
+ "compliance": {
1381
+ "$ref": "#/definitions/compliance"
1382
+ },
1383
+ "assurances": {
1384
+ "$ref": "#/definitions/assurances"
1385
+ },
1386
+ "instructions": {
1387
+ "$ref": "#/definitions/instructions"
1388
+ },
1389
+ "relationships": {
1390
+ "type": "array",
1391
+ "items": { "$ref": "#/definitions/relationship" }
1392
+ },
1393
+ "brand_groupings": {
1394
+ "$ref": "#/definitions/brand_groupings"
1395
+ },
1396
+ "technical_data": {
1397
+ "type": "object",
1398
+ "additionalProperties": true
1399
+ },
1400
+ "pricing": {
1401
+ "$ref": "#/definitions/pricing"
1402
+ },
1403
+ "availability": {
1404
+ "$ref": "#/definitions/availability"
1405
+ },
1406
+ "shipping": {
1407
+ "$ref": "#/definitions/shipping"
1408
+ },
1409
+ "metadata": {
1410
+ "type": "object",
1411
+ "additionalProperties": true
1412
+ }
1413
+ }
1414
+ }
1415
+ },
1416
+ "access_control": {
1417
+ "$ref": "#/definitions/access_control"
1418
+ }
1419
+ }
1420
+ },
1421
+ "content": {
1422
+ "type": "object",
1423
+ "properties": {
1424
+ "name": {
1425
+ "type": "string",
1426
+ "minLength": 1,
1427
+ "maxLength": 255
1428
+ },
1429
+ "description_short": {
1430
+ "type": "string",
1431
+ "minLength": 1,
1432
+ "maxLength": 500
1433
+ },
1434
+ "description_long": {
1435
+ "type": "string",
1436
+ "maxLength": 50000
1437
+ },
1438
+ "features": {
1439
+ "type": "array",
1440
+ "items": {
1441
+ "type": "string",
1442
+ "minLength": 1,
1443
+ "maxLength": 255
1444
+ },
1445
+ "maxItems": 20
1446
+ },
1447
+ "keywords": {
1448
+ "type": "array",
1449
+ "items": {
1450
+ "type": "string",
1451
+ "minLength": 1,
1452
+ "maxLength": 50
1453
+ },
1454
+ "maxItems": 50
1455
+ },
1456
+ "model_name": {
1457
+ "type": "string",
1458
+ "maxLength": 100,
1459
+ "description": "Buyer-facing marketing/series model name (e.g. Amazon model_name 'W3000 Series 20V Impact Wrench'). Distinct from content.name (full title) and identifiers.model_number/mpn (part number). Optional; not added to any required set."
1460
+ },
1461
+ "seo_title": {
1462
+ "type": "string",
1463
+ "minLength": 1,
1464
+ "maxLength": 255,
1465
+ "description": "SEO/meta title for search engines and channel listing pages. Optional; not added to any required set."
1466
+ },
1467
+ "seo_description": {
1468
+ "type": "string",
1469
+ "minLength": 1,
1470
+ "maxLength": 500,
1471
+ "description": "SEO/meta description for search engines and channel listing pages. Optional; not added to any required set."
1472
+ },
1473
+ "locale": {
1474
+ "type": "string",
1475
+ "pattern": "^[a-z]{2}-[A-Z]{2}$",
1476
+ "default": "en-US",
1477
+ "description": "Locale code for this content (e.g., en-US, fr-CA)"
1478
+ }
1479
+ }
1480
+ },
1481
+ "pricing": {
1482
+ "type": "object",
1483
+ "required": ["currency"],
1484
+ "properties": {
1485
+ "currency": {
1486
+ "type": "string",
1487
+ "pattern": "^[A-Z]{3}$"
1488
+ },
1489
+ "list_price": {
1490
+ "type": "number",
1491
+ "minimum": 0,
1492
+ "multipleOf": 0.01
1493
+ },
1494
+ "sale_price": {
1495
+ "type": "number",
1496
+ "minimum": 0,
1497
+ "multipleOf": 0.01
1498
+ },
1499
+ "map_price": {
1500
+ "type": "number",
1501
+ "minimum": 0,
1502
+ "multipleOf": 0.01
1503
+ },
1504
+ "msrp": {
1505
+ "type": "number",
1506
+ "minimum": 0,
1507
+ "multipleOf": 0.01
1508
+ },
1509
+ "cost": {
1510
+ "type": "number",
1511
+ "minimum": 0,
1512
+ "multipleOf": 0.01
1513
+ },
1514
+ "tier_pricing": {
1515
+ "type": "array",
1516
+ "items": {
1517
+ "$ref": "#/definitions/tier_price"
1518
+ },
1519
+ "maxItems": 10
1520
+ },
1521
+ "promotional_pricing": {
1522
+ "$ref": "#/definitions/promotional_pricing"
1523
+ }
1524
+ }
1525
+ },
1526
+ "tier_price": {
1527
+ "type": "object",
1528
+ "required": ["min_quantity", "price"],
1529
+ "properties": {
1530
+ "min_quantity": {
1531
+ "type": "integer",
1532
+ "minimum": 1
1533
+ },
1534
+ "price": {
1535
+ "type": "number",
1536
+ "minimum": 0,
1537
+ "multipleOf": 0.01
1538
+ }
1539
+ }
1540
+ },
1541
+ "promotional_pricing": {
1542
+ "type": "object",
1543
+ "required": ["price", "start_date", "end_date"],
1544
+ "properties": {
1545
+ "price": {
1546
+ "type": "number",
1547
+ "minimum": 0,
1548
+ "multipleOf": 0.01
1549
+ },
1550
+ "start_date": {
1551
+ "type": "string",
1552
+ "format": "date-time"
1553
+ },
1554
+ "end_date": {
1555
+ "type": "string",
1556
+ "format": "date-time"
1557
+ },
1558
+ "promo_code": {
1559
+ "type": "string",
1560
+ "maxLength": 50
1561
+ }
1562
+ }
1563
+ },
1564
+ "availability": {
1565
+ "type": "object",
1566
+ "properties": {
1567
+ "inventory_tracking": {
1568
+ "type": "boolean"
1569
+ },
1570
+ "inventory_quantity": {
1571
+ "type": "integer",
1572
+ "minimum": 0
1573
+ },
1574
+ "inventory_policy": {
1575
+ "type": "string",
1576
+ "enum": ["track", "dont track", "continue selling"]
1577
+ },
1578
+ "fulfillment_method": {
1579
+ "type": "string",
1580
+ "enum": ["merchant", "fba", "wfs", "dropship", "sfs", "3pl"]
1581
+ },
1582
+ "fulfillment_latency": {
1583
+ "type": "integer",
1584
+ "minimum": 0,
1585
+ "maximum": 30
1586
+ },
1587
+ "restock_date": {
1588
+ "type": "string",
1589
+ "format": "date"
1590
+ },
1591
+ "preorder": {
1592
+ "$ref": "#/definitions/preorder"
1593
+ }
1594
+ }
1595
+ },
1596
+ "preorder": {
1597
+ "type": "object",
1598
+ "required": ["enabled"],
1599
+ "properties": {
1600
+ "enabled": {
1601
+ "type": "boolean"
1602
+ },
1603
+ "availability_date": {
1604
+ "type": "string",
1605
+ "format": "date"
1606
+ },
1607
+ "message": {
1608
+ "type": "string",
1609
+ "maxLength": 255
1610
+ }
1611
+ }
1612
+ },
1613
+ "shipping": {
1614
+ "type": "object",
1615
+ "properties": {
1616
+ "free_shipping": {
1617
+ "type": "boolean"
1618
+ },
1619
+ "shipping_class": {
1620
+ "type": "string",
1621
+ "maxLength": 100
1622
+ },
1623
+ "excluded_regions": {
1624
+ "type": "array",
1625
+ "items": {
1626
+ "type": "string",
1627
+ "pattern": "^[A-Z]{2}(-[A-Z0-9]+)?$"
1628
+ }
1629
+ },
1630
+ "expedited_available": {
1631
+ "type": "boolean"
1632
+ },
1633
+ "white_glove_available": {
1634
+ "type": "boolean"
1635
+ }
1636
+ }
1637
+ },
1638
+ "access_control": {
1639
+ "type": "object",
1640
+ "required": ["visibility"],
1641
+ "properties": {
1642
+ "visibility": {
1643
+ "type": "string",
1644
+ "enum": ["public", "private", "restricted"]
1645
+ },
1646
+ "authorized_partners": {
1647
+ "type": "array",
1648
+ "items": {
1649
+ "type": "string"
1650
+ }
1651
+ },
1652
+ "embargo_until": {
1653
+ "type": "string",
1654
+ "format": "date-time"
1655
+ },
1656
+ "geographic_restrictions": {
1657
+ "type": "array",
1658
+ "items": {
1659
+ "type": "string",
1660
+ "pattern": "^[A-Z]{2}$"
1661
+ }
1662
+ },
1663
+ "usage_rights": {
1664
+ "$ref": "#/definitions/usage_rights"
1665
+ }
1666
+ }
1667
+ },
1668
+ "usage_rights": {
1669
+ "type": "object",
1670
+ "properties": {
1671
+ "can_modify_price": {
1672
+ "type": "boolean"
1673
+ },
1674
+ "can_modify_content": {
1675
+ "type": "boolean"
1676
+ },
1677
+ "can_use_enhanced_content": {
1678
+ "type": "boolean"
1679
+ },
1680
+ "can_resyndicate": {
1681
+ "type": "boolean"
1682
+ },
1683
+ "price_floor": {
1684
+ "type": "number",
1685
+ "minimum": 0,
1686
+ "multipleOf": 0.01
1687
+ },
1688
+ "price_ceiling": {
1689
+ "type": "number",
1690
+ "minimum": 0,
1691
+ "multipleOf": 0.01
1692
+ }
1693
+ }
1694
+ },
1695
+ "syndication_metadata": {
1696
+ "type": "object",
1697
+ "properties": {
1698
+ "last_pushed": {
1699
+ "type": "string",
1700
+ "format": "date-time"
1701
+ },
1702
+ "last_success": {
1703
+ "type": "string",
1704
+ "format": "date-time"
1705
+ },
1706
+ "last_error": {
1707
+ "$ref": "#/definitions/syndication_error"
1708
+ },
1709
+ "validation_status": {
1710
+ "type": "string",
1711
+ "enum": ["valid", "invalid", "warnings"]
1712
+ },
1713
+ "validation_errors": {
1714
+ "type": "array",
1715
+ "items": {
1716
+ "$ref": "#/definitions/validation_error"
1717
+ }
1718
+ },
1719
+ "channel_item_id": {
1720
+ "type": "string",
1721
+ "maxLength": 255
1722
+ },
1723
+ "channel_url": {
1724
+ "type": "string",
1725
+ "format": "uri"
1726
+ },
1727
+ "performance_metrics": {
1728
+ "$ref": "#/definitions/performance_metrics"
1729
+ }
1730
+ }
1731
+ },
1732
+ "syndication_error": {
1733
+ "type": "object",
1734
+ "required": ["timestamp", "code", "message"],
1735
+ "properties": {
1736
+ "timestamp": {
1737
+ "type": "string",
1738
+ "format": "date-time"
1739
+ },
1740
+ "code": {
1741
+ "type": "string",
1742
+ "maxLength": 50
1743
+ },
1744
+ "message": {
1745
+ "type": "string",
1746
+ "maxLength": 1000
1747
+ },
1748
+ "details": {
1749
+ "type": "object"
1750
+ }
1751
+ }
1752
+ },
1753
+ "validation_error": {
1754
+ "type": "object",
1755
+ "required": ["field", "error", "severity"],
1756
+ "properties": {
1757
+ "field": {
1758
+ "type": "string",
1759
+ "maxLength": 255
1760
+ },
1761
+ "error": {
1762
+ "type": "string",
1763
+ "maxLength": 500
1764
+ },
1765
+ "severity": {
1766
+ "type": "string",
1767
+ "enum": ["error", "warning", "info"]
1768
+ }
1769
+ }
1770
+ },
1771
+ "performance_metrics": {
1772
+ "type": "object",
1773
+ "properties": {
1774
+ "views": {
1775
+ "type": "integer",
1776
+ "minimum": 0
1777
+ },
1778
+ "clicks": {
1779
+ "type": "integer",
1780
+ "minimum": 0
1781
+ },
1782
+ "conversions": {
1783
+ "type": "integer",
1784
+ "minimum": 0
1785
+ },
1786
+ "revenue": {
1787
+ "type": "number",
1788
+ "minimum": 0,
1789
+ "multipleOf": 0.01
1790
+ }
1791
+ }
1792
+ },
1793
+ "relationship_type": {
1794
+ "type": "string",
1795
+ "enum": ["compatible with", "fits", "replacement for", "works with", "designed for", "requires", "includes", "accessory for"]
1796
+ },
1797
+ "relationship_target": {
1798
+ "type": "object",
1799
+ "properties": {
1800
+ "product_id": { "type": "string", "format": "uuid" },
1801
+ "sku": { "type": "string", "maxLength": 100 },
1802
+ "gtin": { "type": "string", "pattern": "^[0-9]{8,14}$" },
1803
+ "upc": { "type": "string", "pattern": "^[0-9]{12}$" },
1804
+ "ean": { "type": "string", "pattern": "^[0-9]{13}$" },
1805
+ "mpn": { "type": "string", "maxLength": 100 },
1806
+ "model_number": { "type": "string", "maxLength": 100 },
1807
+ "usda_fdc_id": { "type": "string", "maxLength": 20 },
1808
+ "brand": { "type": "string", "maxLength": 255 },
1809
+ "name": { "type": "string", "maxLength": 255 }
1810
+ },
1811
+ "anyOf": [
1812
+ { "required": ["product_id"] },
1813
+ { "required": ["sku"] },
1814
+ { "required": ["gtin"] },
1815
+ { "required": ["upc"] },
1816
+ { "required": ["ean"] },
1817
+ { "required": ["mpn"] },
1818
+ { "required": ["model_number"] },
1819
+ { "required": ["usda_fdc_id"] },
1820
+ { "required": ["name"] }
1821
+ ]
1822
+ },
1823
+ "relationship": {
1824
+ "type": "object",
1825
+ "required": ["type", "target"],
1826
+ "properties": {
1827
+ "type": { "$ref": "#/definitions/relationship_type" },
1828
+ "target": { "$ref": "#/definitions/relationship_target" },
1829
+ "note": { "type": "string", "maxLength": 500 }
1830
+ }
1831
+ },
1832
+ "recommendation_type": {
1833
+ "type": "string",
1834
+ "enum": ["upsell", "cross sell", "frequently bought together", "customers also bought", "recommended", "bundle", "substitute", "similar to", "compare to", "alternative to"]
1835
+ },
1836
+ "recommendation": {
1837
+ "type": "object",
1838
+ "required": ["type", "target"],
1839
+ "properties": {
1840
+ "type": { "$ref": "#/definitions/recommendation_type" },
1841
+ "target": { "$ref": "#/definitions/relationship_target" },
1842
+ "score": { "type": "number", "minimum": 0.0, "maximum": 1.0 },
1843
+ "source": { "type": "string", "maxLength": 100 },
1844
+ "window": { "type": "string", "maxLength": 50 },
1845
+ "generated_at": { "type": "string", "format": "date-time" }
1846
+ }
1847
+ },
1848
+ "brand_groupings": {
1849
+ "type": "object",
1850
+ "properties": {
1851
+ "product_line": { "type": "string", "minLength": 1, "maxLength": 255, "description": "Primary brand product family" },
1852
+ "series": { "type": "string", "minLength": 1, "maxLength": 255, "description": "Sub-family within a product line" },
1853
+ "collection": { "type": "array", "items": { "type": "string", "minLength": 1, "maxLength": 255 }, "minItems": 1, "maxItems": 20, "description": "Curated or seasonal grouping(s)" },
1854
+ "sub_brand": { "type": "string", "minLength": 1, "maxLength": 255, "description": "Distinct brand identity within parent brand" },
1855
+ "platform": { "type": "array", "items": { "type": "string", "minLength": 1, "maxLength": 255 }, "minItems": 1, "maxItems": 10, "description": "Shared technology or compatibility ecosystem(s)" },
1856
+ "generation": { "type": "string", "minLength": 1, "maxLength": 255, "description": "Version or iteration of a product line" },
1857
+ "edition": { "type": "string", "minLength": 1, "maxLength": 255, "description": "Special variant or limited release" }
1858
+ },
1859
+ "additionalProperties": false
1860
+ },
1861
+ "signature": {
1862
+ "type": "object",
1863
+ "required": ["key_ref", "algorithm", "value", "signed_at"],
1864
+ "properties": {
1865
+ "key_ref": {
1866
+ "type": "string",
1867
+ "pattern": "^\\.openpx/keys/[a-z0-9_-]+-\\d{4}-\\d{2}-\\d{2}\\.pub$",
1868
+ "description": "Path to public key file in repo (e.g., .openpx/keys/org-2025-06-15.pub)"
1869
+ },
1870
+ "algorithm": {
1871
+ "type": "string",
1872
+ "enum": ["Ed25519"],
1873
+ "description": "Signing algorithm"
1874
+ },
1875
+ "value": {
1876
+ "type": "string",
1877
+ "description": "Base64-encoded Ed25519 signature"
1878
+ },
1879
+ "signed_at": {
1880
+ "type": "string",
1881
+ "format": "date-time",
1882
+ "description": "ISO 8601 timestamp of when the entity was signed"
1883
+ }
1884
+ },
1885
+ "additionalProperties": false
1886
+ }
1887
+ }
1888
+ }