{
  "openapi": "3.1.0",
  "info": {
    "title": "Reef Label data",
    "version": "2026-09-23",
    "summary": "Sunscreen laws, ingredients and product verdicts as JSON.",
    "description": "Read-only, keyless JSON files generated from the same data as https://reeflabel.com. Free to use with attribution (https://reeflabel.com/terms/, https://reeflabel.com/guide/cite/). Verdicts are reference information, not legal advice. For search and label checking, use the MCP endpoint at https://reeflabel.com/mcp. Contact: legal@reeflabel.com.",
    "license": {
      "name": "Free to use with attribution",
      "url": "https://reeflabel.com/terms/#license"
    },
    "contact": {
      "email": "legal@reeflabel.com",
      "url": "https://reeflabel.com"
    }
  },
  "servers": [
    {
      "url": "https://reeflabel.com"
    }
  ],
  "security": [],
  "paths": {
    "/data/index.json": {
      "get": {
        "description": "Counts, review date and links to every data file.",
        "security": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Manifest"
                }
              }
            }
          }
        }
      }
    },
    "/data/locations.json": {
      "get": {
        "description": "Every sunscreen law and reef rule tracked.",
        "security": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "kind",
                    "count",
                    "attribution",
                    "locations"
                  ],
                  "properties": {
                    "kind": {
                      "const": "locations"
                    },
                    "count": {
                      "type": "integer"
                    },
                    "attribution": {
                      "$ref": "#/components/schemas/Attribution"
                    },
                    "locations": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Location"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/data/ingredients.json": {
      "get": {
        "description": "Every UV filter and additive tracked.",
        "security": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "kind",
                    "count",
                    "attribution",
                    "ingredients"
                  ],
                  "properties": {
                    "kind": {
                      "const": "ingredients"
                    },
                    "count": {
                      "type": "integer"
                    },
                    "attribution": {
                      "$ref": "#/components/schemas/Attribution"
                    },
                    "ingredients": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Ingredient"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/data/brands.json": {
      "get": {
        "description": "Brands with product counts.",
        "security": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "kind",
                    "count",
                    "attribution",
                    "brands"
                  ],
                  "properties": {
                    "kind": {
                      "const": "brands"
                    },
                    "count": {
                      "type": "integer"
                    },
                    "attribution": {
                      "$ref": "#/components/schemas/Attribution"
                    },
                    "brands": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Brand"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/data/products.json": {
      "get": {
        "description": "Every product with a computed verdict for each location.",
        "security": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "kind",
                    "count",
                    "attribution",
                    "products"
                  ],
                  "properties": {
                    "kind": {
                      "const": "products"
                    },
                    "count": {
                      "type": "integer"
                    },
                    "attribution": {
                      "$ref": "#/components/schemas/Attribution"
                    },
                    "products": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Product"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Attribution": {
        "type": "object",
        "properties": {
          "source": {
            "type": "string"
          },
          "url": {
            "type": "string"
          },
          "dataReviewed": {
            "type": "string",
            "format": "date"
          },
          "terms": {
            "type": "string"
          },
          "cite": {
            "type": "string"
          },
          "methodology": {
            "type": "string"
          },
          "notice": {
            "type": "string"
          }
        }
      },
      "Manifest": {
        "type": "object",
        "properties": {
          "counts": {
            "type": "object"
          },
          "files": {
            "type": "object"
          },
          "attribution": {
            "$ref": "#/components/schemas/Attribution"
          }
        }
      },
      "Verdict": {
        "type": "string",
        "enum": [
          "allowed",
          "not-allowed",
          "recommended",
          "not-recommended",
          "no-rule",
          "unverified"
        ],
        "description": "allowed: meets the rule. not-allowed: violates an in-force rule. recommended / not-recommended: advisory guidance only. no-rule: repealed or not enforceable. unverified: passes on what we know but ingredient data is incomplete."
      },
      "Location": {
        "type": "object",
        "required": [
          "slug",
          "name",
          "status",
          "ruleType",
          "bannedIngredients"
        ],
        "properties": {
          "slug": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "status": {
            "enum": [
              "in-force",
              "repealed",
              "pending",
              "advisory"
            ]
          },
          "ruleType": {
            "enum": [
              "banned-list",
              "mineral-only",
              "advisory"
            ]
          },
          "bannedIngredients": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Ingredient ids (see /data/ingredients.json)."
          },
          "allowedActives": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "For mineral-only rules, the only permitted active ingredient ids."
          },
          "effectiveDate": {
            "type": "string",
            "format": "date"
          },
          "law": {
            "type": "string"
          },
          "lawShort": {
            "type": "string"
          },
          "lawUrl": {
            "type": "string"
          },
          "summary": {
            "type": "string"
          },
          "lastVerified": {
            "type": "string",
            "format": "date"
          },
          "url": {
            "type": "string"
          }
        }
      },
      "Ingredient": {
        "type": "object",
        "required": [
          "id",
          "name",
          "category"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "category": {
            "enum": [
              "mineral-uv-filter",
              "chemical-uv-filter",
              "skin-protectant",
              "preservative",
              "other"
            ]
          },
          "aliases": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "bannedIn": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Location slugs that ban it by name."
          },
          "url": {
            "type": "string"
          }
        }
      },
      "Brand": {
        "type": "object",
        "properties": {
          "slug": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "website": {
            "type": "string"
          },
          "mineralOnly": {
            "type": "boolean"
          },
          "productCount": {
            "type": "integer"
          },
          "url": {
            "type": "string"
          }
        }
      },
      "Product": {
        "type": "object",
        "required": [
          "slug",
          "name",
          "brand",
          "activeIngredients",
          "verdicts"
        ],
        "properties": {
          "slug": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "brand": {
            "type": "object",
            "properties": {
              "slug": {
                "type": "string"
              },
              "name": {
                "type": "string"
              }
            }
          },
          "category": {
            "type": "string"
          },
          "format": {
            "type": "string"
          },
          "spf": {
            "type": [
              "integer",
              "null"
            ]
          },
          "isMineral": {
            "type": "boolean"
          },
          "discontinued": {
            "type": "boolean"
          },
          "inciVerified": {
            "type": "boolean",
            "description": "false when the full ingredient list could not be sourced."
          },
          "activeIngredients": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "name": {
                  "type": "string"
                },
                "percent": {
                  "type": [
                    "number",
                    "null"
                  ]
                }
              }
            }
          },
          "activeIds": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "inactiveIngredients": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "inactiveIds": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "gtins": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sourceUrl": {
            "type": "string"
          },
          "legalEverywhere": {
            "type": "boolean",
            "description": "Allowed in every enforced location we track."
          },
          "verdicts": {
            "type": "object",
            "additionalProperties": {
              "$ref": "#/components/schemas/Verdict"
            },
            "description": "Keyed by location slug."
          },
          "blockedBy": {
            "type": "object",
            "additionalProperties": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "description": "Location slug to the ingredient ids that caused a not-allowed verdict."
          },
          "url": {
            "type": "string"
          }
        }
      }
    }
  }
}