{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://www.nutrigraphapi.com/schema/product-submission.v1.schema.json",
  "title": "NutriGraphAPI product submission v1",
  "description": "What a brand supplies when it lists products with NutriGraphAPI. Supply only what is printed on the pack or your own spec sheet. NutriGraph derives the verified (qualified) allergen, dietary and clean-label fields itself.",
  "type": "object",
  "required": ["schema_version", "submitter", "products"],
  "additionalProperties": false,
  "properties": {
    "schema_version": { "const": "1.0" },
    "submitter": {
      "type": "object",
      "required": ["company", "contact_name", "email", "attest_accuracy", "attest_image_rights"],
      "additionalProperties": false,
      "properties": {
        "company": { "type": "string", "minLength": 2, "maxLength": 200 },
        "contact_name": { "type": "string", "minLength": 2, "maxLength": 200 },
        "email": { "type": "string", "format": "email", "maxLength": 254 },
        "role": { "type": "string", "maxLength": 120 },
        "website": { "type": "string", "format": "uri", "maxLength": 500 },
        "partner_ref": { "type": "string", "pattern": "^[a-z0-9][a-z0-9-]{1,40}$", "description": "Code from a VC/accelerator cohort link, if you have one." },
        "lead_ref": { "type": "string", "pattern": "^[a-z0-9]{6,32}$", "description": "Tracking code from an outreach link; set automatically by the submit page." },
        "attest_accuracy": { "const": true, "description": "I confirm the data matches the product as sold." },
        "attest_image_rights": { "const": true, "description": "I own, or am licensed to share, the images linked below." }
      }
    },
    "products": {
      "type": "array",
      "minItems": 1,
      "maxItems": 500,
      "items": { "$ref": "#/$defs/product" }
    }
  },
  "$defs": {
    "allergen": {
      "enum": ["milk", "eggs", "fish", "crustacean_shellfish", "tree_nuts", "peanuts", "wheat", "soybeans", "sesame", "gluten", "celery", "mustard", "lupin", "molluscs", "sulphites"]
    },
    "quantity": {
      "type": "object",
      "required": ["value", "unit"],
      "additionalProperties": false,
      "properties": {
        "value": { "type": "number", "exclusiveMinimum": 0 },
        "unit": { "enum": ["g", "kg", "mg", "oz", "lb", "ml", "l", "fl_oz", "count"] }
      }
    },
    "url": { "type": "string", "format": "uri", "pattern": "^https://", "maxLength": 500 },
    "product": {
      "type": "object",
      "required": ["gtin", "name", "brand", "ingredients_text"],
      "additionalProperties": false,
      "properties": {
        "gtin": { "type": "string", "pattern": "^([0-9]{8}|[0-9]{12}|[0-9]{13}|[0-9]{14})$", "description": "GTIN-8/12/13/14 (UPC-A, EAN-13). Check digit is verified." },
        "name": { "type": "string", "minLength": 2, "maxLength": 200 },
        "brand": { "type": "string", "minLength": 1, "maxLength": 120 },
        "manufacturer": { "type": "string", "maxLength": 200 },
        "category": { "type": "string", "maxLength": 120 },
        "variant": { "type": "string", "maxLength": 120 },
        "net_weight": { "$ref": "#/$defs/quantity" },
        "serving": {
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "size": { "type": "number", "exclusiveMinimum": 0 },
            "unit": { "enum": ["g", "ml", "oz", "fl_oz", "piece", "cup", "tbsp", "tsp"] },
            "servings_per_pack": { "type": "number", "exclusiveMinimum": 0 }
          }
        },
        "ingredients_text": { "type": "string", "minLength": 2, "maxLength": 5000, "description": "Verbatim from the pack, in label order." },
        "allergens_declared": {
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "contains": { "type": "array", "items": { "$ref": "#/$defs/allergen" }, "uniqueItems": true },
            "may_contain": { "type": "array", "items": { "$ref": "#/$defs/allergen" }, "uniqueItems": true }
          }
        },
        "nutrition_per_serving": {
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "energy_kcal": { "type": "number", "minimum": 0, "maximum": 5000 },
            "fat_g": { "type": "number", "minimum": 0, "maximum": 1000 },
            "saturated_fat_g": { "type": "number", "minimum": 0, "maximum": 1000 },
            "trans_fat_g": { "type": "number", "minimum": 0, "maximum": 1000 },
            "cholesterol_mg": { "type": "number", "minimum": 0, "maximum": 100000 },
            "sodium_mg": { "type": "number", "minimum": 0, "maximum": 100000 },
            "carbs_g": { "type": "number", "minimum": 0, "maximum": 1000 },
            "fiber_g": { "type": "number", "minimum": 0, "maximum": 1000 },
            "sugars_g": { "type": "number", "minimum": 0, "maximum": 1000 },
            "added_sugars_g": { "type": "number", "minimum": 0, "maximum": 1000 },
            "protein_g": { "type": "number", "minimum": 0, "maximum": 1000 }
          }
        },
        "claims": {
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "certifications": { "type": "array", "items": { "type": "string", "maxLength": 100 }, "maxItems": 30 },
            "diet_labels": { "type": "array", "items": { "enum": ["vegan", "vegetarian", "pescatarian", "keto_friendly", "low_fodmap", "gluten_free", "dairy_free", "paleo", "no_added_sugar"] }, "uniqueItems": true },
            "religious": { "type": "array", "items": { "enum": ["kosher", "halal", "jain", "hindu"] }, "uniqueItems": true }
          }
        },
        "images": {
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "front": { "$ref": "#/$defs/url" },
            "ingredients": { "$ref": "#/$defs/url" },
            "nutrition": { "$ref": "#/$defs/url" }
          }
        },
        "country_of_sale": { "type": "array", "items": { "type": "string", "pattern": "^[A-Z]{2}$" }, "maxItems": 60 },
        "product_url": { "$ref": "#/$defs/url" },
        "launch_date": { "type": "string", "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$" }
      }
    }
  }
}
