Organization Schema Framework

Use conditional-logic schema generation to keep Organization markup aligned with real page state and avoid stale or invalid static templates.

When To Use It

Google Search CentralOrganization documentation

Use on the home page or a single page that describes the organization, such as the about page; it isn't needed on every page. It informs the logo shown in Search results, knowledge panels and merchant knowledge panels.

Key Implementation Documentation Highlights

  • Google lists no required properties: add the ones that apply to your organization.
  • Recommended properties: name, alternateName, legalName, description, url, logo, sameAs, telephone, email, address, contactPoint, foundingDate, numberOfEmployees, identifiers (iso6523Code, duns, leiCode, globalLocationNumber, naics, taxID, vatID) and the merchant policies hasMerchantReturnPolicy, hasShippingService, hasMemberProgram.
  • Use the same name and alternateName as your WebSite site name markup (alternateName in order of preference); put the registered company name in legalName.
  • logo: at least 112x112px, crawlable, indexable, and it should look right on a white background. A logo ImageObject needs a valid url or contentUrl.
  • Identifiers: Google recommends iso6523Code (ICD, a colon, then the identifier: 0199 for LEI, 0060 for DUNS, 0088 for GLN) over duns and leiCode. taxID must match the address country. telephone includes the country and area code.
  • Use the most specific subtype: OnlineStore for ecommerce rather than OnlineBusiness, and the most specific LocalBusiness subtype for local businesses.
  • hasMerchantReturnPolicy: give applicableCountry and returnPolicyCategory, or merchantReturnLink alone. MerchantReturnFiniteReturnWindow requires merchantReturnDays, returnShippingFeesAmount belongs only with returnFees ReturnShippingFees, and applicableCountry takes at most 50 ISO 3166-1 codes.
  • hasShippingService: a ShippingService requires shippingConditions. shippingRate is a currency plus value (0 for free) or maxValue, never both, or a ShippingRateSettings percentage between 0 and 1; handlingTime and transitTime durations are whole days with unitCode DAY; DefinedRegion.addressRegion works for US, AU and JP only.
  • hasMemberProgram: a MemberProgram requires name, description and hasTiers; each tier requires name and hasTierBenefit (TierBenefitLoyaltyPoints or TierBenefitLoyaltyPrice), plus membershipPointsEarned for points. Give tiers an @id and use one program url. Loyalty program markup is available in Australia, Brazil, Canada, France, Germany, Mexico, the UK and the US.
  • Policy precedence: Content API for Shopping, then Merchant Center or Search Console settings, then product-level markup, then organization-level markup.
  • Google expects content parity: every marked-up value must match what users can see on the page.
  • Validate with the Rich Results Test and URL Inspection, then monitor the related Search Console report for errors and warnings after deployment.

Template Approach

const pageData = {
  siteName: "Trailhead Outfitters",
  homeUrl: "https://www.example.com/",
  logo: "https://www.example.com/images/logo-512.png",
  description: "Online retailer of hiking packs, tents and trail apparel.",
  linkedIn: "https://www.linkedin.com/company/example"
};

const staticTemplate = {
  "@context": "https://schema.org",
  "@type": "OnlineStore",
  "name": pageData.siteName,
  "url": pageData.homeUrl,
  "logo": pageData.logo,
  "description": pageData.description,
  "sameAs": [pageData.linkedIn]
};

Conditional-logic Framework

const ISO_DATE_TIME = /^(\d{4})-(\d{2})-(\d{2})(?:T(\d{2}):(\d{2})(?::(\d{2}))?(Z|[+-]\d{2}:\d{2})?)?$/;

function isAbsoluteUrl(value) {
  return typeof value === "string" && /^https?:\/\/[^\s/?#]+\.[^\s/?#]+(?:[/?#]\S*)?$/i.test(value);
}

// Returns the ISO 8601 string unchanged (timezone offset kept), or null if unparseable.
function toIsoDateTime(value) {
  if (typeof value !== "string") return null;
  const text = value.trim();
  const m = text.match(ISO_DATE_TIME);
  if (!m) return null;
  const [, y, mo, d, h = "00", mi = "00", s = "00"] = m;
  const date = new Date(Date.UTC(+y, +mo - 1, +d));
  if (date.getUTCMonth() !== +mo - 1 || date.getUTCDate() !== +d) return null;
  if (+h > 23 || +mi > 59 || +s > 59) return null;
  return text;
}

function toIsoDate(value) {
  const iso = toIsoDateTime(value);
  return iso ? iso.slice(0, 10) : null;
}

// Drops null, undefined, "", [] and {} recursively.
function compact(value) {
  if (Array.isArray(value)) {
    const items = value.map(compact).filter((v) => v !== undefined);
    return items.length ? items : undefined;
  }
  if (value && typeof value === "object") {
    const out = {};
    for (const [key, v] of Object.entries(value)) {
      const c = compact(v);
      if (c !== undefined) out[key] = c;
    }
    return Object.keys(out).length ? out : undefined;
  }
  return value === null || value === undefined || value === "" ? undefined : value;
}

function passesPageGates(source) {
  if (source.indexable === false) return false;
  if (source.canonicalUrl && source.url && source.canonicalUrl !== source.url) return false;
  return source.contentVisible !== false;
}


const S = "https://schema.org/";
const ORGANIZATION_TYPES = {
  online_store: "OnlineStore",
  online_business: "OnlineBusiness",
  corporation: "Corporation",
  ngo: "NGO",
  school: "EducationalOrganization"
}; // physical local businesses: use the LocalBusiness framework instead
const RETURN_CATEGORY = {
  finite: S + "MerchantReturnFiniteReturnWindow",
  not_permitted: S + "MerchantReturnNotPermitted",
  unlimited: S + "MerchantReturnUnlimitedWindow"
};
const RETURN_FEES = { free: S + "FreeReturn", customer_pays: S + "ReturnFeesCustomerResponsibility", shipping_fee: S + "ReturnShippingFees" };
const RETURN_METHOD = { kiosk: S + "ReturnAtKiosk", mail: S + "ReturnByMail", in_store: S + "ReturnInStore" };
const RETURN_LABEL = { customer: S + "ReturnLabelCustomerResponsibility", download: S + "ReturnLabelDownloadAndPrint", in_box: S + "ReturnLabelInBox" };
const REFUND_TYPE = { exchange: S + "ExchangeRefund", full: S + "FullRefund", store_credit: S + "StoreCreditRefund" };
const ITEM_CONDITION = { new: S + "NewCondition", refurbished: S + "RefurbishedCondition", used: S + "UsedCondition", damaged: S + "DamagedCondition" };
const TIER_BENEFIT = { points: S + "TierBenefitLoyaltyPoints", member_price: S + "TierBenefitLoyaltyPrice" };
const ICD_PREFIX = { lei: "0199", duns: "0060", gln: "0088" }; // ISO 6523 International Code Designators
const WEEKDAYS = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"].map((d) => S + d);

function chooseOrganizationType(source) {
  return ORGANIZATION_TYPES[source.kind] || "Organization";
}

function toCountryCode(value) {
  const code = String(value || "").toUpperCase();
  return /^[A-Z]{2}$/.test(code) ? code : null;
}

function toWholeNumber(value) {
  return Number.isInteger(value) && value >= 0 ? value : null;
}

function mapEnum(keys, table) {
  return (keys || []).map((k) => table[k]).filter(Boolean);
}

function buildMoney(amount) {
  const currency = String((amount && amount.currency) || "").toUpperCase();
  if (!amount || typeof amount.value !== "number" || amount.value < 0 || !/^[A-Z]{3}$/.test(currency)) return null;
  return { "@type": "MonetaryAmount", value: amount.value, currency };
}

function buildServicePeriod([min, max] = [], cutoffTime = null) {
  // Durations are non-negative whole days, minValue <= maxValue, unitCode DAY.
  if (toWholeNumber(min) === null || toWholeNumber(max) === null || min > max) return null;
  return {
    "@type": "ServicePeriod",
    duration: { "@type": "QuantitativeValue", minValue: min, maxValue: max, unitCode: "DAY" },
    businessDays: WEEKDAYS,
    cutoffTime
  };
}

function buildReturnPolicy(policy) {
  // Either applicableCountry + returnPolicyCategory, or merchantReturnLink alone.
  const countries = (policy.countries || []).map(toCountryCode).filter(Boolean);
  const category = RETURN_CATEGORY[policy.category];
  const link = isAbsoluteUrl(policy.link) ? policy.link : null;
  if (countries.length > 50) return null; // at most 50 countries
  if (!(countries.length && category) && !link) return null;
  const days = toWholeNumber(policy.days);
  if (category === RETURN_CATEGORY.finite && days === null) return null; // finite window needs days
  if (category === RETURN_CATEGORY.not_permitted) {
    return { "@type": "MerchantReturnPolicy", applicableCountry: countries, returnPolicyCategory: category, merchantReturnLink: link };
  }
  // returnShippingFeesAmount only (and always) together with ReturnShippingFees.
  const feeAmount = buildMoney(policy.shippingFee);
  let fees = RETURN_FEES[policy.fees] || null;
  if (fees === RETURN_FEES.shipping_fee && !feeAmount) fees = null;
  return {
    "@type": "MerchantReturnPolicy",
    applicableCountry: countries,
    returnPolicyCountry: (policy.returnToCountries || []).map(toCountryCode).filter(Boolean),
    returnPolicyCategory: category,
    merchantReturnDays: category === RETURN_CATEGORY.finite ? days : null,
    merchantReturnLink: link,
    returnMethod: mapEnum(policy.methods, RETURN_METHOD),
    returnFees: fees,
    returnShippingFeesAmount: fees === RETURN_FEES.shipping_fee ? feeAmount : null,
    returnLabelSource: RETURN_LABEL[policy.label] || null,
    refundType: mapEnum(policy.refundTypes, REFUND_TYPE),
    itemCondition: mapEnum(policy.conditions, ITEM_CONDITION),
    restockingFee: typeof policy.restockingFeePercent === "number" ? policy.restockingFeePercent : null
  };
}

function buildShippingConditions(rule) {
  const destination = (rule.destinations || []).map((d) => toCountryCode(d.country) && {
    "@type": "DefinedRegion",
    addressCountry: toCountryCode(d.country),
    // addressRegion is supported for US, AU and JP only
    addressRegion: ["US", "AU", "JP"].includes(toCountryCode(d.country)) ? d.regions : null
  }).filter(Boolean);
  if (!destination.length) return null;
  const base = { "@type": "ShippingConditions", shippingDestination: destination };
  if (rule.doesNotShip) return { ...base, doesNotShip: true }; // no rate or transit time when not shipping
  const currency = String(rule.currency || "").toUpperCase();
  if (!/^[A-Z]{3}$/.test(currency)) return null;
  // shippingRate: currency plus value (0 = free) or maxValue, never both.
  const rate = typeof rule.rate === "number" && rule.rate >= 0
    ? { "@type": "MonetaryAmount", value: rule.rate, currency }
    : typeof rule.maxRate === "number" && rule.maxRate >= 0
      ? { "@type": "MonetaryAmount", maxValue: rule.maxRate, currency }
      : null;
  return {
    ...base,
    shippingOrigin: toCountryCode(rule.originCountry) && { "@type": "DefinedRegion", addressCountry: toCountryCode(rule.originCountry) },
    orderValue: typeof rule.minOrderValue === "number" ? { "@type": "MonetaryAmount", minValue: rule.minOrderValue, currency } : null,
    shippingRate: rate,
    transitTime: buildServicePeriod(rule.transitDays)
  };
}

function buildShippingService(service) {
  const shippingConditions = (service.conditions || []).map(buildShippingConditions).filter(Boolean);
  if (!shippingConditions.length) return null; // shippingConditions is required
  return {
    "@type": "ShippingService",
    name: service.name,
    description: service.description,
    fulfillmentType: S + (service.pickup ? "FulfillmentTypeCollectionPoint" : "FulfillmentTypeDelivery"),
    handlingTime: buildServicePeriod(service.handlingDays, service.cutoffTime),
    shippingConditions
  };
}

function buildTierRequirement(req) {
  if (!req) return null; // no requirement: anyone can join for free
  if (req.type === "card") return req.name ? { "@type": "CreditCard", name: req.name } : null;
  if (req.type === "spend") return buildMoney(req);
  return typeof req.text === "string" ? req.text : null;
}

function buildMemberProgram(program) {
  if (!program || !program.name || !program.description) return null; // name, description, hasTiers required
  const hasTiers = (program.tiers || []).map((tier) => {
    const benefits = mapEnum(tier.benefits, TIER_BENEFIT);
    if (!tier.name || !benefits.length) return null;
    const points = toWholeNumber(tier.pointsPerUnit);
    // TierBenefitLoyaltyPoints requires membershipPointsEarned.
    if (benefits.includes(TIER_BENEFIT.points) && points === null) return null;
    return {
      "@type": "MemberProgramTier",
      "@id": isAbsoluteUrl(tier.id) ? tier.id : null, // referenced by Offer validForMemberTier
      name: tier.name,
      hasTierBenefit: benefits,
      hasTierRequirement: buildTierRequirement(tier.requirement),
      membershipPointsEarned: benefits.includes(TIER_BENEFIT.points) ? { "@type": "QuantitativeValue", value: points } : null,
      url: isAbsoluteUrl(tier.url) ? tier.url : null
    };
  }).filter(Boolean);
  if (!hasTiers.length) return null;
  return {
    "@type": "MemberProgram",
    name: program.name,
    description: program.description,
    url: isAbsoluteUrl(program.url) ? program.url : null, // a single URL only
    hasTiers
  };
}

function buildOrganizationSchema(source) {
  // (a) Page gates: indexable, self-canonical, and the home or about page that describes the organization.
  if (!passesPageGates(source)) return null;
  if (!["home", "about"].includes(source.pageRole)) return null;

  // (b) Google lists no required properties. House rule: a name and an absolute home page URL.
  const name = source.siteName || source.name; // same name as the WebSite site name markup
  if (!name || !isAbsoluteUrl(source.homeUrl)) return null;

  const address = source.address || {};
  const country = toCountryCode(address.country);
  const ids = source.identifiers || {};
  const icd = ["lei", "duns", "gln"].find((k) => ids[k]);
  const logo = source.logo || {};
  const employees = source.employees || {};

  // (c) Recommended properties, only when the source has them; (d) value rules inline.
  const schema = {
    "@context": "https://schema.org",
    "@type": chooseOrganizationType(source),
    "@id": `${source.homeUrl}#organization`,
    name,
    alternateName: source.alternateNames, // same order as the WebSite alternateName
    legalName: source.legalName,
    description: source.description,
    url: source.homeUrl,
    logo: isAbsoluteUrl(logo.url) && !(logo.width < 112 || logo.height < 112) // at least 112x112px
      ? { "@type": "ImageObject", url: logo.url, width: logo.width, height: logo.height }
      : null,
    sameAs: (source.profiles || []).filter(isAbsoluteUrl),
    telephone: /^\+\d/.test(source.telephone || "") ? source.telephone : null,
    email: source.email,
    address: address.street && {
      "@type": "PostalAddress",
      streetAddress: address.street,
      addressLocality: address.locality,
      addressRegion: address.region,
      postalCode: address.postalCode,
      addressCountry: country
    },
    contactPoint: (source.contactPoints || []).map((cp) => ({
      "@type": "ContactPoint",
      contactType: cp.type,
      telephone: /^\+\d/.test(cp.telephone || "") ? cp.telephone : null,
      email: cp.email
    })),
    foundingDate: toIsoDate(source.foundingDate),
    numberOfEmployees: toWholeNumber(employees.value) !== null
      ? { "@type": "QuantitativeValue", value: employees.value }
      : toWholeNumber(employees.min) !== null && toWholeNumber(employees.max) !== null && employees.min <= employees.max
        ? { "@type": "QuantitativeValue", minValue: employees.min, maxValue: employees.max }
        : null,
    iso6523Code: icd ? `${ICD_PREFIX[icd]}:${ids[icd]}` : null, // preferred over duns and leiCode
    globalLocationNumber: ids.gln,
    naics: ids.naics,
    vatID: ids.vatId,
    taxID: ids.taxId && ids.taxIdCountry === country ? ids.taxId : null, // must match the address country
    hasMerchantReturnPolicy: (source.returnPolicies || []).map(buildReturnPolicy),
    hasShippingService: (source.shippingServices || []).map(buildShippingService),
    hasMemberProgram: buildMemberProgram(source.loyaltyProgram)
  };

  // (e) Strip empty values.
  return compact(schema);
}

// Usage:
// const source = {
//   "url": "https://www.example.com/about",
//   "canonicalUrl": "https://www.example.com/about",
//   "indexable": true,
//   "contentVisible": true,
//   "pageRole": "about",
//   "kind": "online_store",
//   "siteName": "Trailhead Outfitters",
//   "alternateNames": [
//     "Trailhead"
//   ],
//   "legalName": "Trailhead Outfitters LLC",
//   "description": "Online retailer of hiking packs, tents and trail apparel, shipping from Massachusetts since 2014.",
//   "homeUrl": "https://www.example.com/",
//   "logo": {
//     "url": "https://www.example.com/images/logo-512.png",
//     "width": 512,
//     "height": 512
//   },
//   "profiles": [
//     "https://www.linkedin.com/company/example",
//     "https://www.instagram.com/example"
//   ],
//   "telephone": "+1-781-555-0190",
//   "email": "hello@example.com",
//   "address": {
//     "street": "50 Main Street",
//     "locality": "Waltham",
//     "region": "MA",
//     "postalCode": "02453",
//     "country": "US"
//   },
//   "contactPoints": [
//     {
//       "type": "customer support",
//       "telephone": "+1-781-555-0191",
//       "email": "support@example.com"
//     }
//   ],
//   "foundingDate": "2014-04-01",
//   "employees": {
//     "min": 40,
//     "max": 60
//   },
//   "identifiers": {
//     "lei": "5493001KJTIIGC8Y1R12",
//     "naics": "459110",
//     "taxId": "04-3456789",
//     "taxIdCountry": "US"
//   },
//   "returnPolicies": [
//     {
//       "countries": [
//         "US",
//         "CA"
//       ],
//       "returnToCountries": [
//         "US"
//       ],
//       "category": "finite",
//       "days": 30,
//       "methods": [
//         "mail",
//         "in_store"
//       ],
//       "fees": "free",
//       "label": "download",
//       "refundTypes": [
//         "full"
//       ],
//       "conditions": [
//         "new"
//       ],
//       "restockingFeePercent": 0
//     }
//   ],
//   "shippingServices": [
//     {
//       "name": "Standard shipping",
//       "description": "Free on orders of $75 or more within the US.",
//       "handlingDays": [
//         0,
//         1
//       ],
//       "cutoffTime": "14:00:00-05:00",
//       "conditions": [
//         {
//           "destinations": [
//             {
//               "country": "US"
//             }
//           ],
//           "originCountry": "US",
//           "currency": "USD",
//           "minOrderValue": 75,
//           "rate": 0,
//           "transitDays": [
//             2,
//             5
//           ]
//         }
//       ]
//     }
//   ],
//   "loyaltyProgram": {
//     "name": "Trail Rewards",
//     "description": "Earn points on every order and unlock member prices.",
//     "url": "https://www.example.com/rewards",
//     "tiers": [
//       {
//         "id": "https://www.example.com/rewards#base",
//         "name": "Base",
//         "benefits": [
//           "points"
//         ],
//         "pointsPerUnit": 1
//       },
//       {
//         "id": "https://www.example.com/rewards#summit",
//         "name": "Summit",
//         "benefits": [
//           "points",
//           "member_price"
//         ],
//         "pointsPerUnit": 2,
//         "requirement": {
//           "type": "spend",
//           "value": 500,
//           "currency": "USD"
//         }
//       }
//     ]
//   }
// };
// const schema = buildOrganizationSchema(source); // null when a gate or required property fails

The Output As An Entity Graph

The conditional-logic output above, parsed in your browser and drawn as the graph a crawler builds from it. Every nested object is a node and the property that holds it is the edge. Tap a node to inspect its properties, or drag to rearrange.

Why Conditional Logic Is Better Than Static Templates

  • Prevents emitting empty, null, or stale fields that frequently trigger rich result warnings.
  • Supports multiple page states (for example: no rating yet, no image yet, no offers yet) without duplicate templates.
  • Lets engineering teams centralize schema policy checks and validation in reusable code paths.
  • Makes large-scale schema maintenance safer when content models evolve over time.

Property Reference

What Google's Organization documentation requires and recommends, property by property. These are the same rules the SchemaCDN validator checks. Each name links to its schema.org definition.

Organization properties in Google's documentation
PropertyGoogleExpectsNotes
addressRecommendedPostalAddress, can repeatThe address (physical or mailing) of your organization.
address.streetAddressRecommendedTextThe street address.
address.addressLocalityRecommendedTextThe city or locality.
address.addressRegionRecommendedTextThe region, state or province.
address.postalCodeRecommendedTextThe postal code.
address.addressCountryRecommendedText or CountryThe country, as a two-letter ISO 3166-1 alpha-2 code.
alternateNameRecommendedText, can repeatAnother common name that your organization goes by, if applicable.
contactPointRecommendedContactPoint, can repeatThe best way for a user to contact your business.
contactPoint.emailRecommendedTextThe email address to contact your business.
contactPoint.telephoneRecommendedTextThe phone number to contact your business; include country and area code.
descriptionRecommendedTextA detailed description of your organization, if applicable.
dunsRecommendedTextThe Dun & Bradstreet DUNS number for identifying your Organization.
emailRecommendedTextThe email address to contact your business.
foundingDateRecommendedDateThe date your Organization was founded, in ISO 8601 date format.
globalLocationNumberRecommendedTextThe GS1 Global Location Number identifying the location of your Organization.
hasMemberProgramRecommendedMemberProgram, can repeatA loyalty program offered by your business.
hasMerchantReturnPolicyRecommendedMerchantReturnPolicy, can repeatThe return policy used by your business.
hasShippingServiceRecommendedShippingService, can repeatShipping policy information used by your business.
iso6523CodeRecommendedTextThe ISO 6523 identifier of your organization, as ICD:identifier.
legalNameRecommendedTextThe registered, legal name of your Organization, if applicable and different from name.
leiCodeRecommendedTextThe ISO 17442 identifier for your Organization.
logoRecommendedURL or ImageObjectA logo representative of your organization, at least 112x112px.
naicsRecommendedTextThe North American Industry Classification System (NAICS) code for your Organization.
nameRecommendedTextThe name of your organization.
numberOfEmployeesRecommendedQuantitativeValueThe number of employees in your Organization.
numberOfEmployees.valueRecommendedNumberExact number of employees.
numberOfEmployees.minValueRecommendedNumberMinimum of an employee range.
numberOfEmployees.maxValueRecommendedNumberMaximum of an employee range.
sameAsRecommendedURL, can repeatThe URL of a page on another website with additional information about your organization.
taxIDRecommendedTextThe tax ID associated with your Organization, matching the country in address.
telephoneRecommendedTextA business phone number meant to be the primary contact method for customers.
urlRecommendedURLThe URL of the website of your organization; helps Google uniquely identify it.
vatIDRecommendedTextThe VAT code associated with your Organization, if applicable.

Explore Other Schema Framework Pages

Retired Practice Problems Use for educational practice content that presents solvable problems and answer validation structure. Quiz Open Product Snippet Use for product pages where pricing, availability, and product identity are visible to users. Product Open Product Variants Use when one product comes in variants such as size or color, grouped with ProductGroup. ProductGroup Open Profile Page Use for creator or contributor profile pages where identity attributes and ownership are explicit. ProfilePage Open Q&A Use for pages where users submit questions and community or editorial answers are displayed. QAPage Open Recipe Use for recipe pages with complete ingredients, instructions, and preparation details. Recipe Open Return Policy Use to publish a merchant return policy once at the organization level, with offer-level overrides. MerchantReturnPolicy Open Review Snippet Use when a page publishes genuine reviews tied to a clearly identified product, service, or entity. Review Open Shipping Policy Use to publish shipping rates, delivery times and destinations once at the organization level. ShippingService Open Site Name Use on the home page so Google shows the preferred site name in search results. WebSite Open Retired Sitelinks Search Box Use on sites with a functioning internal search endpoint that can accept URL query parameters. WebSite Open Software App (Beta) Use for software product pages that describe platform support and application category clearly. SoftwareApplication Open Limited Speakable Use for news-style pages where specific text segments are appropriate for text-to-speech playback. SpeakableSpecification Open Subscription and Paywalled Content Use for pages with restricted sections so Google can distinguish free previews from protected content. CreativeWork Open Limited Vacation Rental Use for rental property detail pages where booking-relevant amenities and location signals are explicit. VacationRental Open Retired Vehicle Listing Use for inventory pages selling vehicles with standardized listing fields and offer information. Car Open Video Use for pages where a primary video is embedded and key media metadata is visible on-page. VideoObject Open Article Use for editorial pages where the visible content is a complete article with a clear byline and publication timestamps. Article Open Limited Book Actions Use when your page helps users read, preview, or purchase books through clearly described actions. Book Open Breadcrumb Use on pages that belong to a clear hierarchy and display navigational trail links users can follow. BreadcrumbList Open Carousel Use when a page lists multiple related entities in a scannable sequence that can be surfaced as cards. ItemList Open Course Use for educational offerings where curriculum details, provider identity, and delivery context are explicit. Course Open Dataset Use for dataset landing pages so datasets are discoverable in Google Dataset Search with license, creator and download details. Dataset Open Discussion Forum Use for forum and community threads where a primary post and subsequent replies are publicly visible. DiscussionForumPosting Open Limited Education Q&A Use for educational question-answer pages where a single canonical answer and supporting context are visible. Quiz Open Employer Aggregate Rating Use on pages that publish employer rating aggregates from a clear and policy-compliant review source. EmployerAggregateRating Open Retired Estimated Salary Use for compensation insight pages that present transparent salary ranges for specific occupations and locations. Occupation Open Event Use for upcoming events with a real-world or virtual occurrence, schedule, and location context. Event Open Retired Fact Check Use for fact-checking pages that evaluate a specific claim with a transparent rating methodology. ClaimReview Open Retired Home Activities Use for virtual classes and activities where participation details and timing are clearly listed. Event Open Retired How-To Use for instructional content that teaches a process through ordered steps and actionable detail. HowTo Open Image Metadata Use on image pages and image hosts that expose ownership and licensing information to search engines. ImageObject Open Job Posting Use for active job listings that include role details, hiring entity, and location/salary context. JobPosting Open Retired Learning Video Use for educational videos where the learning objective and pedagogical structure are explicit. LearningResource Open Local Business Use for physical businesses serving local customers with publicly verifiable contact and location details. LocalBusiness Open Loyalty Program Use to publish a loyalty program and its tiers once at the organization level, so member prices and member shipping can reference them. MemberProgram Open Math Solvers Use for pages that solve mathematical expressions and present step-by-step computational guidance. MathSolver Open Merchant Listing Use on pages where a product can be bought, with price, availability, shipping and return details. Product Open Limited Movie Use for movie detail pages with canonical film information and transparent metadata attribution. Movie Open

Implement Organization Schema Frameworks Correctly

Get implementation support for conditional schema architecture, validation, and deployment governance.