Course

Course markup describes an academic course, online training, professional certification, or any other structured learning resource. It powers Google's Course info rich result, which requires at least one hasCourseInstance entry describing a scheduled offering.

Abstract Course vs concrete CourseInstance

This is the most important lesson on this page. schema.org models an academic course as two separate entities. A Course is the abstract concept: "PED-412 is a graduate course in pediatric clinical frameworks." A CourseInstance is the specific scheduled offering: "PED-412, Fall 2026 semester, taught by Prof. Ana Jensen, meets Tuesdays and Thursdays 14:00 to 15:30 in Room 307." A single Course can have many CourseInstances across semesters.

Most authors conflate the two and lose the rich result. They put the scheduled dates and instructor directly on the Course entity instead of on a nested CourseInstance, which makes the course look like a one-time event and breaks the relationship Google needs. This example shows both entities in the correct relationship.

The Xoo universe thread

The example is PED-412: Post-War Clinical Frameworks in Pediatric Medicine, a graduate course at the Royal Institute of Medicine where students read Jane Xoo's 1945 paper as required material. It follows the schema.org/Course vocabulary. The provider references the EducationalOrganization example's RIM via @id, and the about property references the Article example: the course is literally about Jane Xoo's framework paper.

ISO 8601 durations, second angle

The timeRequired and courseWorkload properties both use ISO 8601 duration format, the same format taught in the Recipe example for cookTime and prepTime. But Course uses different letter codes because it measures longer periods: PT40H means 40 hours of contact time, P8W means 8 weeks elapsed, P1Y means 1 year. See the Common Mistakes section below for the full format breakdown.

Full example of schema.org/Course json-ld markup

The markup is verified as valid with Rich Results Test from Google.

Highlight legend:Required by GoogleRecommendedOptional
schema.org/Course
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@id": "https://roymed.dk/courses/ped-412#course",
  "@type": "Course",
  "name": "Post-War Clinical Frameworks in Pediatric Medicine",
  "alternateName": "PED-412",
  "courseCode": "PED-412",
  "description": "Graduate-level survey of clinical frameworks developed in response to post-conflict pediatric health crises. Uses Jane Xoo's 1945 Rigshospitalet framework as a primary case study, examining how structured triage protocols and nutritional rehabilitation benchmarks transformed post-war children's medicine across Scandinavia. Students analyze primary sources, participate in clinical simulation exercises, and complete a final paper applying the framework principles to a contemporary case.",
  "url": "https://roymed.dk/courses/ped-412",
  "image": [
    "https://roymed.dk/courses/images/ped-412-hero-1x1.jpg",
    "https://roymed.dk/courses/images/ped-412-hero-4x3.jpg",
    "https://roymed.dk/courses/images/ped-412-hero-16x9.jpg"
  ],
  "provider": {
    "@id": "https://roymed.dk#organization"
  },
  "about": {
    "@id": "https://roydanmedjournal.dk/archive/1945/pediatric-care-post-war-denmark#article"
  },
  "inLanguage": "en",
  "teaches": [
    "Historical analysis of post-conflict pediatric clinical frameworks",
    "Applied triage protocol design for pediatric populations",
    "Nutritional rehabilitation metrics and benchmark-driven care",
    "Primary source analysis of 20th century medical literature",
    "Translation of historical frameworks into contemporary practice"
  ],
  "educationalLevel": "Graduate",
  "educationalCredentialAwarded": {
    "@type": "EducationalOccupationalCredential",
    "credentialCategory": "Graduate course credit",
    "recognizedBy": {
      "@id": "https://roymed.dk#organization"
    }
  },
  "competencyRequired": "Completion of PED-301 (Introduction to Pediatric Medicine) or equivalent clinical background",
  "coursePrerequisites": [
    "PED-301: Introduction to Pediatric Medicine",
    "MED-250: History of 20th Century Medicine (recommended but not required)"
  ],
  "numberOfCredits": {
    "@type": "QuantitativeValue",
    "value": "6",
    "unitText": "ECTS credits"
  },
  "timeRequired": "PT40H",
  "totalHistoricalEnrollment": "487",
  "financialAidEligible": "Danish State Education Grants (SU), Nordic Council exchange grants",
  "availableLanguage": [
    "en",
    "da"
  ],
  "teachingLocation": {
    "@type": "Place",
    "name": "Royal Institute of Medicine, Room 307",
    "address": {
      "@type": "PostalAddress",
      "streetAddress": "Blegdamsvej 9",
      "addressLocality": "Copenhagen",
      "postalCode": "2100",
      "addressCountry": "DK"
    }
  },
  "keywords": "pediatric medicine, clinical frameworks, post-war medicine, Jane Xoo, medical history, triage protocols, nutritional rehabilitation",
  "offers": {
    "@type": "Offer",
    "category": "subscription",
    "price": "18500",
    "priceCurrency": "DKK",
    "availability": "https://schema.org/InStock",
    "priceValidUntil": "2026-12-31",
    "description": "Per-semester tuition for non-RIM-enrolled international students. RIM degree students take this course as part of their regular tuition."
  },
  "hasCourseInstance": [
    {
      "@type": "CourseInstance",
      "@id": "https://roymed.dk/courses/ped-412/fall-2026#instance",
      "name": "PED-412 — Fall 2026",
      "courseMode": "Blended",
      "courseWorkload": "P8W",
      "startDate": "2026-09-07",
      "endDate": "2026-11-30",
      "location": {
        "@type": "Place",
        "name": "Royal Institute of Medicine, Room 307",
        "address": {
          "@type": "PostalAddress",
          "streetAddress": "Blegdamsvej 9",
          "addressLocality": "Copenhagen",
          "addressCountry": "DK"
        }
      },
      "instructor": {
        "@type": "Person",
        "name": "Prof. Ana Jensen, MD PhD",
        "jobTitle": "Associate Professor of Pediatric Medicine",
        "worksFor": {
          "@id": "https://roymed.dk#organization"
        }
      },
      "courseSchedule": {
        "@type": "Schedule",
        "repeatFrequency": "P1W",
        "byDay": [
          "https://schema.org/Tuesday",
          "https://schema.org/Thursday"
        ],
        "startTime": "14:00",
        "endTime": "15:30"
      },
      "inLanguage": "en",
      "maximumAttendeeCapacity": "24"
    },
    {
      "@type": "CourseInstance",
      "@id": "https://roymed.dk/courses/ped-412/spring-2027#instance",
      "name": "PED-412 — Spring 2027",
      "courseMode": "Blended",
      "courseWorkload": "P8W",
      "startDate": "2027-02-01",
      "endDate": "2027-04-25",
      "instructor": {
        "@type": "Person",
        "name": "Prof. Lars Mikkelsen, MD",
        "jobTitle": "Professor of Pediatric Clinical History",
        "worksFor": {
          "@id": "https://roymed.dk#organization"
        }
      },
      "inLanguage": "en",
      "maximumAttendeeCapacity": "24"
    }
  ],
  "isAccessibleForFree": false,
  "copyrightHolder": {
    "@id": "https://roymed.dk#organization"
  },
  "audience": {
    "@type": "EducationalAudience",
    "educationalRole": "Graduate medical student, pediatric resident, medical historian"
  }
}
</script>

Rich result preview

Approximate preview of what Google may render from this markup. Hover any element inside the card to see which JSON-LD path produced it. Google decides whether to show any rich result. Markup makes you eligible, not guaranteed.

google.com/search?q=post-war%20clinical%20frameworks%20in%20pediatri%20course
(course image)

Post-War Clinical Frameworks in Pediatric Medicine

Royal Institute of Medicine
Graduate8 weeks workloadBlendedStarts Sep 7, 202618500 DKK

Graduate-level survey of clinical frameworks developed in response to post-conflict pediatric health crises. Uses Jane Xoo's 1945 Rigshospitalet framework as a

Minimal valid version

The smallest markup that still produces a valid Course entity. Use it as the floor. Reach for the advanced example above when you want search engines and AI agents to understand more about your content.

schema.org/Course (minimal)
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "Course",
  "name": "Post-War Clinical Frameworks in Pediatric Medicine",
  "description": "Graduate-level survey of clinical frameworks developed in response to post-conflict pediatric health crises.",
  "provider": {
    "@type": "CollegeOrUniversity",
    "name": "Royal Institute of Medicine",
    "url": "https://www.roymed.dk/"
  },
  "hasCourseInstance": [
    {
      "@type": "CourseInstance",
      "courseMode": "Blended",
      "courseWorkload": "P8W",
      "startDate": "2026-09-07",
      "endDate": "2026-11-30"
    }
  ],
  "offers": {
    "@type": "Offer",
    "price": "18500",
    "priceCurrency": "DKK"
  }
}
</script>

Google rich results this unlocks

Markup matching this example makes your page eligible for the following Google Search rich results. The primary target drives the required / recommended property classification in the advanced code block above.

Common Course mistakes

Mistakes that pass validation but silently fail to earn rich results or mislead consumers walking the graph. Avoid these and your markup will be ahead of most sites in the wild.

  1. 01

    Course with no hasCourseInstance

    Wrong
    Course markup that describes the course abstractly with no CourseInstance entries
    Right
    "hasCourseInstance": [
      {
        "@type": "CourseInstance",
        "courseMode": "Blended",
        "courseWorkload": "P8W",
        "startDate": "2026-09-07",
        "endDate": "2026-11-30"
      }
    ]

    Google's Course info rich result requires at least one CourseInstance. Without hasCourseInstance, your Course markup validates as schema but is completely ineligible for the rich result. CourseInstance represents a specific scheduled offering (Fall 2026 section, Spring 2027 section, etc.) as distinct from the abstract Course itself. A Course with no instances is unshippable from Google's perspective because users can't enroll in anything.

  2. 02

    timeRequired or courseWorkload as a plain string

    Wrong
    "timeRequired": "40 hours"
    "courseWorkload": "8 weeks"
    Right
    "timeRequired": "PT40H"
    "courseWorkload": "P8W"

    Both timeRequired and courseWorkload use ISO 8601 duration format, the same format used by Recipe's cookTime/prepTime/totalTime. The letter codes differ slightly: P starts the period, then optional year (Y), month (M), week (W), day (D), then an optional T followed by hour (H), minute (M), second (S). Examples: PT40H = 40 hours, P8W = 8 weeks, P1Y = 1 year, P3M = 3 months, P1DT8H = 1 day and 8 hours. Google parses these to show 'Workload: 8 weeks' in the Course rich result; plain strings are silently dropped from the display.

  3. 03

    coursePrerequisites as free text when a structured Course reference exists

    Wrong
    "coursePrerequisites": "Completion of PED-301"
    Right
    "coursePrerequisites": {
      "@type": "Course",
      "name": "Introduction to Pediatric Medicine",
      "courseCode": "PED-301",
      "url": "https://roymed.dk/courses/ped-301"
    }

    coursePrerequisites accepts either text, a Course reference, or an AlignmentObject. If the prerequisite is another course on your own site, prefer the Course reference (or an @id to an existing Course entry) over free text. This lets Google and knowledge graphs walk the prerequisite chain and gives users a clickable link to the prerequisite course. Free text is fine when the prerequisite is a general skill or external credential, but always prefer structure when structure exists.

  4. 04

    Confusing Course with CourseInstance

    Wrong
    Treating a specific fall 2026 offering as a top-level Course with its own startDate and instructor
    Right
    A single Course with the abstract description, plus a hasCourseInstance array listing each concrete offering as a CourseInstance with its own startDate, endDate, instructor, location, and courseMode

    Course is the abstract concept (PED-412 as a discipline, taught over many semesters across many years). CourseInstance is the specific scheduled offering (PED-412, Fall 2026, taught by Prof. Jensen, meets in Room 307). Mistakes conflate them by putting startDate/endDate/instructor on the Course itself. This makes the course appear to be a one-time event, breaks the hasCourseInstance relationship Google needs for its rich result, and loses the ability to list multiple sections of the same course. Always: Course = abstract, CourseInstance = concrete scheduled offering, hasCourseInstance links them.

Compare your markup against this exampleruns in your browser
Private. Runs entirely in your browser.

Comments

Loading comments...

Leave a comment