Open Badges Specification

Base Document
Spec Version 3.0
Base Document
Document Version: 1.0
Date Issued: May 27, 2022
Status: This document is for review and comment by 1EdTech Contributing Members.
This version: https://www.imsglobal.org/spec/ob/v3p0/main/
Latest version: https://www.imsglobal.org/spec/ob/latest/main/
Errata: https://www.imsglobal.org/spec/ob/v3p0/errata/
Issue Tracker
https://github.com/IMSGlobal/openbadges-specification/issues

IPR and Distribution Notice

Recipients of this document are requested to submit, with their comments, notification of any relevant patent claims or other intellectual property rights of which they may be aware that might be infringed by any implementation of the specification set forth in this document, and to provide supporting documentation.

1EdTech takes no position regarding the validity or scope of any intellectual property or other rights that might be claimed to pertain implementation or use of the technology described in this document or the extent to which any license under such rights might or might not be available; neither does it represent that it has made any effort to identify any such rights. Information on 1EdTech's procedures with respect to rights in 1EdTech specifications can be found at the 1EdTech Intellectual Property Rights webpage: http://www.imsglobal.org/ipr/imsipr_policyFinal.pdf .

The following participating organizations have made explicit license commitments to this specification:

Org name Date election made Necessary claims Type
Concentric Sky October 24, 2019 No RF RAND (Required & Optional Elements)
Digital Knowledge October 11, 2019 No RF RAND (Required & Optional Elements)
Washington State Board for Community and Technical Colleges (WSBCTC) October 4, 2019 No RF RAND (Required & Optional Elements)
Credly October 3, 2019 No RF RAND (Required & Optional Elements)

Use of this specification to develop products or services is governed by the license with 1EdTech found on the 1EdTech website: http://www.imsglobal.org/speclicense.html.

Permission is granted to all parties to use excerpts from this document as needed in producing requests for proposals.

The limited permissions granted above are perpetual and will not be revoked by 1EdTech or its successors or assigns.

THIS SPECIFICATION IS BEING OFFERED WITHOUT ANY WARRANTY WHATSOEVER, AND IN PARTICULAR, ANY WARRANTY OF NONINFRINGEMENT IS EXPRESSLY DISCLAIMED. ANY USE OF THIS SPECIFICATION SHALL BE MADE ENTIRELY AT THE IMPLEMENTER'S OWN RISK, AND NEITHER THE CONSORTIUM, NOR ANY OF ITS MEMBERS OR SUBMITTERS, SHALL HAVE ANY LIABILITY WHATSOEVER TO ANY IMPLEMENTER OR THIRD PARTY FOR ANY DAMAGES OF ANY NATURE WHATSOEVER, DIRECTLY OR INDIRECTLY, ARISING FROM THE USE OF THIS SPECIFICATION.

Public contributions, comments and questions can be posted here: http://www.imsglobal.org/forums/ims-glc-public-forums-and-resources .

© 2022 1EdTech™ Consortium, Inc. All Rights Reserved.

Trademark information: http://www.imsglobal.org/copyright.html

Abstract

This specification is a new version of the 1EdTech Open Badges Specification that aligns with the conventions of the Verifiable Credentials Data Model v1.1 for the use cases of Defined Achievement Claim and a Skill Claim. The credentials that are produced are easily be bundled into Comprehensive Learner Records and Verifiable Presentations. Portability and learner data privacy are improved by expanding the usage of cryptographic proofs/signatures, because this format will be compatible with a growing array of proof schemas that are developed for the Verifiable Credentials Data Model.

1. Introduction

1.1 Audiences

The target readers for this document are:

1.2 Document Set

The Open Badges Specification has several related documents and artifacts shown below. Together they make up the specification.

1.2.1 OpenAPI 3.0 Files

The Open API Specification (OAS) defines a standard, programming language-agnostic interface description for HTTP APIs, which allows both humans and computers to discover and understand the capabilities of a service without requiring access to source code, additional documentation, or inspection of network traffic. When properly defined via OpenAPI, a consumer can understand and interact with the remote service with a minimal amount of implementation logic. Similar to what interface descriptions have done for lower-level programming, the OpenAPI Specification removes guesswork in calling a service.

-- OpenAPI Specification

1.2.2 JSON-LD Context File

When two people communicate with one another, the conversation takes place in a shared environment, typically called "the context of the conversation". This shared context allows the individuals to use shortcut terms, like the first name of a mutual friend, to communicate more quickly but without losing accuracy. A context in JSON-LD works in the same way. It allows two applications to use shortcut terms to communicate with one another more efficiently, but without losing accuracy.

Simply speaking, a context is used to map terms to IRIs. Terms are case sensitive and any valid string that is not a reserved JSON-LD keyword can be used as a term.

-- JSON-LD 1.1

1.2.3 JSON Schema

All JSON Schema can be found in § E.2 JSON Schema. JSON Schema files for credential and API schema verification are available online:

1.3 Conformance Statements

As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.

The key words MAY, MUST, MUST NOT, NOT RECOMMENDED, NOT REQUIRED, OPTIONAL, RECOMMENDED, REQUIRED, SHALL, SHALL NOT, SHOULD, and SHOULD NOT in this document are to be interpreted as described in [RFC2119].

An implementation of this specification that fails to implement a MUST/REQUIRED/SHALL requirement or fails to abide by a MUST NOT/SHALL NOT prohibition is considered nonconformant. SHOULD/SHOULD NOT/RECOMMENDED statements constitute a best practice. Ignoring a best practice does not violate conformance but a decision to disregard such guidance should be carefully considered. MAY/OPTIONAL statements indicate that implementers are entirely free to choose whether or not to implement the option.

The Conformance and Certification Guide for this specification may introduce greater normative constraints than those defined here for specific service or implementation categories.

1.4 Terminology

1.5 Conceptual Model

This conceptual model describes Open Badges concepts and the relationship between those concepts. The data model in appendix § B.1 Credential Data Models below is the normative reference for the classes and properties that are used to implement the concepts.

The conceptual model is targeted for all § 1.1 Audiences, while the data model is targeted for Solution Architects and Product Developers.

In the diagram below, the concepts are shown in gray boxes (e.g. Assertion). Please see § 1.4 Terminology for definitions of the concepts.

Starting with this version of the Open Badges Specification, an Assertion is also a Verifiable Credential (VC) as defined by the Verifiable Credentials Data Model v1.1 specification. The diagram includes labels that show the relationships between VC terminology and Open Badges terminology (e.g. Issuer is identified by the VC "issuer").

Diagram show the major conceptual components of an Open Badge Verifiable Credential
Figure 1 Diagram show the major conceptual components of an Open Badge Verifiable Credential

2. Overview

This section is non-normative.

2.1 What is the problem this solves for?

Verifiable Credentials (VCs) are a format that is used to publish a limitless variety of claims about a subject person or other entity, typically through a cryptographic proof. VCs can be collected and delivered as part of a presentation whereby authorship of each VC from the same or multiple issuers can be trusted via cryptographic verification.

These layers of cryptographic proof can provide security and privacy enhancements to Open Badges that were not available in version 2.0. Adoption of Verifiable Credentials will increase market penetration and use of Open Badges by addressing market needs for trustworthy machine-ready data to power connected ecosystems in education and workforce. This will unlock the door for Open Badges credentials to be included in a growing number of multi-purpose digital credential wallets entering the market. Stepping further into signed VCs and another associated technology, Decentralized Identifiers (DIDs) v1.0, unlocks increased longevity and resilience of Open Badges that can describe achievements even more expressively than they do today.

2.2 What does adopting Verifiable Credentials entail?

This specification changes the structure of the Open Badges Assertion class, to adopt the conventions of the Verifiable Credentials Data Model v1.1. This means that badges issued under this specification will not be conformant to all of the existing 2.x data model requirements.

Previous versions of an Open Badges Assertion, illustrated in the graphic below, structures its objects like this: An Assertion identifies a recipient with a "recipient" relationship to an IdentityObject that contains identifying properties. It identifies which badge it represents with a "badge" relationship to a BadgeClass. It identifies its verification information with a "verification" relationship to a VerificationObject. It identifies its issuer with an "issuer" relationship between the BadgeClass and the Issuer.

Open Badges 2.0 Diagram
Figure 2 Open Badges 2.0 Diagram

The Verifiable Credentials structure in this specification depicted below offers the same information with a slightly different structure: A Verifiable Credential identifies its recipient with a "credentialSubject" relationship to a subject class that is identified by an identifier. It identifies its issuer with an "issuer" relationship directly to an Issuer. The Credential claims the subject has met the criteria of a specific Achievement (also known as the BadgeClass in previous versions) with an "achievement" relationship to that defined achievement. And it identifies its verification information with a proof.

Diagram show the major conceptual components of an Open Badge Verifiable Credential
Figure 3 Diagram show the major conceptual components of an Open Badge Verifiable Credential

2.3 Benefits and Opportunities

It can be risky to make breaking changes to a specification used as broadly as Open Badges, but there are a range of benefits to making this move now while the Verifiable Credentials ecosystem is young and growing fast. There are strong use cases for digital credentials for learning and skill achievements across the nexus of education and employment, as we have seen from the broad adoption of Open Badges and the proliferation of industry groups making connections between educational institutions and the employment market around digital credentials. Technical compatibility is in a more favorable position when faced with rapid ecosystem growth than competition between large communities issuing these learning credentials and other communities focused on different market verticals from government identity documents, commercial payments, and international trade, to name a few.

This specification opens a path forward for a unified concept of digital credentials in the 1EdTech community, collapsing the relevant differences between Open Badges and Comprehensive Learner Record (CLR), and addressing a clear set of single achievement use cases with a robust, flexible, and future-proof solution that can easily be integrated with the set-of-multiple credentials use cases familiar to CLR.

Below, we present a selection of benefits related to this restructuring of Open Badges, and compare the opportunities opened by becoming compatible with Verifiable Credentials to the limitations that the Open Badges community has encountered with previous versions of Open Badges and CLR.

2.3.1 Interoperability with Digital Wallets, Verifiable Presentations, and Learner Experiences

Open Badges as VCs are designed to be issued and offered to learners who may accept them into their digital wallet. Wallets are software that runs on either the web or as a native app on a mobile device or desktop environment. A web wallet is another term to describe the application role known under [OB-20] as a "Host". There is an existing and growing ecosystem of deployed technology to support VCs; integration with these becomes possible with this specification. For example, a number of generic Verifiable Credential wallet implementations are available from a variety of vendors as native mobile apps. From a wallet, recipients may package their badges along with their other VCs into verifiable presentations. A presentation contains the credentials that the learner wishes to share with a relying party. The digital wallet application digitally signs the presentation using the key of the learner. The verifying third-parties can cryptographically verify that the presentation came unmodified directly from the credential holder as well as the integrity of each of the VCs included in the presentation as credentials signed by each of their respective issuers.

It is possible from a wallet to package credentials into a verifiable presentation in response to a request from a relying party who seeks credentials for a certain purpose. For example, a potential employer seeking to fill an internship role, may need to verify that a student is over 18, has completed a course on communication, and is a current student. A student could use their wallet to package three VCs (driver's license, course completion badge, and student ID) into a presentation that is signed by their private key. When the presentation is sent to the employer's website, the employer can verify that the VCs belong to the student and that the VCs are authentic.

The growing collection of VC wallets is an example of how adopting a Verifiable Credentials-based approach allows Open Badges to grow in impact and take advantage of existing momentum in the digital credentials space around tooling that is entering the market and heading towards maturity.

2.3.2 Verifiable Credentials Support Increases Learner Data Privacy and Trustworthiness of Open Badges

The Verifiable Credentials Data Model v1.1 specification describes how technologies can be used to present cryptographically verifiable and tamper-evident claims. Verifiable Credentials (VCs) can be verified through up-to-date and broadly interoperable schemas for verification. This can provide security and privacy enhancements to 1EdTech Open Badges that are not available in Open Badges 2.0.

Currently, Open Badges 2.0 data can be verified via either (a) publicly accessible hosted JSON badge data or (b) JWS digitally signed badges with a limited number of algorithms and key types, depending on the verification method chosen by the issuer. In order to keep up with evolving cryptographic standards without taking on the burden of writing cryptographic suites as a community not specializing in that function, adopting Verifiable Credentials proofs will allow experts to update algorithms to keep up with improvements to cryptography-breaking processing power.

Publicly hosted badge data has been the preferred method of many Open Badges issuers. This method can risk the privacy of badge recipients who are reliant on the issuers to host their data leaving them with no direct control over its accessibility. There is also the potential that data about individuals is publicly accessible without their knowledge. Most Open Badges don't contain significant amounts of personally identifiable information, but they are subject to correlation. This could lead to on-site identification, email spam, and also cause badges to be correlatable with other personally identifying data on the web.

Hosted badge data is also not tamper-evident since it is hosted on web servers typically as dynamically-generated JSON files populated by queries made to relational databases or static JSON files. This makes the data easy to change without any historic reference or preservation. This can be convenient for issuers but not assuring for relying third-parties seeking to put the data to use. Changes to badge metadata such as criteria, the issue date, and recipient email can reduce the perceived quality of data and reflect incorrect information about the learners' experiences. Digitally signed 2.0 badges provide more assurances and privacy than the hosted badges but are not commonly issued and are not interoperable with VC wallets.

There's been very little evidence that badge JSON data has been readily consumed by machines, but technologies and the education and workforce markets have evolved since Open Badges v2.0 was released in 2018. Machine learning and AI uses have expanded alongside blockchain and other decentralized technologies creating opportunity for connecting learners to opportunities, more accurate skills-based hiring, and updated curricula more equitably reflecting the needs of students. The market is demanding that the achievement data be trustworthy. This means that it should be accessible, protected, have integrity, and communicate what was intended including that the issuer and subjects of the data can be authenticated and that the data has not been tampered with since it was issued. Shifting Open Badges to align with the VC conventions to verify learner achievements meets these expectations and provides learners with more agency over their achievement data by giving them immediate access to it for as long as they need it, allowing them to choose which data they share, protecting it, and making it work with other credentials in and outside of education and workforce.

2.3.3 Decentralized Identifiers and Self-Sovereign Identity

With Open Badges up to 2.0, email addresses have been used as identifiers far more commonly than the other available options. This has been problematic because email addresses may be used by more than one person, are often revoked when an individual leaves a job or school, are insecure, and aren't intended to be identifiers. Identifiers in VCs commonly are HTTP-based URLs, follow another scheme of IRI, or take the form of a Decentralized Identifier.

Decentralized identifiers (DIDs) [DID-CORE] are a type of identifier for people, organizations and any other entity, where each identifier is controlled independently of centralized registries. Each DID can be resolved through an operation described by its particular "DID Method" to reveal a DID document that describes the subject. Whereas previous versions of Open Badges required HTTP(s) identifiers for issuers and typically used email (or rarely URL) identifiers for learners, adoption of the Verifiable Credentials Data Model provides simple conventions for badge issuers and recipients to begin to use DIDs when they desire.

Verification of control of identifiers is an important concept within any type of digital credential, both with respect to the issuer and the subject (recipient) of the credential. For issuers, Open Badges has relied on its own bespoke rules for determining whether a hosted Assertion URL or cryptographic key URL is associated with an issuer profile identified by a particular URL. URLs used for recipient identifiers have no built-in mechanism for authentication. Email and telephone number based recipient identifier authentication are up to the relying party, but there are common methods for performing this task essential to establishing trusted proof of control of credentials presented by a subject.

DIDs typically offer cryptographic proof of control, based on authorized keys or other verification methods expressed in the associated DID Document. While these protocols are not broadly implemented across domains today, the structure provides a forward-looking flexible and extensible mechanism to build the types of protocols needed to connect credentials back to the identities of their issuers and subjects. The Open Badges community may ultimately recommend use of only a small number of these capabilities in early releases or recommend them only for experimental use, like with cryptographic proof methods. But this is still an important step, because there is no reason for the Open Badges community to be closed to interoperability through the protocols being developed for use by the wallets and services coming into being elsewhere by delaying the option to use DIDs for recipient and issuer identifiers.

2.3.4 Aligning Open Badges and CLR with Common Assertion and Achievement Models

As described below, it is possible for Open Badges and CLR to produce coordinated specs particularly if both specs are aligned with Verifiable Credentials. Discussion of the components of individual achievements can occur within the Open Badges workgroup, and discussion of more complex use cases necessitating needs for bundling and association of multiple achievements on behalf of a publisher can occur within the CLR group. The cross-pollination of members of each effort will create opportunities to coordinate and ensure that all important use cases for single assertions and bundles of associated assertions are well-handled. The openness of the Open Badges Specification can be preserved so that the broader community can continue to be aware of and connected to the official developments.

At the core, Open Badges and CLR have similar objectives with the primary difference being single vs a collection of credentials. A common assertion model ensures that Open Badges can be included in CLR collections and that both CLRs and Open Badges can be held separately by learners in their Verifiable Credential wallets.

Both Open Badges and CLR make assertions about achievements and conceptually share many similar properties. With some judicious analysis and renaming of some properties, it has been possible to have cross-alignment of achievement properties served by Open Badges and used by CLR. Examples include but are not limited to achievementType which describes the type of achievement being represented, and Result/ResultDescription which can describe possible levels of mastery associated to specific achievements. This will enrich Open Badges data and increase the perceived significance and usage of Open Badges to deliver verifiable single achievements such as certifications, licenses, courses, etc. Using a common model across [OB-30] and [CLR-20] specifications for the core ideas of assertion and achievement will enable the CLR specification to focus on the more complex requirements of bundling collected assertions and expressing the associations between the achievements.

2.3.5 Differentiating Issuers and Creators

In Open Badges and CLR, the issuer is assumed to be the creator. Over the years, the Open Badges community has requested capabilities to distinguish between the issuer and creator of a badge. This is because there are plenty of examples where the assessor is the issuer but not the creator of the badge. The Original Creator Extensions is a step in this direction but provides no properties to describe the eligibility of issuers trusted by the original creator to duplicate and issue their own assertions of the badge.

In order to open up a wide swath of use cases for shared issuing responsibility of common credentials, we must do more. Conveniently, an issuer property for the entity that is digitally signing the credential is included in the VC assertion. Because of this, the issuer property referenced in the Achievement/BadgeClass is redundant. This property is a logical placement for new properties to describe a creator(s) and the eligibility of potential outside issuers to share or have delegated responsibility for badge issuance. This will enable the use cases and give relying third-parties more contextual information about the achievement and the parties involved.

2.4 Skill Assertions

Many of the use cases for Open Badges and CLR involve describing "defined achievements" with the Achievement/BadgeClass data class. These achievements may sometimes be aligned to skills or competencies, as a means of indicating that those who earn them have achieved the aligned skills. In this specification, we also introduce the concept of a Skill Assertion, showing how the Open Badges Specification can be expanded to assert achievement of single skills in a more flexible manner that is complementary to these use cases and that opens up a wide range of new use cases. A Skill Assertion offers a lightweight structure for issuers to make a claim that a learner has a skill, with a particular assessment result if desired.

A Skill Assertion is an Open Badges assertion that contains a "skill result." The idea of a skill result fits perfectly with the concept from CLR of a Result that is paired against the ResultDescription defined in an Achievement/BadgeClass, but a skill result targets a skill that may have been defined by a third-party organization, such as an industry group. This is a separate claim that may be composed alongside an achievement claim that identifies which Achievement/BadgeClass criteria has been met, or it could appear in an Open Badges Verifiable Credential without the defined achievement claim. This means that an issuer could easily make an assertion that a learner has achieved the criteria of a certain badge, or that they have achieved a specific skill, or both (whether or not the skill is specifically identified in the alignments of the badge).

The following diagram shows how these concepts are connected for a use case in which an issuer asserts that a credential subject has achieved a particular skill, using a "results" claim to establish a relationship with a Result class that identifies which skill is recognized and may describe other aspects of the skill achievement, such as the level at which it was assessed and a degree of confidence. Specific use cases for how this data needs to be consumed will drive the specific skill-specific properties of the Result class that may be added to give issuers the options they need. In this example, a Skill Definition that is identified by a unique URL at which information about the skill is published is referenced by the Result. This pattern, named by the Open Skills Network as a Rich Skill Descriptor (RSD), makes it possible for skills to be precisely referenced in other entities, such as credentials. Here, the RSD was published by an industry organization, and included in this credential by a different issuer. There is no need for the skill author and the credential issuer to have a pre-existing or discoverable relationship in order for a Skill Assertion to be valid. Evidence may also be included, just like in any Assertion.

Skill Assertion with Evidence Diagram
Figure 4 Skill Assertion with Evidence Diagram

The notion of skill results can be combined with a defined achievement assertion claim "achievement". In this example, the same Skill Assertion appears, but additional criteria that the learner has met is described in the Achievement/BadgeClass as in many of our other examples. The Achievement aligns to the same skill that is recognized, but the Result allows the issuer to describe specifics about the assessment results relative to the skill.

Defined Achievement Assertion with Skill Result Diagram
Figure 5 Defined Achievement Assertion with Skill Result Diagram

The inclusion of Skill Assertion claims makes a natural, ergonomic fit with defined achievement claims and evidence claims. Business logic to process each of the available claims can look for just the data a relying party needs, and extraneous claims do not get in the way.

3. Use Cases

This section is non-normative.

The use cases below drive the design of Open Badges 3.0 specification.

3.1 Assertion Issuance to Wallet

Maya has completed an online course for an "Introduction to Web QA" at her local community college. The community college issues a course completion assertion. When Maya is ready to accept the assertion, she presents her wallet's location to the community college, which generates a request that Maya approves to receive the credential. Maya stores the assertion in her Verifiable Credentials enabled digital wallet with her other credentials.

Goal of the Primary Actor: Issue a verifiable credential to a student that she can use to take the next steps in her education journey.

Actors: Community college, Maya (student)

Preconditions for this Use Case:

Flow of Events:

  1. Maya completes course requirements, receives a grade and is marked as complete for the "Introduction to Web QA" course.
  2. Maya provides or selects an identifier to use as her identifier for badges while enrolled at the community college, and proves the identifier represents her to the college if necessary, and through mechanisms appropriate to the identifier type.
  3. The community college issues an assertion of the previously defined achievement to Maya's identifier and cryptographically signs it
  4. Maya accepts the credential into her wallet.

Alternative Flows:

3.2 Assertion Issuance Without a Wallet

A professional development/training vendor Training, Inc. recognizes Dawson's mastery of a competency by issuing an assertion to Dawson's email address.

Goal of the Primary Actor: Training, Inc. wishes to provide a verifiable record that Dawson may use to present proof of competency-based professional development.

Actors: Training, Inc (professional development/training vendor), Dawson (student)

Preconditions for this Use Case:

Flow of Events:

  1. Dawson authenticates to the vendor platform, proving control of a chosen email address.
  2. Dawson connects a Badge Connect backpack to the vendor platform, resulting in the platform holding an auth token on his behalf scoped to allow pushing assertions to his backpack.
  3. Dawson engages with a learning opportunity, gains new knowledge, skills, and abilities, and successfully completes an assessment demonstrating mastery of a specific competency.
  4. Training, Inc. creates an assertion of the achievement that recognizes the competency.
  5. Training, Inc. transmits the assertion to Dawson's backpack via Badge Connect API.

Alternative Flows:

3.3 Recipient Presentation of Assertion

Maya registers for an advanced course and she is asked to provide proof that she completed a prerequisite course. From her wallet, Maya presents the course assertion as a verifiable presentation to the MOOC, which cryptographically verifies the issuer of the assertion, that Maya is the recipient, and that the assertion data has not been altered since it was issued. Upon verification, she is registered for the MOOC.

Editor's note
New to v3.0: Verifiable Credentials (VC) is a W3C specification that describes how to issue tamper-evident credentials that can be cryptographically verified. Maya's digital wallet has the capabilities to create a DID, read the VC data, and store it. From the wallet, Maya can present her credentials and prove that she is the recipient because it was issued to a DID that she created and has the digital keys that demonstrates her control of the Verifiable Credential (VC). This functionality is not specific to the Open Badges standard but using this verification functionality and using a decentralized identifier (DID) to identify the badge recipient instead of an email address is part of the v3.0 update. Maya's badge recognizes a course completion and being able to specify that in the badge is a new aspect of v3.0. As with the CLR, v3.0 will be able to specify the type of achievement that a badge is representing.

Goal of the Primary Actor: Register for advanced "Web QA" course

Actors: Maya, MOOC

Preconditions for this Use Case:

Flow of Events:

  1. Maya authenticates to the MOOC platform
  2. The MOOC platform requests a credential matching a certain criteria (completion of a prerequisite course option)
  3. Maya prepares and transmits a presentation of her assertion to the MOOC platform
  4. The MOOC platform verifies the assertion is valid and fitting its needs
  5. The MOOC platform grants the authenticated user Maya access to the advanced course

Points of Failure:

3.4 License Issuance

After Jeremy takes his electrician licensure exam, he accesses the online system for his state's licensure department to see his results and download his license. After he proves his identity by presenting his government issued ID from his digital wallet, he is informed that he passed the exam. The electrician license badge is issued to the DID Jeremy provided and is stored in his digital wallet with his other digital credentials.

Editor's note
New to v3.0: Similar to Maya's course completion badge, Jeremy's electrician license badge is also issued to a DID that Jeremy provides from his wallet and can also be cryptographically verified following the Verifiable Credentials model. The government issued ID in this use case is not an Open Badge but because it is a Verifiable Credential it can be stored in the same wallet as the electrician's license badge demonstrating interoperability of the verification models.

3.5 Single Skill Assertion

From her school's LMS, Dr. Cara chooses which skills and competencies will be taught in her class. These skills and competencies are aligned with the rubric in the syllabus that is presented to her students. Once the students have successfully completed the course, Dr. Cara assesses each student's assignments and participation and selects which skills and competencies were met and at what level. The selection of skills and competencies triggers an issuing of a skill assertion for each one and includes the assessment results in the evidence and results. The skill assertions are associated with the student's IDs, the students are notified and informed how they can use these skill assessments to inform their choice of classes in the future.

Editor's note
New to v3.0: Single skill assertions are new to 3.0.

3.6 Mapping Skills

Syd is shifting careers after many years working in construction. In their digital wallet they had several skill badges describing their mastery of skills in construction but also in teamwork, communication, and organizational skills. Syd also had badges from some courses they'd taken in science and math over the last few years. After they uploaded the skill and course badges from their wallet to a career planning site, they were offered several opportunities to apply for work in software sales and cybersecurity.

3.7 Verifying Continuing Education

Denise was offered a new job at a hospital as a physician's assistant. Before starting, her continuing education training and license to practice needed to be verified. The last time she switched hospitals, the verification process took three weeks. This time, she was able to provide her badges to prove her training and license. Within minutes her credentials were verified and she was issued a new digital staff credential.

Editor's note
New to v3.0: As with the other use case, this use case emphasizes that Open Badges v3.0 can recognize many different achievement types and be cryptographically verified following the Verifiable Credentials model.

3.8 Self-assertion

Stacy has created a mobile app that demonstrates her abilities as a coder, designer, and product manager. She creates an account on a badging platform and designs the badge to include alignments to the skills that the badge recognizes. With her digital wallet app, she connects to the badging platform and issues this badge to herself which includes screenshots and a link to the mobile app as evidence. Stacy uses this badge and others like it as verifiable portfolio items.

Editor's note
New to v3.0: In previous versions of Open Badges, it was possible to make self-assertion badges and issue badges to peers, however the issuer profile properties were organization specific. With 3.0, the issue properties can be modified to reference either an organization or an individual. It could be considered that both the issuer and recipient profile have similar optional properties so that there is flexibility in describing both profiles. This way, an organization could also be described as the recipient.

3.9 Endorsement

Ralph has been issued a verifiable credential badge for his most recent position at the hospital where he works by the hospital. The badge contains alignments to the skills related to his role. He requests that his peers endorse the skills he has acquired. A platform is able to communicate this request to peers, facilitate review of the skills, and process the issuance of endorsement VC badges that reference the original badge, colleagues as endorsers, and Ralph as the recipient.

Editor's note
New to v3.0: In 2.0, an endorsement is its own type of assertion. In 3.0, an endorsement is its own type of credential. In the example above, the platform verifies the badge data and then acts as an issuer of endorsements on behalf of its users. It could also be that the platform uses AI to process the badge and sends an endorsement back to Ralph as a proof of acceptance and an evaluation of his badge.

3.10 Re-issue a <= 3.0 Badge to a 3.0 Badge

Leo earned several badges while in highschool and graduates soon. The email address used as the recipient identity for these badges was an email address provided by his high school and he will no longer have access to it. Leo downloads a digital wallet and requests that the school reissue the badges to the identifier he created in the wallet.

3.11 Authorization to Issue Given by Creator to Issuer

The data model attributes the issuer of a VC and the creator of the badge class separately.

Standards Organization X (SOX) has created a number of badges related to competencies they certify. SOX wants to authorize an accredited, certified training organization (CTO) to issue their credentials. An Open Badge Platform manages the granting of issuing rights to CTO by SOX and can issue verifiable credentials where CTO is the issuer and SOX is the creator inside the badge class.

Employer receives a credential from a graduate. Employer, in addition to verifying the VC in general, can review and verify that SOX did in fact authorize CTO to issue this badge.

3.12 Revocation of an Issued Credential

Gigantic State University is a badge issuer. It has awarded a badge to a student in the form of a verifiable credential. Some time after issuing the credential, GSU discovers academic misconduct on the part of the student and needs to revoke the credential's status. GSU updates a list of revoked credential IDs, noting the reason why it was revoked. Future verifications of the issued badge by consumers detect that the credential is now revoked and do not erroneously accept it.

Goal of the Primary Actor: Revoke a credential they have already awarded.

Actors: Credential issuer, Credential Subject, Consumer/Verifier

Preconditions for this Use Case:

3.13 Badge Class Status

An institution has issued hundreds of badges in the form of VCs. A situation has arisen that requires the badge class to be effectively deleted or purged from the ecosystem. It is impractical (and arguably inaccurate) to revoke each assertion with individual records in perpetuity. The institution would like to set a status such that the badge class itself is treated as invalid.

4. Getting Started

This section is non-normative.

4.1 New to Open Badges

If you are new to Open Badges, please start here.

Note
@@@TBD

4.2 Migrating from Open Badges 2.x

If you are migrating from Open Badges 2.0 [OB-20] or 2.1 [OB-21] to OB 3.0, please start here.

Note
@@@TBD

4.2.1 Differences Between Version 2.0 and 3.0

4.2.2 Differences Between Version 2.1 and 3.0

5. Open Badges Document Formats

OpenBadgeCredentials can be exchanged as documents as defined in this section, or by using the Open Badges API. Documents can be exchanged as a text file, a web resource, or embedded in an image. The contents of an Open Badge document MUST meet the following criteria:

Example 1: Sample OpenBadgeCredential file contents
{
  "@context": [
    "https://www.w3.org/2018/credentials/v1",
    "https://imsglobal.github.io/openbadges-specification/context.json"
  ],
  "id": "http://example.edu/credentials/3732",
  "type": ["VerifiableCredential", "OpenBadgeCredential"],
  "issuer": {
    "id": "https://example.edu/issuers/565049",
    "type": ["Profile"],
    "name": "Example University"
  },
  "issuanceDate": "2010-01-01T00:00:00Z",
  "name": "Example University Degree",
  "credentialSubject": {
    "id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
    "type": ["AchievementSubject"]
  },
  "credentialSchema": [{
    "id": "https://imsum2.herokuapp.com/jsonschema?classId=org.1edtech.ob.v3p0.achievementcredential.class",
    "type": "JsonSchemaValidator2019"
  }]
}
{
  "@context": [
    "https://www.w3.org/2018/credentials/v1",
    "https://imsglobal.github.io/openbadges-specification/context.json",
    "https://w3id.org/security/suites/ed25519-2020/v1"
  ],
  "id": "http://example.edu/credentials/3732",
  "type": [
    "VerifiableCredential",
    "OpenBadgeCredential"
  ],
  "issuer": {
    "id": "https://example.edu/issuers/565049",
    "type": [
      "Profile"
    ],
    "name": "Example University"
  },
  "issuanceDate": "2010-01-01T00:00:00Z",
  "name": "Example University Degree",
  "credentialSubject": {
    "id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
    "type": [
      "AchievementSubject"
    ]
  },
  "credentialSchema": [
    {
      "id": "https://imsum2.herokuapp.com/jsonschema?classId=org.1edtech.ob.v3p0.achievementcredential.class",
      "type": "JsonSchemaValidator2019"
    }
  ],
  "proof": [
    {
      "type": "Ed25519Signature2020",
      "created": "2022-06-28T16:28:36Z",
      "verificationMethod": "https://example.edu/issuers/565049#key-1",
      "proofPurpose": "assertionMethod",
      "proofValue": "z5TAToFQmvWRG4rFqfrEX8hjidWpb9iHdHbxWignSWjJnMf8i1GGxja2fn1VZCP934jxriC8EaRSBDmeyqrPrUhU5"
    }
  ]
}
---------------- JWT header ---------------
{
  "alg": "RS256",
  "typ": "JWT",
  "jwk": {
    "e": "AQAB",
    "kty": "RSA",
    "n": "3HMIoYHPPcTQI92IvkMiHmo-IN0MWRAby2J4eyuv-mG1ZXKxplDlRxWq5airmvPlg6q-VF
ovThTwRRCPfMn3dJsPhNNL5j3pCDY0gHSuaeuIyYouro563G8_cOHbpaersGjYpujCv3DAE2_QcCUjv6
BPYJha-EUNwhVxxM3-yMzeZoDP6LRILgUazilkHS37blgirgA3WHo7cmDQe8sVaP-vfkFJCVG7yDxPwR
4TfGAR0UWxObsCa73mSoQl72JGZ-aFOmuQyNcH9DUKGpXKCt1TW54j9eGK3uBF8kG08vVLnDg3_7Kupw
oi9QT3fGBZ2CKCmqujjUtABZm_mxNBjQ"
  }
}
--------------- JWT payload ---------------
// NOTE: The example below uses a valid VC-JWT serialization
//       that duplicates the iss, nbf, jti, and sub fields in the
//       Verifiable Credential (vc) field.
{
  "vc": {
    "@context": [
      "https://www.w3.org/2018/credentials/v1",
      "https://imsglobal.github.io/openbadges-specification/context.json"
    ],
    "id": "http://example.edu/credentials/3732",
    "type": [
      "VerifiableCredential",
      "OpenBadgeCredential"
    ],
    "issuer": {
      "id": "https://example.edu/issuers/565049",
      "type": [
        "Profile"
      ],
      "name": "Example University"
    },
    "issuanceDate": "2010-01-01T00:00:00Z",
    "name": "Example University Degree",
    "credentialSubject": {
      "id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
      "type": [
        "AchievementSubject"
      ]
    },
    "credentialSchema": [
      {
        "id": "https://imsum2.herokuapp.com/jsonschema?classId=org.1edtech.ob.v3
p0.achievementcredential.class",
        "type": "JsonSchemaValidator2019"
      }
    ]
  },
  "iss": "https://example.edu/issuers/565049",
  "nbf": 1262304000,
  "jti": "http://example.edu/credentials/3732",
  "sub": "did:example:ebfeb1f712ebc6f1c276e12ec21"
}
--------------- JWT ---------------
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImp3ayI6eyJlIjoiQVFBQiIsImt0eSI6IlJTQSIsIm4i
OiIzSE1Jb1lIUFBjVFFJOTJJdmtNaUhtby1JTjBNV1JBYnkySjRleXV2LW1HMVpYS3hwbERsUnhXcTVh
aXJtdlBsZzZxLVZGb3ZUaFR3UlJDUGZNbjNkSnNQaE5OTDVqM3BDRFkwZ0hTdWFldUl5WW91cm81NjNH
OF9jT0hicGFlcnNHallwdWpDdjNEQUUyX1FjQ1VqdjZCUFlKaGEtRVVOd2hWeHhNMy15TXplWm9EUDZM
UklMZ1Vhemlsa0hTMzdibGdpcmdBM1dIbzdjbURRZThzVmFQLXZma0ZKQ1ZHN3lEeFB3UjRUZkdBUjBV
V3hPYnNDYTczbVNvUWw3MkpHWi1hRk9tdVF5TmNIOURVS0dwWEtDdDFUVzU0ajllR0szdUJGOGtHMDh2
VkxuRGczXzdLdXB3b2k5UVQzZkdCWjJDS0NtcXVqalV0QUJabV9teE5CalEifX0.eyJ2YyI6eyJAY29u
dGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vaW1z
Z2xvYmFsLmdpdGh1Yi5pby9vcGVuYmFkZ2VzLXNwZWNpZmljYXRpb24vY29udGV4dC5qc29uIl0sImlk
IjoiaHR0cDovL2V4YW1wbGUuZWR1L2NyZWRlbnRpYWxzLzM3MzIiLCJ0eXBlIjpbIlZlcmlmaWFibGVD
cmVkZW50aWFsIiwiT3BlbkJhZGdlQ3JlZGVudGlhbCJdLCJpc3N1ZXIiOnsiaWQiOiJodHRwczovL2V4
YW1wbGUuZWR1L2lzc3VlcnMvNTY1MDQ5IiwidHlwZSI6WyJQcm9maWxlIl0sIm5hbWUiOiJFeGFtcGxl
IFVuaXZlcnNpdHkifSwiaXNzdWFuY2VEYXRlIjoiMjAxMC0wMS0wMVQwMDowMDowMFoiLCJuYW1lIjoi
RXhhbXBsZSBVbml2ZXJzaXR5IERlZ3JlZSIsImNyZWRlbnRpYWxTdWJqZWN0Ijp7ImlkIjoiZGlkOmV4
YW1wbGU6ZWJmZWIxZjcxMmViYzZmMWMyNzZlMTJlYzIxIiwidHlwZSI6WyJBY2hpZXZlbWVudFN1Ympl
Y3QiXX0sImNyZWRlbnRpYWxTY2hlbWEiOlt7ImlkIjoiaHR0cHM6Ly9pbXN1bTIuaGVyb2t1YXBwLmNv
bS9qc29uc2NoZW1hP2NsYXNzSWQ9b3JnLjFlZHRlY2gub2IudjNwMC5hY2hpZXZlbWVudGNyZWRlbnRp
YWwuY2xhc3MiLCJ0eXBlIjoiSnNvblNjaGVtYVZhbGlkYXRvcjIwMTkifV19LCJpc3MiOiJodHRwczov
L2V4YW1wbGUuZWR1L2lzc3VlcnMvNTY1MDQ5IiwibmJmIjoxMjYyMzA0MDAwLCJqdGkiOiJodHRwOi8v
ZXhhbXBsZS5lZHUvY3JlZGVudGlhbHMvMzczMiIsInN1YiI6ImRpZDpleGFtcGxlOmViZmViMWY3MTJl
YmM2ZjFjMjc2ZTEyZWMyMSJ9.Se7y0v_UoAD3J6SxsQ-DppqoyvHtKw3XAqf4jyYZh3-pLEzly3p7y7w
5-SyUOgrVhsYiBnv-BnDrniJqFLkBT1_rZ4gJrEVSzbQpDz39MddOVTswT4vgOPwiVw8Vk379JaN9laX
KHaMzGsy_2j9nXzAaVpjmUo-JenGKWUWSg05o4GjErE8PM7SEbVGS8WaDJo9TsHNP36iv-Hjk6syMIRZ
OlF0XUa0bQlp4ltWMRe3fWgM3i_uabE-elqdCetdabTUf8hJGvKLLl1VnI-UWgSv9hLtUdWmWWlQlyty
-_XR554sHeYo-2tPtesXENjRLYg0urtE9uWTLf03UO95VSA

5.1 File Format

If the credential is signed using the § 8.2 JSON Web Token Proof Format (VC-JWT) the contents of the file MUST be the Compact JWS string formed as a result of signing the OpenBadgeCredential with VC-JWT. The file extension SHOULD be ".jws" or ".jwt".

If an embedded proof method is used instead, the contents of the file MUST be the JSON representation of the OpenBadgeCredential. The file extension SHOULD be ".json".

5.2 Web Resource

If the credential is signed using the § 8.2 JSON Web Token Proof Format (VC-JWT) the contents of the response MUST be the Compact JWS string formed as a result of signing the OpenBadgeCredential with VC-JWT. The Content-Type SHOULD be text/plain.

If an embedded proof method is used instead, the contents of the response MUST be the JSON representation of the OpenBadgeCredential. The Content-Type SHOULD be application/json or application/ld+json.

5.3 Baked Badge

OpenBadgeCredentials may be exchanged as image files with the credential encoded (baked) within. This allows the credential to be portable wherever image files may be stored or displayed.

"Baking" is the process of taking an OpenBadgeCredential and embedding it into the image, so that when a user displays the image on a page, software that is Open Badges aware can automatically extract that OpenBadgeCredential data and perform the checks necessary to see if a person legitimately earned the achievement within the image. The image MUST be in either PNG [PNG] or SVG [SVG11] format in order to support baking.

5.3.1 PNG

5.3.1.1 Baking

An iTXt chunk should be inserted into the PNG with keyword openbadgecredential.

If the credential is signed using the § 8.2 JSON Web Token Proof Format (VC-JWT) the text value of the chunk MUST be the Compact JWS string formed as a result of signing the OpenBadgeCredential with VC-JWT. Compression MUST NOT be used.

Example 2: An example of creating a chunk with VC-JWT proof (assuming an iTXt constructor)
var chunk = new iTXt({
  keyword: 'openbadgecredential',
  compression: 0,
  compressionMethod: 0,
  languageTag: '',
  translatedKeyword: '',
  text: 'header.payload.signature'
})

If an embedded proof method is used instead, the text value of the chunk MUST be the JSON representation of the OpenBadgeCredential. Compression MUST NOT be used.

Example 3: An example of creating a chunk with embedded proof (assuming an iTXt constructor)
var chunk = new iTXt({
  keyword: 'openbadgecredential',
  compression: 0,
  compressionMethod: 0,
  languageTag: '',
  translatedKeyword: '',
  text: '{
          "@context": [
            "https://www.w3.org/2018/credentials/v1",
            "https://purl.imsglobal.org/spec/ob/v3p0/context"
          ],
          "id": "http://example.edu/credentials/3732",
          "type": ["VerifiableCredential", "OpenBadgeCredential"],
          "issuer": {
            "id": "https://example.edu/issuers/565049",
            "type": "IssuerProfile",
            "name": "Example University"
          },
          "issuanceDate": "2010-01-01T00:00:00Z",
          "credentialSubject": {
            "id": "did:example:ebfeb1f712ebc6f1c276e12ec21"
          },
          "proof": { }
        }'
})

An iTXt chunk with the keyword openbadgecredential MUST NOT appear in a PNG more than once. When baking an image that already contains credential data, the implementor may choose whether to pass the user an error or overwrite the existing chunk.

5.3.1.2 Extracting

Parse the PNG datastream until the first iTXt chunk is found with the keyword openbadgecredential. The rest of the stream can be safely discarded. The text portion of the iTXt will either be the JSON representation of a § B.1.2 AchievementCredential or the Compact JWS string that was the result of signing the OpenBadgeCredential with § 8.2 JSON Web Token Proof Format.

5.3.2 SVG

5.3.2.1 Baking

First, add an xmlns:openbadges attribute to the <svg> tag with the value "https://purl.imsglobal.org/ob/v3p0". Directly after the <svg> tag, add an <openbadges:credential> tag.

If the credential is signed using the § 8.2 JSON Web Token Proof Format (VC-JWT) add a verify attribute to the <openbadges:credential> tag. The value of verify attribute MUST be the Compact JWS string formed as a result of signing the OpenBadgeCredential with VC-JWT.

Example 4: An example of a well baked SVG with VC-JWT proof
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg"
  xmlns:openbadges="https://purl.imsglobal.org/ob/v3p0"
  viewBox="0 0 512 512">
  <openbadges:credential verify="header.payload.signature"></openbadges:credential>

  <!-- rest-of-image -->
</svg>

If an embedded proof method is used instead, omit the verify attribute, and the JSON representation of the OpenBadgeCredential MUST go into the body of the tag, wrapped in <![CDATA[...]]>.

Example 5: An example of a well baked SVG with embedded proof
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg"
  xmlns:openbadges="https://purl.imsglobal.org/ob/v3p0"
  viewBox="0 0 512 512">
  <openbadges:credential>
    <![CDATA[
      {
        "@context": [
          "https://www.w3.org/2018/credentials/v1",
          "https://purl.imsglobal.org/spec/ob/v3p0/context"
        ],
        "id": "http://example.edu/credentials/3732",
        "type": ["VerifiableCredential", "OpenBadgeCredential"],
        "issuer": {
          "id": "https://example.edu/issuers/565049",
          "type": "IssuerProfile",
          "name": "Example University"
        },
        "issuanceDate": "2010-01-01T00:00:00Z",
        "credentialSubject": {
          "id": "did:example:ebfeb1f712ebc6f1c276e12ec21"
        },
        "proof": { }
      }
    ]]>
  </openbadges:credential>

  <!-- rest-of-image -->
</svg>

There MUST be only one <openbadges:credential> tag in an SVG. When baking an image that already contains OpenBadgeCredential data, the implementor may choose whether to pass the user an error or overwrite the existing tag.

5.3.2.2 Extracting

Parse the SVG until you reach the first <openbadges:credential> tag. The rest of the SVG data can safely be discarded.

6. Open Badges API

Open Badges can be exchanged using the API (application programming interface) defined here, or as documents.

This specification defines a RESTful API protocol to be implemented by applications serving in the roles of Client and Resource Server. The API uses OAuth 2.0 for authentication and granular resource-based permission scopes. Please see the Open Badges Specification Conformance and Certification Guide v3.0 for a list of which endpoints must be implemented for certification.

In addition to the documentation in this section, there are OpenAPI files for the Open Badges API in both JSON and YAML format:

6.1 Architecture

Diagram showing the major components of the Open Badges API
Figure 6 Diagram showing the major components of the Open Badges API

There are five key components to the API architecture.

User
This is the user that owns the resources (badges) that are on the resource server. Also called a Resource Owner.
Web Browser
This is the web browser the user interacts with.
Client
This is the web application that interacts with the resource server on behalf of the user. Also called Consumer in the IMS Global Security Framework v1.1.
Authorization Server
This is a server that implements the OAuth 2.0 endpoints on behalf of the resource server. In many systems, the authorization server and the resource server are combined.
Resource Server
This is the server that has the protected resources (badges). Also called Provider in the IMS Global Security Framework v1.1.

The role of each component during Registration, Obtaining Tokens, and Authenticating with Tokens are described below.

6.2 Secure REST Endpoints

These endpoints are used to exchange OpenBadgeCredentials and Profile information.

All secure endpoint requests MUST be made over secure TLS 1.2 or 1.3 protocol.

All of the Secure REST Endpoints are protected by OAuth 2.0 access tokens as described in § 7. Open Badges API Security.

Scopes

Each endpoint requires an access token with a specific Open Badges scope as shown below.

Operation Scope
getCredentials https://purl.imsglobal.org/spec/ob/v3p0/scope/credential.readonly - Permission to read OpenBadgeCredentials for the authenticated entity.
postCredential https://purl.imsglobal.org/spec/ob/v3p0/scope/credential.create - Permission to create OpenBadgeCredentials for the authenticated entity.
getProfile https://purl.imsglobal.org/spec/ob/v3p0/scope/profile.readonly - Permission to read the profile for the authenticated entity.
postProfile https://purl.imsglobal.org/spec/ob/v3p0/scope/profile.update - Permission to update the profile for the authenticated entity.

6.2.1 getCredentials

Get issued OpenBadgeCredentials from the resource server for the supplied parameters and access token.

Request

GET /ims/ob/v3p0/credentials?limit={limit}&offset={offset}&since={since}

Request header, path, and query parameters
Parameter Paramter Type Description Required
limit
(query)
PositiveInteger The maximum number of OpenBadgeCredentials to return per page. Optional
offset
(query)
NonNegativeInteger The index of the first AchievementCredential to return. (zero indexed) Optional
since
(query)
DateTime Only include OpenBadgeCredentials issued after this timestamp. Optional
Responses
Allowed response codes and content types
Status Code Content-Type Header Content Type Content Description Content Required
200 application/json GetOpenBadgeCredentialsResponse The set of OpenBadgeCredentials that meet the request parameters. Paging applies to the total number of OpenBadgeCredentials in the response. Required
DEFAULT application/json Imsx_StatusInfo The request was invalid or cannot be served. The exact error SHOULD be explained in the response payload. Required
Example 6: Sample getCredentials Request
GET /ims/ob/v3p0/assertions?limit=2&offset=0 HTTP/1.1
Host: example.edu
Authorization: Bearer 863DF0B10F5D432EB2933C2A37CD3135A7BB7B07A68F65D92
Accept: application/json
Example 7: Sample getCredentials Response (line breaks for clarity)
HTTP/1.1 200 OK
Content-Type: application/ld+json
X-Total-Count: 1
Link: <https://www.imsglobal.org/ims/ob/v3p0/assertions?limit=2&offset=1>; rel="next",
      <https://www.imsglobal.org/ims/ob/v3p0/assertions?limit=2&offset=0>; rel="last",
      <https://www.imsglobal.org/ims/ob/v3p0/assertions?limit=2&offset=0>; rel="first",
      <https://www.imsglobal.org/ims/ob/v3p0/assertions?limit=2&offset=0>; rel="prev"

{
  "compactJwsStrings": [
    "header.payload.signature",
    "header.payload.signature"
  ]
}

6.2.2 postCredential

Create or replace an AchievementCredential on the resource server.

Request

POST /ims/ob/v3p0/credentials

Allowed request content types
Content-Type Header Content Type Content Description Content Required
application/json AchievementCredential If the AchievementCredential is not signed with the VC-JWT Proof Format, the request body MUST be a AchievementCredential and the Content-Type MUST be application/json. Required
text/plain CompactJws If the AchievementCredential is signed with the VC-JWT Proof Format, the request body MUST be a CompactJws string and the Content-Type MUST be text/plain. Required
Responses
Allowed response codes and content types
Status Code Content-Type Header Content Type Content Description Content Required
200 application/json AchievementCredential The AchievementCredential was successfully replaced on the resource server. The response body MUST be the AchievementCredential in the request. If the AchievementCredential is not signed with the VC-JWT Proof Format, the response body MUST be a AchievementCredential and the Content-Type MUST be application/json. Required
200 text/plain CompactJws The AchievementCredential was successfully replaced on the resource server. The response body MUST be the AchievementCredential in the request. If the AchievementCredential is signed with the VC-JWT Proof Format, the response body MUST be a CompactJws string and the Content-Type MUST be text/plain. Required
201 application/json AchievementCredential The AchievementCredential was successfully created on the resource server. The response body MUST be the AchievementCredential in the request. If the AchievementCredential is not signed with the VC-JWT Proof Format, the response body MUST be a AchievementCredential and the Content-Type MUST be application/json. Required
201 text/plain CompactJws The AchievementCredential was successfully created on the resource server. The response body MUST be the AchievementCredential in the request. If the AchievementCredential is signed with the VC-JWT Proof Format, the response body MUST be a CompactJws string and the Content-Type MUST be text/plain. Required
DEFAULT application/json Imsx_StatusInfo The request was invalid or cannot be served. The exact error SHOULD be explained in the response payload. Required
Example 8: Sample postCredential Request
POST /ims/ob/v3p0/credentials HTTP/1.1
Host: example.edu
Authorization: Bearer 863DF0B10F5D432EB2933C2A37CD3135A7BB7B07A68F65D92
Accept: text/plain
Content-Type: text/plain

header.payload.signature
Example 9: Sample postCredential Response
HTTP/1.1 200 OK
Content-Type: text/plain

header.payload.signature

6.2.3 getProfile

Fetch the profile from the resource server for the supplied access token. Profiles that are received MAY contain attributes that a Host SHOULD authenticate before using in practice.

Request

GET /ims/ob/v3p0/profile

Responses
Allowed response codes and content types
Status Code Content-Type Header Content Type Content Description Content Required
200 application/json Profile The matching profile. Required
DEFAULT application/json Imsx_StatusInfo The request was invalid or cannot be served. The exact error SHOULD be explained in the response payload. Required
Example 10: Sample getProfile Request
GET /ims/ob/v3p0/profile HTTP/1.1
Host: example.edu
Authorization: Bearer 863DF0B10F5D432EB2933C2A37CD3135A7BB7B07A68F65D92
Accept: application/json
Example 11: Sample getProfile Response
HTTP/1.1 200 OK
Content-Type: application/json

{
  "@context": [
    "https://purl.imsglobal.org/spec/ob/v3p0/context/ob_v3p0.jsonld"
  ],
  "type": "Profile",
  "id": "https://example.edu/issuers/565049",
  "name": "Example University"
}

6.2.4 postProfile

Update the profile for the authenticate entity.

Request

POST /ims/ob/v3p0/profile

Allowed request content types
Content-Type Header Content Type Content Description Content Required
application/json Profile The request SHOULD only include profile identifier properties to be added to the profile, not any existing data. The resource server MAY respond with 400 BAD_REQUEST to reject data that is known immediately to not be acceptable by the platform, e.g. to reject a "telephone" property if the resource server cannot validate telephone numbers. Required
Responses
Allowed response codes and content types
Status Code Content-Type Header Content Type Content Description Content Required
200 application/json Profile The matching profile. Successful request responses will be the same as GET Profile and may not include the patched values (as the resource server may be waiting for asynchronous processes to complete before accepting the value). The values may never become part of the published profile. Required
DEFAULT application/json Imsx_StatusInfo The request was invalid or cannot be served. The exact error SHOULD be explained in the response payload. Required
Example 12: Sample postProfile Request
POST /ims/ob/v3p0/profile HTTP/1.1
Host: example.edu
Authorization: Bearer 863DF0B10F5D432EB2933C2A37CD3135A7BB7B07A68F65D92
Accept: application/json
Content-Type: application/json

{
  "@context": [
    "https://purl.imsglobal.org/spec/ob/v3p0/context/ob_v3p0.jsonld"
  ],
  "telephone": "111-222-3333"
}
Example 13: Sample postProfile Response
{
  "@context": [
      "https://purl.imsglobal.org/spec/ob/v3p0/context/ob_v3p0.jsonld"
  ],
  "type": "Profile",
  "id": "https://example.edu/issuers/565049",
  "name": "Example University"
}

6.3 Service Discovery Endpoint

Access to the discovery endpoint MUST NOT be protected. The Service Description Document (SDD) MUST be provided over HTTPS with TLS 1.2 or 1.3.

6.3.1 getServiceDescription

Fetch the Service Description Document from the resource server.

Request

GET /ims/ob/v3p0/discovery

Responses
Allowed response codes and content types
Status Code Content-Type Header Content Type Content Description Content Required
200 application/json ServiceDescriptionDocument The service discovery document. Required
DEFAULT application/json Imsx_StatusInfo The request was invalid or cannot be served. The exact error SHOULD be explained in the response payload. Required
Example 14: Sample getServiceDescription request
GET /ims/ob/v3p0/discovery HTTP/1.1
Host: example.edu
Accept: application/json
Example 15: Sample getServiceDescription response
HTTP/1.1 200 OK
Content-Type: application/json

...
"components": {
    "securitySchemes": {
        "OAuth2CCG": {
            "type": "oauth2",
            "description": "OAuth 2.0 Client Credentials authorization",
            "x-imssf-name": "Example Provider",
            "x-imssf-privacyPolicyUrl": "provider.example.com/privacy",
            "x-imssf-registrationUrl": "provider.example.com/registration",
            "x-imssf-termsOfServiceUrl": "provider.example.com/terms",
            "flows": {
                "clientCredentials": {
                    "tokenUrl": "provider.example.com/token",
                    "scopes": {
                        "https://purl.imsglobal.org/spec/clr/v2p0/scope/delete" : "...",
                        "https://purl.imsglobal.org/spec/clr/v2p0/scope/readonly" : "...",
                        "https://purl.imsglobal.org/spec/clr/v2p0/scope/replace" : "..."
                    }
                }
            }
        },
        "OAuth2ACG": {
            "type": "oauth2",
            "description": "OAuth 2.0 Authorization Code Grant authorization",
            "x-imssf-name": "Example Provider",
            "x-imssf-privacyPolicyUrl": "provider.example.com/privacy",
            "x-imssf-registrationUrl": "provider.example.com/registration",
            "x-imssf-termsOfServiceUrl": "provider.example.com/terms",
            "flows": {
                "authorizationCode": {
                    "tokenUrl": "provider.example.com/token",
                    "authorizationUrl": "provider.example.com/authorize",
                    "refreshUrl": "provider.example.com/token",
                    "scopes": {
                        "https://purl.imsglobal.org/spec/clr/v2p0/scope/delete" : "...",
                        "https://purl.imsglobal.org/spec/clr/v2p0/scope/readonly" : "...",
                        "https://purl.imsglobal.org/spec/clr/v2p0/scope/replace" : "..."
                    }
                }
            }
        }
    },
    "schemas": {
        ...
    }
}
...

6.4 Paging

Pagination of getCredentials results is controlled by two query string parameters appended to the request. The response includes the following pagination headers.

Response Header Description Required
X-Total-Count: <total_count> The resource server MUST include an X-Total-Count response header if the total result count is known. If the total result count is not known, the total count header MUST be ommitted. Conditionally Required for 200 OK Response
Link: <pagination_links> The resource server MUST include a Link response header if the list of credentials in the response is incomplete; and MAY include the Link header if the response is complete. Conditionally Required for 200 OK Response

If present, the Link header MUST support all of the following link relations (rel values):

Relation Description
next The link relation for the immediate next page of results. This MUST appear when the current list response is incomplete.
last The link relation for the last page of results. This MUST always appear.
first The link relation for the first page of results. This MUST always appear.
prev The link relation for the immediate previous page of results. This MUST appear when the offset is greater than zero.

6.5 Retry Behavior

Resource Servers MAY implement a Retry-After header to indicate a period of time to wait before attempting the request again.

If no Retry-After header is present and the response is non-2XX, it is recommended to retry the request in 30 minutes for an additional two attempts. After which, it MAY be desirable to alert the user that there is an issue with the connection (e.g. perhaps they need to reauthenticate or manually trigger the request when they believe services are back up).

7. Open Badges API Security

The Open Badges API endpoints use the methods outlined in Section 4, "Securing Web Services" of the IMS Global Security Framework v1.1. Clients and servers that have an established trust relationship and shared ownership of the resources (Open Badges) MUST use the OAuth 2.0 Client-Credentials Grant method. Clients and servers that give individual users control over access to their resources MUST use the OAuth 2.0 Authorization Code Grant method.

7.1 Using OAuth 2.0 Client-Credentials Grant

Clients and servers that have a pre-established trust relationship and shared ownership of the protected resources (Comprehensive Learner Records) MUST use the OAuth 2.0 Client-Credentials Grant (CCG) method.

Clients and servers implementing this method of security MUST comply with Section 4.1, "Using OAuth 2.0 Client-Credentials Grant" of the IMS Global Security Framework v1.1.

7.1.1 CCG - Registration

To get started, the client and authorization server must share the four pieces of information shown below. These can be shared manually or by using § 7.2.1 Dynamic Client Registration.

client_id
This is the public identifier for the communication exchange. Also called a Secret in the IMS Global Security Framework v1.1.
client_secret
This is the shared secret for the communication exchange. Also called a Secret in the IMS Global Security Framework v1.1.
List of Scopes
The list of scopes that identify the set of endpoints for which access permission is being requested.
OAuth 2.0 Access Token Service Endpoint
The endpoint from which the approved, requesting client can obtain an access token.

If the client and authorization server support Token Revocation, they should also share:

OAuth 2.0 Revocation Service Endpoint
The endpoint a client can use to revoke an access token.

7.1.2 CCG - Obtaining Tokens

Sequence diagram for obtaining an access token using the CCG flow
Figure 7 Sequence diagram for obtaining an access token using the CCG flow

Obtaining an access token using client credentials is a simple, one step process. Once obtained, the client can freely re-use the access token until the token's expiry time. When the token expires, the client will need to obtain a new access token.

CCG - Access Token Request

To obtain an access token, the client posts a "client_credentials" grant token request to the OAuth 2.0 Access Token Service Endpoint established during Registration. Requests for an access token MUST use an HTTP POST over HTTPS and TLS 1.2 or 1.3 protocol. The client MUST use its client_id and client_secret with the HTTP Basic Authentication method (as described in [RFC2617]) for this request and MUST NOT put its key and secret into the request body.

The set of request parameters (see Section 4.4 of [RFC6749]) used to request a CCG access token are shown below. The request MUST use the POST method and the request parameters MUST be placed in the request body and MUST NOT be sent as URL query parameters.

Parameter Type Description Required
grant_type String The value MUST be set to "client_credentials" Required
scope String The space delimited list of scopes of the access request.

The authorization server is responsible for validating the scopes identified in the request and the response MUST include a scope parameter which confirms this list or comprises a subset of the services requested.

Required
Example 16: Sample access token request with 1 scope
POST /token HTTP/1.1
Host: auth.1edtech.org
Authorization: Basic YWQyMmU5ZjYxNzlhNzljODo5Y2MxYzEzY2NmZTAxYWQ1
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials&?scope=https%3a%2f%2fpurl.imsglobal.org%2fspec%2fob%2fv3p0%2fscope%2freadonly
CCG - Access Token Response

If the authorization server grants this request (see Section 5.1 in [RFC6749] for the detailed description), it returns the HTTP 200 OK status code with content type "application/json" consisting of a JSON object containing the access token and its expiry lifetime (1EdTech recommends a default expiry lifetime of 3600 seconds, one hour, for access tokens) and confirms the set of scopes supported by this access token:

Property Name Type Description Required
access_token String The access token issued by the authorization server. Required
token_type String The type of the token issued. The case insensitive value MUST be "bearer". Required
scope String The space delimited list of scopes of the access token. The authorization server is responsible for validating the scopes identified in the request and the response MUST include a scope parameter which confirms this list or comprises a subset of the services requested. Required
expires_in PositiveInteger The lifetime in seconds of the access token. For example, the value "3600" denotes that the access token will expire in one hour from the time the response was generated. 1EdTech recommends a default expiry lifetime of 3600 seconds, one hour, for access tokens. If omitted, the authorization server SHOULD provide the expiration time via other means or document the default value. Optional
Example 17: Sample CCG access token response
HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
Cache-Control: no-store
Pragma: no-cache

{
    "access_token": "863DF0B10F5D432EB2933C2A37CD3135A7BB7B07A68F65D92",
    "expires_in": 3600,
    "token_type": "Bearer",
    "scope": "https://purl.imsglobal.org/spec/ob/v3p0/scope/readonly"
}
Access Token Error Response

The authorization server MAY decide not to issue an access token. This could be because the request scopes are invalid, the credentials from the client may be invalid, etc. In this case the authorization server MUST return an HTTP 400 Bad Request status code with content type "application/json" consisting of a JSON object describing the error in the response body. The properties used to describe the error are:

Property Name Type Description Required
error TokenError Vocabulary A single ASCII [RFC20] error code. See Section 5.2 of [RFC6749]. Required
error_description ASCIIString Human-readable ASCII [RFC20] text providing additional information, used to assist the client developer in understanding the error that occurred. Values for the "error_description" parameter MUST NOT include characters outside the set %x20-21 / %x23-5B / %x5D-7E. Optional
error_uri URI A URI identifying a human-readable web page with information about the error, used to provide the client developer with additional information about the error. Values for the "error_uri" parameter MUST conform to the URI-reference syntax and thus MUST NOT include characters outside the set %x21 / %x23-5B / %x5D-7E. Optional
Example 18: Sample access token error response
HTTP/1.1 400 Bad Request
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache

{
    "error": "invalid_request"
}

7.1.3 CCG - Authenticating with Tokens

The client uses the access token to authenticate with the resource server using the HTTP Authorization request header field [RFC2617] with a Bearer Token [RFC6750].

Example 19: Sample getCredentials Request
GET ims/ob/v3p0/credentials?limit=2&offset=0 HTTP/1.1
HOST: provider.1edtech.org
Authorization: Bearer 863DF0B10F5D432EB2933C2A37CD3135A7BB7B07A68F65D92
Accept: application/json

7.2 Using OAuth 2.0 Authorization Code Grant

Making a secured Open Badges API request using authorization code grant comprises three steps:

  1. § 7.2.1 Dynamic Client Registration - Share configuration information between the client and the server. This is typically done only once unless the registration is revoked.
  2. § 7.2.2 Obtaining Tokens - Obtain an authorization code using a choreography between the client, web browser, user, and authorization server. Then request an access token by sending a request, using the previously obtained authorization code, to the Access Token service endpoint.
  3. § 7.2.3 Authenticating with Tokens - Use the access token in the Authorization header of the API request.

7.2.1 Dynamic Client Registration

To get started, the client and authorization server MUST share the four pieces of information shown below using the OAuth 2.0 Dynamic Client Registration Protocol [RFC7591] as described in this section.

client_id
This is the public identifier for the communication exchange. Also called a Secret in the IMS Global Security Framework v1.1.
client_secret
This is the shared secret for the communication exchange. Also called a Secret in the IMS Global Security Framework v1.1.
List of Scopes
The list of scopes that identify the set of endpoints for which access permission is being requested.
OAuth 2.0 Access Token Service Endpoint
The endpoint from which the approved, requesting client can obtain an access token.

If the client and authorization server support Token Revocation, they should also share:

OAuth 2.0 Revocation Service Endpoint
The endpoint a client can use to revoke an access token.

There are two steps to dynamic client registration:

  1. Request a Service Description Document (SDD) from the resource server
  2. Register with the authorization server
Sequence diagram for registration
Figure 8 Sequence diagram for dynamic client registration

The client only needs to register a client_id with the authorization server once. Each user will use the same client_id when they request their own authorization code.

Request the Service Description Document

To start the registration process, the user supplies the client with the resource server's base URL. When presented with an unknown resource server the client MUST request the resource server's Service Description Document (SDD) at the path {baseUrl}/ims/ob/v3p0/discovery. Rate-limited access to this endpoint is RECOMMENDED. An example request for an SDD takes the form of:

Example 20: Sample request for a service description document
GET /tenant/ims/ob/v3p0/discovery HTTP/1.1
Host: 1edtech.org
Accept: application/json

Access to the discovery endpoint MUST NOT be protected. The SDD MUST be provided over HTTPS with TLS 1.2 or 1.3.

The response to this request is the SDD supplied as a JSON encoded payload. The structure and format of this payload MUST follow that of the OpenAPI 3.0 Specification [OPENAPIS-3.0]. The SDD supplied MUST be a profiled version of the OpenAPI 3.0 (JSON) file provided with this specification (see § 1.2.1 OpenAPI 3.0 Files). The profiled version contains all of the details about the supported set of service end-points, the supported optional data fields, definitions of the proprietary data fields supplied using the permitted extension mechanisms, definitions of the available proprietary endpoints, and information about the security mechanisms.

The x-imssf-privacyPolicyUrl property is inserted into the securitySchemes within the components section of the OpenAPI file structure. This is an 1EdTech controlled extension to the OpenAPI specification.

Property Name Type Description Required
x-imssf-privacyPolicyUrl URL A fully qualified URL to the resource server's privacy policy. Required

The x-imssf-image and x-imssf-privacyPolicy properties are inserted into the info section of the OpenAPI file structure. These are also 1EdTech controlled extensions to the OpenAPI specification. Also note that the standard title and termsOfService property is required in a Service Description Document. These may be displayed to the user during the registration process.

Property Name Type Description Required
x-imssf-image URI An image representing the resource server. May be a Data URI or the URL where the image may be found. Optional
x-imssf-privacyPolicyUrl URL A fully qualified URL to the resource server's privacy policy. Required
title String The name of the resource server. Required
termsOfService URL A fully qualified URL to the resource server's terms of service. Required
Example 21: Sample response with a Service Discovery Document
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

...
"info": {
  "x-imssf-image": "https://1edtech.org/logo",
  "x-imssf-privacyPolicy": "https://1edtech.org/privacy",
  "title": "Example",
  "termsOfService": "https://1edtech.org/tos",
  ...
},
...
"components": {
  "securitySchemes": {
    "OAuth2ACG": {
      "type": "oauth2",
      "description": "OAuth 2.0 Authorization Code Grant authorization",
      "x-imssf-registrationUrl": "1edtech.org/registration",
      "flows": {
        "authorizationCode": {
          "tokenUrl": "1edtech.org/token",
          "authorizationUrl": "1edtech.org/authorize",
          "refreshUrl": "1edtech.org/token",
          "scopes": {
            "https://purl.imsglobal.org/spec/ob/v3p0/scope/assertion.update" : "...",
            "https://purl.imsglobal.org/spec/ob/v3p0/scope/assertion.readonly" : "...",
            "https://purl.imsglobal.org/spec/ob/v3p0/scope/profile.readonly" : "...",
            "https://purl.imsglobal.org/spec/ob/v3p0/scope/profile.update" : "..."
          }
        }
      }
    }
  },
  "schemas": {
    ...
  }
}
...

Upon receiving a SDD from a resource server, the client SHOULD respect the Cache-Control and Expires headers if present in the response and configure local cache to match the directives it declares. If directives include one of no-cache, no-store, the client SHOULD NOT cache the data for future interactions. If directives include max-age or if an Expires header is present, the client SHOULD cache the SDD data, if valid, up to the expiration indicated, either at the time indicated by the Expires header or max-age seconds from request time.

An Etag header MAY be offered with the SDD response. If so, after a resource's declared expiration, a client MAY include an If-None-Match header containing the value of the Etag to check if the resource is still fresh. If so the resource server may return a 304 Not Modified response status code, and a new Expires or Cache-Control header MAY be included, which the client SHOULD use to update the cache expiration.

Register with Authorization Server

With the Registration URL in hand (the value of the x-imssf-registrationUrl property of the SDD), the client SHOULD post a registration request to the authorization server. The registration request MUST comply with OAuth 2.0 Dynamic Client Registration Protocol [RFC7591]. The registration request MUST NOT require an Initial Access Token. Use of the 'Software Statement' is NOT RECOMMENDED. The client registration request is sent to the Client Registration URL. The request MUST be sent using HTTPS with TLS 1.2 or 1.3 protocol.

The properties of the JSON body MUST be implemented as described in the following table. All URLs MUST use HTTPS (e.g. https://1edtech.org/logo.png) and all URLs MUST have the same hostname. All required properties MUST be present in the registration request in order for it to be accepted by the authorization server. Arrays MUST be used even when a single value is to be sent.

Name Type Description Required
client_name String The human-readable name of the client application. Required
client_uri URL A page that which describes the client application. Required
logo_uri URL The logo of the client application. If present, the authorization server SHOULD display this image to the end-user during approval. The value of this field MUST point to a valid image file. Required
tos_uri URL The human-readable Terms of Service for the client application that describes a contractural relationship between the end-user and the client that the end-user accepts when authorizing the client. Required
policy_uri URL The human-readable Privacy Policy for the client application that describes how the deployment organization collects, uses, retains, and discloses personal data. Required
software_id String A unique idenfitier assigned by the client application developer or software published used by registration endpoints to identify the client application to be dynamically registered. As described in [rfc7591], it SHOULD remain the same for all instances of the client application software. Required
software_version String A version identifier string for the client application software identifies by software_id. The value of software_version SHOULD change on any update to the client application software identified by the same software_id. Required
redirect_uris URL[] Array of redirection URI strings for use in the OAuth 2.0 flow. Required
scope String In the registration request, this is a string containing a space-separated list of scope values that this client application may include when requesting access tokens. If omitted, the authorization server MAY register a client application with a default set of scopes. In the registration response, this is a list of scopes the authorization server supports.

The list of scopes that can be requested are shown in § Scopes.

Required
token_endpoint_auth_method String String indicator of the requested authentication method for the token endpoint. In this specification only "client_secret_basic" is allowed:
  • "client_secret_basic": The client application uses the HTTP Basic authentication method as defined in OAuth 2.0.
If omitted, the default is "client_secret_basic".
Optional
grant_types String[] Array of OAuth 2.0 grant type strings. In this specification only "authorization_code" and refresh_token" are allowed:
  • "authorization_code": The authorization code grant type defined in OAuth 2.0.
  • "refresh_token": The refresh token grant type defined in OAuth 2.0.
If omitted, the default behavior is that the client will use only the "authorization_code" grant type.
Optional
response_types String[] Array of OAuth 2.0 response type strings. In this specification only "code" is allowed:
  • "code": The authorization code response type defined in OAuth 2.0.
If omitted, the default is that the client will use only the "code" response type.
Optional
contacts String[] Array of strings representing ways to contact people responsible for this client, typically email addresses. The authorization server MAY make these contact addresses available to end-users for support requests for the client application. Privacy constraints MUST be supported as applicable. Optional
Example 22: Sample registration request
  POST /connect/register HTTP/1.1
  Host: auth.1edtech.org
  Accept: application/json
  Content-Type: application/json; charset=utf-8
  
  {
    "client_name": "Example Client Application",
    "client_uri": "https://client.1edtech.org/",
    "logo_uri": "https://client.1edtech.org/logo.png",
    "tos_uri": "https://client.1edtech.org/terms",
    "policy_uri": "https://client.1edtech.org/privacy",
    "software_id": "c88b6ed8-269e-448e-99be-7e2ff47167d1",
    "software_version": "v4.0.30319",
    "redirect_uris": [
      "https://client.1edtech.org/Authorize"
    ],
    "token_endpoint_auth_method": "client_secret_basic",
    "grant_types": [
      "authorization_code",
      "refresh_token"
    ],
    "response_types": [
      "code"
    ],
    "scope": "https://purl.imsglobal.org/spec/ob/v3p0/scope/delete https://purl.imsglobal.org/spec/ob/v3p0/scope/assertion.readonly https://purl.imsglobal.org/spec/ob/v3p0/scope/replace offline_access"
}

If the authorization server accepts the registration request, it will store the information provided in the request and respond HTTP 201 Created with a registration response that includes a set of client credentials for the client application to use when requesting access tokens. All the information provided by the client application MUST be returned to the client application, including modifications to the properties as the authorization server deems necessary. An example response looks like this:

Example 23: Sample registration response
HTTP/1.1 201 Created
Content-Type: application/json; charset=utf-8

{
  "client_id": "4ad36680810420ed",
  "client_secret": "af7aa0d679778e12",
  "client_id_issued_at": 1565715850,
  "client_secret_expires_at": 1597338250,
  "client_name": "Example Client Application",
  "client_uri": "https://client.1edtech.org/",
  "logo_uri": "https://client.1edtech.org/logo.png",
  "tos_uri": "https://client.1edtech.org/terms",
  "policy_uri": "https://client.1edtech.org/privacy",
  "software_id": "c88b6ed8-269e-448e-99be-7e2ff47167d1",
  "software_version": "v4.0.30319",
  "redirect_uris": [
    "https://client.1edtech.org/Authorize"
  ],
  "token_endpoint_auth_method": "client_secret_basic",
  "grant_types": [
    "authorization_code",
    "refresh_token"
  ],
  "response_types": [
    "code"
  ],
  "scope": "https://purl.imsglobal.org/spec/ob/v3p0/scope/delete https://purl.imsglobal.org/spec/ob/v3p0/scope/assertion.readonly https://purl.imsglobal.org/spec/ob/v3p0/scope/replace offline_access"
}

The following table describes the properties present in the client registration response that were not included in the request. These are all REQUIRED properties.

Name Type Description Required
client_id String An OAuth 2.0 client identifier string. The value SHOULD NOT be currently valid for any other registered client. Required
client_secret String An OAuth 2.0 client secret string. Required
client_id_issued_at NonNegativeInteger The time at which the client_id was issued. The time is represented as the number of seconds from 1970-01-01T00:00:00Z as measured in UTC until the date/time of issuance. Required
client_secret_expires_at NonNegativeInteger The time at which the client_secret will expire. MAY be 0 for no expiration. The time is represented as the number of seconds from 1970-01-01T00:00:00Z as measured in UTC until the date/time of expiration. Required

When a registration error condition occurs, the authorization server returns an HTTP 400 status code (unless otherwise specified) with content type "application/json" consisting of a JSON object describing the error in the response body. The properties used are:

Name Type Description Required
error RegistrationError The error. Required
error ASCII String Human-readable ASCII text description of the error used for debugging. Optional

7.2.2 Obtaining Tokens

Sequence diagram for obtaining access tokens when using the ACG flow
Figure 9 Sequence diagram for obtaining access tokens when using the ACG flow

Obtaining an access token using an authorization code has two steps:

Once obtained, the client can freely re-use the access token up until the token's expiry time, so that the client need not repeat steps of obtaining an authorization code and requesting an access token for every API request. Token refresh is also available (see § Token Refresh Request).

Authorization Request

After the client application is registered with the authorization server as described in § 7.2.1 Dynamic Client Registration, the client application then MAY initiate an authorization request as described in Section 4.2 of the IMS Security Framework [SEC-11] by redirecting the user to the authorizationUrl as declared in the resource server's Service Description Document (SDD).

In the OAuth 2.0 Security Best Practices document [OAUTH2-SBP] the use of Proof Key for Code Exchange (PKCE) [RFC7636] is recommended in order to (with the help of the authorization server) detect and prevent attempts to inject (replay) authorization codes into the authorization response. When using 1EdTech specifications, PKCE MUST be used to protect Authorization Code Grant based access. The PKCE has two stages:

  • First the client MUST supply a code_challenge and code_challenge_method in the request for an authorization code. The authorization server is responsible for associating the code_challenge with the issued authorization code.
  • Then the client MUST supply the code_verifier in the Access Token Request, and the authorization server verifies the code_verifier.

Parameter Name Type Description Required
response_type String Value MUST be set to "code". Required
client_id String The client application identifier. MUST be the client_id provided in the Dynamic Client Registration § Register with Authorization Server response. Required
redirect_uri URL The client application's redirection endpoint. MUST match one of the redirect_uris in the § 7.2.1 Dynamic Client Registration request. Although this is optional in the IMS Security Framework [SEC-11], it is REQUIRED by this specification. Required
scope String The scope of the authorization request. The authorization server is responsible for validating the scopes identified in the request and the response MUST include a scope parameter which confirms this list or comprises a subset of the services requested. Required
state String An opaque value used by the client application to maintain state between the request and callback. The authorization server includes this value when redirecting the web browser back to the client. This parameter MUST be used for preventing cross-site request forgery. Required
code_challenge String This is BASE64URL-ENCODE(SHA256(ASCII(code_verifier))). Required
code_challenge_method String This MUST have a value of "S256" to indicate the SHA256 code verifier transformation method is used. Required

All of the authorization request parameters are encoded in the authorization request as query string parameters. The request MUST be made by redirecting the browser to the OAuth 2.0 Authorization endpoint. The request MUST use HTTPS with TLS 1.2 or 1.3 protocol.

Example 24: Sample ACG authorization request (line breaks for clarity)
HTTP/1.1 302 Found
Location: https://auth.1edtech.org/authorize?
  client_id=4ad36680810420ed
  &response_type=code
  &scope=https%3A%2F%2Fpurl.imsglobal.org%2Fspec%ob%2Fv3p0%2Fscope%2Fassertion.readonly%20offline_access
  &redirect_uri=https%3A%2F%client.1edtech.org%2FAuthorize
  &state=26357667-94df-4a14-bcb1-f55449ddd98d
  &code_challenge=XeDw66i9FLjn7XaecT_xaFyUWWfUub02Kw118n-jbEs
  &code_challenge_method=S256
Authorization Response

If the redirect_uri matches a known client_id, the authorization server SHOULD present a UI asking the user to authenticate themself and grant the access request. The authorization server SHOULD display the client_name, client_uri, logo_uri, tos_uri, and policy_uri collected during Dynamic Client Registration to the user to help them decide whether to grant the access request.

If the user authorizes the client application to access their resources with the requested scopes, the authorization server MUST redirect the browser back to the redirect_uri with the code, scope, and state query string parameters.

The Authorization Code MUST be used only once. A lifetime for the authorization code of 600 seconds (10 minutes) is RECOMMENDED. If an authorization code is used more than once, the authorization server MUST deny the request and SHOULD revoke (when possible) all tokens previously issued based on that authorization code. The authorization code is bound to the client identifier and redirection URI.

Parameter Name Type Description Required
code String The authorization code. Required
scope String The authorized scope for the access request (this MAY be a subset of the scopes in the request). The value is a space delimited set of scopes. Required
state String The opaque value supplied by the client to maintain state between the request and callback. Required
Example 25: Sample ACG authorization response (line breaks for clarity)
HTTP/1.1 302 Found
Location https://client.1edtech.org/Authorize?
  code=dcf95d196ae04d60aad7e19d18b9af755a7b593b680055158b8ad9c2975f0d86
  &scope=https%3A%2F%2Fpurl.imsglobal.org%2Fspec%ob%2Fv3p0%2Fscope%2Fassertion.readonly%20offline_access
  &state=26357667-94df-4a14-bcb1-f55449ddd98d
Authorization Error Response

If the authorization server does not recognize the client applications's redirection endpoint from a prior connection with this client application, the authorization server SHOULD inform the user of the error and MUST NOT automatically redirect to the web browser to the invalid redirection URI.

If the user denies the authorization request or if the request fails for reasons other than a missing or invalid redirection URI, the authorization server informs the client by adding the following parameters to the query component of the redirection URI.

Parameter Name Type Description Required
error AuthorizationError A single ASCII [RFC20] error code from the AuthorizationError vocabulary. Required
error_description String Human-readable ASCII [RFC20] text providing additional information, used to assist the client developer in understanding the error that occurred. Values for the "error_description" parameter MUST NOT include characters outside the set %x20-21 / %x23-5B / %x5D-7E.
error_uri URI A URI identifying a human-readable web page with information about the error, used to provide the client developer with additional information about the error. Values for the "error_uri" parameter MUST conform to the URI-reference syntax and thus MUST NOT include characters outside the set %x21 / %x23-5B / %x5D-7E.
state String The opaque value supplied by the client to maintain state between the request and callback. Required
Example 26: Sample authorization error response
HTTP/1.1 302 Found
Location: https://client.1edtech.org/cb?error=access_denied&state=xyz
Access Token Request

With the supplied code, the client application SHOULD attempt to exchange the code for an access_token. The client application makes an authorization grant POST request to the tokenUrl as declared in the resource server's Discovery Document. The HTTP POST request MUST include a Basic authorization header with the client_id and client_secret provided in the registration response. The body of the token request MUST include the following form fields:

Field Name Type Description Required
grant_type String Value MUST be set to "authorization_code". Required
code String The authorization code received from the authorization server. Required
redirect_uri URL The client application's redirection endpoint. Required
scope String The scope of the access request. Required
code_verifier String The PKCE code verifier. Required
Example 27: Sample ACG token request (line breaks for clarity)
POST /token HTTP/1.1
Host: auth.1edtech.org
Authorization: Basic NDE2ZjI1YjhjMWQ5OThlODoxNWQ5MDA4NTk2NDdkZDlm
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code
  &code=7c7a73263ee14b2b48073d0615f286ec74f6636689046cb8dbede0b5e87a1338
  &redirect_uri=https%3A%2F%client.1edtech.org%2FAuthorize
  &scope=https%3A%2F%2Fpurl.imsglobal.org%2Fspec%2Fob%2Fv3p0%2Fscope%2Fassertion.readonly+offline_access
  &code_verifier=mYUQfKNgI1lSbY8EqtvNHLPzu0x%2FcVKO3fpWnX4VE5I%3D
Access Token Response

If the authorization server grants this request (see Section 5.1 in [RFC6749] for the detailed description), it returns HTTP 200 OK status code with content type "application/json" consisting of a JSON object containing the access token and its expiry lifetime (1EdTech recommends a default expiry lifetime of 3600 seconds, one hour, for access tokens), optionally a refresh token, and confirms the set of scopes supported by the access token:

Property Name Type Description Required
access_token String The access token issued by the authorization server. Required
token_type String The type of the token issued. The case insensitive value MUST be "bearer". Required
scope String The scope of the access token. This is a space-separated list of scopes. Required
expires_in PositiveInteger The lifetime in seconds of the access token. For example, the value "3600" denotes that the access token will expire in one hour from the time the response was generated. 1EdTech recommends a default expiry lifetime of 3600 seconds, one hour, for access tokens. If omitted, the authorization server SHOULD provide the expiration time via other means or document the default value. Optional
refresh_token String The refresh token, which can be used to obtain new access tokens using the same authorization grant as described in § Token Refresh Request. Optional
Example 28: Sample ACG token response
HTTP/1.1 200 OK
Cache-Control: no-store, no-cache, max-age=0
Pragma: no-cache
Content-Type: application/json; charset=UTF-8

{
  "access_token": "863DF0B10F5D432EB2933C2A37CD3135A7BB7B07A68F65D92",
  "refresh_token": "tGzv3JOkF0XG5Qx2TlKWIA",
  "expires_in": 3600,
  "token_type": "Bearer",
  "scope": "https://purl.imsglobal.org/spec/ob/v3p0/scope/assertion.readonly offline_access"
}
Access Token Error Response

The authorization server MAY decide not to issue an access token. This could be because the request scopes are invalid, the credentials from the client may be invalid, etc. In this case the authorization server MUST return an HTTP 400 Bad Request status code with content type "application/json" consisting of a JSON object describing the error in the response body. The properties used to describe the error are:

Property Name Type Description Required
error TokenError A single ASCII [RFC20] error code]. See Section 5.2 of [RFC6749]. Required
error_description ASCIIString Human-readable ASCII [RFC20] text providing additional information, used to assist the client developer in understanding the error that occurred. Values for the "error_description" parameter MUST NOT include characters outside the set %x20-21 / %x23-5B / %x5D-7E. Optional
error_uri URI A URI identifying a human-readable web page with information about the error, used to provide the client developer with additional information about the error. Values for the "error_uri" parameter MUST conform to the URI-reference syntax and thus MUST NOT include characters outside the set %x21 / %x23-5B / %x5D-7E. Optional
Example 29: Sample access token error response
HTTP/1.1 400 Bad Request
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache

{
  "error": "invalid_request"
}

7.2.3 Authenticating with Tokens

After obtaining an access_token and optionally a refresh_token using the method above, a client application MAY issue request that access resources controlled by the user on the resource server using the access_token in the HTTP Authorization header [RFC2617] with a Bearer Token [RFC6750]. For example, a getCredentials request would look like this:

Example 30: Sample getCredentials request
GET /ims/ob/v3p0/credentials HTTP/1.1
Host: example.edu
Authorization: Bearer 863DF0B10F5D432EB2933C2A37CD3135A7BB7B07A68F65D92
Accept: application/json

7.3 Token Refresh

The recommended value of the access token's expires_in attribute is 3600 i.e. one hour. This means that the validity of the access token expires one hour after the time it was issued.

When requesting an access token as part of the Authorization Code Grant process, an authorization server MAY return a 'Refresh Token'. The refresh token can be used to obtain an access token using the same authorization grant: this is described in Section 6 of [RFC6749]. The use of the Refresh Token avoids the choreography for obtaining the credentials to gain access to the authorization server.

An Authorization Server is NOT REQUIRED to support token refresh.

Token Refresh Request

If the access_token is expired or about to expire, and the client application received a refresh_token, the client application can use OAuth 2.0 Token Refresh to get a new access_token and refresh_token.

The client makes a refresh POST request to the token endpoint by adding the following parameters using the "application/x-www-form-urlencoded" format in the HTTP request entity-body:

Parameter Name Type Description Required
grant_type String Value MUST be set to "refresh_token". Required
refresh_token String The refresh token issued to the client. Required
scope String The scope of the access request. The requested scope MUST NOT include any scope not originally granted by the user, and if omitted is treated as equal to the scope originally granted by the user. Required
Example 31: Sample ACG token refresh request (line breaks for clarity)
POST /token HTTP/1.1
Host: auth.1edtech.org
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded

grant_type=refresh_token
  &refresh_token=tGzv3JOkF0XG5Qx2TlKWIA
  &scope=https%3A%2F%2Fpurl.imsglobal.org%2Fspec%2Fob%2Fv3p0%2Fscope%2assertion.readonly

Token Refresh Response

If valid and authorized, the authorization server issues a new access token and optionally a new refresh token as described earlier in § Access Token Response. If the request failed verification or is invalid, the authorization server returns an error response as described earlier in § Access Token Error Response.

7.4 Token Revocation

There may be deployments in which revocation of an access token is useful. The Token Revocation process is based upon [RFC7009]. The client requests the revocation of a particular token by making an HTTP POST request (using TLS) to the token revocation endpoint URL. Note that [RFC7009] states that implementations MUST support the revocation of refresh tokens and SHOULD support the revocation of access tokens.

Token Revocation Request

The client constructs the request by including the following parameters using the "application/x-www-form-urlencoded" format in the HTTP request entity-body:

Parameter Name Type Description Required
token String The token that the client wants to get revoked. Required
token_type_hint String MUST be set to either "access_token" or "refresh_token". Required
Example 32: Sample token revocation request
POST /revoke HTTP/1.1
Host: auth.1edtech.org
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded

token=45ghiukldjahdnhzdauz&token_type_hint=refresh_token

Token Revocation Response

The authorization server responds with HTTP 200 OK status code if the token has been revoked successfully or if the client submitted an invalid token.

When the request for revocation is rejected, the authorization server returns an error response as described earlier in § Access Token Error Response with an error code of "unsupported_token_type".

8. Proofs (Signatures)

This section describes mechanisms for ensuring the authenticity and integrity of OpenBadgeCredentials. At least one proof mechanism, and the details necessary to evaluate that proof, MUST be expressed for a credential to be a verifiable credential; that is, to be verifiable.

8.1 Proof Formats

The proof formats included in this specification fall into two categories:

Note
The issuer MAY use multiple proofs. If multiple proofs are provided, the verifier MAY use any one proof to verify the credential.

A third category of proof format called Non-Signature Proof is not covered by this specification. This category includes proofs such as proof of work.

8.2 JSON Web Token Proof Format

This proof format relies on the well established JWT (JSON Web Token) [RFC7519] and JWS (JSON Web Signature) [RFC7515] specifications. A JSON Web Token Proof is a JWT signed and encoded as a Compact JWS string. The proof format is described in detail in Section 6.3.1 "JSON Web Token" of Verifiable Credentials Data Model v1.1. That description allows several options which may inhibit interoperability. This specification limits the options while maintaining compatibility with [VC-DATA-MODEL] to help ensure interoperability.

8.2.1 Terminology

Some of the terms used in this section include:

  • JWT - "JSON Web Token (JWT) is a compact, URL-safe means of representing claims to be transferred between two parties. The claims in a JWT are encoded as a JSON object that is used as the payload of a JSON Web Signature (JWS) structure or as the plaintext of a JSON Web Encryption (JWE) structure, enabling the claims to be digitally signed or integrity protected with a Message Authentication Code (MAC) and/or encrypted." [RFC7519]
  • JWS - "JSON Web Signature (JWS) represents content secured with digital signatures or Message Authentication Codes (MACs) using JSON-based data structures. Cryptographic algorithms and identifiers for use with this specification are described in the separate JSON Web Algorithms (JWA) specification and an IANA registry defined by that specification." [RFC7515]
  • JWK - "A JSON Web Key (JWK) is a JavaScript Object Notation (JSON) data structure that represents a cryptographic key." [RFC7517]
  • Compact JWS - "A compact representation of a JWS." [RFC7515]

8.2.2 Overview

A JWS is a signed JWT with three parts separated by period (".") characters. Each part contains a base64url-encoded value.

  • JOSE Header - Describes the cryptographic operations applied to the JWT and optionally, additional properties of the JWT. [RFC7515]
  • JWT Payload - The JSON object that will be signed. In this specification, the JWT Payload includes the OpenBadgeCredential.
  • JWS Signature - The computed signature of the JWT Payload.

The JOSE Header, JWT Payload, and JWS Signature are combined to form a Compact JWS. To transform a credential into a Compact JWS takes 4 steps:

  1. Create the JOSE Header, specifying the signing algorithm to use
  2. Create the JWT Payload from the credential to be signed
  3. Compute the signature of the JWT Payload
  4. Encode the resulting JWS as a Compact JWS

The resulting JWS proves that the issuer signed the JWT Payload turning the credential into a verifiable credential.

When using the JSON Web Token Proof Format, the proof property MAY be ommitted from the OpenBadgeCredential. If a Linked Data Proof is also provided, it MUST be created before the JSON Web Token Proof Format is created.

8.2.3 Create the JOSE Header

The JOSE Header is a JSON object with the following properties (also called JOSE Headers). Additional JOSE Headers are NOT allowed.

Property / JOSE Header Type Description Required?
alg String The signing algorithm MUST be "RS256" as a minimum as defined in [RFC7518]. Support for other algorithms is permitted but their use limits interoperability. Later versions of this specification MAY add OPTIONAL support for other algorithms. See Section 6.1 RSA Key of the IMS Global Security Framework v1.1. Required
kid URI A URI that can be dereferenced to an object of type JWK representing the public key used to verify the signature. If you do not include a kid property in the header, you MUST include the public key in the jwk property.
Be careful not to accidentally expose the JWK representation of a private key. See RFC7517 for examples of private key representations. The JWK MUST never contain "d".
Optional
jwk JWK A JWK representing the public key used to verify the signature. If you do not include a jwk property in the header, you MUST include the kid property.
Be careful not to accidentally expose the JWK representation of a private key. See RFC7517 for examples of private key representations. The JWK MUST never contain "d".
Optional
typ String If present, MUST be set to "JWT". Optional
Example 33: Sample JOSE Header with reference to a public key in a JWKS
{
  "alg": "RS256",
  "kid": "https://example.edu/keys#key-1",
  "typ": "JWT"
}

8.2.4 Create the JWT Payload

If you are going to use both external and embedded proof formats, add the embedded proofs prior to creating the JWT Payload.

8.2.4.1 JWT Payload Format

The JWT Payload is a JSON object with the following properties (JWT Claims). Additional standard JWT Claims Names are allowed, but their relationship to the credential is not defined.

Property / Claim Name Type Description Required?
exp NumericDate The expirationDate property of the OpenBadgeCredential. Required if the OpenBadgeCredential has an expirationDate. Optional
iss URI The issuer.id property of the OpenBadgeCredential. Required
jti URI The id property of the OpenBadgeCredential. Required
nbf NumericDate The issuanceDate property of the OpenBadgeCredential. Required
sub URI The credentialSubject.id property of the OpenBadgeCredential. Required
vc OpenBadgeCredential The OpenBadgeCredential being signed. Required

8.2.5 Create the Proof

Note: Sign and Encode the JWS

1EdTech strongly recommends using an existing, stable library for this step.

This section uses the follow notations:

  • JOSE Header - denotes the JSON string representation of the JOSE Header.
  • JWT Payload - denotes the JSON string representation of the JWT Payload.
  • BASE64URL(OCTETS) - denotes the base64url encoding of OCTETS per [RFC7515].
  • UTF8(STRING) - denotes the octets of the UTF-8 [RFC3629] representation of STRING, where STRING is a sequence of Unicode [UNICODE] characters.
  • The concatenation of two values A and B is denoted as A || B.

The steps to sign and encode the credential as a Compact JWS are shown below:

  1. Encode the JOSE Header as BASE64URL(UTF8(JOSE Header)).
  2. Encode the JWT Payload as BASE64URL(JWT Payload).
  3. Concatenate the encoded JOSE Header and the encoded JSW Payload as A | "." | B.
  4. Calculate the JWS Signature for C as described in [RFC7515].
  5. Encode the signature as BASE64URL(JWS Signature).
  6. Concatenate C and E as C | "." | E.

The resulting string is the Compact JWS representation of the credential. The Compact JWS includes the credential AND acts as the proof for the credential.

8.2.6 Verify a Credential

Verifiers that receive a OpenBadgeCredential in Compact JWS format MUST perform the following steps to verify the embedded credential.

  1. Base64url-decode the JOSE Header.
  2. If the header includes a kid property, Dereference the kid value to retrieve the public key JWK.
  3. If the header includes a jwk property, convert the jwk value into the public key JWK.
  4. Use the public key JWK to verify the signature as described in "Section 5.2 Message Signature or MAC Validation" of [RFC7515]. If the signature is not valid, the credential proof is not valid.
    Note: Verifying the JWS Signature

    1EdTech strongly recommends using an existing, stable library for this step.

  5. Base64url-decode the JWT Payload segment of the Compact JWS and parse it into a JSON object.
  6. Convert the value of vc claim to an OpenBadgeCredential and continue with § 8.2.6.1 Verify a Credential VC-JWT Signature.
8.2.6.1 Verify a Credential VC-JWT Signature
  • The JSON object MUST have the iss claim, and the value MUST match the issuer.id of the OpenBadgeCredential object. If they do not match, the credential is not valid.
  • The JSON object MUST have the sub claim, and the value MUST match the credentialSubject.id of the OpenBadgeCredential object. If they do not match, the credential is not valid.
  • The JSON object MUST have the nbf claim, and the NumericDate value MUST be converted to a DateTime, and MUST equal the issuanceDate of the OpenBadgeCredential object. If they do not match or if the issuanceDate has not yet occurred, the credential is not valid.
  • The JSON object MUST have the jti claim, and the value MUST match the id of the OpenBadgeCredential object. If they do not match, the credential is not valid.
  • If the JSON object has the exp claim, the NumericDate MUST be converted to a DateTime, and MUST be used to set the value of the expirationDate of the OpenBadgeCredential object. If the credential has expired, the credential is not valid.

8.3 Linked Data Proof Format

This standard supports the Linked Data Proof format using the Ed25519 Signature 2020 suite.

Note
Whenever possible, you should use a library or service to create and verify a Linked Data Proof. For example, Digital Bazaar, Inc. has a GitHub project that implements the Ed25519 Signature 2020 suite at [https://github.com/digitalbazaar/ed25519-signature-2020](https://github.com/digitalbazaar/ed25519-signature-2020).

8.3.1 Create the Proof

Perform these steps to attach a Linked Data Proof to the credential:

  1. Create an instance of Ed25519VerificationKey2020 as shown in Section 3.1.1 Ed25519VerificationKey2020 of [LDS-ED25519-2020].
  2. Using the key material, sign the credential object as shown in Section 7.1 Proof Algothim of [DATA-INTEGRITY-SPEC] to produce a Proof as shown in Section 3.2.1 Ed25519 Signature 2020 with a proofPurpose of "assertionMethod".
  3. Add the resulting proof object to the credential proof property.

8.3.2 Verify an OpenBadgeCredential Linked Data Signature

Verify the Linked Data Proof signature as shown in Section 7.2 Proof Verification Algorthim of [DATA-INTEGRITY-SPEC].

8.4 Key Management

Issuers will need to manage asymmetric keys. The mechanisms by which keys are minted and distributed is outside the scope of this specification. See Section 6. Key Management of the IMS Global Security Framework v1.1.

8.5 Dereferencing the Public Key

All the proof formats in this specification, and all Digital Integrity proofs in general, require the verifier to "dereference" the public key from a URI. Dereferencing means using the URI to get the public key in JWK format. This specification allows the use of an HTTP URL (e.g. https://1edtech.org/keys/1) or a DID URL (e.g. did:key:123), but only requires HTTP URL support.

9. Verificaton and Validation

Verification is the process to determine whether a verifiable credential or verifiable presentation is an authentic and timely statement of the issuer or presenter respectively. This includes checking that: the credential (or presentation) conforms to the specification; the proof method is satisfied; and, if present, the status check succeeds. Verification of a credential does not imply evaluation of the truth of claims encoded in the credential.

Validation is the process of assuring the verifiable credential or verifiable presentation meets the needs of the verifier and other dependent stakeholders. Validating verifiable credentials or verifiable presentations is outside the scope of this specification.

Note
The 1EdTech Validator performs verification as described here.

9.1 OpenBadgeCredential Verification

This section applies to Verifiable Credentials with a type of "OpenBadgeCredential" or "AchievementCredential".

  1. Check that the OpenBadgeCredential conforms to the specification:

    • If the OpenBadgeCredential has a credentialSchema property, and the type of the CredentialSchema object is "1EdTechJsonSchemaValidator2019", check that the credential conforms to JSON Schema as shown in 1EdTech JSON Schema Validator 2019. If it does not, the credential does not conform to the specification.
    • Check that the credentialSubject is identified by an id and/or an identifier. If neither is present, the credential does not conform to the specification.
  2. Check that the proof method is satisfied:

    Note
    The OpenBadgeCredential may have a VC-JWT proof and one or more Linked Data proofs. In this case, the Linked Data proofs will be attached to the OpenBadgeCredential in the vc claim of the signed JWT Payload. You may accept any one proof for verification. You do not need to verify all the signatures.
  3. Refresh the OpenBadgeCredential:

    Note
    Refresh must be completed after checking the proof so that the verifier is not spoofed into receiving a refreshed OpenBadgeCredential from a bad actor.
    • If the refreshService property is present, and the type of the RefreshService object is "1EdTechCredentialRefresh", refresh the OpenBadgeCredential as shown in 1EdTech Credential Refresh Service and then repeat steps 1 and 2. If the refresh is not successful, continue the verification process using the original OpenBadgeCredential.
      Note
      Only perform Refresh once. That is, do not complete Refresh a second time even if the refreshed OpenBadgeCredential also has a refreshService defined.
  4. Check the status:

    • If the credentialStatus property is present, and the type of the CredentialStatus object is "1EdTechRevocationList", determine if the OpenBadgeCredential has been revoked as shown in 1EdTech Revocation List Status Method.
    • If the current date and time is before the issuanceDate, the OpenBadgeCredential is not yet valid.
    • If the current date and time is after the expirationDate, the OpenBadgeCredential is expired.
  5. Optionally verify the subject (recipient):

    Note
    This step is optional, but RECOMMENDED when the OpenBadgeCredential has been exchanged with the verifier as one of the § 5. Open Badges Document Formats.
    • An OpenBadgeCredential is about a person called the recipient. The recipient is identified in the credentialSubject (see AchievementSubject) by id and/or one or more identifier (see IdentityObject). The id or identifier value to use for verification must be shared with the verifier in an out-of-band process such as by email. This is called the known value.
    • To verify the recipient using a known id, simply compare the known value with the id in the ClrSubject. If they are equal then the recipient is verified.
    • To verify the recipient using a known identifier such as email address follow these steps shown in § 9.3 Verify the Recipient Using an Identifier. If you find a match then the recipient is verified.
    • If no match is found, the recipient is not verified.
  6. Verify EndorsementCredentials:

    1. If the OpenBadgeCredential contains any EndorsementCredentials, verify the EndorsementCredentials as shown in § 9.2 EndorsementCredential Verification.

If all the above steps pass, the OpenBadgeCredential may be treated as verified.

9.2 EndorsementCredential Verification

This section applies to Verifiable Credentials with a type of "EndorsementCredential".

  1. Check that the EndorsementCredential conforms to the specification:
    1. If the credential has a credentialSchema property, and the type of the CredentialSchema object is "1EdTechJsonSchemaValidator2019", check that the credential conforms to JSON Schema as shown in 1EdTech JSON Schema Validator 2019. If it does not, the credential does not conform to the specification.
  2. Check that the proof method is satisfied:
    1. If the EndorsementCredential is signed using the § 8.2 JSON Web Token Proof Format (VC-JWT), verify the signature as shown in § 8.2.6 Verify a Credential. If the EndorsementCredential is signed using an embedded proof, verify the signature as shown in § 8.3.2 Verify an OpenBadgeCredential Linked Data Signature. If the signature cannot be verified, the proof method is not satisfied.
      Note
      The EndorsementCredential may have a VC-JWT proof and one or more Linked Data proofs. In this case, the Linked Data proofs will be attached to the EndorsementCredential in the vc claim of the signed JWT Payload. You may accept any one proof for verification. You do not need to verify all the signatures.
  3. Refresh the EndorsementCredential:
    1. If the refreshService property is present, and the type of the RefreshService object is "1EdTechCredentialRefresh", refresh the EndorsementCredential as shown in 1EdTech Credential Refresh Service and then repeat steps 1 and 2. If the refresh is not successful, continue the verification process using the original EndorsementCredential.
      Note
      Refresh must be completed after checking the proof so that the verifier is not spoofed into receiving a refreshed EndorsementCredential from a bad actor.
      Note
      Only perform Refresh once. That is, do not complete Refresh a second time even if the refreshed EndorsementCredential also has a refreshService defined.
  4. Check the status:
    1. If the credentialStatus property is present, and the type of the CredentialStatus object is "1EdTechRevocationList", determine if the EndorsementCredential has been revoked as shown in 1EdTech Revocation List Status Method.
    2. If the current date and time is before the issuanceDate, the EndorsementCredential is not yet valid.
    3. If the current date and time is after the expirationDate, the EndorsementCredential is expired.

If all the above steps pass, the EndorsementCredential may be treated as verified.

9.3 Verify the Recipient Using an Identifier

The known identifier MUST be a plaintext string value. The known identifier type MUST be one of the types in IdentifierTypeEnum or an extension type. For example, if the known identifier is an email address, the known identifier type is emailAddress.

The ClrCredential issuer may include multiple identifiers that can be used for verification. The verifier should compare the known identifier (e.g. known email address) with all the identifiers included by the issuer until a match is found.

  1. If identifier.identityType does not match the known identifier type, skip to the next identifier.
  2. If identifier.hashed is true, calculate the known identifier IdentityHash using the known identifier and the identifier.salt. If the known identifier IdentityHash matches the identifier.identityHash, the recipient is verified.
  3. If identifier.hashed is false, and if the known identifier matches the identifier.identityHash, the recipient is verified.

10. Verifiable Credentials Extensions

The Verifiable Credentials Data Model v1.1 standard defines several types of extensions to enable "permissionless innovation". Conformant extensions are tracked in the Verifiable Credentials Extension Registry.

This standard references four VC Extensions:

Note
The 1EdTech extensions are designed to work with any verifiable credential and may be contributed to the [VC-EXTENSION-REGISTRY] in the future.

11. Best Practices and Implementation Guide

This section is non-normative.

11.1 Terminology

Some of the terms used in this section:

11.2 Support for Decentralized Identifiers (DIDs)

This specification supports the use of DID URLs as an identifier for the issuer and subject of a credential. This specification also supports the use of DID URLs to identify the public key used to verify verifiable credentials with Linked Data Proofs. Until the Decentralized Identifiers (DIDs) v1.0 specification is approved by W3C and this specification is updated, conformance will not require DID support.

12. Conformance and Certification Guide

The goal of 1EdTech certification for Open Badges [OB-30] is to ensure interoperable implementations of badging systems that generate and issue digital badges as well as those that host and display badges.

1EdTech certification for Open Badges demands features and capabilities beyond those that are strictly required by the specification. These additional features are defined in this document. The specification is intentionally left very flexible to allow it to be used for many purposes. Gaining this certification is expected to be more difficult than simply meeting the minimum requirements for producing a valid Open Badge.

Certification may be achieved in one or more of the following services:

The service types and associated certification tests are defined below.

12.1 The Conformance Process

The process for conformance testing role implementations of Open Badges includes the following:

To pass certification, you must take the following steps:

After 1EdTech reviews your submitted information and notifies you that your application is approved, you can claim certification to Open Badges 3.0 and display the 1EdTech certified logo on your website and in your software. The 1EdTech Global Certified Products Directory will list your conformance details.

12.2 Open Badges 3.0 Issuer Service Conformance

A Open Badges Issuer is an application that allows for the creation of OpenBadgeCredentials and the subsequent delivery of OpenBadgeCredentials to recipients that conform to the Open Badges Specification. The candidate platform must issue a valid baked badge and demonstrate how the badge is retrieved by the recipient. The candidate platform must also meet Service Consumer (Write) requirements and can send an AchievementCredential or a Profile to a product that conforms to Service Provider (Write) requirements.

12.2.1 Tests

  1. Create a valid baked 3.0 badge and issue it to the recipient conformance@imsglobal.org and submit the issued badge to the conformance test system.
  2. Complete § 12.6 Service Consumer (Write) Conformance.

12.3 Open Badges 3.0 Displayer Service Conformance

An Open Badges Displayer is an application that displays and verifies badges for viewers. The candidate platform must support viewer-initiated verification of a badge.

12.3.1 Tests

  1. Verify the three badges listed below and submit the status in the conformance test system.
    1. https://someurl/OB30-conformance-verify-1.json
    2. https://someurl/OB30-conformance-verify-2.json
    3. https://someurl/OB30-conformance-verify-3.json

12.4 Open Badges 3.0 Host Service Conformance

An Open Badges Host is an application that can aggregate and publicly host OpenBadgeCredential for recipients. It also supports export of badges at user request. The candidate platform must be able to import all formats of Open Badges as well as prove that badge metadata is not lost upon export of the badge. The candidate platform must also meet § 12.8 Service Provider (Write) Conformance requirements and accept an AchievementCredential or a Profile from an Issuer application. And meet § 12.5 Service Consumer (Read) Conformance and § 12.7 Service Provider (Read) Conformance requirements for exchanging AchievementCredentials with other Host applications.

12.4.1 Tests

  1. Import each of the provided artifacts (baked PNG badge, baked SVG badge, and AchievementCredential URL), verify the badge, and submit the status to the conformance test system.
  2. Export the imported badge and submit the exported badge to the conformance test system.
  3. Complete § 12.8 Service Provider (Write) Conformance.
  4. Complete § 12.5 Service Consumer (Read) Conformance.
  5. Complete § 12.7 Service Provider (Read) Conformance.
Required OpenBadgeCredential Format Use this resource for certification
Baked OpenBadgeCredential (PNG) format https://someurl/OB30-conformance.png
Baked OpenBadgeCredential (SVG) format https://someurl/OB30-conformance.svg
OpenBadgeCredential JSON Resource URL https://someurl/OB30-conformance.jws

12.5 Service Consumer (Read) Conformance

A product that conforms to Service Consumer (Read) requirements can request badges from a product that conforms to Service Provider (Read) requirements.

12.5.1 Required Service Consumer (Read) Endpoint Support

The service endpoints that MUST be supported for Service Consumer (Read) are listed in the table below:

Service Call Endpoint HTTP Verb Mode Authorization
Required
getServiceDescription /ims/ob/v3p0/discovery GET Initiate No
OAuth 2.0 Registration from Service Discovery Document (SDD) GET Initiate No
OAuth 2.0 Authorize from SDD GET Initiate No
OAuth 2.0 Token from SDD POST Initiate No
getCredentials /ims/ob/v3p0/credentials GET Initiate Yes
getProfile /ims/ob/v3p0/profile GET Initiate Yes

12.5.2 Service Consumer (Read) Compliance

The functional capabilities of such systems are:

  • They MUST support the required service endpoints
  • They MUST supply an access token with the appropriate scope to the service endpoints that require authorization
  • They MUST supply or 'handle' all of the required data fields in payloads
  • They MUST be capable of supplying or 'handling' all of the optional data fields in payloads
  • They MUST NOT provide extension data fields in the payloads
  • They MAY support the endpoint payload pagination query parameters. If supported, the corresponding response HTTP pagination headers MUST be supported

12.6 Service Consumer (Write) Conformance

A product that conforms to Service Consumer (Write) requirements can send an OpenBadgeCredential or a Profile to a product that conforms to Service Provider (Write) requirements.

12.6.1 Required Service Consumer (Write) Endpoint Support

The service endpoints that MUST be supported for Service Consumer (Write) are listed in the table below:

Service Call Endpoint HTTP Verb Mode Authorization
Required
getServiceDescription /ims/ob/v3p0/discovery GET Initiate No
OAuth 2.0 Registration from Service Discovery Document (SDD) GET Initiate No
OAuth 2.0 Authorize from SDD GET Initiate No
OAuth 2.0 Token from SDD POST Initiate No
postCredential /ims/ob/v3p0/credentials POST Initiate Yes

12.6.2 Optional Service Consumer (Write) Endpoint Support

The service endpoints that MAY be supported for Service Consumer (Write) are listed in the table below:

Service Call Endpoint HTTP Verb Mode Authorization
Required
postProfile /ims/ob/v3p0/profile POST Initiate Yes

12.6.3 Service Consumer (Write) Compliance

The functional capabilities of such systems are:

  • They MUST support the required endpoints
  • They MAY support the optional endpoints
  • They MUST supply an access token with the appropriate scope to the service endpoints that require authorization
  • They MUST supply or 'handle' all of the required data fields in payloads
  • They MUST be capable of supplying or 'handling' all of the optional data fields in payloads
  • They MUST NOT provide extension data fields in the payloads

12.7 Service Provider (Read) Conformance

A product that conforms to Service Provider (Read) requirements can provide badges to a product that conforms to Service Consumer (Read) requirements.

12.7.1 Required Service Provider (Read) Endpoint Support

The service endpoints that MUST be supported for Service Provider (Read) are listed in the table below:

Service Call Endpoint HTTP Verb Mode Authorization
Required
getServiceDescription /ims/ob/v3p0/discovery GET Respond No
OAuth 2.0 Registration from Service Discovery Document (SDD) GET Respond No
OAuth 2.0 Authorize from SDD GET Respond No
OAuth 2.0 Token from SDD POST Respond No
getCredentials /ims/ob/v3p0/credentials GET Respond Yes
getProfile /ims/ob/v3p0/profile GET Respond Yes

12.7.2 Service Provider (Read) Compliance

The functional capabilities of such systems are:

  • They MUST support the required service endpoints
  • They MUST require an access token with the appropriate scope for endpoints that require authorization
  • They MUST supply or 'handle' all of the required data fields in payloads
  • They MUST be capable of supplying or 'handling' all of the optional data fields in payloads
  • They MUST NOT provide extension data fields in the payloads
  • They MUST support the endpoint payload pagination query parameters, and the corresponding response HTTP pagination headers MUST be supported

12.8 Service Provider (Write) Conformance

A product that conforms to Service Provider (Write) requirements can accept an OpenBadgeCredential or a Profile from a product that conforms to Service Consumer (Write) requirements.

12.8.1 Required Service Provider (Write) Endpoint Support

The service endpoints that MUST be supported for Service Provider (Write) are listed in the table below:

Service Call Endpoint HTTP Verb Mode Authorization
Required
getServiceDescription /ims/ob/v3p0/discovery GET Respond No
OAuth 2.0 Registration from Service Discovery Document (SDD) GET Respond No
OAuth 2.0 Authorize from SDD GET Respond No
OAuth 2.0 Token from SDD POST Respond No
postCredential /ims/ob/v3p0/credentials POST Respond Yes

12.8.2 Optional Service Provider (Write) Endpoint Support

The service endpoints that MAY be supported for Service Provider (Write) are listed in the table below:

Service Call Endpoint HTTP Verb Mode Authorization
Required
postProfile /ims/ob/v3p0/profile POST Respond Yes

12.8.3 Service Provider (Write) Compliance

The functional capabilities of such systems are:

  • They MUST support the required endpoints
  • They MAY support the optional endpoints
  • They MUST require an access token with the appropriate scope for the endpoints that require authorization
  • They MUST supply or 'handle' all of the required data fields in payloads
  • They MUST be capable of supplying or 'handling' all of the optional data fields in payloads
  • They MUST NOT provide extension data fields in the payloads

A. Serialization

The data model as described in Appendix § B. Data Models is the canonical structural representation of an Open Badges verifiable credential (AchievementCredential). All serializations are representations of that data model in a specific format. This section specifies how the data model is realized in JSON-LD and plain JSON.

A.1 JSON

The data model can be encoded in Javascript Object Notation (JSON) [RFC8259] by mapping property types in the Data Model to JSON types as follows:

A.2 JSON-LD

[JSON-LD] is a JSON-based format used to serialize Linked Data. The syntax is designed to easily integrate into deployed systems already using JSON, and provides a smooth upgrade path from JSON to [JSON-LD]. It is primarily intended to be a way to use Linked Data in Web-based programming environments, to build interoperable Web services, and to store Linked Data in JSON-based storage engines.

Instances of the data model are encoded in [JSON-LD] in the same way they are encoded in JSON (Section § A.1 JSON), with the addition of the @context property. The JSON-LD context is described in detail in the [JSON-LD] specification and its use is elaborated on in Section § C. Extending and Profiling the Standard.

Multiple contexts MAY be used or combined to express any arbitrary information about verifiable credentials in idiomatic JSON. The JSON-LD context for all verifiable credentials, available at https://www.w3.org/2018/credentials/v1, is a static document that is never updated and can therefore be downloaded and cached client side. The associated vocabulary document for the Verifiable Credentials Data Model is available at https://www.w3.org/2018/credentials. The JSON-LD context for Open Badges verifiable credentials is available at https://purl.imsglobal.org/spec/ob/v3p0/context/ob_v3p0.jsonld. The associated vocabulary document for the Open Badges Data Model is available at https://purl.imsglobal.org/spec/ob/v3p0/context/ob_v3p0.html. Open Badges verifiable credentials MUST be serialized with both JSON-LD contexts.

Note
Though this specification requires that a @context property be present, it is not required that the value of the @context property be processed using JSON-LD. This is to support processing using plain JSON libraries, such as those that might be used when the verifiable credential is encoded as a JWT. All libraries or processors MUST ensure that the order of the values in the @context property is what is expected for the specific application. Libraries or processors that support JSON-LD can process the @context property using full JSON-LD processing as expected.
Example 34: JSON-LD @context serialization
"@context": [
  "https://www.w3.org/2018/credentials/v1",
  "https://purl.imsglobal.org/spec/ob/v3p0/context/ob_v3p0.jsonld"
]

B. Data Models

B.1 Credential Data Models

The data models in this section are shared by Open Badges Specification v3.0 and Comprehensive Learner Record Standard v2.0.

B.1.1 Achievement

A collection of information about the accomplishment recognized by the Assertion. Many assertions may be created corresponding to one Achievement.

Property Type Description Multiplicity
id URI Unique URI for the Achievement. [1]
type IRI [1..*]
alignment Alignment An object describing which objectives or educational standards this achievement aligns to, if any. [0..*]
achievementType AchievementType Enumeration The type of achievement. This is an extensible vocabulary. [0..1]
creator Profile The person or organization that created the achievement definition. [0..1]
creditsAvailable Float Credit hours associated with this entity, or credit hours possible. For example 3.0. [0..1]
criteria Criteria Criteria describing how to earn the achievement. [1]
description String A short description of the achievement. [1]
endorsement EndorsementCredential Allows endorsers to make specific claims about the Achievement. These endorsements are signed with a Data Integrity proof format. [0..*]
endorsementJwt CompactJws Allows endorsers to make specific claims about the Achievement. These endorsements are signed with the VC-JWT proof format. [0..*]
fieldOfStudy String Category, subject, area of study, discipline, or general branch of knowledge. Examples include Business, Education, Psychology, and Technology. [0..1]
humanCode String The code, generally human readable, associated with an achievement. [0..1]
image Image An image representing the achievement. [0..1]
@language LanguageCode The language of the achievement. [0..1]
name String The name of the achievement. [1]
otherIdentifier IdentifierEntry A list of identifiers for the described entity. [0..*]
related Related The related property identifies another Achievement that should be considered the same for most purposes. It is primarily intended to identify alternate language editions or previous versions of Achievements. [0..*]
resultDescription ResultDescription The set of result descriptions that may be asserted as results with this achievement. [0..*]
specialization String Name given to the focus, concentration, or specific area of study defined in the achievement. Examples include 'Entrepreneurship', 'Technical Communication', and 'Finance'. [0..1]
tag String Tags that describes the type of achievement. [0..*]
version String The version property allows issuers to set a version string for an Achievement. This is particularly useful when replacing a previous version with an update. [0..1]
This class can be extended with additional properties.

B.1.2 AchievementCredential

AchievementCredentials are representations of an awarded achievement, used to share information about a achievement belonging to one earner. Maps to a Verifiable Credential as defined in the [VC-DATA-MODEL].

Property Type Description Multiplicity
@context URI The value of the @context property MUST be an ordered set where the first item is a URI with the value 'https://www.w3.org/2018/credentials/v1', and the second item is a URI with the value 'https://purl.imsglobal.org/spec/ob/v3p0/context/ob_v3p0.jsonld'. [1..*]
id URI Unambiguous reference to the credential. [1]
type IRI The value of the type property MUST be an unordered set. One of the items MUST be the URI 'VerifiableCredential', and one of the items MUST be the URI 'AchievementCredential' or the URI 'OpenBadgeCredential'. [1..*]
name String The name of the credential for display purposes in wallets. For example, in a list of credentials and in detail views. [1]
description String The short description of the credential for display purposes in wallets. [0..1]
image Image The image representing the credential for display purposes in wallets. [0..1]
credentialSubject AchievementSubject The recipient of the achievement. [1]
endorsement EndorsementCredential Allows endorsers to make specific claims about the credential, and the achievement and profiles in the credential. These endorsements are signed with a Data Integrity proof format. [0..*]
endorsementJwt CompactJws Allows endorsers to make specific claims about the credential, and the achievement and profiles in the credential. These endorsements are signed with the VC-JWT proof format. [0..*]
evidence Evidence A description of the work that the recipient did to earn the achievement. This can be a page that links out to other pages if linking directly to the work is infeasible. [0..*]
issuer Profile A description of the individual, entity, or organization that issued the credential. [1]
issuanceDate DateTime Timestamp of when the credential was awarded. [1]
expirationDate DateTime If the credential has some notion of expiry, this indicates a timestamp when a credential should no longer be considered valid. After this time, the credential should be considered expired. [0..1]
proof Proof If present, one or more embedded cryptographic proofs that can be used to detect tampering and verify the authorship of the credential. [0..*]
credentialSchema CredentialSchema The value of the credentialSchema property MUST be one or more data schemas that provide verifiers with enough information to determine if the provided data conforms to the provided schema. [0..*]
credentialStatus CredentialStatus The information in CredentialStatus is used to discover information about the current status of a verifiable credential, such as whether it is suspended or revoked. [0..1]
refreshService RefreshService The information in RefreshService is used to refresh the verifiable credential. [0..1]
This class can be extended with additional properties.

B.1.3 AchievementSubject

A collection of information about the recipient of an achievement. Maps to Credential Subject in [VC-DATA-MODEL].

Property Type Description Multiplicity
id URI An identifier for the Credential Subject. Either id or at least one identifier MUST be supplied. [0..1]
type IRI The value of the type property MUST be an unordered set. One of the items MUST be the IRI 'AchievementSubject'. [1..*]
activityEndDate DateTime The datetime the activity ended. [0..1]
activityStartDate DateTime The datetime the activity started. [0..1]
creditsEarned Float The number of credits earned, generally in semester or quarter credit hours. This field correlates with the Achievement creditsAvailable field. [0..1]
achievement Achievement The achievement being awarded. [0..1]
identifier IdentityObject Other identifiers for the recipient of the achievement. Either id or at least one identifier MUST be supplied. [0..*]
image Image An image representing this user's achievement. If present, this must be a PNG or SVG image, and should be prepared via the 'baking' instructions. An 'unbaked' image for the achievement is defined in the Achievement class and should not be duplicated here. [0..1]
licenseNumber String The license number that was issued with this credential. [0..1]
narrative Markdown A narrative that connects multiple pieces of evidence. Likely only present at this location if evidence is a multi-value array. [0..1]
result Result The set of results being asserted. [0..*]
role String Role, position, or title of the learner when demonstrating or performing the achievement or evidence of learning being asserted. Examples include 'Student President', 'Intern', 'Captain', etc. [0..1]
source Profile The person, organization, or system that assessed the achievement on behalf of the issuer. For example, a school may assess the achievement, while the school district issues the credential. [0..1]
term String The academic term in which this assertion was achieved. [0..1]

B.1.4 Address

Property Type Description Multiplicity
type IRI The value of the type property MUST be an unordered set. One of the items MUST be the IRI 'Address'. [1..*]
addressCountry String A country. [0..1]
addressCountryCode CountryCode A country code. The value must be a ISO 3166-1 alpha-2 country code [ISO3166-1]. [0..1]
addressRegion String A region within the country. [0..1]
addressLocality String A locality within the region. [0..1]
streetAddress String A street address within the locality. [0..1]
postOfficeBoxNumber String A post office box number for PO box addresses. [0..1]
postalCode String A postal code. [0..1]
geo GeoCoordinates The geographic coordinates of the location. [0..1]

B.1.5 Alignment

Describes an alignment between an achievement and a node in an educational framework.

Property Type Description Multiplicity
type IRI The value of the type property MUST be an unordered set. One of the items MUST be the IRI 'Alignment'. [1..*]
targetCode String If applicable, a locally unique string identifier that identifies the alignment target within its framework and/or targetUrl. [0..1]
targetDescription String Short description of the alignment target. [0..1]
targetName String Name of the alignment. [1]
targetFramework String Name of the framework the alignment target. [0..1]
targetType AlignmentTargetType Enumeration The type of the alignment target node. [0..1]
targetUrl URL URL linking to the official description of the alignment target, for example an individual standard within an educational framework. [1]
This class can be extended with additional properties.

B.1.6 Criteria

Descriptive metadata about the achievements necessary to be recognized with an assertion of a particular achievement. This data is added to the Achievement class so that it may be rendered when the achievement assertion is displayed, instead of simply a link to human-readable criteria external to the achievement. Embedding criteria allows either enhancement of an external criteria page or increased portability and ease of use by allowing issuers to skip hosting the formerly-required external criteria page altogether. Criteria is used to allow would-be recipients to learn what is required of them to be recognized with an assertion of a particular achievement. It is also used after the assertion is awarded to a recipient to let those inspecting earned achievements know the general requirements that the recipients met in order to earn it.

Property Type Description Multiplicity
id URI The URI of a webpage that describes in a human-readable format the criteria for the achievement. [0..1]
narrative Markdown A narrative of what is needed to earn the achievement. Markdown is allowed. [0..1]
This class can be extended with additional properties.

B.1.7 EndorsementCredential

A verifiable credential that asserts a claim about an entity.

Property Type Description Multiplicity
@context URI The value of the @context property MUST be an ordered set where the first item is a URI with the value 'https://www.w3.org/2018/credentials/v1', and the second item is a URI with the value 'https://purl.imsglobal.org/spec/ob/v3p0/context/ob_v3p0.jsonld'. [1..*]
type IRI The value of the type property MUST be an unordered set. One of the items MUST be the URI 'VerifiableCredential', and one of the items MUST be the URI 'EndorsementCredential'. [1..*]
credentialSubject EndorsementSubject The individual, entity, organization, assertion, or achievement that is endorsed and the endorsement comment. [1]
id URI Unambiguous reference to the credential. [0..1]
issuer Profile A description of the individual, entity, or organization that issued the credential. [1]
issuanceDate DateTime Timestamp of when the credential was awarded. [1]
expirationDate DateTime If the credential has some notion of expiry, this indicates a timestamp when a credential should no longer be considered valid. After this time, the credential should be considered expired. [0..1]
proof Proof If present, one or more embedded cryptographic proofs that can be used to detect tampering and verify the authorship of the credential. [0..*]
credentialSchema CredentialSchema The value of the credentialSchema property MUST be one or more data schemas that provide verifiers with enough information to determine if the provided data conforms to the provided schema. [0..*]
credentialStatus CredentialStatus The information in CredentialStatus is used to discover information about the current status of a verifiable credential, such as whether it is suspended or revoked. [0..1]
refreshService RefreshService The information in RefreshService is used to refresh the verifiable credential. [0..1]

B.1.8 EndorsementSubject

A collection of information about the subject of the endorsement.

Property Type Description Multiplicity
id URI The identifier of the individual, entity, organization, assertion, or achievement that is endorsed. [1]
type IRI The value of the type property MUST be an unordered set. One of the items MUST be the URI 'VerifiableCredential', and one of the items MUST be the URI 'EndorsementSubject'. [1..*]
endorsementComment Markdown Allows endorsers to make a simple claim in writing about the entity. [0..1]

B.1.9 Evidence

Descriptive metadata about evidence related to the achievement assertion. Each instance of the evidence class present in an assertion corresponds to one entity, though a single entry can describe a set of items collectively. There may be multiple evidence entries referenced from an assertion. The narrative property is also in scope of the assertion class to provide an overall description of the achievement related to the assertion in rich text. It is used here to provide a narrative of achievement of the specific entity described. If both the description and narrative properties are present, displayers can assume the narrative value goes into more detail and is not simply a recapitulation of description.

Property Type Description Multiplicity
id URI The URL of a webpage presenting evidence of achievement or the evidence encoded as a Data URI. The schema of the webpage is undefined. [0..1]
type IRI The value of the type property MUST be an unordered set. One of the items MUST be the IRI 'Evidence'. [1..*]
narrative Markdown A narrative that describes the evidence and process of achievement that led to an assertion. [0..1]
name String A descriptive title of the evidence. [0..1]
description String A longer description of the evidence. [0..1]
genre String A string that describes the type of evidence. For example, Poetry, Prose, Film. [0..1]
audience String A description of the intended audience for a piece of evidence. [0..1]
This class can be extended with additional properties.

B.1.10 GeoCoordinates

The geographic coordinates of a location.

Property Type Description Multiplicity
type IRI The value of the type property MUST be an unordered set. One of the items MUST be the IRI 'GeoCoordinates'. [1]
latitude Float The latitude of the location [WGS84]. [1]
longitude Float The longitude of the location [WGS84]. [1]

B.1.11 IdentifierEntry

Property Type Description Multiplicity
type IRI The value of the type property MUST be an unordered set. One of the items MUST be the IRI 'IdentifierEntry'. [1]
identifier Identifier An identifier. [1]
identifierType IdentifierTypeEnum Enumeration The identifier type. [1]

B.1.12 IdentityObject

A collection of information about the recipient of an achievement.

Property Type Description Multiplicity
type IRI MUST be the IRI 'IdentityObject'. [1]
hashed Boolean Whether or not the identityHash value is hashed. [1]
identityHash IdentityHash Either the IdentityHash of the identity or the plaintext value. If it's possible that the plaintext transmission and storage of the identity value would leak personally identifiable information where there is an expectation of privacy, it is strongly recommended that an IdentityHash be used. [1]
identityType IdentifierTypeEnum Enumeration The identity type. [1]
salt String If the identityHash is hashed, this should contain the string used to salt the hash. If this value is not provided, it should be assumed that the hash was not salted. [0..1]

B.1.13 Image

Metadata about images that represent assertions, achieve or profiles. These properties can typically be represented as just the id string of the image, but using a fleshed-out document allows for including captions and other applicable metadata.

Property Type Description Multiplicity
id URI The URI or Data URI of the image. [1]
type IRI MUST be the IRI 'Image'. [1]
caption String The caption for the image. [0..1]

B.1.14 Profile

A Profile is a collection of information that describes the entity or organization using Open Badges. Issuers must be represented as Profiles, and recipients, endorsers, or other entities may also be represented using this vocabulary. Each Profile that represents an Issuer may be referenced in many BadgeClasses that it has defined. Anyone can create and host an Issuer file to start issuing Open Badges. Issuers may also serve as recipients of Open Badges, often identified within an Assertion by specific properties, like their url or contact email address.

Property Type Description Multiplicity
id URI Unique URI for the Issuer/Profile file. [1]
type IRI The value of the type property MUST be an unordered set. One of the items MUST be the IRI 'Profile'. [1..*]
name String The name of the entity or organization. [0..1]
url URI The homepage or social media profile of the entity, whether individual or institutional. Should be a URL/URI Accessible via HTTP. [0..1]
phone PhoneNumber A phone number. [0..1]
description String A short description of the issuer entity or organization. [0..1]
endorsement EndorsementCredential Allows endorsers to make specific claims about the individual or organization represented by this profile. These endorsements are signed with a Data Integrity proof format. [0..*]
endorsementJwt CompactJws Allows endorsers to make specific claims about the individual or organization represented by this profile. These endorsements are signed with the VC-JWT proof format. [0..*]
image Image An image representing the issuer. This must be a PNG or SVG image. [0..1]
email EmailAddress An email address. [0..1]
address Address An address for the individual or organization. [0..1]
otherIdentifier IdentifierEntry A list of identifiers for the described entity. [0..*]
official String If the entity is an organization, official is the name of an authorized official of the organization. [0..1]
parentOrg Profile The parent organization of the entity. [0..1]
familyName String Family name. In the western world, often referred to as the 'last name' of a person. [0..1]
givenName String Given name. In the western world, often referred to as the 'first name' of a person. [0..1]
additionalName String Additional name. Includes what is often referred to as 'middle name' in the western world. [0..1]
patronymicName String Patronymic name. [0..1]
honorificPrefix String Honorific prefix(es) preceding a person's name (e.g. 'Dr', 'Mrs' or 'Mr'). [0..1]
honorificSuffix String Honorific suffix(es) following a person's name (e.g. 'M.D, PhD'). [0..1]
familyNamePrefix String Family name prefix. As used in some locales, this is the leading part of a family name (e.g. 'de' in the name 'de Boer'). [0..1]
dateOfBirth Date [0..1]
This class can be extended with additional properties.

Identifies a related achievement.

Property Type Description Multiplicity
id URI The related achievement. [1]
@language LanguageCode The language of the related achievement. [0..1]
version String The version of the related achievement. [0..1]

B.1.16 Result

Describes a result that was achieved.

Property Type Description Multiplicity
type IRI The value of the type property MUST be an unordered set. One of the items MUST be the IRI 'Result'. [1..*]
achievedLevel URI If the result represents an achieved rubric criterion level (e.g. Mastered), the value is the id of the RubricCriterionLevel in linked ResultDescription. [0..1]
alignment Alignment The alignments between this result and nodes in external frameworks. This set of alignments are in addition to the set of alignments defined in the corresponding ResultDescription object. [0..*]
resultDescription URI An achievement can have many result descriptions describing possible results. The value of resultDescription is the id of the result description linked to this result. The linked result description must be in the achievement that is being asserted. [0..1]
status ResultStatusType Enumeration The status of the achievement. Required if resultType of the linked ResultDescription is Status. [0..1]
value String A string representing the result of the performance, or demonstration, of the achievement. For example, 'A' if the recipient received an A grade in class. [0..1]
This class can be extended with additional properties.

B.1.17 ResultDescription

Describes a possible achievement result.

Property Type Description Multiplicity
id URI The unique URI for this result description. Required so a result can link to this result description. [1]
type IRI The value of the type property MUST be an unordered set. One of the items MUST be the IRI 'ResultDescription'. [1..*]
alignment Alignment Alignments between this result description and nodes in external frameworks. [0..*]
allowedValue String An ordered list of allowed values. The values should be ordered from low to high as determined by the achievement creator. [0..*]
name String The name of the result. [1]
requiredLevel URI The id of the rubric criterion level required to pass as determined by the achievement creator. [0..1]
requiredValue String A value from allowedValue or within the range of valueMin to valueMax required to pass as determined by the achievement creator. [0..1]
resultType ResultType Enumeration The type of result this description represents. This is an extensible enumerated vocabulary. [1]
rubricCriterionLevel RubricCriterionLevel An ordered array of rubric criterion levels that may be asserted in the linked result. The levels should be ordered from low to high as determined by the achievement creator. [0..*]
valueMax String The maximum possible value that may be asserted in a linked result. [0..1]
valueMin String The minimum possible value that may be asserted in a linked result. [0..1]
This class can be extended with additional properties.

B.1.18 RubricCriterionLevel

Describes a rubric criterion level.

Property Type Description Multiplicity
id URI The unique URI for this rubric criterion level. Required so a result can link to this rubric criterion level. [1]
type IRI The value of the type property MUST be an unordered set. One of the items MUST be the IRI 'RubricCriterionLevel'. [1..*]
alignment Alignment Alignments between this rubric criterion level and a rubric criterion levels defined in external frameworks. [0..*]
description String Description of the rubric criterion level. [0..1]
level String The rubric performance level in terms of success. [0..1]
name String The name of the rubric criterion level. [1]
points String The points associated with this rubric criterion level. [0..1]
This class can be extended with additional properties.

B.1.19 VerifiableCredential

A Verifiable Credential as defined in the [VC-DATA-MODEL].

Property Type Description Multiplicity
@context URI The value of the @context property MUST be an ordered set where the first item is a URI with the value 'https://www.w3.org/2018/credentials/v1'. [1..*]
id URI Unambiguous reference to the credential. [0..1]
type IRI The value of the type property MUST be an unordered set. One of the items MUST be the URI 'VerifiableCredential'. [1..*]
issuer Profile A description of the individual, entity, or organization that issued the credential. [1]
issuanceDate DateTime Timestamp of when the credential was awarded. [1]
expirationDate DateTime If the credential has some notion of expiry, this indicates a timestamp when a credential should no longer be considered valid. After this time, the credential should be considered expired. [0..1]
credentialSubject CredentialSubject The subject of the credential. [1]
proof Proof If present, one or more embedded cryptographic proofs that can be used to detect tampering and verify the authorship of the credential. [0..*]
credentialSchema CredentialSchema The value of the credentialSchema property MUST be one or more data schemas that provide verifiers with enough information to determine if the provided data conforms to the provided schema. [0..*]
credentialStatus CredentialStatus The information in CredentialStatus is used to discover information about the current status of a verifiable credential, such as whether it is suspended or revoked. [0..1]
refreshService RefreshService The information in RefreshService is used to refresh the verifiable credential. [0..1]
This class can be extended with additional properties.

B.1.20 CredentialSchema

Identify the type and location of a data schema.

Property Type Description Multiplicity
id URI The value MUST be a URI identifying the schema file. One instance of CredentialSchema MUST have an id that is the URL of the JSON Schema for this credential defined by this specification. [1]
type IRI The value MUST identify the type of data schema validation. One instance of CredentialSchema MUST have a type of 'JsonSchemaValidator2019'. [1]

B.1.21 CredentialStatus

The information in CredentialStatus is used to discover information about the current status of a verifiable credential, such as whether it is suspended or revoked.

Property Type Description Multiplicity
id URI The value MUST be the URL of the issuer's credential status method. [1]
type IRI The name of the credential status method. [1]

B.1.22 CredentialSubject

Claims about the credential subject. Maps to Credential Subject as defined in the [VC-DATA-MODEL].

Property Type Description Multiplicity
id URI The identity of the credential subject. [0..1]
This class can be extended with additional properties.

B.1.23 Proof

A JSON-LD Linked Data proof.

Property Type Description Multiplicity
type IRI Signature suite used to produce proof. [1]
created DateTime Date the proof was created. [1]
challenge String A value chosen by the verifier to mitigate authentication proof replay attacks. [0..1]
domain String The domain of the proof to restrict its use to a particular target. [0..1]
nonce String A value chosen by the creator of proof to randomize proof values for privacy purposes. [0..1]
proofPurpose String The purpose of the proof to be used with verificationMethod. MUST be 'assertionMethod'. [1]
proofValue String Value of the proof. [1]
verificationMethod URI The URL of the public key that can verify the signature. [1]
This class can be extended with additional properties.

B.1.24 RefreshService

The information in RefreshService is used to refresh the verifiable credential.

Property Type Description Multiplicity
id URI The value MUST be the URL of the issuer's refresh service. [1]
type IRI The name of the refresh service method. [1]
This class can be extended with additional properties.

B.1.25 AchievementType Enumeration

The type of achievement, for example 'Award' or 'Certification'. This is an extensible enumerated vocabulary. Extending the vocabulary makes use of a naming convention.

Term Description
Achievement Represents a generic achievement.
ApprenticeshipCertificate Credential earned through work-based learning and earn-and-learn models that meet standards and are applicable to industry trades and professions. This is an exact match of ApprenticeshipCertificate in [CTDL-TERMS].
Assessment Direct, indirect, formative, and summative evaluation or estimation of the nature, ability, or quality of an entity, performance, or outcome of an action. This is an exact match of Assessment in [CTDL-TERMS].
Assignment Represents the result of a curricular, or co-curricular assignment or exam.
AssociateDegree College/university award for students typically completing the first one to two years of post secondary school education. Equivalent to an award at UNESCO ISCED 2011, Level 5. This is an exact match of AssociateDegree in [CTDL-TERMS].
Award Represents an award.
Badge Visual symbol containing verifiable claims in accordance with the Open Badges specification and delivered digitally. This is an exact match of Badge in [CTDL-TERMS].
BachelorDegree College/university award for students typically completing three to five years of education where course work and activities advance skills beyond those of the first one to two years of college/university study. Equivalent to an award at UNESCO ISCED 2011, Level 6. Use for 5-year cooperative (work-study) programs. A cooperative plan provides for alternate class attendance and employment in business, industry, or government; thus, it allows students to combine actual work experience with their college studies. Also includes bachelor's degrees in which the normal 4 years of work are completed in 3 years. This is an exact match of BachelorDegree in [CTDL-TERMS].
Certificate Credential that designates requisite knowledge and skills of an occupation, profession, or academic program. This is an exact match of Certificate in [CTDL-TERMS].
CertificateOfCompletion Credential that acknowledges completion of an assignment, training or other activity. A record of the activity may or may not exist, and the credential may or may not be designed as preparation for another resource such as a credential, assessment, or learning opportunity. This is an exact match of CertificateOfCompletion in [CTDL-TERMS].
Certification Time-limited, revocable, renewable credential awarded by an authoritative body for demonstrating the knowledge, skills, and abilities to perform specific tasks or an occupation. Certifications can typically be revoked if not renewed, for a violation of a code of ethics (if applicable) or proven incompetence after due process. Description of revocation criteria for a specific Certification should be defined using Revocation Profile. This is an exact match of Certification in [CTDL-TERMS].
CommunityService Represents community service.
Competency Measurable or observable knowledge, skill, or ability necessary to successful performance of a person. This is an exact match of Competency in [CTDL-ASN-TERMS].
Course Represents a course completion.
CoCurricular Represents a co-curricular activity.
Degree Academic credential conferred upon completion of a program or course of study, typically over multiple years at a college or university. This is an exact match of Degree in [CTDL-TERMS].
Diploma Credential awarded by educational institutions for successful completion of a course of study or its equivalent. This is an exact match of Diploma in [CTDL-TERMS].
DoctoralDegree Highest credential award for students who have completed both a bachelor's degree and a master's degree or their equivalent as well as independent research and/or a significant project or paper. Equivalent to UNESCO ISCED, Level 8. This is an exact match of DoctoralDegree in [CTDL-TERMS].
Fieldwork Represents practical activities that are done away school, college, or place of work. Includes internships and practicums.
GeneralEducationDevelopment (GED) Credential awarded by examination that demonstrates that an individual has acquired secondary school-level academic skills. Equivalent to a secondary school diploma, based on passing a state- or province-selected examination such as GED, HiSET, or TASC; or to an award at UNESCO ISCED 2011 Levels 2 or 3. This is an exact match of GeneralEducationDevelopment in [CTDL-TERMS].
JourneymanCertificate Credential awarded to skilled workers on successful completion of an apprenticeship in industry trades and professions. This is an exact match of JourneymanCertificate in [CTDL-TERMS].
LearningProgram Set of learning opportunities that leads to an outcome, usually a credential like a degree or certificate. This is an exact match of LearningProgram in [CTDL-TERMS].
License Credential awarded by a government agency or other authorized organization that constitutes legal authority to do a specific job and/or utilize a specific item, system or infrastructure and are typically earned through some combination of degree or certificate attainment, certifications, assessments, work experience, and/or fees, and are time-limited and must be renewed periodically. This is an exact match of License in [CTDL-TERMS].
Membership Represents membership.
ProfessionalDoctorate Doctoral degree conferred upon completion of a program providing the knowledge and skills for the recognition, credential, or license required for professional practice. Equivalent to an award at UNESCO ISCED 2011, Level 8. This is an exact match of ProfessionalDoctorate in [CTDL-TERMS].
QualityAssuranceCredential Credential assuring that an organization, program, or awarded credential meets prescribed requirements and may include development and administration of qualifying examinations. This is an exact match of QualityAssuranceCredential in [CTDL-TERMS].
MasterCertificate Credential awarded upon demonstration through apprenticeship of the highest level of skills and performance in industry trades and professions. This is an exact match of MasterCertificate in [CTDL-TERMS].
MasterDegree Credential awarded for a graduate level course of study where course work and activities advance skills beyond those of the bachelor's degree or its equivalent. Equivalent to an award at UNESCO ISCED 2011, Level 7. This is an exact match of MasterDegree in [CTDL-TERMS].
MicroCredential Credential that addresses a subset of field-specific knowledge, skills, or competencies; often developmental with relationships to other micro-credentials and field credentials. This is an exact match of MicroCredential in [CTDL-TERMS].
ResearchDoctorate Doctoral degree conferred for advanced work beyond the master level, including the preparation and defense of a thesis or dissertation based on original research, or the planning and execution of an original project demonstrating substantial artistic or scholarly achievement. Equivalent to an award at UNESCO ISCED 2011, Level 8. This is an exact match of ResearchDoctorate in [CTDL-TERMS].
SecondarySchoolDiploma Diploma awarded by secondary education institutions for successful completion of a secondary school program of study. Equivalent to an award at UNESCO ISCED 2011 Levels 2 or 3. This is an exact match of SecondarySchoolDiploma in [CTDL-TERMS].
This enumeration can be extended with new, proprietary terms. The new terms must start with the substring 'ext:'.

B.1.26 AlignmentTargetType Enumeration

The type of the alignment target node in the target framework.

Term Description
ceasn:Competency An alignment to a CTDL-ASN/CTDL competency published by Credential Engine.
ceterms:Credential An alignment to a CTDL Credential published by Credential Engine.
CFItem An alignment to a CASE Framework Item.
CFRubric An alignment to a CASE Framework Rubric.
CFRubricCriterion An alignment to a CASE Framework Rubric Criterion.
CFRubricCriterionLevel An alignment to a CASE Framework Rubric Criterion Level.
CTDL An alignment to a Credential Engine Item.
This enumeration can be extended with new, proprietary terms. The new terms must start with the substring 'ext:'.

B.1.27 IdentifierTypeEnum Enumeration

Term Description
sourcedId
systemId
productId
userName
accountId
emailAddress
nationalIdentityNumber
isbn
issn
lisSourcedId
oneRosterSourcedId
sisSourcedId
ltiContextId
ltiDeploymentId
ltiToolId
ltiPlatformId
ltiUserId
identifier
This enumeration can be extended with new, proprietary terms. The new terms must start with the substring 'ext:'.

B.1.28 ResultType Enumeration

The type of result. This is an extensible enumerated vocabulary. Extending the vocabulary makes use of a naming convention.

Term Description
GradePointAverage The result is a grade point average.
LetterGrade The result is a letter grade.
Percent The result is a percent score.
PerformanceLevel The result is a performance level.
PredictedScore The result is a predicted score.
RawScore The result is a raw score.
Result A generic result.
RubricCriterion The result is from a rubric criterion.
RubricCriterionLevel The result is a rubric criterion level.
RubricScore The result represents a rubric score with both a name and a numeric value.
ScaledScore The result is a scaled score.
Status The result conveys the status of the achievement.
This enumeration can be extended with new, proprietary terms. The new terms must start with the substring 'ext:'.

B.1.29 ResultStatusType Enumeration

Defined vocabulary to convey the status of an achievement.

Term Description
Completed The learner has successfully completed the achievement. This is the default status if no status result is included.
Enrolled The learner is enrolled in the activity described by the achievement.
Failed The learner has unsuccessfully completed the achievement.
InProgress The learner has started progress in the activity described by the achievement.
OnHold The learner has completed the activity described by the achievement, but successful completion has not been awarded, typically for administrative reasons.
Withdrew The learner withdrew from the activity described by the achievement before completion.

B.2 Open Badges API Data Models

The data models in this section are used by the § 6. Open Badges API.

B.2.1 GetOpenBadgeCredentialsResponse

Property Type Description Multiplicity
credential AchievementCredential OpenBadgeCredentials that have not been signed with the VC-JWT Proof Format MUST be in the credential array. [0..*]
compactJwsString CompactJws OpenBadgeCredentials that have been signed with the VC-JWT Proof Format MUST be in the compactJwsString array. [0..*]

B.3 Shared API Data Models

The data models in this section are shared by all 1EdTech service specifications.

B.3.1 Imsx_StatusInfo

This is the container for the status code and associated information returned within the HTTP messages received from the Service Provider.

Property Type Description Multiplicity
imsx_codeMajor Imsx_CodeMajor Enumeration The code major value (from the corresponding enumerated vocabulary). [1]
imsx_severity Imsx_Severity Enumeration The severity value (from the corresponding enumerated vocabulary). [1]
imsx_description String A human readable description supplied by the entity creating the status code information. [0..1]
imsx_codeMinor Imsx_CodeMinor The set of reported code minor status codes. [0..1]

B.3.2 Imsx_CodeMajor Enumeration

This is the set of primary status report values i.e. the major code assigned to the status block. This is used in conjunction with the 'Severity' structure in the status object.

Term Description
failure Denotes that the transaction request has failed. The detailed reason will be reported in the accompanying 'codeMinor' fields.
processing Denotes that the request is being processed at the destination or there has been a local transmission failure. This value is used in asynchronous services.
success Denotes that the request has been successfully completed. If the associated 'severity' value is 'warning' then the request has been partially successful i.e. best effort by the service provider. Other parts of the status information may provide more insight into a partial success response.
unsupported Denotes that the service provider does not support the requested operation. This is the required default response for an unsupported operation by an implementation.

B.3.3 Imsx_Severity Enumeration

This is the context for the status report values. This is used in conjunction with the 'CodeMajor' structure in the status object.

Term Description
error A catastrophic error has occurred in processing the request and so the request was not completed (the Service Provider may not even have received the request).
status The request has been completed and a response was received from the Service Provider.
warning The request has only been partially completed. For an asynchronous service a further response should be expected.

B.3.4 Imsx_CodeMinor

This is the container for the set of code minor status codes reported in the responses from the Service Provider.

Property Type Description Multiplicity
imsx_codeMinorField Imsx_CodeMinorField Each reported code minor status code. [1..*]

B.3.5 Imsx_CodeMinorField

This is the container for a single code minor status code.

Property Type Description Multiplicity
imsx_codeMinorFieldName NormalizedString This should contain the identity of the system that has produced the code minor status code report. [1]
imsx_codeMinorFieldValue Imsx_CodeMinorFieldValue Enumeration The code minor status code (this is a value from the corresponding enumerated vocabulary). [1]

B.3.6 Imsx_CodeMinorFieldValue Enumeration

This is the set of codeMinor status codes that are used to provide further insight into the completion status of the end-to-end transaction i.e. this should be used to provide more information than would be supplied by an HTTP code.

Term Description
forbidden This is used to indicate that the server can be reached and process the request but refuses to take any further action. This would be accompanied by the 'codeMajor/severity' values of 'failure/error' and for a REST binding a HTTP code of '403'.
fullsuccess The request has been fully and successfully implemented by the service provider. For a REST binding this will have an HTTP code of '200' for a successful search request.
internal_server_error This should be used only if there is catastrophic error and there is not a more appropriate code. This would be accompanied by the 'codeMajor/severity' values of 'failure/error' and for a REST binding a HTTP code of '500'.
invalid_data This error condition may occur if a JSON request/response body contains well-formed (i.e. syntactically correct), but semantically erroneous, JSON instructions. This would be accompanied by the 'codeMajor/severity' values of 'failure/error' and a HTTP code of '422'.
invalid_query_parameter An invalid data query parameter field was supplied and the query could not be processed. This would be accompanied by the 'codeMajor/severity' values of 'failure/error' and for a REST binding a HTTP code of '400'.
misdirected_request This is used to indicate that the request was made with a protocol that is not supported by the server. This would be accompanied by the 'codeMajor/severity' values of 'failure/error' and for a REST binding a HTTP code of '421'.
not_acceptable This is used to indicate that the server cannot provide a response with a Content-Type that matches any of the content types in the request Accept header. This would be accompanied by the 'codeMajor/severity' values of 'failure/error' and for a REST binding a HTTP code of '406'.
not_allowed This is used to indicate that the server does not allow the HTTP method. This would be accompanied by the 'codeMajor/severity' values of 'failure/error' and for a REST binding a HTTP code of '405'.
not_modified This is used to indicate that the server did not modify the resource. This would be accompanied by the 'codeMajor/severity' values of 'success/status' and for a REST binding a HTTP code of '304'.
server_busy The server is receiving too many requests. Retry at a later time. This would be accompanied by the 'codeMajor/severity' values of 'failure/error' and for a REST binding a HTTP code of '429'.
unauthorizedrequest The request was not correctly authorised. This would be accompanied by the 'codeMajor/severity' values of 'failure/error' and for a REST binding a HTTP code of '401'.
unknown Any other error occurred. This would be accompanied by the 'codeMajor/severity' values of 'failure/error' and for a REST binding a HTTP code corresponding to the error.

B.4 Shared API Security Data Models

The data models in this section are shared by all 1EdTech service specifications.

B.4.1 ServiceDescriptionDocument

The Service Description Document (SDD) is a machine readable document that contains the description of the service features supported by the Provider/Platform. The SDD is an OpenAPI 3.0 (JSON) [OPENAPIS-3.0] structured document that MUST be a profiled version of the OpenAPI 3.0 (JSON) file provided provided with this specification. This profiled version contains all of the details about the supported set of service end-points, the supported optional data fields, definitions of the proprietary data fields supplied using the permitted extension mechanisms, definitions of the available proprietary endpoints, and information about the security mechanisms.

Note
Only a subset of the object properties are shown here.
Property Type Description Multiplicity
openapi String This string MUST be the semantic version number of the OpenAPI Specification version that the OpenAPI document uses. The openapi field SHOULD be used by tooling specifications and clients to interpret the OpenAPI document. This is not related to the API info.version string. [1]
info OpenApiInfo Information about the API and the resource server.
Note
The proprietary fields x-imssf-image and x-imssf-privacyPolicyUrl are found here.
[1]
components OpenApiComponents Holds a set of reusable objects for different aspects of the OAS.
Note
The proprietary field x-imssf-registrationUrl is found in the securitySchemes components.
[1]

B.4.2 OpenApiComponents

Holds a set of reusable objects for different aspects of the OAS. All objects defined within the components object will have no effect on the API unless they are explicitly referenced from properties outside the components object.

Note
Only a subset of the object properties are shown here.
Property Type Description Multiplicity
securitySchemes OpenApiSecuritySchemes The Map of security scheme objects supported by this specification. [1]

B.4.3 OpenApiInfo

The object provides metadata about the API. The metadata MAY be used by the clients if needed, and MAY be presented in editing or documentation generation tools for convenience.

Note
Only a subset of the object properties are shown here.
Property Type Description Multiplicity
termsOfService URL A fully qualified URL to the resource server's terms of service. [1]
title String The name of the resource server. [1]
version String The version of the API. [1]
x-imssf-image URI An image representing the resource server. MAY be a Data URI or the URL where the image may be found. [0..1]
x-imssf-privacyPolicyUrl URL A fully qualified URL to the resource server's privacy policy. [1]

B.4.4 OpenApiOAuth2SecurityScheme

Defines an OAuth2 security scheme that can be used by the operations.

Note
Only a subset of the object properties are shown here.
Property Type Description Multiplicity
type String MUST be the string oauth2. [1]
description String A short description for the security scheme. [0..1]
x-imssf-registrationUrl URL A fully qualified URL to the Client Registration endpoint. [1]

B.4.5 OpenApiSecuritySchemes

The Map of security scheme objects supported by this specification.

Note
Only a subset of the object properties are shown here.
Property Type Description Multiplicity
OAuth2CCG OpenApiOAuth2SecurityScheme REQUIRED if the authorization server supports the Client Credentials Grant Flow. [0..1]
OAuth2ACG OpenApiOAuth2SecurityScheme REQUIRED if the authorization server supports the Authorization Code Grant Flow. [0..1]

B.5 Shared OAuth 2.0 Data Models

The data models in this section are shared by all 1EdTech service specifications.

B.5.1 AuthorizationError Vocabulary

This is the set of ASCII error code strings that may be returned in response to a client authorization request. See Section 4.1 of [RFC6749].

Term Description
invalid_request The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed.
unauthorized_client The client is not authorized to request an authorization code using this method.
access_denied The resource owner or authorization server denied the request.
unsupported_response_type The authorization server does not support obtaining an authorization code using this method.
invalid_scope The requested scope is invalid, unknown, or malformed.
server_error The authorization server encountered an unexpected condition that prevented it from fulfilling the request. (This error code is needed because a 500 Internal Server Error HTTP status code cannot be returned to the client via an HTTP redirect.)
temporarily_unavailable The authorization server is currently unable to handle the request due to a temporary overloading or maintenance of the server. (This error code is needed because a 503 Service Unavailable HTTP status code cannot be returned to the client via an HTTP redirect.)

B.5.2 RegistrationError Vocabulary

This is the set of ASCII error code strings that may be returned in response to a client registration request. See [RFC7591].

Term Description
invalid_redirect_uri The value of one or more redirection URIs is invalid.
invalid_client_metadata The value of one of the client metadata fields is invalid and the server has rejected this request. Note that an authorization server MAY choose to substitute a valid value for any requested parameter of a client's metadata.
invalid_software_statement The software statement presented is invalid. This MUST only be returned if a Software Statement has been supplied in the registration request. Use of a Software Statement is NOT RECOMMENDED.
unapproved_software_statement The software statement presented is not approved for use by this authorization server. This MUST only be returned if a Software Statement has been supplied in the registration request. Use of a Software Statement is NOT RECOMMENDED.

B.5.3 TokenError Vocabulary

This is the set of ASCII error code strings that may be returned in response to a client token request. See Section 5.2 of [RFC6749].

Term Description
invalid_request The request is missing a required parameter, includes an unsupported parameter value (other than grant type), repeats a parameter, includes multiple credentials, utilizes more than one mechanism for authenticating the client, or is otherwise malformed.
invalid_client Client authentication failed (e.g., unknown client, no client authentication included, or unsupported authentication method). The authorization server MAY return an HTTP 401 (Unauthorized) status code to indicate which HTTP authentication schemes are supported. If the client attempted to authenticate via the "Authorization" request header field, the authorization server MUST respond with an HTTP 401 (Unauthorized) status code and include the "WWW-Authenticate" response header field matching the authentication scheme used by the client.
invalid_grant The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client.
unauthorized_client The authenticated client is not authorized to use this authorization grant type.
unsupported_grant_type The authorization grant type is not supported by the authorization server.
unsupported_token_type The authorization server does not support the revocation of the presented token type. That is, the client tried to revoke an access token on a server not supporting this feature.
invalid_scope The requested scope is invalid, unknown, malformed, or exceeds the scope granted by the resource owner.

B.6 Shared Proof Data Models

Data models for the JSON Web Token Proof Format (VC-JWT) [VC-DATA-MODEL] shared by Open Badges Specification v3.0 and Comprehensive Learner Record Standard v2.0.

B.6.1 Ed25519VerificationKey2020

Property Type Description Multiplicity
id URI The id of the verification method MUST be the JWK thumbprint calculated from the publicKeyMultibase property value according to [MULTIBASE]. [1]
type String The type of the verification method MUST be the string Ed25519VerificationKey2020. [0..1]
controller URI The identify of the entity that controls this public key. [0..1]
publicKeyMultibase String The publicKeyMultibase property of the verification method MUST be a public key encoded according to [MULTICODEC] and formatted according to [MULTIBASE]. The multicodec encoding of a Ed25519 public key is the two-byte prefix 0xed01 followed by the 32-byte public key data. [1]

B.6.2 JWK

A JSON Web Key (JWK) formatted according to [RFC7517].

Property Type Description Multiplicity
kty String The kty (key type) parameter identifies the cryptographic algorithm family used with the key, such as RSA or EC. [1]
use String The use (public key use) parameter identifies the intended use of the public key, such as sig (signature) or end (encryption). [0..1]
key_ops String The key_ops (key operations) parameter identifies the operation(s) for which the key is intended to be used, such as sign (compute digital signature or MAC) or verify (verify digital signature or MAC). [0..1]
alg String The alg (algorithm) parameter identifies the algorithm intended for use with the key, such as RS256 or PS256. [0..1]
kid String The kid (key ID) parameter is used to match a specific key. [0..1]
x5u URI The x5u (X.509 URL) parameter is a URI that refers to a resource for an X.509 public key certificate or certificate chain [RFC5280]. [0..1]
x5c String The x5c (X.509 certificate chain) parameter contains a chain of one or more PKIX certificates [RFC5280]. [0..*]
x5t String The x5t (X.509 certificate SHA-1 thumbprint) parameter is a base64url-encoded SHA-1 thumbprint (a.k.a. digest) of the DER encoding of an X.509 certificate [RFC5280]. [0..1]
x5t_S256 String The x5t#S256 (X.509 certificate SHA-256 thumbprint) parameter is a base64url-encoded SHA-256 thumbprint (a.k.a. digest) of the DER encoding of an X.509 certificate [RFC5280]. [0..1]
This class can be extended with additional properties.

B.6.3 JWKS

A JWK Set (JWKS) formatted according to [RFC7517].

Property Type Description Multiplicity
keys JWK A JWK Set is a JSON object that represents a set of JWKs. [1..*]

B.7 Derived Types

The derived types in this section are shared by all 1EdTech specifications.

Type Description
ASCIIString An ASCII [RFC20] string. The string MUST NOT include characters outside the set %x20-21 / %x23-5B / %x5D-7E.
BaseTerm A term in an enumeration which serves as a common term for all other entries in this enumeration, and as such is less specific. The lexical constraints are the same as for Term.
CompactJws A String in Compact JWS format [RFC7515].
CountryCode A two-digit ISO 3166-1 alpha-2 country code [ISO3166-1].
EmailAddress A NormalizedString representing an email address.
Identifier A NormalizedString that functions as an identifier.
IdentityHash A hash string containing an algorithm identifier and a resulting hash of an identifier, separated by a dollar sign ('$') and the algorithm used to generate the hash. The only supported algorithms are MD5 [RFC1321] and SHA-256 [FIPS-180-4], identified by the strings md5 and sha256 respectively. Resulting hash for each of these algorithms MUST be expressed in hexadecimal using uppercase (A-F, 0-9) or lowercase character (a-f, 0-9) sets. For example: sha256$7a1a1b3f7d40552e4299180e346e3add12bf9a751a43d9c4ca4518febc2c60c6 represents the result of calculating a SHA-256 hash on the string 'mayze'.
IRI A NormalizedString that represents an Internationalized Resource Identifier (IRI), which extends the ASCII characters subset of the Uniform Resource Identifier (URI).
LanguageCode A language code [BCP47].
Markdown A String that may contain Markdown.
NumericDate An Integer representing the number of seconds from from 1970-01-01T00:00:00Z UTC until the specified UTC data/time, ignoring leap seconds.
PhoneNumber A NormalizedString representing a phone number.
Term A term in an enumeration. The lexical constraints are the same as for Token.
URI A NormalizedString that respresents a Uniform Resource Identifier (URI).
URL A URI that represents a Uniform Resource Locator (URL).
UUID An Identifier with the lexical restrictions of a UUID [RFC4122]

B.8 Primitive Types

The primitive types in this section are shared by all 1EdTech specifications.

Type Description
Boolean
Date An [ISO8601] calendar date using the syntax YYYY-MM-DD.
DateTime An [ISO8601] time using the syntax YYYY-MM-DDThh:mm:ss.
Float
Integer
Language A language code [BCP47].
Namespace A namespace data type for defining data from a context other than that as the default for the data model. This is used for importing other data models.
NonNegativeInteger
NormalizedString A String conforming to the normalizedString definition in [XMLSCHEMA-2].
PositiveInteger
String Character strings.

C. Extending and Profiling the Standard

This standard can be extended in three ways:

Extensions SHOULD be presented to the Comprehensive Learner Record project group for review and socialization.

Extensions MUST NOT be required.

Extensions WILL NOT be tested during conformance testing.

This standard can also be profiled. In general, profiling is used to:

C.1 Extending the Data Model

A data model extension may add new classes to the Data Model and/or new properties to existing extensible classes. Extensible classes are identified by the phrase, "This class can be extended with additional properties" shown at the bottom of the table of properties. For example, the Alignment class is extensible.

The extension SHOULD be documented with the following artifacts:

To use the extension implementers MUST do the following:

C.2 Extending Enumerated Vocabularies

All extensible enumerated vocabularies may be extended with custom terms. Extensible vocabularies are identified by the phrase, "This enumeration can be extended with new, proprietary terms" shown at the bottom of the table of terms. For example, the AchivementType enumeration is extensible.

Extended terms MUST start with the prefix "ext:". For example, "ext:MyTerm".

The extended terms SHOULD be documented with the following artifacts:

To use the extended vocabulary implementers MAY do the following:

C.3 Extending the API

An API extension may add new endpoints (with or without new scopes) to the CLR Standard API and/or new responses to the existing endpoints.

The extension SHOULD be documented with the following artifacts:

C.4 Profiles

Profiling is the process by which an 1EdTech specification is tailored to meet the requirements of a specific community: the community could be a reflection of a market sector, a geographic location, etc. An example of such a community is the Norwegian K-12/Schools for whom a profile of the 1EdTech OneRoster 1.2 specification has been created. The process of profiling starts with the corresponding base specification and defines a set of new constraints to make the subsequent modified specification better fit the requirements of the target community. Once the profile has been defined, the next step is to create the corresponding Conformance Test Systems and Certification process for that profile: these will be modified versions of the equivalents created for the base specification. It is recommended that profiling is undertaken within 1EdTech so that the 1EdTech model driven specification tools can be used.

A profile is the product produced by the process of specification Profiling. A Profile of an 1EdTech specification consists of a set of new constraints. In general an 1EdTech specification enables a wide range education and learning workflows, processes and practices. A profile is designed to establish and impose best practices for the target community. A profile MUST only increase constraints i.e. it MUST NOT relax constraints in the base specification. For example the multiplicity of a property in the data model MAY be changed from [1..] (required and permitting many) to [1..1] (required and only one) but MUST NOT become [0..] (optional and permitting many). The most common profiling changes include more strict data typing, changes to enumerations, vocabulary changes, prohibition of endpoints and creation of new endpoints. A profile could make use of the extension capabilties to extend the specification to support new features. The key objective of a rofile is to remove, wherever possible, interoperability uncertainty e.g. by removing optionality.

It is strongly recommended that a profile of this standard is undertaken either by, or with the close support, of 1EdTech. However, no matter who is responsible for creating the profile artefacts (documents, schemas, etc.), it is strongly recommended that 1EdTech specification tools are used. This will ensure that the artefacts are consistent with the base specifications and that useful support documentation is automatically produced e.g. creation of a document that summarises the differences between the base specification and the profile.

D. Examples

D.1 Basic OpenBadgeCredential

Example 35: Sample OpenBadgeCredential
{
  "@context": [
    "https://www.w3.org/2018/credentials/v1",
    "https://imsglobal.github.io/openbadges-specification/context.json"
  ],
  "id": "http://example.edu/credentials/3732",
  "type": ["VerifiableCredential", "OpenBadgeCredential"],
  "issuer": {
    "id": "https://example.edu/issuers/565049",
    "type": ["Profile"],
    "name": "Example University"
  },
  "issuanceDate": "2010-01-01T00:00:00Z",
  "name": "Example University Degree",
  "credentialSubject": {
    "id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
    "type": ["AchievementSubject"]
  }
}
{
  "@context": [
    "https://www.w3.org/2018/credentials/v1",
    "https://imsglobal.github.io/openbadges-specification/context.json",
    "https://w3id.org/security/suites/ed25519-2020/v1"
  ],
  "id": "http://example.edu/credentials/3732",
  "type": [
    "VerifiableCredential",
    "OpenBadgeCredential"
  ],
  "issuer": {
    "id": "https://example.edu/issuers/565049",
    "type": [
      "Profile"
    ],
    "name": "Example University"
  },
  "issuanceDate": "2010-01-01T00:00:00Z",
  "name": "Example University Degree",
  "credentialSubject": {
    "id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
    "type": [
      "AchievementSubject"
    ]
  },
  "proof": [
    {
      "type": "Ed25519Signature2020",
      "created": "2022-06-28T16:28:36Z",
      "verificationMethod": "did:key:z6MkkUD3J14nkYzn46QeuaVSnp7dF85QJKwKvJvfsjx79aXj",
      "proofPurpose": "assertionMethod",
      "proofValue": "z3MUt2ZuU8Byqivxh6GphEM65AFYyNaGYibm97xLTafM7uGufZQLKvJR8itZwxKskvtFM3CUty46v26DZidMNoQnM"
    }
  ]
}
---------------- JWT header ---------------
{
  "alg": "RS256",
  "typ": "JWT",
  "jwk": {
    "e": "AQAB",
    "kty": "RSA",
    "n": "3HMIoYHPPcTQI92IvkMiHmo-IN0MWRAby2J4eyuv-mG1ZXKxplDlRxWq5airmvPlg6q-VF
ovThTwRRCPfMn3dJsPhNNL5j3pCDY0gHSuaeuIyYouro563G8_cOHbpaersGjYpujCv3DAE2_QcCUjv6
BPYJha-EUNwhVxxM3-yMzeZoDP6LRILgUazilkHS37blgirgA3WHo7cmDQe8sVaP-vfkFJCVG7yDxPwR
4TfGAR0UWxObsCa73mSoQl72JGZ-aFOmuQyNcH9DUKGpXKCt1TW54j9eGK3uBF8kG08vVLnDg3_7Kupw
oi9QT3fGBZ2CKCmqujjUtABZm_mxNBjQ"
  }
}
--------------- JWT payload ---------------
// NOTE: The example below uses a valid VC-JWT serialization
//       that duplicates the iss, nbf, jti, and sub fields in the
//       Verifiable Credential (vc) field.
{
  "vc": {
    "@context": [
      "https://www.w3.org/2018/credentials/v1",
      "https://imsglobal.github.io/openbadges-specification/context.json"
    ],
    "id": "http://example.edu/credentials/3732",
    "type": [
      "VerifiableCredential",
      "OpenBadgeCredential"
    ],
    "issuer": {
      "id": "https://example.edu/issuers/565049",
      "type": [
        "Profile"
      ],
      "name": "Example University"
    },
    "issuanceDate": "2010-01-01T00:00:00Z",
    "name": "Example University Degree",
    "credentialSubject": {
      "id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
      "type": [
        "AchievementSubject"
      ]
    }
  },
  "iss": "https://example.edu/issuers/565049",
  "nbf": 1262304000,
  "jti": "http://example.edu/credentials/3732",
  "sub": "did:example:ebfeb1f712ebc6f1c276e12ec21"
}
--------------- JWT ---------------
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImp3ayI6eyJlIjoiQVFBQiIsImt0eSI6IlJTQSIsIm4i
OiIzSE1Jb1lIUFBjVFFJOTJJdmtNaUhtby1JTjBNV1JBYnkySjRleXV2LW1HMVpYS3hwbERsUnhXcTVh
aXJtdlBsZzZxLVZGb3ZUaFR3UlJDUGZNbjNkSnNQaE5OTDVqM3BDRFkwZ0hTdWFldUl5WW91cm81NjNH
OF9jT0hicGFlcnNHallwdWpDdjNEQUUyX1FjQ1VqdjZCUFlKaGEtRVVOd2hWeHhNMy15TXplWm9EUDZM
UklMZ1Vhemlsa0hTMzdibGdpcmdBM1dIbzdjbURRZThzVmFQLXZma0ZKQ1ZHN3lEeFB3UjRUZkdBUjBV
V3hPYnNDYTczbVNvUWw3MkpHWi1hRk9tdVF5TmNIOURVS0dwWEtDdDFUVzU0ajllR0szdUJGOGtHMDh2
VkxuRGczXzdLdXB3b2k5UVQzZkdCWjJDS0NtcXVqalV0QUJabV9teE5CalEifX0.eyJ2YyI6eyJAY29u
dGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vaW1z
Z2xvYmFsLmdpdGh1Yi5pby9vcGVuYmFkZ2VzLXNwZWNpZmljYXRpb24vY29udGV4dC5qc29uIl0sImlk
IjoiaHR0cDovL2V4YW1wbGUuZWR1L2NyZWRlbnRpYWxzLzM3MzIiLCJ0eXBlIjpbIlZlcmlmaWFibGVD
cmVkZW50aWFsIiwiT3BlbkJhZGdlQ3JlZGVudGlhbCJdLCJpc3N1ZXIiOnsiaWQiOiJodHRwczovL2V4
YW1wbGUuZWR1L2lzc3VlcnMvNTY1MDQ5IiwidHlwZSI6WyJQcm9maWxlIl0sIm5hbWUiOiJFeGFtcGxl
IFVuaXZlcnNpdHkifSwiaXNzdWFuY2VEYXRlIjoiMjAxMC0wMS0wMVQwMDowMDowMFoiLCJuYW1lIjoi
RXhhbXBsZSBVbml2ZXJzaXR5IERlZ3JlZSIsImNyZWRlbnRpYWxTdWJqZWN0Ijp7ImlkIjoiZGlkOmV4
YW1wbGU6ZWJmZWIxZjcxMmViYzZmMWMyNzZlMTJlYzIxIiwidHlwZSI6WyJBY2hpZXZlbWVudFN1Ympl
Y3QiXX19LCJpc3MiOiJodHRwczovL2V4YW1wbGUuZWR1L2lzc3VlcnMvNTY1MDQ5IiwibmJmIjoxMjYy
MzA0MDAwLCJqdGkiOiJodHRwOi8vZXhhbXBsZS5lZHUvY3JlZGVudGlhbHMvMzczMiIsInN1YiI6ImRp
ZDpleGFtcGxlOmViZmViMWY3MTJlYmM2ZjFjMjc2ZTEyZWMyMSJ9.MclgyiKPVDDYWcYsQDyP4yhPncX
asMITvGMQwhPUvm_-w5VsVPVnOQIjsLx6URPdWOJR1DNiaAxmVkSQ8rlXP0L1D2HsExbpjSUBV4C2G1H
i-ZEbw2lyYm9wRuLxQRbtEjK7vIeR25hfIM7IQZNl0HvvmewL9JkLp45InWnH3S9bVMV0_o-F5c7QvMz
CXAu6eipnvETmFiPZkKlHr1fyXb42y2YaC9GKSPwvT6vVK9Y4B-InUwXOpruNzO1leHkmpl1x9wCf7wC
7-vyubO3Eest6m86LcdO-e4RBERJwnVuGUvvSQBZ2dJYggNWMO53E82XwOM0xXfWupHxecFNDSA

D.2 Complete OpenBadgeCredential

In this example, all required and optional properties are populated.

Note: Endorsements
The endorsements were signed by different issuers and provided to the issuer of this OpenBadgeCredential.
Example 36: Complete OpenBadgeCredential
{
  "@context": [
    "https://www.w3.org/2018/credentials/v1",
    "https://imsglobal.github.io/openbadges-specification/context.json"
  ],
  "id": "http://1edtech.edu/credentials/3732",
  "type": [
    "VerifiableCredential",
    "OpenBadgeCredential"
  ],
  "name": "1EdTech University Degree for Example Student",
  "description": "1EdTech University Degree Description",
  "image": {
    "id": "https://1edtech.edu/credentials/3732/image",
    "type": "Image",
    "caption": "1EdTech University Degree for Example Student"
  },
  "credentialSubject": {
    "id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
    "type": [
      "AchievementSubject"
    ],
    "activityEndDate": "2010-01-02T00:00:00Z",
    "activityStartDate": "2010-01-01T00:00:00Z",
    "creditsEarned": 42.0,
    "licenseNumber": "A-9320041",
    "role": "Major Domo",
    "source": {
      "id": "https://school.edu/issuers/201234",
      "type": ["Profile"],
      "name": "1EdTech College of Arts"
    },
    "term": "Fall",
    "identifier": [
      {
        "type": "IdentityObject",
        "identityHash": "student@1edtech.edu",
        "identityType": "emailAddress",
        "hashed": false,
        "salt": "not-used"
      },
      {
        "type": "IdentityObject",
        "identityHash": "somebody@gmail.com",
        "identityType": "emailAddress",
        "hashed": false,
        "salt": "not-used"
      }
    ],
    "achievement": {
      "id": "https://1edtech.edu/achievements/degree",
      "type": [
        "Achievement"
      ],
      "alignment": [
        {
          "type": [
            "Alignment"
          ],
          "targetCode": "degree",
          "targetDescription": "1EdTech University Degree programs.",
          "targetName": "1EdTech University Degree",
          "targetFramework": "1EdTech University Program and Course Catalog",
          "targetType": "CFItem",
          "targetUrl": "https://1edtech.edu/catalog/degree"
        },
        {
          "type": [
            "Alignment"
          ],
          "targetCode": "degree",
          "targetDescription": "1EdTech University Degree programs.",
          "targetName": "1EdTech University Degree",
          "targetFramework": "1EdTech University Program and Course Catalog",
          "targetType": "CTDL",
          "targetUrl": "https://credentialengineregistry.org/resources/ce-98cb027b-95ef-4494-908d-6f7790ec6b6b"
        }
      ],
      "achievementType": "Degree",
      "creator": {
        "id": "https://1edtech.edu/issuers/565049",
        "type": [
          "Profile"
        ],
        "name": "1EdTech University",
        "url": "https://1edtech.edu",
        "phone": "1-222-333-4444",
        "description": "1EdTech University provides online degree programs.",
        "endorsement": [
          {
            "@context": [
              "https://www.w3.org/2018/credentials/v1",
              "https://imsglobal.github.io/openbadges-specification/context.json",
              "https://w3id.org/security/suites/ed25519-2020/v1"
            ],
            "type": [
              "VerifiableCredential",
              "EndorsementCredential"
            ],
            "issuer": {
              "id": "https://accrediter.edu/issuers/565049",
              "type": [
                "Profile"
              ],
              "name": "Example Accrediting Agency"
            },
            "issuanceDate": "2010-01-01T00:00:00Z",
            "expirationDate": "2020-01-01T00:00:00Z",
            "credentialSubject": {
              "id": "https://1edtech.edu/issuers/565049",
              "type": [
                "EndorsementSubject"
              ],
              "endorsementComment": "1EdTech University is in good standing"
            },
            "credentialSchema": [
              {
                "id": "https://purl.imsglobal.org/spec/ob/v3p0/schema/endorsementcredential.json",
                "type": "1EdTechJsonSchemaValidator2019"
              },
              {
                "id": "https://accrediter.edu/schema/endorsementcredential.json",
                "type": "JsonSchemaValidator2018"
              }
            ],
            "credentialStatus": {
              "id": "https://1edtech.edu/credentials/3732/revocations",
              "type": "1EdTechRevocationList"
            },
            "refreshService": {
              "id": "http://1edtech.edu/credentials/3732",
              "type": "1EdTechCredentialRefresh"
            },
            "proof": [
              {
                "type": "Ed25519Signature2020",
                "created": "2022-05-26T18:17:08Z",
                "verificationMethod": "https://accrediter.edu/issuers/565049#key-1",
                "proofPurpose": "assertionMethod",
                "proofValue": "zvPkQiUFfJrgnCRhyPkTSkgrGXbnLR15pHH5HZVYNdM4TCAwQHqG7fMeMPLtYNRnEgoV1aJdR5E61eWu5sWRYgtA"
              }
            ]
          },
          {
            "@context": [
              "https://www.w3.org/2018/credentials/v1",
              "https://imsglobal.github.io/openbadges-specification/context.json",
              "https://w3id.org/security/suites/ed25519-2020/v1"
            ],
            "type": [
              "VerifiableCredential",
              "EndorsementCredential"
            ],
            "issuer": {
              "id": "https://state.gov/issuers/565049",
              "type": [
                "Profile"
              ],
              "name": "State Department of Education"
            },
            "issuanceDate": "2010-01-01T00:00:00Z",
            "expirationDate": "2020-01-01T00:00:00Z",
            "credentialSubject": {
              "id": "https://1edtech.edu/issuers/565049",
              "type": [
                "EndorsementSubject"
              ],
              "endorsementComment": "1EdTech University is in good standing"
            },
            "credentialSchema": [
              {
                "id": "https://purl.imsglobal.org/spec/ob/v3p0/schema/endorsementcredential.json",
                "type": "1EdTechJsonSchemaValidator2019"
              },
              {
                "id": "https://state.gov/schema/endorsementcredential.json",
                "type": "JsonSchemaValidator2018"
              }
            ],
            "credentialStatus": {
              "id": "https://state.gov/credentials/3732/revocations",
              "type": "1EdTechRevocationList"
            },
            "refreshService": {
              "id": "http://state.gov/credentials/3732",
              "type": "1EdTechCredentialRefresh"
            },
            "proof": [
              {
                "type": "Ed25519Signature2020",
                "created": "2022-05-26T18:25:59Z",
                "verificationMethod": "https://accrediter.edu/issuers/565049#key-1",
                "proofPurpose": "assertionMethod",
                "proofValue": "z5bDnmSgDczXwZGya6ZjxKaxkdKxzsCMiVSsgEVWxnaWK7ZqbKnzcCd7mUKE9DQaAL2QMXP5AquPeW6W2CWrZ7jNC"
              }
            ]
          }
        ],
        "image": {
          "id": "https://1edtech.edu/logo.png",
          "type": "Image",
          "caption": "1EdTech University logo"
        },
        "email": "registrar@1edtech.edu",
        "address": {
          "type": [
            "Address"
          ],
          "addressCountry": "USA",
          "addressCountryCode": "US",
          "addressRegion": "TX",
          "addressLocality": "Austin",
          "streetAddress": "123 First St",
          "postOfficeBoxNumber": "1",
          "postalCode": "12345",
          "geo": {
            "type": "GeoCoordinates",
            "latitude": 1.0,
            "longitude": 1.0
          }
        },
        "otherIdentifier": [
          {
            "type": "IdentifierEntry",
            "identifier": "12345",
            "identifierType": "sourcedId"
          },
          {
            "type": "IdentifierEntry",
            "identifier": "67890",
            "identifierType": "nationalIdentityNumber"
          }
        ],
        "official": "Horace Mann",
        "parentOrg": {
          "id": "did:example:123456789",
          "type": [
            "Profile"
          ],
          "name": "Universal Universities"
        }
      },
      "creditsAvailable": 36.0,
      "criteria": {
        "id": "https://1edtech.edu/achievements/degree",
        "narrative": "# Degree Requirements\nStudents must complete..."
      },
      "description": "1EdTech University Degree Description",
      "endorsement": [
        {
          "@context": [
            "https://www.w3.org/2018/credentials/v1",
            "https://imsglobal.github.io/openbadges-specification/context.json",
            "https://w3id.org/security/suites/ed25519-2020/v1"
          ],
          "type": [
            "VerifiableCredential",
            "EndorsementCredential"
          ],
          "issuer": {
            "id": "https://accrediter.edu/issuers/565049",
            "type": [
              "Profile"
            ],
            "name": "Example Accrediting Agency"
          },
          "issuanceDate": "2010-01-01T00:00:00Z",
          "expirationDate": "2020-01-01T00:00:00Z",
          "credentialSubject": {
            "id": "https://1edtech.edu/issuers/565049",
            "type": [
              "EndorsementSubject"
            ],
            "endorsementComment": "1EdTech University is in good standing"
          },
          "credentialSchema": [
            {
              "id": "https://purl.imsglobal.org/spec/ob/v3p0/schema/endorsementcredential.json",
              "type": "1EdTechJsonSchemaValidator2019"
            },
            {
              "id": "https://accrediter.edu/schema/endorsementcredential.json",
              "type": "JsonSchemaValidator2018"
            }
          ],
          "credentialStatus": {
            "id": "https://1edtech.edu/credentials/3732/revocations",
            "type": "1EdTechRevocationList"
          },
          "refreshService": {
            "id": "http://1edtech.edu/credentials/3732",
            "type": "1EdTechCredentialRefresh"
          },
          "proof": [
            {
              "type": "Ed25519Signature2020",
              "created": "2022-05-26T18:17:08Z",
              "verificationMethod": "https://accrediter.edu/issuers/565049#key-1",
              "proofPurpose": "assertionMethod",
              "proofValue": "zvPkQiUFfJrgnCRhyPkTSkgrGXbnLR15pHH5HZVYNdM4TCAwQHqG7fMeMPLtYNRnEgoV1aJdR5E61eWu5sWRYgtA"
            }
          ]
        }
      ],
      "fieldOfStudy": "Research",
      "humanCode": "R1",
      "image": {
        "id": "https://1edtech.edu/achievements/degree/image",
        "type": "Image",
        "caption": "1EdTech University Degree"
      },
      "name": "1EdTech University Degree",
      "otherIdentifier": [
        {
          "type": "IdentifierEntry",
          "identifier": "abde",
          "identifierType": "identifier"
        }
      ],
      "resultDescription": [
        {
          "id": "urn:uuid:f6ab24cd-86e8-4eaf-b8c6-ded74e8fd41c",
          "type": [
            "ResultDescription"
          ],
          "alignment": [
            {
              "type": [
                "Alignment"
              ],
              "targetCode": "project",
              "targetDescription": "Project description",
              "targetName": "Final Project",
              "targetFramework": "1EdTech University Program and Course Catalog",
              "targetType": "CFItem",
              "targetUrl": "https://1edtech.edu/catalog/degree/project"
            }
          ],
          "allowedValue": [
            "D",
            "C",
            "B",
            "A"
          ],
          "name": "Final Project Grade",
          "requiredValue": "C",
          "resultType": "LetterGrade"
        },
        {
          "id": "urn:uuid:a70ddc6a-4c4a-4bd8-8277-cb97c79f40c5",
          "type": [
            "ResultDescription"
          ],
          "alignment": [
            {
              "type": [
                "Alignment"
              ],
              "targetCode": "project",
              "targetDescription": "Project description",
              "targetName": "Final Project",
              "targetFramework": "1EdTech University Program and Course Catalog",
              "targetType": "CFItem",
              "targetUrl": "https://1edtech.edu/catalog/degree/project"
            }
          ],
          "allowedValue": [
            "D",
            "C",
            "B",
            "A"
          ],
          "name": "Final Project Grade",
          "requiredLevel": "urn:uuid:d05a0867-d0ad-4b03-bdb5-28fb5d2aab7a",
          "resultType": "RubricCriterionLevel",
          "rubricCriterionLevel": [
            {
              "id": "urn:uuid:d05a0867-d0ad-4b03-bdb5-28fb5d2aab7a",
              "type": [
                "RubricCriterionLevel"
              ],
              "alignment": [
                {
                  "type": [
                    "Alignment"
                  ],
                  "targetCode": "project",
                  "targetDescription": "Project description",
                  "targetName": "Final Project",
                  "targetFramework": "1EdTech University Program and Course Catalog",
                  "targetType": "CFRubricCriterionLevel",
                  "targetUrl": "https://1edtech.edu/catalog/degree/project/rubric/levels/mastered"
                }
              ],
              "description": "The author demonstrated...",
              "level": "Mastered",
              "name": "Mastery",
              "points": "4"
            },
            {
              "id": "urn:uuid:6b84b429-31ee-4dac-9d20-e5c55881f80e",
              "type": [
                "RubricCriterionLevel"
              ],
              "alignment": [
                {
                  "type": [
                    "Alignment"
                  ],
                  "targetCode": "project",
                  "targetDescription": "Project description",
                  "targetName": "Final Project",
                  "targetFramework": "1EdTech University Program and Course Catalog",
                  "targetType": "CFRubricCriterionLevel",
                  "targetUrl": "https://1edtech.edu/catalog/degree/project/rubric/levels/basic"
                }
              ],
              "description": "The author demonstrated...",
              "level": "Basic",
              "name": "Basic",
              "points": "4"
            }
          ]
        },
        {
          "id": "urn:uuid:b07c0387-f2d6-4b65-a3f4-f4e4302ea8f7",
          "type": [
            "ResultDescription"
          ],
          "name": "Project Status",
          "resultType": "Status"
        }
      ],
      "specialization": "Computer Science Research",
      "tag": [
        "research",
        "computer science"
      ]
    },
    "image": {
      "id": "https://1edtech.edu/credentials/3732/image",
      "type": "Image",
      "caption": "1EdTech University Degree for Example Student"
    },
    "narrative": "There is a final project report and source code evidence.",
    "result": [
      {
        "type": [
          "Result"
        ],
        "alignment": [
          {
            "type": [
              "Alignment"
            ],
            "targetCode": "project",
            "targetDescription": "Project description",
            "targetName": "Final Project",
            "targetFramework": "1EdTech University Program and Course Catalog",
            "targetType": "CFItem",
            "targetUrl": "https://1edtech.edu/catalog/degree/project/result/1"
          }
        ],
        "resultDescription": "urn:uuid:f6ab24cd-86e8-4eaf-b8c6-ded74e8fd41c",
        "value": "A"
      },
      {
        "type": [
          "Result"
        ],
        "achievedLevel": "urn:uuid:d05a0867-d0ad-4b03-bdb5-28fb5d2aab7a",
        "alignment": [
          {
            "type": [
              "Alignment"
            ],
            "targetCode": "project",
            "targetDescription": "Project description",
            "targetName": "Final Project",
            "targetFramework": "1EdTech University Program and Course Catalog",
            "targetType": "CFItem",
            "targetUrl": "https://1edtech.edu/catalog/degree/project/result/1"
          }
        ],
        "resultDescription": "urn:uuid:f6ab24cd-86e8-4eaf-b8c6-ded74e8fd41c"
      },
      {
        "type": [
          "Result"
        ],
        "resultDescription": "urn:uuid:f6ab24cd-86e8-4eaf-b8c6-ded74e8fd41c",
        "status": "Completed"
      }
    ]
  },
  "endorsement": [
    {
      "@context": [
        "https://www.w3.org/2018/credentials/v1",
        "https://imsglobal.github.io/openbadges-specification/context.json",
        "https://w3id.org/security/suites/ed25519-2020/v1"
      ],
      "type": [
        "VerifiableCredential",
        "EndorsementCredential"
      ],
      "issuer": {
        "id": "https://accrediter.edu/issuers/565049",
        "type": [
          "Profile"
        ],
        "name": "Example Accrediting Agency"
      },
      "issuanceDate": "2010-01-01T00:00:00Z",
      "expirationDate": "2020-01-01T00:00:00Z",
      "credentialSubject": {
        "id": "https://1edtech.edu/issuers/565049",
        "type": [
          "EndorsementSubject"
        ],
        "endorsementComment": "1EdTech University is in good standing"
      },
      "credentialSchema": [
        {
          "id": "https://purl.imsglobal.org/spec/ob/v3p0/schema/endorsementcredential.json",
          "type": "1EdTechJsonSchemaValidator2019"
        },
        {
          "id": "https://accrediter.edu/schema/endorsementcredential.json",
          "type": "JsonSchemaValidator2018"
        }
      ],
      "credentialStatus": {
        "id": "https://1edtech.edu/credentials/3732/revocations",
        "type": "1EdTechRevocationList"
      },
      "refreshService": {
        "id": "http://1edtech.edu/credentials/3732",
        "type": "1EdTechCredentialRefresh"
      },
      "proof": [
        {
          "type": "Ed25519Signature2020",
          "created": "2022-05-26T18:17:08Z",
          "verificationMethod": "https://accrediter.edu/issuers/565049#key-1",
          "proofPurpose": "assertionMethod",
          "proofValue": "zvPkQiUFfJrgnCRhyPkTSkgrGXbnLR15pHH5HZVYNdM4TCAwQHqG7fMeMPLtYNRnEgoV1aJdR5E61eWu5sWRYgtA"
        }
      ]
    }
  ],
  "evidence": [
    {
      "id": "https://1edtech.edu/credentials/3732/evidence/1",
      "type": [
        "Evidence"
      ],
      "narrative": "# Final Project Report \n This project was ...",
      "name": "Final Project Report",
      "description": "This is the final project report.",
      "genre": "Research",
      "audience": "Department"
    },
    {
      "id": "https://github.com/somebody/project",
      "type": [
        "Evidence"
      ],
      "name": "Final Project Code",
      "description": "This is the source code for the final project app.",
      "genre": "Research",
      "audience": "Department"
    }
  ],
  "issuer": {
    "id": "https://1edtech.edu/issuers/565049",
    "type": [
      "Profile"
    ],
    "name": "1EdTech University",
    "url": "https://1edtech.edu",
    "phone": "1-222-333-4444",
    "description": "1EdTech University provides online degree programs.",
    "endorsement": [
      {
        "@context": [
          "https://www.w3.org/2018/credentials/v1",
          "https://imsglobal.github.io/openbadges-specification/context.json",
          "https://w3id.org/security/suites/ed25519-2020/v1"
        ],
        "type": [
          "VerifiableCredential",
          "EndorsementCredential"
        ],
        "issuer": {
          "id": "https://accrediter.edu/issuers/565049",
          "type": [
            "Profile"
          ],
          "name": "Example Accrediting Agency"
        },
        "issuanceDate": "2010-01-01T00:00:00Z",
        "expirationDate": "2020-01-01T00:00:00Z",
        "credentialSubject": {
          "id": "https://1edtech.edu/issuers/565049",
          "type": [
            "EndorsementSubject"
          ],
          "endorsementComment": "1EdTech University is in good standing"
        },
        "credentialSchema": [
          {
            "id": "https://purl.imsglobal.org/spec/ob/v3p0/schema/endorsementcredential.json",
            "type": "1EdTechJsonSchemaValidator2019"
          },
          {
            "id": "https://accrediter.edu/schema/endorsementcredential.json",
            "type": "JsonSchemaValidator2018"
          }
        ],
        "credentialStatus": {
          "id": "https://1edtech.edu/credentials/3732/revocations",
          "type": "1EdTechRevocationList"
        },
        "refreshService": {
          "id": "http://1edtech.edu/credentials/3732",
          "type": "1EdTechCredentialRefresh"
        },
        "proof": [
          {
            "type": "Ed25519Signature2020",
            "created": "2022-05-26T18:17:08Z",
            "verificationMethod": "https://accrediter.edu/issuers/565049#key-1",
            "proofPurpose": "assertionMethod",
            "proofValue": "zvPkQiUFfJrgnCRhyPkTSkgrGXbnLR15pHH5HZVYNdM4TCAwQHqG7fMeMPLtYNRnEgoV1aJdR5E61eWu5sWRYgtA"
          }
        ]
      }
    ],
    "image": {
      "id": "https://1edtech.edu/logo.png",
      "type": "Image",
      "caption": "1EdTech University logo"
    },
    "email": "registrar@1edtech.edu",
    "address": {
      "type": [
        "Address"
      ],
      "addressCountry": "USA",
      "addressCountryCode": "US",
      "addressRegion": "TX",
      "addressLocality": "Austin",
      "streetAddress": "123 First St",
      "postOfficeBoxNumber": "1",
      "postalCode": "12345",
      "geo": {
        "type": "GeoCoordinates",
        "latitude": 1.0,
        "longitude": 1.0
      }
    },
    "otherIdentifier": [
      {
        "type": "IdentifierEntry",
        "identifier": "12345",
        "identifierType": "sourcedId"
      },
      {
        "type": "IdentifierEntry",
        "identifier": "67890",
        "identifierType": "nationalIdentityNumber"
      }
    ],
    "official": "Horace Mann",
    "parentOrg": {
      "id": "did:example:123456789",
      "type": [
        "Profile"
      ],
      "name": "Universal Universities"
    }
  },
  "issuanceDate": "2010-01-01T00:00:00Z",
  "expirationDate": "2020-01-01T00:00:00Z",
  "credentialSchema": [
    {
      "id": "https://purl.imsglobal.org/spec/ob/v3p0/schema/achievementcredential.json",
      "type": "1EdTechJsonSchemaValidator2019"
    }
  ],
  "credentialStatus": {
    "id": "https://1edtech.edu/credentials/3732/revocations",
    "type": "1EdTechRevocationList"
  },
  "refreshService": {
    "id": "http://1edtech.edu/credentials/3732",
    "type": "1EdTechCredentialRefresh"
  }
}
{
  "@context": [
    "https://www.w3.org/2018/credentials/v1",
    "https://imsglobal.github.io/openbadges-specification/context.json",
    "https://w3id.org/security/suites/ed25519-2020/v1"
  ],
  "id": "http://1edtech.edu/credentials/3732",
  "type": [
    "VerifiableCredential",
    "OpenBadgeCredential"
  ],
  "name": "1EdTech University Degree for Example Student",
  "description": "1EdTech University Degree Description",
  "image": {
    "id": "https://1edtech.edu/credentials/3732/image",
    "type": "Image",
    "caption": "1EdTech University Degree for Example Student"
  },
  "credentialSubject": {
    "id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
    "type": [
      "AchievementSubject"
    ],
    "activityEndDate": "2010-01-02T00:00:00Z",
    "activityStartDate": "2010-01-01T00:00:00Z",
    "creditsEarned": 42,
    "licenseNumber": "A-9320041",
    "role": "Major Domo",
    "source": {
      "id": "https://school.edu/issuers/201234",
      "type": [
        "Profile"
      ],
      "name": "1EdTech College of Arts"
    },
    "term": "Fall",
    "identifier": [
      {
        "type": "IdentityObject",
        "identityHash": "student@1edtech.edu",
        "identityType": "emailAddress",
        "hashed": false,
        "salt": "not-used"
      },
      {
        "type": "IdentityObject",
        "identityHash": "somebody@gmail.com",
        "identityType": "emailAddress",
        "hashed": false,
        "salt": "not-used"
      }
    ],
    "achievement": {
      "id": "https://1edtech.edu/achievements/degree",
      "type": [
        "Achievement"
      ],
      "alignment": [
        {
          "type": [
            "Alignment"
          ],
          "targetCode": "degree",
          "targetDescription": "1EdTech University Degree programs.",
          "targetName": "1EdTech University Degree",
          "targetFramework": "1EdTech University Program and Course Catalog",
          "targetType": "CFItem",
          "targetUrl": "https://1edtech.edu/catalog/degree"
        },
        {
          "type": [
            "Alignment"
          ],
          "targetCode": "degree",
          "targetDescription": "1EdTech University Degree programs.",
          "targetName": "1EdTech University Degree",
          "targetFramework": "1EdTech University Program and Course Catalog",
          "targetType": "CTDL",
          "targetUrl": "https://credentialengineregistry.org/resources/ce-98cb027b-95ef-4494-908d-6f7790ec6b6b"
        }
      ],
      "achievementType": "Degree",
      "creator": {
        "id": "https://1edtech.edu/issuers/565049",
        "type": [
          "Profile"
        ],
        "name": "1EdTech University",
        "url": "https://1edtech.edu",
        "phone": "1-222-333-4444",
        "description": "1EdTech University provides online degree programs.",
        "endorsement": [
          {
            "@context": [
              "https://www.w3.org/2018/credentials/v1",
              "https://imsglobal.github.io/openbadges-specification/context.json",
              "https://w3id.org/security/suites/ed25519-2020/v1"
            ],
            "type": [
              "VerifiableCredential",
              "EndorsementCredential"
            ],
            "issuer": {
              "id": "https://accrediter.edu/issuers/565049",
              "type": [
                "Profile"
              ],
              "name": "Example Accrediting Agency"
            },
            "issuanceDate": "2010-01-01T00:00:00Z",
            "expirationDate": "2020-01-01T00:00:00Z",
            "credentialSubject": {
              "id": "https://1edtech.edu/issuers/565049",
              "type": [
                "EndorsementSubject"
              ],
              "endorsementComment": "1EdTech University is in good standing"
            },
            "credentialSchema": [
              {
                "id": "https://purl.imsglobal.org/spec/ob/v3p0/schema/endorsementcredential.json",
                "type": "1EdTechJsonSchemaValidator2019"
              },
              {
                "id": "https://accrediter.edu/schema/endorsementcredential.json",
                "type": "JsonSchemaValidator2018"
              }
            ],
            "credentialStatus": {
              "id": "https://1edtech.edu/credentials/3732/revocations",
              "type": "1EdTechRevocationList"
            },
            "refreshService": {
              "id": "http://1edtech.edu/credentials/3732",
              "type": "1EdTechCredentialRefresh"
            },
            "proof": [
              {
                "type": "Ed25519Signature2020",
                "created": "2022-05-26T18:17:08Z",
                "verificationMethod": "https://accrediter.edu/issuers/565049#key-1",
                "proofPurpose": "assertionMethod",
                "proofValue": "zvPkQiUFfJrgnCRhyPkTSkgrGXbnLR15pHH5HZVYNdM4TCAwQHqG7fMeMPLtYNRnEgoV1aJdR5E61eWu5sWRYgtA"
              }
            ]
          },
          {
            "@context": [
              "https://www.w3.org/2018/credentials/v1",
              "https://imsglobal.github.io/openbadges-specification/context.json",
              "https://w3id.org/security/suites/ed25519-2020/v1"
            ],
            "type": [
              "VerifiableCredential",
              "EndorsementCredential"
            ],
            "issuer": {
              "id": "https://state.gov/issuers/565049",
              "type": [
                "Profile"
              ],
              "name": "State Department of Education"
            },
            "issuanceDate": "2010-01-01T00:00:00Z",
            "expirationDate": "2020-01-01T00:00:00Z",
            "credentialSubject": {
              "id": "https://1edtech.edu/issuers/565049",
              "type": [
                "EndorsementSubject"
              ],
              "endorsementComment": "1EdTech University is in good standing"
            },
            "credentialSchema": [
              {
                "id": "https://purl.imsglobal.org/spec/ob/v3p0/schema/endorsementcredential.json",
                "type": "1EdTechJsonSchemaValidator2019"
              },
              {
                "id": "https://state.gov/schema/endorsementcredential.json",
                "type": "JsonSchemaValidator2018"
              }
            ],
            "credentialStatus": {
              "id": "https://state.gov/credentials/3732/revocations",
              "type": "1EdTechRevocationList"
            },
            "refreshService": {
              "id": "http://state.gov/credentials/3732",
              "type": "1EdTechCredentialRefresh"
            },
            "proof": [
              {
                "type": "Ed25519Signature2020",
                "created": "2022-05-26T18:25:59Z",
                "verificationMethod": "https://accrediter.edu/issuers/565049#key-1",
                "proofPurpose": "assertionMethod",
                "proofValue": "z5bDnmSgDczXwZGya6ZjxKaxkdKxzsCMiVSsgEVWxnaWK7ZqbKnzcCd7mUKE9DQaAL2QMXP5AquPeW6W2CWrZ7jNC"
              }
            ]
          }
        ],
        "image": {
          "id": "https://1edtech.edu/logo.png",
          "type": "Image",
          "caption": "1EdTech University logo"
        },
        "email": "registrar@1edtech.edu",
        "address": {
          "type": [
            "Address"
          ],
          "addressCountry": "USA",
          "addressCountryCode": "US",
          "addressRegion": "TX",
          "addressLocality": "Austin",
          "streetAddress": "123 First St",
          "postOfficeBoxNumber": "1",
          "postalCode": "12345",
          "geo": {
            "type": "GeoCoordinates",
            "latitude": 1,
            "longitude": 1
          }
        },
        "otherIdentifier": [
          {
            "type": "IdentifierEntry",
            "identifier": "12345",
            "identifierType": "sourcedId"
          },
          {
            "type": "IdentifierEntry",
            "identifier": "67890",
            "identifierType": "nationalIdentityNumber"
          }
        ],
        "official": "Horace Mann",
        "parentOrg": {
          "id": "did:example:123456789",
          "type": [
            "Profile"
          ],
          "name": "Universal Universities"
        }
      },
      "creditsAvailable": 36,
      "criteria": {
        "id": "https://1edtech.edu/achievements/degree",
        "narrative": "# Degree Requirements\nStudents must complete..."
      },
      "description": "1EdTech University Degree Description",
      "endorsement": [
        {
          "@context": [
            "https://www.w3.org/2018/credentials/v1",
            "https://imsglobal.github.io/openbadges-specification/context.json",
            "https://w3id.org/security/suites/ed25519-2020/v1"
          ],
          "type": [
            "VerifiableCredential",
            "EndorsementCredential"
          ],
          "issuer": {
            "id": "https://accrediter.edu/issuers/565049",
            "type": [
              "Profile"
            ],
            "name": "Example Accrediting Agency"
          },
          "issuanceDate": "2010-01-01T00:00:00Z",
          "expirationDate": "2020-01-01T00:00:00Z",
          "credentialSubject": {
            "id": "https://1edtech.edu/issuers/565049",
            "type": [
              "EndorsementSubject"
            ],
            "endorsementComment": "1EdTech University is in good standing"
          },
          "credentialSchema": [
            {
              "id": "https://purl.imsglobal.org/spec/ob/v3p0/schema/endorsementcredential.json",
              "type": "1EdTechJsonSchemaValidator2019"
            },
            {
              "id": "https://accrediter.edu/schema/endorsementcredential.json",
              "type": "JsonSchemaValidator2018"
            }
          ],
          "credentialStatus": {
            "id": "https://1edtech.edu/credentials/3732/revocations",
            "type": "1EdTechRevocationList"
          },
          "refreshService": {
            "id": "http://1edtech.edu/credentials/3732",
            "type": "1EdTechCredentialRefresh"
          },
          "proof": [
            {
              "type": "Ed25519Signature2020",
              "created": "2022-05-26T18:17:08Z",
              "verificationMethod": "https://accrediter.edu/issuers/565049#key-1",
              "proofPurpose": "assertionMethod",
              "proofValue": "zvPkQiUFfJrgnCRhyPkTSkgrGXbnLR15pHH5HZVYNdM4TCAwQHqG7fMeMPLtYNRnEgoV1aJdR5E61eWu5sWRYgtA"
            }
          ]
        }
      ],
      "fieldOfStudy": "Research",
      "humanCode": "R1",
      "image": {
        "id": "https://1edtech.edu/achievements/degree/image",
        "type": "Image",
        "caption": "1EdTech University Degree"
      },
      "name": "1EdTech University Degree",
      "otherIdentifier": [
        {
          "type": "IdentifierEntry",
          "identifier": "abde",
          "identifierType": "identifier"
        }
      ],
      "resultDescription": [
        {
          "id": "urn:uuid:f6ab24cd-86e8-4eaf-b8c6-ded74e8fd41c",
          "type": [
            "ResultDescription"
          ],
          "alignment": [
            {
              "type": [
                "Alignment"
              ],
              "targetCode": "project",
              "targetDescription": "Project description",
              "targetName": "Final Project",
              "targetFramework": "1EdTech University Program and Course Catalog",
              "targetType": "CFItem",
              "targetUrl": "https://1edtech.edu/catalog/degree/project"
            }
          ],
          "allowedValue": [
            "D",
            "C",
            "B",
            "A"
          ],
          "name": "Final Project Grade",
          "requiredValue": "C",
          "resultType": "LetterGrade"
        },
        {
          "id": "urn:uuid:a70ddc6a-4c4a-4bd8-8277-cb97c79f40c5",
          "type": [
            "ResultDescription"
          ],
          "alignment": [
            {
              "type": [
                "Alignment"
              ],
              "targetCode": "project",
              "targetDescription": "Project description",
              "targetName": "Final Project",
              "targetFramework": "1EdTech University Program and Course Catalog",
              "targetType": "CFItem",
              "targetUrl": "https://1edtech.edu/catalog/degree/project"
            }
          ],
          "allowedValue": [
            "D",
            "C",
            "B",
            "A"
          ],
          "name": "Final Project Grade",
          "requiredLevel": "urn:uuid:d05a0867-d0ad-4b03-bdb5-28fb5d2aab7a",
          "resultType": "RubricCriterionLevel",
          "rubricCriterionLevel": [
            {
              "id": "urn:uuid:d05a0867-d0ad-4b03-bdb5-28fb5d2aab7a",
              "type": [
                "RubricCriterionLevel"
              ],
              "alignment": [
                {
                  "type": [
                    "Alignment"
                  ],
                  "targetCode": "project",
                  "targetDescription": "Project description",
                  "targetName": "Final Project",
                  "targetFramework": "1EdTech University Program and Course Catalog",
                  "targetType": "CFRubricCriterionLevel",
                  "targetUrl": "https://1edtech.edu/catalog/degree/project/rubric/levels/mastered"
                }
              ],
              "description": "The author demonstrated...",
              "level": "Mastered",
              "name": "Mastery",
              "points": "4"
            },
            {
              "id": "urn:uuid:6b84b429-31ee-4dac-9d20-e5c55881f80e",
              "type": [
                "RubricCriterionLevel"
              ],
              "alignment": [
                {
                  "type": [
                    "Alignment"
                  ],
                  "targetCode": "project",
                  "targetDescription": "Project description",
                  "targetName": "Final Project",
                  "targetFramework": "1EdTech University Program and Course Catalog",
                  "targetType": "CFRubricCriterionLevel",
                  "targetUrl": "https://1edtech.edu/catalog/degree/project/rubric/levels/basic"
                }
              ],
              "description": "The author demonstrated...",
              "level": "Basic",
              "name": "Basic",
              "points": "4"
            }
          ]
        },
        {
          "id": "urn:uuid:b07c0387-f2d6-4b65-a3f4-f4e4302ea8f7",
          "type": [
            "ResultDescription"
          ],
          "name": "Project Status",
          "resultType": "Status"
        }
      ],
      "specialization": "Computer Science Research",
      "tag": [
        "research",
        "computer science"
      ]
    },
    "image": {
      "id": "https://1edtech.edu/credentials/3732/image",
      "type": "Image",
      "caption": "1EdTech University Degree for Example Student"
    },
    "narrative": "There is a final project report and source code evidence.",
    "result": [
      {
        "type": [
          "Result"
        ],
        "alignment": [
          {
            "type": [
              "Alignment"
            ],
            "targetCode": "project",
            "targetDescription": "Project description",
            "targetName": "Final Project",
            "targetFramework": "1EdTech University Program and Course Catalog",
            "targetType": "CFItem",
            "targetUrl": "https://1edtech.edu/catalog/degree/project/result/1"
          }
        ],
        "resultDescription": "urn:uuid:f6ab24cd-86e8-4eaf-b8c6-ded74e8fd41c",
        "value": "A"
      },
      {
        "type": [
          "Result"
        ],
        "achievedLevel": "urn:uuid:d05a0867-d0ad-4b03-bdb5-28fb5d2aab7a",
        "alignment": [
          {
            "type": [
              "Alignment"
            ],
            "targetCode": "project",
            "targetDescription": "Project description",
            "targetName": "Final Project",
            "targetFramework": "1EdTech University Program and Course Catalog",
            "targetType": "CFItem",
            "targetUrl": "https://1edtech.edu/catalog/degree/project/result/1"
          }
        ],
        "resultDescription": "urn:uuid:f6ab24cd-86e8-4eaf-b8c6-ded74e8fd41c"
      },
      {
        "type": [
          "Result"
        ],
        "resultDescription": "urn:uuid:f6ab24cd-86e8-4eaf-b8c6-ded74e8fd41c",
        "status": "Completed"
      }
    ]
  },
  "endorsement": [
    {
      "@context": [
        "https://www.w3.org/2018/credentials/v1",
        "https://imsglobal.github.io/openbadges-specification/context.json",
        "https://w3id.org/security/suites/ed25519-2020/v1"
      ],
      "type": [
        "VerifiableCredential",
        "EndorsementCredential"
      ],
      "issuer": {
        "id": "https://accrediter.edu/issuers/565049",
        "type": [
          "Profile"
        ],
        "name": "Example Accrediting Agency"
      },
      "issuanceDate": "2010-01-01T00:00:00Z",
      "expirationDate": "2020-01-01T00:00:00Z",
      "credentialSubject": {
        "id": "https://1edtech.edu/issuers/565049",
        "type": [
          "EndorsementSubject"
        ],
        "endorsementComment": "1EdTech University is in good standing"
      },
      "credentialSchema": [
        {
          "id": "https://purl.imsglobal.org/spec/ob/v3p0/schema/endorsementcredential.json",
          "type": "1EdTechJsonSchemaValidator2019"
        },
        {
          "id": "https://accrediter.edu/schema/endorsementcredential.json",
          "type": "JsonSchemaValidator2018"
        }
      ],
      "credentialStatus": {
        "id": "https://1edtech.edu/credentials/3732/revocations",
        "type": "1EdTechRevocationList"
      },
      "refreshService": {
        "id": "http://1edtech.edu/credentials/3732",
        "type": "1EdTechCredentialRefresh"
      },
      "proof": [
        {
          "type": "Ed25519Signature2020",
          "created": "2022-05-26T18:17:08Z",
          "verificationMethod": "https://accrediter.edu/issuers/565049#key-1",
          "proofPurpose": "assertionMethod",
          "proofValue": "zvPkQiUFfJrgnCRhyPkTSkgrGXbnLR15pHH5HZVYNdM4TCAwQHqG7fMeMPLtYNRnEgoV1aJdR5E61eWu5sWRYgtA"
        }
      ]
    }
  ],
  "evidence": [
    {
      "id": "https://1edtech.edu/credentials/3732/evidence/1",
      "type": [
        "Evidence"
      ],
      "narrative": "# Final Project Report \n This project was ...",
      "name": "Final Project Report",
      "description": "This is the final project report.",
      "genre": "Research",
      "audience": "Department"
    },
    {
      "id": "https://github.com/somebody/project",
      "type": [
        "Evidence"
      ],
      "name": "Final Project Code",
      "description": "This is the source code for the final project app.",
      "genre": "Research",
      "audience": "Department"
    }
  ],
  "issuer": {
    "id": "https://1edtech.edu/issuers/565049",
    "type": [
      "Profile"
    ],
    "name": "1EdTech University",
    "url": "https://1edtech.edu",
    "phone": "1-222-333-4444",
    "description": "1EdTech University provides online degree programs.",
    "endorsement": [
      {
        "@context": [
          "https://www.w3.org/2018/credentials/v1",
          "https://imsglobal.github.io/openbadges-specification/context.json",
          "https://w3id.org/security/suites/ed25519-2020/v1"
        ],
        "type": [
          "VerifiableCredential",
          "EndorsementCredential"
        ],
        "issuer": {
          "id": "https://accrediter.edu/issuers/565049",
          "type": [
            "Profile"
          ],
          "name": "Example Accrediting Agency"
        },
        "issuanceDate": "2010-01-01T00:00:00Z",
        "expirationDate": "2020-01-01T00:00:00Z",
        "credentialSubject": {
          "id": "https://1edtech.edu/issuers/565049",
          "type": [
            "EndorsementSubject"
          ],
          "endorsementComment": "1EdTech University is in good standing"
        },
        "credentialSchema": [
          {
            "id": "https://purl.imsglobal.org/spec/ob/v3p0/schema/endorsementcredential.json",
            "type": "1EdTechJsonSchemaValidator2019"
          },
          {
            "id": "https://accrediter.edu/schema/endorsementcredential.json",
            "type": "JsonSchemaValidator2018"
          }
        ],
        "credentialStatus": {
          "id": "https://1edtech.edu/credentials/3732/revocations",
          "type": "1EdTechRevocationList"
        },
        "refreshService": {
          "id": "http://1edtech.edu/credentials/3732",
          "type": "1EdTechCredentialRefresh"
        },
        "proof": [
          {
            "type": "Ed25519Signature2020",
            "created": "2022-05-26T18:17:08Z",
            "verificationMethod": "https://accrediter.edu/issuers/565049#key-1",
            "proofPurpose": "assertionMethod",
            "proofValue": "zvPkQiUFfJrgnCRhyPkTSkgrGXbnLR15pHH5HZVYNdM4TCAwQHqG7fMeMPLtYNRnEgoV1aJdR5E61eWu5sWRYgtA"
          }
        ]
      }
    ],
    "image": {
      "id": "https://1edtech.edu/logo.png",
      "type": "Image",
      "caption": "1EdTech University logo"
    },
    "email": "registrar@1edtech.edu",
    "address": {
      "type": [
        "Address"
      ],
      "addressCountry": "USA",
      "addressCountryCode": "US",
      "addressRegion": "TX",
      "addressLocality": "Austin",
      "streetAddress": "123 First St",
      "postOfficeBoxNumber": "1",
      "postalCode": "12345",
      "geo": {
        "type": "GeoCoordinates",
        "latitude": 1,
        "longitude": 1
      }
    },
    "otherIdentifier": [
      {
        "type": "IdentifierEntry",
        "identifier": "12345",
        "identifierType": "sourcedId"
      },
      {
        "type": "IdentifierEntry",
        "identifier": "67890",
        "identifierType": "nationalIdentityNumber"
      }
    ],
    "official": "Horace Mann",
    "parentOrg": {
      "id": "did:example:123456789",
      "type": [
        "Profile"
      ],
      "name": "Universal Universities"
    }
  },
  "issuanceDate": "2010-01-01T00:00:00Z",
  "expirationDate": "2020-01-01T00:00:00Z",
  "credentialSchema": [
    {
      "id": "https://purl.imsglobal.org/spec/ob/v3p0/schema/achievementcredential.json",
      "type": "1EdTechJsonSchemaValidator2019"
    }
  ],
  "credentialStatus": {
    "id": "https://1edtech.edu/credentials/3732/revocations",
    "type": "1EdTechRevocationList"
  },
  "refreshService": {
    "id": "http://1edtech.edu/credentials/3732",
    "type": "1EdTechCredentialRefresh"
  },
  "proof": [
    {
      "type": "Ed25519Signature2020",
      "created": "2022-06-28T16:28:36Z",
      "verificationMethod": "did:key:z6MkkUD3J14nkYzn46QeuaVSnp7dF85QJKwKvJvfsjx79aXj",
      "proofPurpose": "assertionMethod",
      "proofValue": "z5JEFccUSxFatzowYoF2S7kvebeTYv4JBA26zfrTnpRU6H28Q5EnL3G7XVNBvBw95sk5vMDSqF1YTMVJE68kuYbJk"
    }
  ]
}
---------------- JWT header ---------------
{
  "alg": "RS256",
  "typ": "JWT",
  "jwk": {
    "e": "AQAB",
    "kty": "RSA",
    "n": "3HMIoYHPPcTQI92IvkMiHmo-IN0MWRAby2J4eyuv-mG1ZXKxplDlRxWq5airmvPlg6q-VF
ovThTwRRCPfMn3dJsPhNNL5j3pCDY0gHSuaeuIyYouro563G8_cOHbpaersGjYpujCv3DAE2_QcCUjv6
BPYJha-EUNwhVxxM3-yMzeZoDP6LRILgUazilkHS37blgirgA3WHo7cmDQe8sVaP-vfkFJCVG7yDxPwR
4TfGAR0UWxObsCa73mSoQl72JGZ-aFOmuQyNcH9DUKGpXKCt1TW54j9eGK3uBF8kG08vVLnDg3_7Kupw
oi9QT3fGBZ2CKCmqujjUtABZm_mxNBjQ"
  }
}
--------------- JWT payload ---------------
// NOTE: The example below uses a valid VC-JWT serialization
//       that duplicates the iss, nbf, jti, and sub fields in the
//       Verifiable Credential (vc) field.
{
  "vc": {
    "@context": [
      "https://www.w3.org/2018/credentials/v1",
      "https://imsglobal.github.io/openbadges-specification/context.json"
    ],
    "id": "http://1edtech.edu/credentials/3732",
    "type": [
      "VerifiableCredential",
      "OpenBadgeCredential"
    ],
    "name": "1EdTech University Degree for Example Student",
    "description": "1EdTech University Degree Description",
    "image": {
      "id": "https://1edtech.edu/credentials/3732/image",
      "type": "Image",
      "caption": "1EdTech University Degree for Example Student"
    },
    "credentialSubject": {
      "id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
      "type": [
        "AchievementSubject"
      ],
      "activityEndDate": "2010-01-02T00:00:00Z",
      "activityStartDate": "2010-01-01T00:00:00Z",
      "creditsEarned": 42,
      "licenseNumber": "A-9320041",
      "role": "Major Domo",
      "source": {
        "id": "https://school.edu/issuers/201234",
        "type": [
          "Profile"
        ],
        "name": "1EdTech College of Arts"
      },
      "term": "Fall",
      "identifier": [
        {
          "type": "IdentityObject",
          "identityHash": "student@1edtech.edu",
          "identityType": "emailAddress",
          "hashed": false,
          "salt": "not-used"
        },
        {
          "type": "IdentityObject",
          "identityHash": "somebody@gmail.com",
          "identityType": "emailAddress",
          "hashed": false,
          "salt": "not-used"
        }
      ],
      "achievement": {
        "id": "https://1edtech.edu/achievements/degree",
        "type": [
          "Achievement"
        ],
        "alignment": [
          {
            "type": [
              "Alignment"
            ],
            "targetCode": "degree",
            "targetDescription": "1EdTech University Degree programs.",
            "targetName": "1EdTech University Degree",
            "targetFramework": "1EdTech University Program and Course Catalog",
            "targetType": "CFItem",
            "targetUrl": "https://1edtech.edu/catalog/degree"
          },
          {
            "type": [
              "Alignment"
            ],
            "targetCode": "degree",
            "targetDescription": "1EdTech University Degree programs.",
            "targetName": "1EdTech University Degree",
            "targetFramework": "1EdTech University Program and Course Catalog",
            "targetType": "CTDL",
            "targetUrl": "https://credentialengineregistry.org/resources/ce-98cb
027b-95ef-4494-908d-6f7790ec6b6b"
          }
        ],
        "achievementType": "Degree",
        "creator": {
          "id": "https://1edtech.edu/issuers/565049",
          "type": [
            "Profile"
          ],
          "name": "1EdTech University",
          "url": "https://1edtech.edu",
          "phone": "1-222-333-4444",
          "description": "1EdTech University provides online degree programs.",
          "endorsement": [
            {
              "@context": [
                "https://www.w3.org/2018/credentials/v1",
                "https://imsglobal.github.io/openbadges-specification/context.js
on",
                "https://w3id.org/security/suites/ed25519-2020/v1"
              ],
              "type": [
                "VerifiableCredential",
                "EndorsementCredential"
              ],
              "issuer": {
                "id": "https://accrediter.edu/issuers/565049",
                "type": [
                  "Profile"
                ],
                "name": "Example Accrediting Agency"
              },
              "issuanceDate": "2010-01-01T00:00:00Z",
              "expirationDate": "2020-01-01T00:00:00Z",
              "credentialSubject": {
                "id": "https://1edtech.edu/issuers/565049",
                "type": [
                  "EndorsementSubject"
                ],
                "endorsementComment": "1EdTech University is in good standing"
              },
              "credentialSchema": [
                {
                  "id": "https://purl.imsglobal.org/spec/ob/v3p0/schema/endorsem
entcredential.json",
                  "type": "1EdTechJsonSchemaValidator2019"
                },
                {
                  "id": "https://accrediter.edu/schema/endorsementcredential.jso
n",
                  "type": "JsonSchemaValidator2018"
                }
              ],
              "credentialStatus": {
                "id": "https://1edtech.edu/credentials/3732/revocations",
                "type": "1EdTechRevocationList"
              },
              "refreshService": {
                "id": "http://1edtech.edu/credentials/3732",
                "type": "1EdTechCredentialRefresh"
              },
              "proof": [
                {
                  "type": "Ed25519Signature2020",
                  "created": "2022-05-26T18:17:08Z",
                  "verificationMethod": "https://accrediter.edu/issuers/565049#k
ey-1",
                  "proofPurpose": "assertionMethod",
                  "proofValue": "zvPkQiUFfJrgnCRhyPkTSkgrGXbnLR15pHH5HZVYNdM4TCA
wQHqG7fMeMPLtYNRnEgoV1aJdR5E61eWu5sWRYgtA"
                }
              ]
            },
            {
              "@context": [
                "https://www.w3.org/2018/credentials/v1",
                "https://imsglobal.github.io/openbadges-specification/context.js
on",
                "https://w3id.org/security/suites/ed25519-2020/v1"
              ],
              "type": [
                "VerifiableCredential",
                "EndorsementCredential"
              ],
              "issuer": {
                "id": "https://state.gov/issuers/565049",
                "type": [
                  "Profile"
                ],
                "name": "State Department of Education"
              },
              "issuanceDate": "2010-01-01T00:00:00Z",
              "expirationDate": "2020-01-01T00:00:00Z",
              "credentialSubject": {
                "id": "https://1edtech.edu/issuers/565049",
                "type": [
                  "EndorsementSubject"
                ],
                "endorsementComment": "1EdTech University is in good standing"
              },
              "credentialSchema": [
                {
                  "id": "https://purl.imsglobal.org/spec/ob/v3p0/schema/endorsem
entcredential.json",
                  "type": "1EdTechJsonSchemaValidator2019"
                },
                {
                  "id": "https://state.gov/schema/endorsementcredential.json",
                  "type": "JsonSchemaValidator2018"
                }
              ],
              "credentialStatus": {
                "id": "https://state.gov/credentials/3732/revocations",
                "type": "1EdTechRevocationList"
              },
              "refreshService": {
                "id": "http://state.gov/credentials/3732",
                "type": "1EdTechCredentialRefresh"
              },
              "proof": [
                {
                  "type": "Ed25519Signature2020",
                  "created": "2022-05-26T18:25:59Z",
                  "verificationMethod": "https://accrediter.edu/issuers/565049#k
ey-1",
                  "proofPurpose": "assertionMethod",
                  "proofValue": "z5bDnmSgDczXwZGya6ZjxKaxkdKxzsCMiVSsgEVWxnaWK7Z
qbKnzcCd7mUKE9DQaAL2QMXP5AquPeW6W2CWrZ7jNC"
                }
              ]
            }
          ],
          "image": {
            "id": "https://1edtech.edu/logo.png",
            "type": "Image",
            "caption": "1EdTech University logo"
          },
          "email": "registrar@1edtech.edu",
          "address": {
            "type": [
              "Address"
            ],
            "addressCountry": "USA",
            "addressCountryCode": "US",
            "addressRegion": "TX",
            "addressLocality": "Austin",
            "streetAddress": "123 First St",
            "postOfficeBoxNumber": "1",
            "postalCode": "12345",
            "geo": {
              "type": "GeoCoordinates",
              "latitude": 1,
              "longitude": 1
            }
          },
          "otherIdentifier": [
            {
              "type": "IdentifierEntry",
              "identifier": "12345",
              "identifierType": "sourcedId"
            },
            {
              "type": "IdentifierEntry",
              "identifier": "67890",
              "identifierType": "nationalIdentityNumber"
            }
          ],
          "official": "Horace Mann",
          "parentOrg": {
            "id": "did:example:123456789",
            "type": [
              "Profile"
            ],
            "name": "Universal Universities"
          }
        },
        "creditsAvailable": 36,
        "criteria": {
          "id": "https://1edtech.edu/achievements/degree",
          "narrative": "# Degree Requirements\nStudents must complete..."
        },
        "description": "1EdTech University Degree Description",
        "endorsement": [
          {
            "@context": [
              "https://www.w3.org/2018/credentials/v1",
              "https://imsglobal.github.io/openbadges-specification/context.json
",
              "https://w3id.org/security/suites/ed25519-2020/v1"
            ],
            "type": [
              "VerifiableCredential",
              "EndorsementCredential"
            ],
            "issuer": {
              "id": "https://accrediter.edu/issuers/565049",
              "type": [
                "Profile"
              ],
              "name": "Example Accrediting Agency"
            },
            "issuanceDate": "2010-01-01T00:00:00Z",
            "expirationDate": "2020-01-01T00:00:00Z",
            "credentialSubject": {
              "id": "https://1edtech.edu/issuers/565049",
              "type": [
                "EndorsementSubject"
              ],
              "endorsementComment": "1EdTech University is in good standing"
            },
            "credentialSchema": [
              {
                "id": "https://purl.imsglobal.org/spec/ob/v3p0/schema/endorsemen
tcredential.json",
                "type": "1EdTechJsonSchemaValidator2019"
              },
              {
                "id": "https://accrediter.edu/schema/endorsementcredential.json"
,
                "type": "JsonSchemaValidator2018"
              }
            ],
            "credentialStatus": {
              "id": "https://1edtech.edu/credentials/3732/revocations",
              "type": "1EdTechRevocationList"
            },
            "refreshService": {
              "id": "http://1edtech.edu/credentials/3732",
              "type": "1EdTechCredentialRefresh"
            },
            "proof": [
              {
                "type": "Ed25519Signature2020",
                "created": "2022-05-26T18:17:08Z",
                "verificationMethod": "https://accrediter.edu/issuers/565049#key
-1",
                "proofPurpose": "assertionMethod",
                "proofValue": "zvPkQiUFfJrgnCRhyPkTSkgrGXbnLR15pHH5HZVYNdM4TCAwQ
HqG7fMeMPLtYNRnEgoV1aJdR5E61eWu5sWRYgtA"
              }
            ]
          }
        ],
        "fieldOfStudy": "Research",
        "humanCode": "R1",
        "image": {
          "id": "https://1edtech.edu/achievements/degree/image",
          "type": "Image",
          "caption": "1EdTech University Degree"
        },
        "name": "1EdTech University Degree",
        "otherIdentifier": [
          {
            "type": "IdentifierEntry",
            "identifier": "abde",
            "identifierType": "identifier"
          }
        ],
        "resultDescription": [
          {
            "id": "urn:uuid:f6ab24cd-86e8-4eaf-b8c6-ded74e8fd41c",
            "type": [
              "ResultDescription"
            ],
            "alignment": [
              {
                "type": [
                  "Alignment"
                ],
                "targetCode": "project",
                "targetDescription": "Project description",
                "targetName": "Final Project",
                "targetFramework": "1EdTech University Program and Course Catalo
g",
                "targetType": "CFItem",
                "targetUrl": "https://1edtech.edu/catalog/degree/project"
              }
            ],
            "allowedValue": [
              "D",
              "C",
              "B",
              "A"
            ],
            "name": "Final Project Grade",
            "requiredValue": "C",
            "resultType": "LetterGrade"
          },
          {
            "id": "urn:uuid:a70ddc6a-4c4a-4bd8-8277-cb97c79f40c5",
            "type": [
              "ResultDescription"
            ],
            "alignment": [
              {
                "type": [
                  "Alignment"
                ],
                "targetCode": "project",
                "targetDescription": "Project description",
                "targetName": "Final Project",
                "targetFramework": "1EdTech University Program and Course Catalo
g",
                "targetType": "CFItem",
                "targetUrl": "https://1edtech.edu/catalog/degree/project"
              }
            ],
            "allowedValue": [
              "D",
              "C",
              "B",
              "A"
            ],
            "name": "Final Project Grade",
            "requiredLevel": "urn:uuid:d05a0867-d0ad-4b03-bdb5-28fb5d2aab7a",
            "resultType": "RubricCriterionLevel",
            "rubricCriterionLevel": [
              {
                "id": "urn:uuid:d05a0867-d0ad-4b03-bdb5-28fb5d2aab7a",
                "type": [
                  "RubricCriterionLevel"
                ],
                "alignment": [
                  {
                    "type": [
                      "Alignment"
                    ],
                    "targetCode": "project",
                    "targetDescription": "Project description",
                    "targetName": "Final Project",
                    "targetFramework": "1EdTech University Program and Course Ca
talog",
                    "targetType": "CFRubricCriterionLevel",
                    "targetUrl": "https://1edtech.edu/catalog/degree/project/rub
ric/levels/mastered"
                  }
                ],
                "description": "The author demonstrated...",
                "level": "Mastered",
                "name": "Mastery",
                "points": "4"
              },
              {
                "id": "urn:uuid:6b84b429-31ee-4dac-9d20-e5c55881f80e",
                "type": [
                  "RubricCriterionLevel"
                ],
                "alignment": [
                  {
                    "type": [
                      "Alignment"
                    ],
                    "targetCode": "project",
                    "targetDescription": "Project description",
                    "targetName": "Final Project",
                    "targetFramework": "1EdTech University Program and Course Ca
talog",
                    "targetType": "CFRubricCriterionLevel",
                    "targetUrl": "https://1edtech.edu/catalog/degree/project/rub
ric/levels/basic"
                  }
                ],
                "description": "The author demonstrated...",
                "level": "Basic",
                "name": "Basic",
                "points": "4"
              }
            ]
          },
          {
            "id": "urn:uuid:b07c0387-f2d6-4b65-a3f4-f4e4302ea8f7",
            "type": [
              "ResultDescription"
            ],
            "name": "Project Status",
            "resultType": "Status"
          }
        ],
        "specialization": "Computer Science Research",
        "tag": [
          "research",
          "computer science"
        ]
      },
      "image": {
        "id": "https://1edtech.edu/credentials/3732/image",
        "type": "Image",
        "caption": "1EdTech University Degree for Example Student"
      },
      "narrative": "There is a final project report and source code evidence.",
      "result": [
        {
          "type": [
            "Result"
          ],
          "alignment": [
            {
              "type": [
                "Alignment"
              ],
              "targetCode": "project",
              "targetDescription": "Project description",
              "targetName": "Final Project",
              "targetFramework": "1EdTech University Program and Course Catalog"
,
              "targetType": "CFItem",
              "targetUrl": "https://1edtech.edu/catalog/degree/project/result/1"
            }
          ],
          "resultDescription": "urn:uuid:f6ab24cd-86e8-4eaf-b8c6-ded74e8fd41c",
          "value": "A"
        },
        {
          "type": [
            "Result"
          ],
          "achievedLevel": "urn:uuid:d05a0867-d0ad-4b03-bdb5-28fb5d2aab7a",
          "alignment": [
            {
              "type": [
                "Alignment"
              ],
              "targetCode": "project",
              "targetDescription": "Project description",
              "targetName": "Final Project",
              "targetFramework": "1EdTech University Program and Course Catalog"
,
              "targetType": "CFItem",
              "targetUrl": "https://1edtech.edu/catalog/degree/project/result/1"
            }
          ],
          "resultDescription": "urn:uuid:f6ab24cd-86e8-4eaf-b8c6-ded74e8fd41c"
        },
        {
          "type": [
            "Result"
          ],
          "resultDescription": "urn:uuid:f6ab24cd-86e8-4eaf-b8c6-ded74e8fd41c",
          "status": "Completed"
        }
      ]
    },
    "endorsement": [
      {
        "@context": [
          "https://www.w3.org/2018/credentials/v1",
          "https://imsglobal.github.io/openbadges-specification/context.json",
          "https://w3id.org/security/suites/ed25519-2020/v1"
        ],
        "type": [
          "VerifiableCredential",
          "EndorsementCredential"
        ],
        "issuer": {
          "id": "https://accrediter.edu/issuers/565049",
          "type": [
            "Profile"
          ],
          "name": "Example Accrediting Agency"
        },
        "issuanceDate": "2010-01-01T00:00:00Z",
        "expirationDate": "2020-01-01T00:00:00Z",
        "credentialSubject": {
          "id": "https://1edtech.edu/issuers/565049",
          "type": [
            "EndorsementSubject"
          ],
          "endorsementComment": "1EdTech University is in good standing"
        },
        "credentialSchema": [
          {
            "id": "https://purl.imsglobal.org/spec/ob/v3p0/schema/endorsementcre
dential.json",
            "type": "1EdTechJsonSchemaValidator2019"
          },
          {
            "id": "https://accrediter.edu/schema/endorsementcredential.json",
            "type": "JsonSchemaValidator2018"
          }
        ],
        "credentialStatus": {
          "id": "https://1edtech.edu/credentials/3732/revocations",
          "type": "1EdTechRevocationList"
        },
        "refreshService": {
          "id": "http://1edtech.edu/credentials/3732",
          "type": "1EdTechCredentialRefresh"
        },
        "proof": [
          {
            "type": "Ed25519Signature2020",
            "created": "2022-05-26T18:17:08Z",
            "verificationMethod": "https://accrediter.edu/issuers/565049#key-1",
            "proofPurpose": "assertionMethod",
            "proofValue": "zvPkQiUFfJrgnCRhyPkTSkgrGXbnLR15pHH5HZVYNdM4TCAwQHqG7
fMeMPLtYNRnEgoV1aJdR5E61eWu5sWRYgtA"
          }
        ]
      }
    ],
    "evidence": [
      {
        "id": "https://1edtech.edu/credentials/3732/evidence/1",
        "type": [
          "Evidence"
        ],
        "narrative": "# Final Project Report \n This project was ...",
        "name": "Final Project Report",
        "description": "This is the final project report.",
        "genre": "Research",
        "audience": "Department"
      },
      {
        "id": "https://github.com/somebody/project",
        "type": [
          "Evidence"
        ],
        "name": "Final Project Code",
        "description": "This is the source code for the final project app.",
        "genre": "Research",
        "audience": "Department"
      }
    ],
    "issuer": {
      "id": "https://1edtech.edu/issuers/565049",
      "type": [
        "Profile"
      ],
      "name": "1EdTech University",
      "url": "https://1edtech.edu",
      "phone": "1-222-333-4444",
      "description": "1EdTech University provides online degree programs.",
      "endorsement": [
        {
          "@context": [
            "https://www.w3.org/2018/credentials/v1",
            "https://imsglobal.github.io/openbadges-specification/context.json",
            "https://w3id.org/security/suites/ed25519-2020/v1"
          ],
          "type": [
            "VerifiableCredential",
            "EndorsementCredential"
          ],
          "issuer": {
            "id": "https://accrediter.edu/issuers/565049",
            "type": [
              "Profile"
            ],
            "name": "Example Accrediting Agency"
          },
          "issuanceDate": "2010-01-01T00:00:00Z",
          "expirationDate": "2020-01-01T00:00:00Z",
          "credentialSubject": {
            "id": "https://1edtech.edu/issuers/565049",
            "type": [
              "EndorsementSubject"
            ],
            "endorsementComment": "1EdTech University is in good standing"
          },
          "credentialSchema": [
            {
              "id": "https://purl.imsglobal.org/spec/ob/v3p0/schema/endorsementc
redential.json",
              "type": "1EdTechJsonSchemaValidator2019"
            },
            {
              "id": "https://accrediter.edu/schema/endorsementcredential.json",
              "type": "JsonSchemaValidator2018"
            }
          ],
          "credentialStatus": {
            "id": "https://1edtech.edu/credentials/3732/revocations",
            "type": "1EdTechRevocationList"
          },
          "refreshService": {
            "id": "http://1edtech.edu/credentials/3732",
            "type": "1EdTechCredentialRefresh"
          },
          "proof": [
            {
              "type": "Ed25519Signature2020",
              "created": "2022-05-26T18:17:08Z",
              "verificationMethod": "https://accrediter.edu/issuers/565049#key-1
",
              "proofPurpose": "assertionMethod",
              "proofValue": "zvPkQiUFfJrgnCRhyPkTSkgrGXbnLR15pHH5HZVYNdM4TCAwQHq
G7fMeMPLtYNRnEgoV1aJdR5E61eWu5sWRYgtA"
            }
          ]
        }
      ],
      "image": {
        "id": "https://1edtech.edu/logo.png",
        "type": "Image",
        "caption": "1EdTech University logo"
      },
      "email": "registrar@1edtech.edu",
      "address": {
        "type": [
          "Address"
        ],
        "addressCountry": "USA",
        "addressCountryCode": "US",
        "addressRegion": "TX",
        "addressLocality": "Austin",
        "streetAddress": "123 First St",
        "postOfficeBoxNumber": "1",
        "postalCode": "12345",
        "geo": {
          "type": "GeoCoordinates",
          "latitude": 1,
          "longitude": 1
        }
      },
      "otherIdentifier": [
        {
          "type": "IdentifierEntry",
          "identifier": "12345",
          "identifierType": "sourcedId"
        },
        {
          "type": "IdentifierEntry",
          "identifier": "67890",
          "identifierType": "nationalIdentityNumber"
        }
      ],
      "official": "Horace Mann",
      "parentOrg": {
        "id": "did:example:123456789",
        "type": [
          "Profile"
        ],
        "name": "Universal Universities"
      }
    },
    "issuanceDate": "2010-01-01T00:00:00Z",
    "expirationDate": "2020-01-01T00:00:00Z",
    "credentialSchema": [
      {
        "id": "https://purl.imsglobal.org/spec/ob/v3p0/schema/achievementcredent
ial.json",
        "type": "1EdTechJsonSchemaValidator2019"
      }
    ],
    "credentialStatus": {
      "id": "https://1edtech.edu/credentials/3732/revocations",
      "type": "1EdTechRevocationList"
    },
    "refreshService": {
      "id": "http://1edtech.edu/credentials/3732",
      "type": "1EdTechCredentialRefresh"
    }
  },
  "exp": 1577836800,
  "iss": "https://1edtech.edu/issuers/565049",
  "nbf": 1262304000,
  "jti": "http://1edtech.edu/credentials/3732",
  "sub": "did:example:ebfeb1f712ebc6f1c276e12ec21"
}
--------------- JWT ---------------
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImp3ayI6eyJlIjoiQVFBQiIsImt0eSI6IlJTQSIsIm4i
OiIzSE1Jb1lIUFBjVFFJOTJJdmtNaUhtby1JTjBNV1JBYnkySjRleXV2LW1HMVpYS3hwbERsUnhXcTVh
aXJtdlBsZzZxLVZGb3ZUaFR3UlJDUGZNbjNkSnNQaE5OTDVqM3BDRFkwZ0hTdWFldUl5WW91cm81NjNH
OF9jT0hicGFlcnNHallwdWpDdjNEQUUyX1FjQ1VqdjZCUFlKaGEtRVVOd2hWeHhNMy15TXplWm9EUDZM
UklMZ1Vhemlsa0hTMzdibGdpcmdBM1dIbzdjbURRZThzVmFQLXZma0ZKQ1ZHN3lEeFB3UjRUZkdBUjBV
V3hPYnNDYTczbVNvUWw3MkpHWi1hRk9tdVF5TmNIOURVS0dwWEtDdDFUVzU0ajllR0szdUJGOGtHMDh2
VkxuRGczXzdLdXB3b2k5UVQzZkdCWjJDS0NtcXVqalV0QUJabV9teE5CalEifX0.eyJ2YyI6eyJAY29u
dGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vaW1z
Z2xvYmFsLmdpdGh1Yi5pby9vcGVuYmFkZ2VzLXNwZWNpZmljYXRpb24vY29udGV4dC5qc29uIl0sImlk
IjoiaHR0cDovLzFlZHRlY2guZWR1L2NyZWRlbnRpYWxzLzM3MzIiLCJ0eXBlIjpbIlZlcmlmaWFibGVD
cmVkZW50aWFsIiwiT3BlbkJhZGdlQ3JlZGVudGlhbCJdLCJuYW1lIjoiMUVkVGVjaCBVbml2ZXJzaXR5
IERlZ3JlZSBmb3IgRXhhbXBsZSBTdHVkZW50IiwiZGVzY3JpcHRpb24iOiIxRWRUZWNoIFVuaXZlcnNp
dHkgRGVncmVlIERlc2NyaXB0aW9uIiwiaW1hZ2UiOnsiaWQiOiJodHRwczovLzFlZHRlY2guZWR1L2Ny
ZWRlbnRpYWxzLzM3MzIvaW1hZ2UiLCJ0eXBlIjoiSW1hZ2UiLCJjYXB0aW9uIjoiMUVkVGVjaCBVbml2
ZXJzaXR5IERlZ3JlZSBmb3IgRXhhbXBsZSBTdHVkZW50In0sImNyZWRlbnRpYWxTdWJqZWN0Ijp7Imlk
IjoiZGlkOmV4YW1wbGU6ZWJmZWIxZjcxMmViYzZmMWMyNzZlMTJlYzIxIiwidHlwZSI6WyJBY2hpZXZl
bWVudFN1YmplY3QiXSwiYWN0aXZpdHlFbmREYXRlIjoiMjAxMC0wMS0wMlQwMDowMDowMFoiLCJhY3Rp
dml0eVN0YXJ0RGF0ZSI6IjIwMTAtMDEtMDFUMDA6MDA6MDBaIiwiY3JlZGl0c0Vhcm5lZCI6NDIsImxp
Y2Vuc2VOdW1iZXIiOiJBLTkzMjAwNDEiLCJyb2xlIjoiTWFqb3IgRG9tbyIsInNvdXJjZSI6eyJpZCI6
Imh0dHBzOi8vc2Nob29sLmVkdS9pc3N1ZXJzLzIwMTIzNCIsInR5cGUiOlsiUHJvZmlsZSJdLCJuYW1l
IjoiMUVkVGVjaCBDb2xsZWdlIG9mIEFydHMifSwidGVybSI6IkZhbGwiLCJpZGVudGlmaWVyIjpbeyJ0
eXBlIjoiSWRlbnRpdHlPYmplY3QiLCJpZGVudGl0eUhhc2giOiJzdHVkZW50QDFlZHRlY2guZWR1Iiwi
aWRlbnRpdHlUeXBlIjoiZW1haWxBZGRyZXNzIiwiaGFzaGVkIjpmYWxzZSwic2FsdCI6Im5vdC11c2Vk
In0seyJ0eXBlIjoiSWRlbnRpdHlPYmplY3QiLCJpZGVudGl0eUhhc2giOiJzb21lYm9keUBnbWFpbC5j
b20iLCJpZGVudGl0eVR5cGUiOiJlbWFpbEFkZHJlc3MiLCJoYXNoZWQiOmZhbHNlLCJzYWx0Ijoibm90
LXVzZWQifV0sImFjaGlldmVtZW50Ijp7ImlkIjoiaHR0cHM6Ly8xZWR0ZWNoLmVkdS9hY2hpZXZlbWVu
dHMvZGVncmVlIiwidHlwZSI6WyJBY2hpZXZlbWVudCJdLCJhbGlnbm1lbnQiOlt7InR5cGUiOlsiQWxp
Z25tZW50Il0sInRhcmdldENvZGUiOiJkZWdyZWUiLCJ0YXJnZXREZXNjcmlwdGlvbiI6IjFFZFRlY2gg
VW5pdmVyc2l0eSBEZWdyZWUgcHJvZ3JhbXMuIiwidGFyZ2V0TmFtZSI6IjFFZFRlY2ggVW5pdmVyc2l0
eSBEZWdyZWUiLCJ0YXJnZXRGcmFtZXdvcmsiOiIxRWRUZWNoIFVuaXZlcnNpdHkgUHJvZ3JhbSBhbmQg
Q291cnNlIENhdGFsb2ciLCJ0YXJnZXRUeXBlIjoiQ0ZJdGVtIiwidGFyZ2V0VXJsIjoiaHR0cHM6Ly8x
ZWR0ZWNoLmVkdS9jYXRhbG9nL2RlZ3JlZSJ9LHsidHlwZSI6WyJBbGlnbm1lbnQiXSwidGFyZ2V0Q29k
ZSI6ImRlZ3JlZSIsInRhcmdldERlc2NyaXB0aW9uIjoiMUVkVGVjaCBVbml2ZXJzaXR5IERlZ3JlZSBw
cm9ncmFtcy4iLCJ0YXJnZXROYW1lIjoiMUVkVGVjaCBVbml2ZXJzaXR5IERlZ3JlZSIsInRhcmdldEZy
YW1ld29yayI6IjFFZFRlY2ggVW5pdmVyc2l0eSBQcm9ncmFtIGFuZCBDb3Vyc2UgQ2F0YWxvZyIsInRh
cmdldFR5cGUiOiJDVERMIiwidGFyZ2V0VXJsIjoiaHR0cHM6Ly9jcmVkZW50aWFsZW5naW5lcmVnaXN0
cnkub3JnL3Jlc291cmNlcy9jZS05OGNiMDI3Yi05NWVmLTQ0OTQtOTA4ZC02Zjc3OTBlYzZiNmIifV0s
ImFjaGlldmVtZW50VHlwZSI6IkRlZ3JlZSIsImNyZWF0b3IiOnsiaWQiOiJodHRwczovLzFlZHRlY2gu
ZWR1L2lzc3VlcnMvNTY1MDQ5IiwidHlwZSI6WyJQcm9maWxlIl0sIm5hbWUiOiIxRWRUZWNoIFVuaXZl
cnNpdHkiLCJ1cmwiOiJodHRwczovLzFlZHRlY2guZWR1IiwicGhvbmUiOiIxLTIyMi0zMzMtNDQ0NCIs
ImRlc2NyaXB0aW9uIjoiMUVkVGVjaCBVbml2ZXJzaXR5IHByb3ZpZGVzIG9ubGluZSBkZWdyZWUgcHJv
Z3JhbXMuIiwiZW5kb3JzZW1lbnQiOlt7IkBjb250ZXh0IjpbImh0dHBzOi8vd3d3LnczLm9yZy8yMDE4
L2NyZWRlbnRpYWxzL3YxIiwiaHR0cHM6Ly9pbXNnbG9iYWwuZ2l0aHViLmlvL29wZW5iYWRnZXMtc3Bl
Y2lmaWNhdGlvbi9jb250ZXh0Lmpzb24iLCJodHRwczovL3czaWQub3JnL3NlY3VyaXR5L3N1aXRlcy9l
ZDI1NTE5LTIwMjAvdjEiXSwidHlwZSI6WyJWZXJpZmlhYmxlQ3JlZGVudGlhbCIsIkVuZG9yc2VtZW50
Q3JlZGVudGlhbCJdLCJpc3N1ZXIiOnsiaWQiOiJodHRwczovL2FjY3JlZGl0ZXIuZWR1L2lzc3VlcnMv
NTY1MDQ5IiwidHlwZSI6WyJQcm9maWxlIl0sIm5hbWUiOiJFeGFtcGxlIEFjY3JlZGl0aW5nIEFnZW5j
eSJ9LCJpc3N1YW5jZURhdGUiOiIyMDEwLTAxLTAxVDAwOjAwOjAwWiIsImV4cGlyYXRpb25EYXRlIjoi
MjAyMC0wMS0wMVQwMDowMDowMFoiLCJjcmVkZW50aWFsU3ViamVjdCI6eyJpZCI6Imh0dHBzOi8vMWVk
dGVjaC5lZHUvaXNzdWVycy81NjUwNDkiLCJ0eXBlIjpbIkVuZG9yc2VtZW50U3ViamVjdCJdLCJlbmRv
cnNlbWVudENvbW1lbnQiOiIxRWRUZWNoIFVuaXZlcnNpdHkgaXMgaW4gZ29vZCBzdGFuZGluZyJ9LCJj
cmVkZW50aWFsU2NoZW1hIjpbeyJpZCI6Imh0dHBzOi8vcHVybC5pbXNnbG9iYWwub3JnL3NwZWMvb2Iv
djNwMC9zY2hlbWEvZW5kb3JzZW1lbnRjcmVkZW50aWFsLmpzb24iLCJ0eXBlIjoiMUVkVGVjaEpzb25T
Y2hlbWFWYWxpZGF0b3IyMDE5In0seyJpZCI6Imh0dHBzOi8vYWNjcmVkaXRlci5lZHUvc2NoZW1hL2Vu
ZG9yc2VtZW50Y3JlZGVudGlhbC5qc29uIiwidHlwZSI6Ikpzb25TY2hlbWFWYWxpZGF0b3IyMDE4In1d
LCJjcmVkZW50aWFsU3RhdHVzIjp7ImlkIjoiaHR0cHM6Ly8xZWR0ZWNoLmVkdS9jcmVkZW50aWFscy8z
NzMyL3Jldm9jYXRpb25zIiwidHlwZSI6IjFFZFRlY2hSZXZvY2F0aW9uTGlzdCJ9LCJyZWZyZXNoU2Vy
dmljZSI6eyJpZCI6Imh0dHA6Ly8xZWR0ZWNoLmVkdS9jcmVkZW50aWFscy8zNzMyIiwidHlwZSI6IjFF
ZFRlY2hDcmVkZW50aWFsUmVmcmVzaCJ9LCJwcm9vZiI6W3sidHlwZSI6IkVkMjU1MTlTaWduYXR1cmUy
MDIwIiwiY3JlYXRlZCI6IjIwMjItMDUtMjZUMTg6MTc6MDhaIiwidmVyaWZpY2F0aW9uTWV0aG9kIjoi
aHR0cHM6Ly9hY2NyZWRpdGVyLmVkdS9pc3N1ZXJzLzU2NTA0OSNrZXktMSIsInByb29mUHVycG9zZSI6
ImFzc2VydGlvbk1ldGhvZCIsInByb29mVmFsdWUiOiJ6dlBrUWlVRmZKcmduQ1JoeVBrVFNrZ3JHWGJu
TFIxNXBISDVIWlZZTmRNNFRDQXdRSHFHN2ZNZU1QTHRZTlJuRWdvVjFhSmRSNUU2MWVXdTVzV1JZZ3RB
In1dfSx7IkBjb250ZXh0IjpbImh0dHBzOi8vd3d3LnczLm9yZy8yMDE4L2NyZWRlbnRpYWxzL3YxIiwi
aHR0cHM6Ly9pbXNnbG9iYWwuZ2l0aHViLmlvL29wZW5iYWRnZXMtc3BlY2lmaWNhdGlvbi9jb250ZXh0
Lmpzb24iLCJodHRwczovL3czaWQub3JnL3NlY3VyaXR5L3N1aXRlcy9lZDI1NTE5LTIwMjAvdjEiXSwi
dHlwZSI6WyJWZXJpZmlhYmxlQ3JlZGVudGlhbCIsIkVuZG9yc2VtZW50Q3JlZGVudGlhbCJdLCJpc3N1
ZXIiOnsiaWQiOiJodHRwczovL3N0YXRlLmdvdi9pc3N1ZXJzLzU2NTA0OSIsInR5cGUiOlsiUHJvZmls
ZSJdLCJuYW1lIjoiU3RhdGUgRGVwYXJ0bWVudCBvZiBFZHVjYXRpb24ifSwiaXNzdWFuY2VEYXRlIjoi
MjAxMC0wMS0wMVQwMDowMDowMFoiLCJleHBpcmF0aW9uRGF0ZSI6IjIwMjAtMDEtMDFUMDA6MDA6MDBa
IiwiY3JlZGVudGlhbFN1YmplY3QiOnsiaWQiOiJodHRwczovLzFlZHRlY2guZWR1L2lzc3VlcnMvNTY1
MDQ5IiwidHlwZSI6WyJFbmRvcnNlbWVudFN1YmplY3QiXSwiZW5kb3JzZW1lbnRDb21tZW50IjoiMUVk
VGVjaCBVbml2ZXJzaXR5IGlzIGluIGdvb2Qgc3RhbmRpbmcifSwiY3JlZGVudGlhbFNjaGVtYSI6W3si
aWQiOiJodHRwczovL3B1cmwuaW1zZ2xvYmFsLm9yZy9zcGVjL29iL3YzcDAvc2NoZW1hL2VuZG9yc2Vt
ZW50Y3JlZGVudGlhbC5qc29uIiwidHlwZSI6IjFFZFRlY2hKc29uU2NoZW1hVmFsaWRhdG9yMjAxOSJ9
LHsiaWQiOiJodHRwczovL3N0YXRlLmdvdi9zY2hlbWEvZW5kb3JzZW1lbnRjcmVkZW50aWFsLmpzb24i
LCJ0eXBlIjoiSnNvblNjaGVtYVZhbGlkYXRvcjIwMTgifV0sImNyZWRlbnRpYWxTdGF0dXMiOnsiaWQi
OiJodHRwczovL3N0YXRlLmdvdi9jcmVkZW50aWFscy8zNzMyL3Jldm9jYXRpb25zIiwidHlwZSI6IjFF
ZFRlY2hSZXZvY2F0aW9uTGlzdCJ9LCJyZWZyZXNoU2VydmljZSI6eyJpZCI6Imh0dHA6Ly9zdGF0ZS5n
b3YvY3JlZGVudGlhbHMvMzczMiIsInR5cGUiOiIxRWRUZWNoQ3JlZGVudGlhbFJlZnJlc2gifSwicHJv
b2YiOlt7InR5cGUiOiJFZDI1NTE5U2lnbmF0dXJlMjAyMCIsImNyZWF0ZWQiOiIyMDIyLTA1LTI2VDE4
OjI1OjU5WiIsInZlcmlmaWNhdGlvbk1ldGhvZCI6Imh0dHBzOi8vYWNjcmVkaXRlci5lZHUvaXNzdWVy
cy81NjUwNDkja2V5LTEiLCJwcm9vZlB1cnBvc2UiOiJhc3NlcnRpb25NZXRob2QiLCJwcm9vZlZhbHVl
IjoiejViRG5tU2dEY3pYd1pHeWE2Wmp4S2F4a2RLeHpzQ01pVlNzZ0VWV3huYVdLN1pxYktuemNDZDdt
VUtFOURRYUFMMlFNWFA1QXF1UGVXNlcyQ1dyWjdqTkMifV19XSwiaW1hZ2UiOnsiaWQiOiJodHRwczov
LzFlZHRlY2guZWR1L2xvZ28ucG5nIiwidHlwZSI6IkltYWdlIiwiY2FwdGlvbiI6IjFFZFRlY2ggVW5p
dmVyc2l0eSBsb2dvIn0sImVtYWlsIjoicmVnaXN0cmFyQDFlZHRlY2guZWR1IiwiYWRkcmVzcyI6eyJ0
eXBlIjpbIkFkZHJlc3MiXSwiYWRkcmVzc0NvdW50cnkiOiJVU0EiLCJhZGRyZXNzQ291bnRyeUNvZGUi
OiJVUyIsImFkZHJlc3NSZWdpb24iOiJUWCIsImFkZHJlc3NMb2NhbGl0eSI6IkF1c3RpbiIsInN0cmVl
dEFkZHJlc3MiOiIxMjMgRmlyc3QgU3QiLCJwb3N0T2ZmaWNlQm94TnVtYmVyIjoiMSIsInBvc3RhbENv
ZGUiOiIxMjM0NSIsImdlbyI6eyJ0eXBlIjoiR2VvQ29vcmRpbmF0ZXMiLCJsYXRpdHVkZSI6MSwibG9u
Z2l0dWRlIjoxfX0sIm90aGVySWRlbnRpZmllciI6W3sidHlwZSI6IklkZW50aWZpZXJFbnRyeSIsImlk
ZW50aWZpZXIiOiIxMjM0NSIsImlkZW50aWZpZXJUeXBlIjoic291cmNlZElkIn0seyJ0eXBlIjoiSWRl
bnRpZmllckVudHJ5IiwiaWRlbnRpZmllciI6IjY3ODkwIiwiaWRlbnRpZmllclR5cGUiOiJuYXRpb25h
bElkZW50aXR5TnVtYmVyIn1dLCJvZmZpY2lhbCI6IkhvcmFjZSBNYW5uIiwicGFyZW50T3JnIjp7Imlk
IjoiZGlkOmV4YW1wbGU6MTIzNDU2Nzg5IiwidHlwZSI6WyJQcm9maWxlIl0sIm5hbWUiOiJVbml2ZXJz
YWwgVW5pdmVyc2l0aWVzIn19LCJjcmVkaXRzQXZhaWxhYmxlIjozNiwiY3JpdGVyaWEiOnsiaWQiOiJo
dHRwczovLzFlZHRlY2guZWR1L2FjaGlldmVtZW50cy9kZWdyZWUiLCJuYXJyYXRpdmUiOiIjIERlZ3Jl
ZSBSZXF1aXJlbWVudHNcblN0dWRlbnRzIG11c3QgY29tcGxldGUuLi4ifSwiZGVzY3JpcHRpb24iOiIx
RWRUZWNoIFVuaXZlcnNpdHkgRGVncmVlIERlc2NyaXB0aW9uIiwiZW5kb3JzZW1lbnQiOlt7IkBjb250
ZXh0IjpbImh0dHBzOi8vd3d3LnczLm9yZy8yMDE4L2NyZWRlbnRpYWxzL3YxIiwiaHR0cHM6Ly9pbXNn
bG9iYWwuZ2l0aHViLmlvL29wZW5iYWRnZXMtc3BlY2lmaWNhdGlvbi9jb250ZXh0Lmpzb24iLCJodHRw
czovL3czaWQub3JnL3NlY3VyaXR5L3N1aXRlcy9lZDI1NTE5LTIwMjAvdjEiXSwidHlwZSI6WyJWZXJp
ZmlhYmxlQ3JlZGVudGlhbCIsIkVuZG9yc2VtZW50Q3JlZGVudGlhbCJdLCJpc3N1ZXIiOnsiaWQiOiJo
dHRwczovL2FjY3JlZGl0ZXIuZWR1L2lzc3VlcnMvNTY1MDQ5IiwidHlwZSI6WyJQcm9maWxlIl0sIm5h
bWUiOiJFeGFtcGxlIEFjY3JlZGl0aW5nIEFnZW5jeSJ9LCJpc3N1YW5jZURhdGUiOiIyMDEwLTAxLTAx
VDAwOjAwOjAwWiIsImV4cGlyYXRpb25EYXRlIjoiMjAyMC0wMS0wMVQwMDowMDowMFoiLCJjcmVkZW50
aWFsU3ViamVjdCI6eyJpZCI6Imh0dHBzOi8vMWVkdGVjaC5lZHUvaXNzdWVycy81NjUwNDkiLCJ0eXBl
IjpbIkVuZG9yc2VtZW50U3ViamVjdCJdLCJlbmRvcnNlbWVudENvbW1lbnQiOiIxRWRUZWNoIFVuaXZl
cnNpdHkgaXMgaW4gZ29vZCBzdGFuZGluZyJ9LCJjcmVkZW50aWFsU2NoZW1hIjpbeyJpZCI6Imh0dHBz
Oi8vcHVybC5pbXNnbG9iYWwub3JnL3NwZWMvb2IvdjNwMC9zY2hlbWEvZW5kb3JzZW1lbnRjcmVkZW50
aWFsLmpzb24iLCJ0eXBlIjoiMUVkVGVjaEpzb25TY2hlbWFWYWxpZGF0b3IyMDE5In0seyJpZCI6Imh0
dHBzOi8vYWNjcmVkaXRlci5lZHUvc2NoZW1hL2VuZG9yc2VtZW50Y3JlZGVudGlhbC5qc29uIiwidHlw
ZSI6Ikpzb25TY2hlbWFWYWxpZGF0b3IyMDE4In1dLCJjcmVkZW50aWFsU3RhdHVzIjp7ImlkIjoiaHR0
cHM6Ly8xZWR0ZWNoLmVkdS9jcmVkZW50aWFscy8zNzMyL3Jldm9jYXRpb25zIiwidHlwZSI6IjFFZFRl
Y2hSZXZvY2F0aW9uTGlzdCJ9LCJyZWZyZXNoU2VydmljZSI6eyJpZCI6Imh0dHA6Ly8xZWR0ZWNoLmVk
dS9jcmVkZW50aWFscy8zNzMyIiwidHlwZSI6IjFFZFRlY2hDcmVkZW50aWFsUmVmcmVzaCJ9LCJwcm9v
ZiI6W3sidHlwZSI6IkVkMjU1MTlTaWduYXR1cmUyMDIwIiwiY3JlYXRlZCI6IjIwMjItMDUtMjZUMTg6
MTc6MDhaIiwidmVyaWZpY2F0aW9uTWV0aG9kIjoiaHR0cHM6Ly9hY2NyZWRpdGVyLmVkdS9pc3N1ZXJz
LzU2NTA0OSNrZXktMSIsInByb29mUHVycG9zZSI6ImFzc2VydGlvbk1ldGhvZCIsInByb29mVmFsdWUi
OiJ6dlBrUWlVRmZKcmduQ1JoeVBrVFNrZ3JHWGJuTFIxNXBISDVIWlZZTmRNNFRDQXdRSHFHN2ZNZU1Q
THRZTlJuRWdvVjFhSmRSNUU2MWVXdTVzV1JZZ3RBIn1dfV0sImZpZWxkT2ZTdHVkeSI6IlJlc2VhcmNo
IiwiaHVtYW5Db2RlIjoiUjEiLCJpbWFnZSI6eyJpZCI6Imh0dHBzOi8vMWVkdGVjaC5lZHUvYWNoaWV2
ZW1lbnRzL2RlZ3JlZS9pbWFnZSIsInR5cGUiOiJJbWFnZSIsImNhcHRpb24iOiIxRWRUZWNoIFVuaXZl
cnNpdHkgRGVncmVlIn0sIm5hbWUiOiIxRWRUZWNoIFVuaXZlcnNpdHkgRGVncmVlIiwib3RoZXJJZGVu
dGlmaWVyIjpbeyJ0eXBlIjoiSWRlbnRpZmllckVudHJ5IiwiaWRlbnRpZmllciI6ImFiZGUiLCJpZGVu
dGlmaWVyVHlwZSI6ImlkZW50aWZpZXIifV0sInJlc3VsdERlc2NyaXB0aW9uIjpbeyJpZCI6InVybjp1
dWlkOmY2YWIyNGNkLTg2ZTgtNGVhZi1iOGM2LWRlZDc0ZThmZDQxYyIsInR5cGUiOlsiUmVzdWx0RGVz
Y3JpcHRpb24iXSwiYWxpZ25tZW50IjpbeyJ0eXBlIjpbIkFsaWdubWVudCJdLCJ0YXJnZXRDb2RlIjoi
cHJvamVjdCIsInRhcmdldERlc2NyaXB0aW9uIjoiUHJvamVjdCBkZXNjcmlwdGlvbiIsInRhcmdldE5h
bWUiOiJGaW5hbCBQcm9qZWN0IiwidGFyZ2V0RnJhbWV3b3JrIjoiMUVkVGVjaCBVbml2ZXJzaXR5IFBy
b2dyYW0gYW5kIENvdXJzZSBDYXRhbG9nIiwidGFyZ2V0VHlwZSI6IkNGSXRlbSIsInRhcmdldFVybCI6
Imh0dHBzOi8vMWVkdGVjaC5lZHUvY2F0YWxvZy9kZWdyZWUvcHJvamVjdCJ9XSwiYWxsb3dlZFZhbHVl
IjpbIkQiLCJDIiwiQiIsIkEiXSwibmFtZSI6IkZpbmFsIFByb2plY3QgR3JhZGUiLCJyZXF1aXJlZFZh
bHVlIjoiQyIsInJlc3VsdFR5cGUiOiJMZXR0ZXJHcmFkZSJ9LHsiaWQiOiJ1cm46dXVpZDphNzBkZGM2
YS00YzRhLTRiZDgtODI3Ny1jYjk3Yzc5ZjQwYzUiLCJ0eXBlIjpbIlJlc3VsdERlc2NyaXB0aW9uIl0s
ImFsaWdubWVudCI6W3sidHlwZSI6WyJBbGlnbm1lbnQiXSwidGFyZ2V0Q29kZSI6InByb2plY3QiLCJ0
YXJnZXREZXNjcmlwdGlvbiI6IlByb2plY3QgZGVzY3JpcHRpb24iLCJ0YXJnZXROYW1lIjoiRmluYWwg
UHJvamVjdCIsInRhcmdldEZyYW1ld29yayI6IjFFZFRlY2ggVW5pdmVyc2l0eSBQcm9ncmFtIGFuZCBD
b3Vyc2UgQ2F0YWxvZyIsInRhcmdldFR5cGUiOiJDRkl0ZW0iLCJ0YXJnZXRVcmwiOiJodHRwczovLzFl
ZHRlY2guZWR1L2NhdGFsb2cvZGVncmVlL3Byb2plY3QifV0sImFsbG93ZWRWYWx1ZSI6WyJEIiwiQyIs
IkIiLCJBIl0sIm5hbWUiOiJGaW5hbCBQcm9qZWN0IEdyYWRlIiwicmVxdWlyZWRMZXZlbCI6InVybjp1
dWlkOmQwNWEwODY3LWQwYWQtNGIwMy1iZGI1LTI4ZmI1ZDJhYWI3YSIsInJlc3VsdFR5cGUiOiJSdWJy
aWNDcml0ZXJpb25MZXZlbCIsInJ1YnJpY0NyaXRlcmlvbkxldmVsIjpbeyJpZCI6InVybjp1dWlkOmQw
NWEwODY3LWQwYWQtNGIwMy1iZGI1LTI4ZmI1ZDJhYWI3YSIsInR5cGUiOlsiUnVicmljQ3JpdGVyaW9u
TGV2ZWwiXSwiYWxpZ25tZW50IjpbeyJ0eXBlIjpbIkFsaWdubWVudCJdLCJ0YXJnZXRDb2RlIjoicHJv
amVjdCIsInRhcmdldERlc2NyaXB0aW9uIjoiUHJvamVjdCBkZXNjcmlwdGlvbiIsInRhcmdldE5hbWUi
OiJGaW5hbCBQcm9qZWN0IiwidGFyZ2V0RnJhbWV3b3JrIjoiMUVkVGVjaCBVbml2ZXJzaXR5IFByb2dy
YW0gYW5kIENvdXJzZSBDYXRhbG9nIiwidGFyZ2V0VHlwZSI6IkNGUnVicmljQ3JpdGVyaW9uTGV2ZWwi
LCJ0YXJnZXRVcmwiOiJodHRwczovLzFlZHRlY2guZWR1L2NhdGFsb2cvZGVncmVlL3Byb2plY3QvcnVi
cmljL2xldmVscy9tYXN0ZXJlZCJ9XSwiZGVzY3JpcHRpb24iOiJUaGUgYXV0aG9yIGRlbW9uc3RyYXRl
ZC4uLiIsImxldmVsIjoiTWFzdGVyZWQiLCJuYW1lIjoiTWFzdGVyeSIsInBvaW50cyI6IjQifSx7Imlk
IjoidXJuOnV1aWQ6NmI4NGI0MjktMzFlZS00ZGFjLTlkMjAtZTVjNTU4ODFmODBlIiwidHlwZSI6WyJS
dWJyaWNDcml0ZXJpb25MZXZlbCJdLCJhbGlnbm1lbnQiOlt7InR5cGUiOlsiQWxpZ25tZW50Il0sInRh
cmdldENvZGUiOiJwcm9qZWN0IiwidGFyZ2V0RGVzY3JpcHRpb24iOiJQcm9qZWN0IGRlc2NyaXB0aW9u
IiwidGFyZ2V0TmFtZSI6IkZpbmFsIFByb2plY3QiLCJ0YXJnZXRGcmFtZXdvcmsiOiIxRWRUZWNoIFVu
aXZlcnNpdHkgUHJvZ3JhbSBhbmQgQ291cnNlIENhdGFsb2ciLCJ0YXJnZXRUeXBlIjoiQ0ZSdWJyaWND
cml0ZXJpb25MZXZlbCIsInRhcmdldFVybCI6Imh0dHBzOi8vMWVkdGVjaC5lZHUvY2F0YWxvZy9kZWdy
ZWUvcHJvamVjdC9ydWJyaWMvbGV2ZWxzL2Jhc2ljIn1dLCJkZXNjcmlwdGlvbiI6IlRoZSBhdXRob3Ig
ZGVtb25zdHJhdGVkLi4uIiwibGV2ZWwiOiJCYXNpYyIsIm5hbWUiOiJCYXNpYyIsInBvaW50cyI6IjQi
fV19LHsiaWQiOiJ1cm46dXVpZDpiMDdjMDM4Ny1mMmQ2LTRiNjUtYTNmNC1mNGU0MzAyZWE4ZjciLCJ0
eXBlIjpbIlJlc3VsdERlc2NyaXB0aW9uIl0sIm5hbWUiOiJQcm9qZWN0IFN0YXR1cyIsInJlc3VsdFR5
cGUiOiJTdGF0dXMifV0sInNwZWNpYWxpemF0aW9uIjoiQ29tcHV0ZXIgU2NpZW5jZSBSZXNlYXJjaCIs
InRhZyI6WyJyZXNlYXJjaCIsImNvbXB1dGVyIHNjaWVuY2UiXX0sImltYWdlIjp7ImlkIjoiaHR0cHM6
Ly8xZWR0ZWNoLmVkdS9jcmVkZW50aWFscy8zNzMyL2ltYWdlIiwidHlwZSI6IkltYWdlIiwiY2FwdGlv
biI6IjFFZFRlY2ggVW5pdmVyc2l0eSBEZWdyZWUgZm9yIEV4YW1wbGUgU3R1ZGVudCJ9LCJuYXJyYXRp
dmUiOiJUaGVyZSBpcyBhIGZpbmFsIHByb2plY3QgcmVwb3J0IGFuZCBzb3VyY2UgY29kZSBldmlkZW5j
ZS4iLCJyZXN1bHQiOlt7InR5cGUiOlsiUmVzdWx0Il0sImFsaWdubWVudCI6W3sidHlwZSI6WyJBbGln
bm1lbnQiXSwidGFyZ2V0Q29kZSI6InByb2plY3QiLCJ0YXJnZXREZXNjcmlwdGlvbiI6IlByb2plY3Qg
ZGVzY3JpcHRpb24iLCJ0YXJnZXROYW1lIjoiRmluYWwgUHJvamVjdCIsInRhcmdldEZyYW1ld29yayI6
IjFFZFRlY2ggVW5pdmVyc2l0eSBQcm9ncmFtIGFuZCBDb3Vyc2UgQ2F0YWxvZyIsInRhcmdldFR5cGUi
OiJDRkl0ZW0iLCJ0YXJnZXRVcmwiOiJodHRwczovLzFlZHRlY2guZWR1L2NhdGFsb2cvZGVncmVlL3By
b2plY3QvcmVzdWx0LzEifV0sInJlc3VsdERlc2NyaXB0aW9uIjoidXJuOnV1aWQ6ZjZhYjI0Y2QtODZl
OC00ZWFmLWI4YzYtZGVkNzRlOGZkNDFjIiwidmFsdWUiOiJBIn0seyJ0eXBlIjpbIlJlc3VsdCJdLCJh
Y2hpZXZlZExldmVsIjoidXJuOnV1aWQ6ZDA1YTA4NjctZDBhZC00YjAzLWJkYjUtMjhmYjVkMmFhYjdh
IiwiYWxpZ25tZW50IjpbeyJ0eXBlIjpbIkFsaWdubWVudCJdLCJ0YXJnZXRDb2RlIjoicHJvamVjdCIs
InRhcmdldERlc2NyaXB0aW9uIjoiUHJvamVjdCBkZXNjcmlwdGlvbiIsInRhcmdldE5hbWUiOiJGaW5h
bCBQcm9qZWN0IiwidGFyZ2V0RnJhbWV3b3JrIjoiMUVkVGVjaCBVbml2ZXJzaXR5IFByb2dyYW0gYW5k
IENvdXJzZSBDYXRhbG9nIiwidGFyZ2V0VHlwZSI6IkNGSXRlbSIsInRhcmdldFVybCI6Imh0dHBzOi8v
MWVkdGVjaC5lZHUvY2F0YWxvZy9kZWdyZWUvcHJvamVjdC9yZXN1bHQvMSJ9XSwicmVzdWx0RGVzY3Jp
cHRpb24iOiJ1cm46dXVpZDpmNmFiMjRjZC04NmU4LTRlYWYtYjhjNi1kZWQ3NGU4ZmQ0MWMifSx7InR5
cGUiOlsiUmVzdWx0Il0sInJlc3VsdERlc2NyaXB0aW9uIjoidXJuOnV1aWQ6ZjZhYjI0Y2QtODZlOC00
ZWFmLWI4YzYtZGVkNzRlOGZkNDFjIiwic3RhdHVzIjoiQ29tcGxldGVkIn1dfSwiZW5kb3JzZW1lbnQi
Olt7IkBjb250ZXh0IjpbImh0dHBzOi8vd3d3LnczLm9yZy8yMDE4L2NyZWRlbnRpYWxzL3YxIiwiaHR0
cHM6Ly9pbXNnbG9iYWwuZ2l0aHViLmlvL29wZW5iYWRnZXMtc3BlY2lmaWNhdGlvbi9jb250ZXh0Lmpz
b24iLCJodHRwczovL3czaWQub3JnL3NlY3VyaXR5L3N1aXRlcy9lZDI1NTE5LTIwMjAvdjEiXSwidHlw
ZSI6WyJWZXJpZmlhYmxlQ3JlZGVudGlhbCIsIkVuZG9yc2VtZW50Q3JlZGVudGlhbCJdLCJpc3N1ZXIi
OnsiaWQiOiJodHRwczovL2FjY3JlZGl0ZXIuZWR1L2lzc3VlcnMvNTY1MDQ5IiwidHlwZSI6WyJQcm9m
aWxlIl0sIm5hbWUiOiJFeGFtcGxlIEFjY3JlZGl0aW5nIEFnZW5jeSJ9LCJpc3N1YW5jZURhdGUiOiIy
MDEwLTAxLTAxVDAwOjAwOjAwWiIsImV4cGlyYXRpb25EYXRlIjoiMjAyMC0wMS0wMVQwMDowMDowMFoi
LCJjcmVkZW50aWFsU3ViamVjdCI6eyJpZCI6Imh0dHBzOi8vMWVkdGVjaC5lZHUvaXNzdWVycy81NjUw
NDkiLCJ0eXBlIjpbIkVuZG9yc2VtZW50U3ViamVjdCJdLCJlbmRvcnNlbWVudENvbW1lbnQiOiIxRWRU
ZWNoIFVuaXZlcnNpdHkgaXMgaW4gZ29vZCBzdGFuZGluZyJ9LCJjcmVkZW50aWFsU2NoZW1hIjpbeyJp
ZCI6Imh0dHBzOi8vcHVybC5pbXNnbG9iYWwub3JnL3NwZWMvb2IvdjNwMC9zY2hlbWEvZW5kb3JzZW1l
bnRjcmVkZW50aWFsLmpzb24iLCJ0eXBlIjoiMUVkVGVjaEpzb25TY2hlbWFWYWxpZGF0b3IyMDE5In0s
eyJpZCI6Imh0dHBzOi8vYWNjcmVkaXRlci5lZHUvc2NoZW1hL2VuZG9yc2VtZW50Y3JlZGVudGlhbC5q
c29uIiwidHlwZSI6Ikpzb25TY2hlbWFWYWxpZGF0b3IyMDE4In1dLCJjcmVkZW50aWFsU3RhdHVzIjp7
ImlkIjoiaHR0cHM6Ly8xZWR0ZWNoLmVkdS9jcmVkZW50aWFscy8zNzMyL3Jldm9jYXRpb25zIiwidHlw
ZSI6IjFFZFRlY2hSZXZvY2F0aW9uTGlzdCJ9LCJyZWZyZXNoU2VydmljZSI6eyJpZCI6Imh0dHA6Ly8x
ZWR0ZWNoLmVkdS9jcmVkZW50aWFscy8zNzMyIiwidHlwZSI6IjFFZFRlY2hDcmVkZW50aWFsUmVmcmVz
aCJ9LCJwcm9vZiI6W3sidHlwZSI6IkVkMjU1MTlTaWduYXR1cmUyMDIwIiwiY3JlYXRlZCI6IjIwMjIt
MDUtMjZUMTg6MTc6MDhaIiwidmVyaWZpY2F0aW9uTWV0aG9kIjoiaHR0cHM6Ly9hY2NyZWRpdGVyLmVk
dS9pc3N1ZXJzLzU2NTA0OSNrZXktMSIsInByb29mUHVycG9zZSI6ImFzc2VydGlvbk1ldGhvZCIsInBy
b29mVmFsdWUiOiJ6dlBrUWlVRmZKcmduQ1JoeVBrVFNrZ3JHWGJuTFIxNXBISDVIWlZZTmRNNFRDQXdR
SHFHN2ZNZU1QTHRZTlJuRWdvVjFhSmRSNUU2MWVXdTVzV1JZZ3RBIn1dfV0sImV2aWRlbmNlIjpbeyJp
ZCI6Imh0dHBzOi8vMWVkdGVjaC5lZHUvY3JlZGVudGlhbHMvMzczMi9ldmlkZW5jZS8xIiwidHlwZSI6
WyJFdmlkZW5jZSJdLCJuYXJyYXRpdmUiOiIjIEZpbmFsIFByb2plY3QgUmVwb3J0IFxuIFRoaXMgcHJv
amVjdCB3YXMgLi4uIiwibmFtZSI6IkZpbmFsIFByb2plY3QgUmVwb3J0IiwiZGVzY3JpcHRpb24iOiJU
aGlzIGlzIHRoZSBmaW5hbCBwcm9qZWN0IHJlcG9ydC4iLCJnZW5yZSI6IlJlc2VhcmNoIiwiYXVkaWVu
Y2UiOiJEZXBhcnRtZW50In0seyJpZCI6Imh0dHBzOi8vZ2l0aHViLmNvbS9zb21lYm9keS9wcm9qZWN0
IiwidHlwZSI6WyJFdmlkZW5jZSJdLCJuYW1lIjoiRmluYWwgUHJvamVjdCBDb2RlIiwiZGVzY3JpcHRp
b24iOiJUaGlzIGlzIHRoZSBzb3VyY2UgY29kZSBmb3IgdGhlIGZpbmFsIHByb2plY3QgYXBwLiIsImdl
bnJlIjoiUmVzZWFyY2giLCJhdWRpZW5jZSI6IkRlcGFydG1lbnQifV0sImlzc3VlciI6eyJpZCI6Imh0
dHBzOi8vMWVkdGVjaC5lZHUvaXNzdWVycy81NjUwNDkiLCJ0eXBlIjpbIlByb2ZpbGUiXSwibmFtZSI6
IjFFZFRlY2ggVW5pdmVyc2l0eSIsInVybCI6Imh0dHBzOi8vMWVkdGVjaC5lZHUiLCJwaG9uZSI6IjEt
MjIyLTMzMy00NDQ0IiwiZGVzY3JpcHRpb24iOiIxRWRUZWNoIFVuaXZlcnNpdHkgcHJvdmlkZXMgb25s
aW5lIGRlZ3JlZSBwcm9ncmFtcy4iLCJlbmRvcnNlbWVudCI6W3siQGNvbnRleHQiOlsiaHR0cHM6Ly93
d3cudzMub3JnLzIwMTgvY3JlZGVudGlhbHMvdjEiLCJodHRwczovL2ltc2dsb2JhbC5naXRodWIuaW8v
b3BlbmJhZGdlcy1zcGVjaWZpY2F0aW9uL2NvbnRleHQuanNvbiIsImh0dHBzOi8vdzNpZC5vcmcvc2Vj
dXJpdHkvc3VpdGVzL2VkMjU1MTktMjAyMC92MSJdLCJ0eXBlIjpbIlZlcmlmaWFibGVDcmVkZW50aWFs
IiwiRW5kb3JzZW1lbnRDcmVkZW50aWFsIl0sImlzc3VlciI6eyJpZCI6Imh0dHBzOi8vYWNjcmVkaXRl
ci5lZHUvaXNzdWVycy81NjUwNDkiLCJ0eXBlIjpbIlByb2ZpbGUiXSwibmFtZSI6IkV4YW1wbGUgQWNj
cmVkaXRpbmcgQWdlbmN5In0sImlzc3VhbmNlRGF0ZSI6IjIwMTAtMDEtMDFUMDA6MDA6MDBaIiwiZXhw
aXJhdGlvbkRhdGUiOiIyMDIwLTAxLTAxVDAwOjAwOjAwWiIsImNyZWRlbnRpYWxTdWJqZWN0Ijp7Imlk
IjoiaHR0cHM6Ly8xZWR0ZWNoLmVkdS9pc3N1ZXJzLzU2NTA0OSIsInR5cGUiOlsiRW5kb3JzZW1lbnRT
dWJqZWN0Il0sImVuZG9yc2VtZW50Q29tbWVudCI6IjFFZFRlY2ggVW5pdmVyc2l0eSBpcyBpbiBnb29k
IHN0YW5kaW5nIn0sImNyZWRlbnRpYWxTY2hlbWEiOlt7ImlkIjoiaHR0cHM6Ly9wdXJsLmltc2dsb2Jh
bC5vcmcvc3BlYy9vYi92M3AwL3NjaGVtYS9lbmRvcnNlbWVudGNyZWRlbnRpYWwuanNvbiIsInR5cGUi
OiIxRWRUZWNoSnNvblNjaGVtYVZhbGlkYXRvcjIwMTkifSx7ImlkIjoiaHR0cHM6Ly9hY2NyZWRpdGVy
LmVkdS9zY2hlbWEvZW5kb3JzZW1lbnRjcmVkZW50aWFsLmpzb24iLCJ0eXBlIjoiSnNvblNjaGVtYVZh
bGlkYXRvcjIwMTgifV0sImNyZWRlbnRpYWxTdGF0dXMiOnsiaWQiOiJodHRwczovLzFlZHRlY2guZWR1
L2NyZWRlbnRpYWxzLzM3MzIvcmV2b2NhdGlvbnMiLCJ0eXBlIjoiMUVkVGVjaFJldm9jYXRpb25MaXN0
In0sInJlZnJlc2hTZXJ2aWNlIjp7ImlkIjoiaHR0cDovLzFlZHRlY2guZWR1L2NyZWRlbnRpYWxzLzM3
MzIiLCJ0eXBlIjoiMUVkVGVjaENyZWRlbnRpYWxSZWZyZXNoIn0sInByb29mIjpbeyJ0eXBlIjoiRWQy
NTUxOVNpZ25hdHVyZTIwMjAiLCJjcmVhdGVkIjoiMjAyMi0wNS0yNlQxODoxNzowOFoiLCJ2ZXJpZmlj
YXRpb25NZXRob2QiOiJodHRwczovL2FjY3JlZGl0ZXIuZWR1L2lzc3VlcnMvNTY1MDQ5I2tleS0xIiwi
cHJvb2ZQdXJwb3NlIjoiYXNzZXJ0aW9uTWV0aG9kIiwicHJvb2ZWYWx1ZSI6Inp2UGtRaVVGZkpyZ25D
Umh5UGtUU2tnckdYYm5MUjE1cEhINUhaVllOZE00VENBd1FIcUc3Zk1lTVBMdFlOUm5FZ29WMWFKZFI1
RTYxZVd1NXNXUllndEEifV19XSwiaW1hZ2UiOnsiaWQiOiJodHRwczovLzFlZHRlY2guZWR1L2xvZ28u
cG5nIiwidHlwZSI6IkltYWdlIiwiY2FwdGlvbiI6IjFFZFRlY2ggVW5pdmVyc2l0eSBsb2dvIn0sImVt
YWlsIjoicmVnaXN0cmFyQDFlZHRlY2guZWR1IiwiYWRkcmVzcyI6eyJ0eXBlIjpbIkFkZHJlc3MiXSwi
YWRkcmVzc0NvdW50cnkiOiJVU0EiLCJhZGRyZXNzQ291bnRyeUNvZGUiOiJVUyIsImFkZHJlc3NSZWdp
b24iOiJUWCIsImFkZHJlc3NMb2NhbGl0eSI6IkF1c3RpbiIsInN0cmVldEFkZHJlc3MiOiIxMjMgRmly
c3QgU3QiLCJwb3N0T2ZmaWNlQm94TnVtYmVyIjoiMSIsInBvc3RhbENvZGUiOiIxMjM0NSIsImdlbyI6
eyJ0eXBlIjoiR2VvQ29vcmRpbmF0ZXMiLCJsYXRpdHVkZSI6MSwibG9uZ2l0dWRlIjoxfX0sIm90aGVy
SWRlbnRpZmllciI6W3sidHlwZSI6IklkZW50aWZpZXJFbnRyeSIsImlkZW50aWZpZXIiOiIxMjM0NSIs
ImlkZW50aWZpZXJUeXBlIjoic291cmNlZElkIn0seyJ0eXBlIjoiSWRlbnRpZmllckVudHJ5IiwiaWRl
bnRpZmllciI6IjY3ODkwIiwiaWRlbnRpZmllclR5cGUiOiJuYXRpb25hbElkZW50aXR5TnVtYmVyIn1d
LCJvZmZpY2lhbCI6IkhvcmFjZSBNYW5uIiwicGFyZW50T3JnIjp7ImlkIjoiZGlkOmV4YW1wbGU6MTIz
NDU2Nzg5IiwidHlwZSI6WyJQcm9maWxlIl0sIm5hbWUiOiJVbml2ZXJzYWwgVW5pdmVyc2l0aWVzIn19
LCJpc3N1YW5jZURhdGUiOiIyMDEwLTAxLTAxVDAwOjAwOjAwWiIsImV4cGlyYXRpb25EYXRlIjoiMjAy
MC0wMS0wMVQwMDowMDowMFoiLCJjcmVkZW50aWFsU2NoZW1hIjpbeyJpZCI6Imh0dHBzOi8vcHVybC5p
bXNnbG9iYWwub3JnL3NwZWMvb2IvdjNwMC9zY2hlbWEvYWNoaWV2ZW1lbnRjcmVkZW50aWFsLmpzb24i
LCJ0eXBlIjoiMUVkVGVjaEpzb25TY2hlbWFWYWxpZGF0b3IyMDE5In1dLCJjcmVkZW50aWFsU3RhdHVz
Ijp7ImlkIjoiaHR0cHM6Ly8xZWR0ZWNoLmVkdS9jcmVkZW50aWFscy8zNzMyL3Jldm9jYXRpb25zIiwi
dHlwZSI6IjFFZFRlY2hSZXZvY2F0aW9uTGlzdCJ9LCJyZWZyZXNoU2VydmljZSI6eyJpZCI6Imh0dHA6
Ly8xZWR0ZWNoLmVkdS9jcmVkZW50aWFscy8zNzMyIiwidHlwZSI6IjFFZFRlY2hDcmVkZW50aWFsUmVm
cmVzaCJ9fSwiZXhwIjoxNTc3ODM2ODAwLCJpc3MiOiJodHRwczovLzFlZHRlY2guZWR1L2lzc3VlcnMv
NTY1MDQ5IiwibmJmIjoxMjYyMzA0MDAwLCJqdGkiOiJodHRwOi8vMWVkdGVjaC5lZHUvY3JlZGVudGlh
bHMvMzczMiIsInN1YiI6ImRpZDpleGFtcGxlOmViZmViMWY3MTJlYmM2ZjFjMjc2ZTEyZWMyMSJ9.IAH
SDBXr0NPk62oCd_37vBaoAFg4cEUVC39re_6-HFcyXq3BHmS-M-S7vE4AuvmDGcLXX1IuD8Iy0KWyqmb
ZmiCDsB6WL5K0N06DDIwcArr6Jt_Bvp4PwdUQwVeKQB296B6RTF65duVz5NncASNNnqqD9zatnOT2kTO
UZuxNgAdtoH5s8QqVyGxF5HGSFlsorsLMLQ7x-6jkdRu4mQz1o47jWB5KvsDX5aB2Dclzi9zwlz_Zd6z
Qul-aU-LkbAzjIoE0RBSCuhXP4koabaopAHCs3gS_TmPkXj6p1-1PRZ08wwO-tJIJctlnSwIYbEKoHgy
YpZONwzg2YdRL5PoklA

D.3 EndorsementCredential

Example 37: Sample EndorsementCredential
{
  "@context": [
    "https://www.w3.org/2018/credentials/v1",
    "https://imsglobal.github.io/openbadges-specification/context.json",
    "https://w3id.org/security/suites/ed25519-2020/v1"
  ],
  "type": [
    "VerifiableCredential",
    "EndorsementCredential"
  ],
  "issuer": {
    "id": "https://state.gov/issuers/565049",
    "type": [
      "Profile"
    ],
    "name": "State Department of Education"
  },
  "issuanceDate": "2010-01-01T00:00:00Z",
  "expirationDate": "2020-01-01T00:00:00Z",
  "credentialSubject": {
    "id": "https://1edtech.edu/issuers/565049",
    "type": [
      "EndorsementSubject"
    ],
    "endorsementComment": "1EdTech University is in good standing"
  },
  "credentialSchema": [
    {
      "id": "https://purl.imsglobal.org/spec/ob/v3p0/schema/endorsementcredential.json",
      "type": "1EdTechJsonSchemaValidator2019"
    },
    {
      "id": "https://state.gov/schema/endorsementcredential.json",
      "type": "JsonSchemaValidator2018"
    }
  ],
  "credentialStatus": {
    "id": "https://state.gov/credentials/3732/revocations",
    "type": "1EdTechRevocationList"
  },
  "refreshService": {
    "id": "http://state.gov/credentials/3732",
    "type": "1EdTechCredentialRefresh"
  }
}
{
  "@context": [
    "https://www.w3.org/2018/credentials/v1",
    "https://imsglobal.github.io/openbadges-specification/context.json",
    "https://w3id.org/security/suites/ed25519-2020/v1"
  ],
  "type": [
    "VerifiableCredential",
    "EndorsementCredential"
  ],
  "issuer": {
    "id": "https://state.gov/issuers/565049",
    "type": [
      "Profile"
    ],
    "name": "State Department of Education"
  },
  "issuanceDate": "2010-01-01T00:00:00Z",
  "expirationDate": "2020-01-01T00:00:00Z",
  "credentialSubject": {
    "id": "https://1edtech.edu/issuers/565049",
    "type": [
      "EndorsementSubject"
    ],
    "endorsementComment": "1EdTech University is in good standing"
  },
  "credentialSchema": [
    {
      "id": "https://purl.imsglobal.org/spec/ob/v3p0/schema/endorsementcredential.json",
      "type": "1EdTechJsonSchemaValidator2019"
    },
    {
      "id": "https://state.gov/schema/endorsementcredential.json",
      "type": "JsonSchemaValidator2018"
    }
  ],
  "credentialStatus": {
    "id": "https://state.gov/credentials/3732/revocations",
    "type": "1EdTechRevocationList"
  },
  "refreshService": {
    "id": "http://state.gov/credentials/3732",
    "type": "1EdTechCredentialRefresh"
  },
  "proof": [
    {
      "type": "Ed25519Signature2020",
      "created": "2022-06-28T16:28:36Z",
      "verificationMethod": "did:key:z6MkkUD3J14nkYzn46QeuaVSnp7dF85QJKwKvJvfsjx79aXj",
      "proofPurpose": "assertionMethod",
      "proofValue": "z5JvEzKid2bzhRWw4KZXpzTo9NVbFZinobyjtQSW9tzSRsh38Zpy91tQXhqyzD98wQ9LkDC8SG3YMQMaTeCdvH73t"
    }
  ]
}
---------------- JWT header ---------------
{
  "alg": "RS256",
  "typ": "JWT",
  "jwk": {
    "e": "AQAB",
    "kty": "RSA",
    "n": "3HMIoYHPPcTQI92IvkMiHmo-IN0MWRAby2J4eyuv-mG1ZXKxplDlRxWq5airmvPlg6q-VF
ovThTwRRCPfMn3dJsPhNNL5j3pCDY0gHSuaeuIyYouro563G8_cOHbpaersGjYpujCv3DAE2_QcCUjv6
BPYJha-EUNwhVxxM3-yMzeZoDP6LRILgUazilkHS37blgirgA3WHo7cmDQe8sVaP-vfkFJCVG7yDxPwR
4TfGAR0UWxObsCa73mSoQl72JGZ-aFOmuQyNcH9DUKGpXKCt1TW54j9eGK3uBF8kG08vVLnDg3_7Kupw
oi9QT3fGBZ2CKCmqujjUtABZm_mxNBjQ"
  }
}
--------------- JWT payload ---------------
// NOTE: The example below uses a valid VC-JWT serialization
//       that duplicates the iss, nbf, jti, and sub fields in the
//       Verifiable Credential (vc) field.
{
  "vc": {
    "@context": [
      "https://www.w3.org/2018/credentials/v1",
      "https://imsglobal.github.io/openbadges-specification/context.json",
      "https://w3id.org/security/suites/ed25519-2020/v1"
    ],
    "type": [
      "VerifiableCredential",
      "EndorsementCredential"
    ],
    "issuer": {
      "id": "https://state.gov/issuers/565049",
      "type": [
        "Profile"
      ],
      "name": "State Department of Education"
    },
    "issuanceDate": "2010-01-01T00:00:00Z",
    "expirationDate": "2020-01-01T00:00:00Z",
    "credentialSubject": {
      "id": "https://1edtech.edu/issuers/565049",
      "type": [
        "EndorsementSubject"
      ],
      "endorsementComment": "1EdTech University is in good standing"
    },
    "credentialSchema": [
      {
        "id": "https://purl.imsglobal.org/spec/ob/v3p0/schema/endorsementcredent
ial.json",
        "type": "1EdTechJsonSchemaValidator2019"
      },
      {
        "id": "https://state.gov/schema/endorsementcredential.json",
        "type": "JsonSchemaValidator2018"
      }
    ],
    "credentialStatus": {
      "id": "https://state.gov/credentials/3732/revocations",
      "type": "1EdTechRevocationList"
    },
    "refreshService": {
      "id": "http://state.gov/credentials/3732",
      "type": "1EdTechCredentialRefresh"
    }
  },
  "exp": 1577836800,
  "iss": "https://state.gov/issuers/565049",
  "nbf": 1262304000,
  "sub": "https://1edtech.edu/issuers/565049"
}
--------------- JWT ---------------
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImp3ayI6eyJlIjoiQVFBQiIsImt0eSI6IlJTQSIsIm4i
OiIzSE1Jb1lIUFBjVFFJOTJJdmtNaUhtby1JTjBNV1JBYnkySjRleXV2LW1HMVpYS3hwbERsUnhXcTVh
aXJtdlBsZzZxLVZGb3ZUaFR3UlJDUGZNbjNkSnNQaE5OTDVqM3BDRFkwZ0hTdWFldUl5WW91cm81NjNH
OF9jT0hicGFlcnNHallwdWpDdjNEQUUyX1FjQ1VqdjZCUFlKaGEtRVVOd2hWeHhNMy15TXplWm9EUDZM
UklMZ1Vhemlsa0hTMzdibGdpcmdBM1dIbzdjbURRZThzVmFQLXZma0ZKQ1ZHN3lEeFB3UjRUZkdBUjBV
V3hPYnNDYTczbVNvUWw3MkpHWi1hRk9tdVF5TmNIOURVS0dwWEtDdDFUVzU0ajllR0szdUJGOGtHMDh2
VkxuRGczXzdLdXB3b2k5UVQzZkdCWjJDS0NtcXVqalV0QUJabV9teE5CalEifX0.eyJ2YyI6eyJAY29u
dGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vaW1z
Z2xvYmFsLmdpdGh1Yi5pby9vcGVuYmFkZ2VzLXNwZWNpZmljYXRpb24vY29udGV4dC5qc29uIiwiaHR0
cHM6Ly93M2lkLm9yZy9zZWN1cml0eS9zdWl0ZXMvZWQyNTUxOS0yMDIwL3YxIl0sInR5cGUiOlsiVmVy
aWZpYWJsZUNyZWRlbnRpYWwiLCJFbmRvcnNlbWVudENyZWRlbnRpYWwiXSwiaXNzdWVyIjp7ImlkIjoi
aHR0cHM6Ly9zdGF0ZS5nb3YvaXNzdWVycy81NjUwNDkiLCJ0eXBlIjpbIlByb2ZpbGUiXSwibmFtZSI6
IlN0YXRlIERlcGFydG1lbnQgb2YgRWR1Y2F0aW9uIn0sImlzc3VhbmNlRGF0ZSI6IjIwMTAtMDEtMDFU
MDA6MDA6MDBaIiwiZXhwaXJhdGlvbkRhdGUiOiIyMDIwLTAxLTAxVDAwOjAwOjAwWiIsImNyZWRlbnRp
YWxTdWJqZWN0Ijp7ImlkIjoiaHR0cHM6Ly8xZWR0ZWNoLmVkdS9pc3N1ZXJzLzU2NTA0OSIsInR5cGUi
OlsiRW5kb3JzZW1lbnRTdWJqZWN0Il0sImVuZG9yc2VtZW50Q29tbWVudCI6IjFFZFRlY2ggVW5pdmVy
c2l0eSBpcyBpbiBnb29kIHN0YW5kaW5nIn0sImNyZWRlbnRpYWxTY2hlbWEiOlt7ImlkIjoiaHR0cHM6
Ly9wdXJsLmltc2dsb2JhbC5vcmcvc3BlYy9vYi92M3AwL3NjaGVtYS9lbmRvcnNlbWVudGNyZWRlbnRp
YWwuanNvbiIsInR5cGUiOiIxRWRUZWNoSnNvblNjaGVtYVZhbGlkYXRvcjIwMTkifSx7ImlkIjoiaHR0
cHM6Ly9zdGF0ZS5nb3Yvc2NoZW1hL2VuZG9yc2VtZW50Y3JlZGVudGlhbC5qc29uIiwidHlwZSI6Ikpz
b25TY2hlbWFWYWxpZGF0b3IyMDE4In1dLCJjcmVkZW50aWFsU3RhdHVzIjp7ImlkIjoiaHR0cHM6Ly9z
dGF0ZS5nb3YvY3JlZGVudGlhbHMvMzczMi9yZXZvY2F0aW9ucyIsInR5cGUiOiIxRWRUZWNoUmV2b2Nh
dGlvbkxpc3QifSwicmVmcmVzaFNlcnZpY2UiOnsiaWQiOiJodHRwOi8vc3RhdGUuZ292L2NyZWRlbnRp
YWxzLzM3MzIiLCJ0eXBlIjoiMUVkVGVjaENyZWRlbnRpYWxSZWZyZXNoIn19LCJleHAiOjE1Nzc4MzY4
MDAsImlzcyI6Imh0dHBzOi8vc3RhdGUuZ292L2lzc3VlcnMvNTY1MDQ5IiwibmJmIjoxMjYyMzA0MDAw
LCJzdWIiOiJodHRwczovLzFlZHRlY2guZWR1L2lzc3VlcnMvNTY1MDQ5In0.setjatmriAh76k-T8BqF
GGvk5RbGMCfOpzPODIUZBM0qp_u2-uvKFEI8cUwLcfNp_YYKPwcXFhzkz8bLEhWxPN6CnH5FS8tn2lZi
9ceE3DKtrC2XEXb3Z2_HUDhGzV3OMZ5yGILJ606znwsR7k70AYh5gYnvKXpmhW8yRtqQeCVwvTjyOujt
Ev5uSx5-pTaxdNrw9V4zcwdJuOxLMIcsVALD02mhKkx42Fj8K6myhE5wTSs3C1TuFGZ26t28k6BOcfZT
JH-KCkV8jTlU2083ThFX0htA5-xQsRvdAvQlCnNqm_sMvFxx1seGASZTpHGy1pd0e7OGaDTkZwbnRCtN
cQ

D.4 Achievement Alignment (CASE)

Example 38: Achievement alignment (Credential Engine)
{
  "@context": [
    "https://www.w3.org/2018/credentials/v1",
    "https://imsglobal.github.io/openbadges-specification/context.json"
  ],
  "id": "http://example.edu/credentials/3732",
  "type": ["VerifiableCredential", "OpenBadgeCredential"],
  "issuer": {
    "id": "https://example.edu/issuers/565049",
    "type": ["Profile"],
    "name": "Example University"
  },
  "issuanceDate": "2010-01-01T00:00:00Z",
  "name": "Example University Degree",
  "credentialSubject": {
    "id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
    "type": ["AchievementSubject"],
    "achievement": {
      "id": "https://1edtech.edu/achievements/1",
      "type": ["Achievement"],
      "criteria": {
        "narrative": "Cite strong and thorough textual evidence to support analysis of what the text says explicitly as well as inferences drawn from the text, including determining where the text leaves matters uncertain"
      },
      "description": "Analyze a sample text",
      "name": "Text analysis",
      "alignment": [{
        "type": ["Alignment"],
        "targetCode": "ce-cf4dee18-7cea-443a-b920-158a0762c6bf",
        "targetFramework": "Edmonds College Course Catalog",
        "targetName": "Requirements Analysis",
        "targetType": "ceterms:Credential",
        "targetUrl": "https://credentialfinder.org/credential/20229/Requirements_Analysis"
      }]
    }
  }
}
{
  "@context": [
    "https://www.w3.org/2018/credentials/v1",
    "https://imsglobal.github.io/openbadges-specification/context.json",
    "https://w3id.org/security/suites/ed25519-2020/v1"
  ],
  "id": "http://example.edu/credentials/3732",
  "type": [
    "VerifiableCredential",
    "OpenBadgeCredential"
  ],
  "issuer": {
    "id": "https://example.edu/issuers/565049",
    "type": [
      "Profile"
    ],
    "name": "Example University"
  },
  "issuanceDate": "2010-01-01T00:00:00Z",
  "name": "Example University Degree",
  "credentialSubject": {
    "id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
    "type": [
      "AchievementSubject"
    ],
    "achievement": {
      "id": "https://1edtech.edu/achievements/1",
      "type": [
        "Achievement"
      ],
      "criteria": {
        "narrative": "Cite strong and thorough textual evidence to support analysis of what the text says explicitly as well as inferences drawn from the text, including determining where the text leaves matters uncertain"
      },
      "description": "Analyze a sample text",
      "name": "Text analysis",
      "alignment": [
        {
          "type": [
            "Alignment"
          ],
          "targetCode": "ce-cf4dee18-7cea-443a-b920-158a0762c6bf",
          "targetFramework": "Edmonds College Course Catalog",
          "targetName": "Requirements Analysis",
          "targetType": "ceterms:Credential",
          "targetUrl": "https://credentialfinder.org/credential/20229/Requirements_Analysis"
        }
      ]
    }
  },
  "proof": [
    {
      "type": "Ed25519Signature2020",
      "created": "2022-06-28T16:28:36Z",
      "verificationMethod": "did:key:z6MkkUD3J14nkYzn46QeuaVSnp7dF85QJKwKvJvfsjx79aXj",
      "proofPurpose": "assertionMethod",
      "proofValue": "z5qeWFBuAF34mPioJq6PBQLTbSF2U1enDuXzWV1S1cKWxYy7WDUxqbn4qSWzWGhg13uvmP62diHBt4edgT5rVyCV2"
    }
  ]
}
---------------- JWT header ---------------
{
  "alg": "RS256",
  "typ": "JWT",
  "jwk": {
    "e": "AQAB",
    "kty": "RSA",
    "n": "3HMIoYHPPcTQI92IvkMiHmo-IN0MWRAby2J4eyuv-mG1ZXKxplDlRxWq5airmvPlg6q-VF
ovThTwRRCPfMn3dJsPhNNL5j3pCDY0gHSuaeuIyYouro563G8_cOHbpaersGjYpujCv3DAE2_QcCUjv6
BPYJha-EUNwhVxxM3-yMzeZoDP6LRILgUazilkHS37blgirgA3WHo7cmDQe8sVaP-vfkFJCVG7yDxPwR
4TfGAR0UWxObsCa73mSoQl72JGZ-aFOmuQyNcH9DUKGpXKCt1TW54j9eGK3uBF8kG08vVLnDg3_7Kupw
oi9QT3fGBZ2CKCmqujjUtABZm_mxNBjQ"
  }
}
--------------- JWT payload ---------------
// NOTE: The example below uses a valid VC-JWT serialization
//       that duplicates the iss, nbf, jti, and sub fields in the
//       Verifiable Credential (vc) field.
{
  "vc": {
    "@context": [
      "https://www.w3.org/2018/credentials/v1",
      "https://imsglobal.github.io/openbadges-specification/context.json"
    ],
    "id": "http://example.edu/credentials/3732",
    "type": [
      "VerifiableCredential",
      "OpenBadgeCredential"
    ],
    "issuer": {
      "id": "https://example.edu/issuers/565049",
      "type": [
        "Profile"
      ],
      "name": "Example University"
    },
    "issuanceDate": "2010-01-01T00:00:00Z",
    "name": "Example University Degree",
    "credentialSubject": {
      "id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
      "type": [
        "AchievementSubject"
      ],
      "achievement": {
        "id": "https://1edtech.edu/achievements/1",
        "type": [
          "Achievement"
        ],
        "criteria": {
          "narrative": "Cite strong and thorough textual evidence to support ana
lysis of what the text says explicitly as well as inferences drawn from the text
, including determining where the text leaves matters uncertain"
        },
        "description": "Analyze a sample text",
        "name": "Text analysis",
        "alignment": [
          {
            "type": [
              "Alignment"
            ],
            "targetCode": "ce-cf4dee18-7cea-443a-b920-158a0762c6bf",
            "targetFramework": "Edmonds College Course Catalog",
            "targetName": "Requirements Analysis",
            "targetType": "ceterms:Credential",
            "targetUrl": "https://credentialfinder.org/credential/20229/Requirem
ents_Analysis"
          }
        ]
      }
    }
  },
  "iss": "https://example.edu/issuers/565049",
  "nbf": 1262304000,
  "jti": "http://example.edu/credentials/3732",
  "sub": "did:example:ebfeb1f712ebc6f1c276e12ec21"
}
--------------- JWT ---------------
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImp3ayI6eyJlIjoiQVFBQiIsImt0eSI6IlJTQSIsIm4i
OiIzSE1Jb1lIUFBjVFFJOTJJdmtNaUhtby1JTjBNV1JBYnkySjRleXV2LW1HMVpYS3hwbERsUnhXcTVh
aXJtdlBsZzZxLVZGb3ZUaFR3UlJDUGZNbjNkSnNQaE5OTDVqM3BDRFkwZ0hTdWFldUl5WW91cm81NjNH
OF9jT0hicGFlcnNHallwdWpDdjNEQUUyX1FjQ1VqdjZCUFlKaGEtRVVOd2hWeHhNMy15TXplWm9EUDZM
UklMZ1Vhemlsa0hTMzdibGdpcmdBM1dIbzdjbURRZThzVmFQLXZma0ZKQ1ZHN3lEeFB3UjRUZkdBUjBV
V3hPYnNDYTczbVNvUWw3MkpHWi1hRk9tdVF5TmNIOURVS0dwWEtDdDFUVzU0ajllR0szdUJGOGtHMDh2
VkxuRGczXzdLdXB3b2k5UVQzZkdCWjJDS0NtcXVqalV0QUJabV9teE5CalEifX0.eyJ2YyI6eyJAY29u
dGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vaW1z
Z2xvYmFsLmdpdGh1Yi5pby9vcGVuYmFkZ2VzLXNwZWNpZmljYXRpb24vY29udGV4dC5qc29uIl0sImlk
IjoiaHR0cDovL2V4YW1wbGUuZWR1L2NyZWRlbnRpYWxzLzM3MzIiLCJ0eXBlIjpbIlZlcmlmaWFibGVD
cmVkZW50aWFsIiwiT3BlbkJhZGdlQ3JlZGVudGlhbCJdLCJpc3N1ZXIiOnsiaWQiOiJodHRwczovL2V4
YW1wbGUuZWR1L2lzc3VlcnMvNTY1MDQ5IiwidHlwZSI6WyJQcm9maWxlIl0sIm5hbWUiOiJFeGFtcGxl
IFVuaXZlcnNpdHkifSwiaXNzdWFuY2VEYXRlIjoiMjAxMC0wMS0wMVQwMDowMDowMFoiLCJuYW1lIjoi
RXhhbXBsZSBVbml2ZXJzaXR5IERlZ3JlZSIsImNyZWRlbnRpYWxTdWJqZWN0Ijp7ImlkIjoiZGlkOmV4
YW1wbGU6ZWJmZWIxZjcxMmViYzZmMWMyNzZlMTJlYzIxIiwidHlwZSI6WyJBY2hpZXZlbWVudFN1Ympl
Y3QiXSwiYWNoaWV2ZW1lbnQiOnsiaWQiOiJodHRwczovLzFlZHRlY2guZWR1L2FjaGlldmVtZW50cy8x
IiwidHlwZSI6WyJBY2hpZXZlbWVudCJdLCJjcml0ZXJpYSI6eyJuYXJyYXRpdmUiOiJDaXRlIHN0cm9u
ZyBhbmQgdGhvcm91Z2ggdGV4dHVhbCBldmlkZW5jZSB0byBzdXBwb3J0IGFuYWx5c2lzIG9mIHdoYXQg
dGhlIHRleHQgc2F5cyBleHBsaWNpdGx5IGFzIHdlbGwgYXMgaW5mZXJlbmNlcyBkcmF3biBmcm9tIHRo
ZSB0ZXh0LCBpbmNsdWRpbmcgZGV0ZXJtaW5pbmcgd2hlcmUgdGhlIHRleHQgbGVhdmVzIG1hdHRlcnMg
dW5jZXJ0YWluIn0sImRlc2NyaXB0aW9uIjoiQW5hbHl6ZSBhIHNhbXBsZSB0ZXh0IiwibmFtZSI6IlRl
eHQgYW5hbHlzaXMiLCJhbGlnbm1lbnQiOlt7InR5cGUiOlsiQWxpZ25tZW50Il0sInRhcmdldENvZGUi
OiJjZS1jZjRkZWUxOC03Y2VhLTQ0M2EtYjkyMC0xNThhMDc2MmM2YmYiLCJ0YXJnZXRGcmFtZXdvcmsi
OiJFZG1vbmRzIENvbGxlZ2UgQ291cnNlIENhdGFsb2ciLCJ0YXJnZXROYW1lIjoiUmVxdWlyZW1lbnRz
IEFuYWx5c2lzIiwidGFyZ2V0VHlwZSI6ImNldGVybXM6Q3JlZGVudGlhbCIsInRhcmdldFVybCI6Imh0
dHBzOi8vY3JlZGVudGlhbGZpbmRlci5vcmcvY3JlZGVudGlhbC8yMDIyOS9SZXF1aXJlbWVudHNfQW5h
bHlzaXMifV19fX0sImlzcyI6Imh0dHBzOi8vZXhhbXBsZS5lZHUvaXNzdWVycy81NjUwNDkiLCJuYmYi
OjEyNjIzMDQwMDAsImp0aSI6Imh0dHA6Ly9leGFtcGxlLmVkdS9jcmVkZW50aWFscy8zNzMyIiwic3Vi
IjoiZGlkOmV4YW1wbGU6ZWJmZWIxZjcxMmViYzZmMWMyNzZlMTJlYzIxIn0.yEvfn3sZ1glEd0tybvAU
RjEAukbWGGOa7gSx7v1tlQ9RQbjoUZeoprqXC3nKyDO_48fwJQSZXeEhmp1AT6wxHIoQTWDhM4BkPVs4
B8mKasAhUgOvrWRAFpS7Rjrq9n-on3q5xzcE-jNx3sI4vG5a84ZclWas2GBgzKRMhy-h3Jt0K63pdTr7
JfylQZa0eoR7xXPcABQyLPATuJV6zeFVrxZdN5erP9mxhXYPCX-XVBMFf_Yr1KBiNQVite2e62ODaiVV
3H7aWm3sPeEredCFWgJ3wT3FbtmtywvFbUisqNKufPSzDt9s2133fDuojjgJERC7pXZvqg4BnXysfic3
xQ

D.5 Achievement Alignment (Credential Engine)

Example 39: Achievement alignment (Credential Engine)
{
  "@context": [
    "https://www.w3.org/2018/credentials/v1",
    "https://imsglobal.github.io/openbadges-specification/context.json"
  ],
  "id": "http://example.edu/credentials/3732",
  "type": ["VerifiableCredential", "OpenBadgeCredential"],
  "issuer": {
    "id": "https://example.edu/issuers/565049",
    "type": ["Profile"],
    "name": "Example University"
  },
  "issuanceDate": "2010-01-01T00:00:00Z",
  "name": "Example University Degree",
  "credentialSubject": {
    "id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
    "type": ["AchievementSubject"],
    "achievement": {
      "id": "https://1edtech.edu/achievements/1",
      "type": ["Achievement"],
      "criteria": {
        "narrative": "Cite strong and thorough textual evidence to support analysis of what the text says explicitly as well as inferences drawn from the text, including determining where the text leaves matters uncertain"
      },
      "description": "Analyze a sample text",
      "name": "Text analysis",
      "alignment": [{
        "type": ["Alignment"],
        "targetCode": "ce-cf4dee18-7cea-443a-b920-158a0762c6bf",
        "targetFramework": "Edmonds College Course Catalog",
        "targetName": "Requirements Analysis",
        "targetType": "ceterms:Credential",
        "targetUrl": "https://credentialfinder.org/credential/20229/Requirements_Analysis"
      }]
    }
  }
}
{
  "@context": [
    "https://www.w3.org/2018/credentials/v1",
    "https://imsglobal.github.io/openbadges-specification/context.json",
    "https://w3id.org/security/suites/ed25519-2020/v1"
  ],
  "id": "http://example.edu/credentials/3732",
  "type": [
    "VerifiableCredential",
    "OpenBadgeCredential"
  ],
  "issuer": {
    "id": "https://example.edu/issuers/565049",
    "type": [
      "Profile"
    ],
    "name": "Example University"
  },
  "issuanceDate": "2010-01-01T00:00:00Z",
  "name": "Example University Degree",
  "credentialSubject": {
    "id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
    "type": [
      "AchievementSubject"
    ],
    "achievement": {
      "id": "https://1edtech.edu/achievements/1",
      "type": [
        "Achievement"
      ],
      "criteria": {
        "narrative": "Cite strong and thorough textual evidence to support analysis of what the text says explicitly as well as inferences drawn from the text, including determining where the text leaves matters uncertain"
      },
      "description": "Analyze a sample text",
      "name": "Text analysis",
      "alignment": [
        {
          "type": [
            "Alignment"
          ],
          "targetCode": "ce-cf4dee18-7cea-443a-b920-158a0762c6bf",
          "targetFramework": "Edmonds College Course Catalog",
          "targetName": "Requirements Analysis",
          "targetType": "ceterms:Credential",
          "targetUrl": "https://credentialfinder.org/credential/20229/Requirements_Analysis"
        }
      ]
    }
  },
  "proof": [
    {
      "type": "Ed25519Signature2020",
      "created": "2022-06-28T16:28:36Z",
      "verificationMethod": "did:key:z6MkkUD3J14nkYzn46QeuaVSnp7dF85QJKwKvJvfsjx79aXj",
      "proofPurpose": "assertionMethod",
      "proofValue": "z5qeWFBuAF34mPioJq6PBQLTbSF2U1enDuXzWV1S1cKWxYy7WDUxqbn4qSWzWGhg13uvmP62diHBt4edgT5rVyCV2"
    }
  ]
}
---------------- JWT header ---------------
{
  "alg": "RS256",
  "typ": "JWT",
  "jwk": {
    "e": "AQAB",
    "kty": "RSA",
    "n": "3HMIoYHPPcTQI92IvkMiHmo-IN0MWRAby2J4eyuv-mG1ZXKxplDlRxWq5airmvPlg6q-VF
ovThTwRRCPfMn3dJsPhNNL5j3pCDY0gHSuaeuIyYouro563G8_cOHbpaersGjYpujCv3DAE2_QcCUjv6
BPYJha-EUNwhVxxM3-yMzeZoDP6LRILgUazilkHS37blgirgA3WHo7cmDQe8sVaP-vfkFJCVG7yDxPwR
4TfGAR0UWxObsCa73mSoQl72JGZ-aFOmuQyNcH9DUKGpXKCt1TW54j9eGK3uBF8kG08vVLnDg3_7Kupw
oi9QT3fGBZ2CKCmqujjUtABZm_mxNBjQ"
  }
}
--------------- JWT payload ---------------
// NOTE: The example below uses a valid VC-JWT serialization
//       that duplicates the iss, nbf, jti, and sub fields in the
//       Verifiable Credential (vc) field.
{
  "vc": {
    "@context": [
      "https://www.w3.org/2018/credentials/v1",
      "https://imsglobal.github.io/openbadges-specification/context.json"
    ],
    "id": "http://example.edu/credentials/3732",
    "type": [
      "VerifiableCredential",
      "OpenBadgeCredential"
    ],
    "issuer": {
      "id": "https://example.edu/issuers/565049",
      "type": [
        "Profile"
      ],
      "name": "Example University"
    },
    "issuanceDate": "2010-01-01T00:00:00Z",
    "name": "Example University Degree",
    "credentialSubject": {
      "id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
      "type": [
        "AchievementSubject"
      ],
      "achievement": {
        "id": "https://1edtech.edu/achievements/1",
        "type": [
          "Achievement"
        ],
        "criteria": {
          "narrative": "Cite strong and thorough textual evidence to support ana
lysis of what the text says explicitly as well as inferences drawn from the text
, including determining where the text leaves matters uncertain"
        },
        "description": "Analyze a sample text",
        "name": "Text analysis",
        "alignment": [
          {
            "type": [
              "Alignment"
            ],
            "targetCode": "ce-cf4dee18-7cea-443a-b920-158a0762c6bf",
            "targetFramework": "Edmonds College Course Catalog",
            "targetName": "Requirements Analysis",
            "targetType": "ceterms:Credential",
            "targetUrl": "https://credentialfinder.org/credential/20229/Requirem
ents_Analysis"
          }
        ]
      }
    }
  },
  "iss": "https://example.edu/issuers/565049",
  "nbf": 1262304000,
  "jti": "http://example.edu/credentials/3732",
  "sub": "did:example:ebfeb1f712ebc6f1c276e12ec21"
}
--------------- JWT ---------------
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImp3ayI6eyJlIjoiQVFBQiIsImt0eSI6IlJTQSIsIm4i
OiIzSE1Jb1lIUFBjVFFJOTJJdmtNaUhtby1JTjBNV1JBYnkySjRleXV2LW1HMVpYS3hwbERsUnhXcTVh
aXJtdlBsZzZxLVZGb3ZUaFR3UlJDUGZNbjNkSnNQaE5OTDVqM3BDRFkwZ0hTdWFldUl5WW91cm81NjNH
OF9jT0hicGFlcnNHallwdWpDdjNEQUUyX1FjQ1VqdjZCUFlKaGEtRVVOd2hWeHhNMy15TXplWm9EUDZM
UklMZ1Vhemlsa0hTMzdibGdpcmdBM1dIbzdjbURRZThzVmFQLXZma0ZKQ1ZHN3lEeFB3UjRUZkdBUjBV
V3hPYnNDYTczbVNvUWw3MkpHWi1hRk9tdVF5TmNIOURVS0dwWEtDdDFUVzU0ajllR0szdUJGOGtHMDh2
VkxuRGczXzdLdXB3b2k5UVQzZkdCWjJDS0NtcXVqalV0QUJabV9teE5CalEifX0.eyJ2YyI6eyJAY29u
dGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vaW1z
Z2xvYmFsLmdpdGh1Yi5pby9vcGVuYmFkZ2VzLXNwZWNpZmljYXRpb24vY29udGV4dC5qc29uIl0sImlk
IjoiaHR0cDovL2V4YW1wbGUuZWR1L2NyZWRlbnRpYWxzLzM3MzIiLCJ0eXBlIjpbIlZlcmlmaWFibGVD
cmVkZW50aWFsIiwiT3BlbkJhZGdlQ3JlZGVudGlhbCJdLCJpc3N1ZXIiOnsiaWQiOiJodHRwczovL2V4
YW1wbGUuZWR1L2lzc3VlcnMvNTY1MDQ5IiwidHlwZSI6WyJQcm9maWxlIl0sIm5hbWUiOiJFeGFtcGxl
IFVuaXZlcnNpdHkifSwiaXNzdWFuY2VEYXRlIjoiMjAxMC0wMS0wMVQwMDowMDowMFoiLCJuYW1lIjoi
RXhhbXBsZSBVbml2ZXJzaXR5IERlZ3JlZSIsImNyZWRlbnRpYWxTdWJqZWN0Ijp7ImlkIjoiZGlkOmV4
YW1wbGU6ZWJmZWIxZjcxMmViYzZmMWMyNzZlMTJlYzIxIiwidHlwZSI6WyJBY2hpZXZlbWVudFN1Ympl
Y3QiXSwiYWNoaWV2ZW1lbnQiOnsiaWQiOiJodHRwczovLzFlZHRlY2guZWR1L2FjaGlldmVtZW50cy8x
IiwidHlwZSI6WyJBY2hpZXZlbWVudCJdLCJjcml0ZXJpYSI6eyJuYXJyYXRpdmUiOiJDaXRlIHN0cm9u
ZyBhbmQgdGhvcm91Z2ggdGV4dHVhbCBldmlkZW5jZSB0byBzdXBwb3J0IGFuYWx5c2lzIG9mIHdoYXQg
dGhlIHRleHQgc2F5cyBleHBsaWNpdGx5IGFzIHdlbGwgYXMgaW5mZXJlbmNlcyBkcmF3biBmcm9tIHRo
ZSB0ZXh0LCBpbmNsdWRpbmcgZGV0ZXJtaW5pbmcgd2hlcmUgdGhlIHRleHQgbGVhdmVzIG1hdHRlcnMg
dW5jZXJ0YWluIn0sImRlc2NyaXB0aW9uIjoiQW5hbHl6ZSBhIHNhbXBsZSB0ZXh0IiwibmFtZSI6IlRl
eHQgYW5hbHlzaXMiLCJhbGlnbm1lbnQiOlt7InR5cGUiOlsiQWxpZ25tZW50Il0sInRhcmdldENvZGUi
OiJjZS1jZjRkZWUxOC03Y2VhLTQ0M2EtYjkyMC0xNThhMDc2MmM2YmYiLCJ0YXJnZXRGcmFtZXdvcmsi
OiJFZG1vbmRzIENvbGxlZ2UgQ291cnNlIENhdGFsb2ciLCJ0YXJnZXROYW1lIjoiUmVxdWlyZW1lbnRz
IEFuYWx5c2lzIiwidGFyZ2V0VHlwZSI6ImNldGVybXM6Q3JlZGVudGlhbCIsInRhcmdldFVybCI6Imh0
dHBzOi8vY3JlZGVudGlhbGZpbmRlci5vcmcvY3JlZGVudGlhbC8yMDIyOS9SZXF1aXJlbWVudHNfQW5h
bHlzaXMifV19fX0sImlzcyI6Imh0dHBzOi8vZXhhbXBsZS5lZHUvaXNzdWVycy81NjUwNDkiLCJuYmYi
OjEyNjIzMDQwMDAsImp0aSI6Imh0dHA6Ly9leGFtcGxlLmVkdS9jcmVkZW50aWFscy8zNzMyIiwic3Vi
IjoiZGlkOmV4YW1wbGU6ZWJmZWIxZjcxMmViYzZmMWMyNzZlMTJlYzIxIn0.yEvfn3sZ1glEd0tybvAU
RjEAukbWGGOa7gSx7v1tlQ9RQbjoUZeoprqXC3nKyDO_48fwJQSZXeEhmp1AT6wxHIoQTWDhM4BkPVs4
B8mKasAhUgOvrWRAFpS7Rjrq9n-on3q5xzcE-jNx3sI4vG5a84ZclWas2GBgzKRMhy-h3Jt0K63pdTr7
JfylQZa0eoR7xXPcABQyLPATuJV6zeFVrxZdN5erP9mxhXYPCX-XVBMFf_Yr1KBiNQVite2e62ODaiVV
3H7aWm3sPeEredCFWgJ3wT3FbtmtywvFbUisqNKufPSzDt9s2133fDuojjgJERC7pXZvqg4BnXysfic3
xQ

D.6 Skill Assertion (CASE)

Note
A Skill Assertion credential should only have one Result and one Alignment.
Example 40: Skill Assertion (CASE)
{
  "@context": [
    "https://www.w3.org/2018/credentials/v1",
    "https://imsglobal.github.io/openbadges-specification/context.json"
  ],
  "type": ["VerifiableCredential", "OpenBadgeCredential"],
  "id": "https://issuer-website.com/awards/abc123",
  "issuer": {
    "id": "did:example:issuer",
    "type": ["Profile"],
    "name": "An Example Issuer",
    "image": {
      "id": "https://example.org/logo.png",
      "type": "Image"
    },
    "url": "https://example.org",
    "email": "contact@example.org"
  },
  "issuanceDate": "2022-05-01T19:23:24Z",
  "name": "Cite strong and thorough textual evidence to support analysis of what the text says explicitly as well as inferences drawn from the text, including determining where the text leaves matters uncertain",
  "credentialSubject": {
    "id": "did:example:learner",
    "type": ["AchievementSubject"],
    "result": [{
      "type": ["Result"],
      "alignment": [{
        "type": ["Alignment"],
        "targetCode": "74f5bb7d-d7cc-11e8-824f-0242ac160002",
        "targetFramework": "Alabama Course of Study: English Language Arts",
        "targetName": "Cite strong and thorough textual evidence to support analysis of what the text says explicitly as well as inferences drawn from the text, including determining where the text leaves matters uncertain",
        "targetType": "CFItem",
        "targetUrl": "https://caseregistry.imsglobal.org/uri/74f5bb7d-d7cc-11e8-824f-0242ac160002"
      }]
    }]
  }
}
{
  "@context": [
    "https://www.w3.org/2018/credentials/v1",
    "https://imsglobal.github.io/openbadges-specification/context.json",
    "https://w3id.org/security/suites/ed25519-2020/v1"
  ],
  "type": [
    "VerifiableCredential",
    "OpenBadgeCredential"
  ],
  "id": "https://issuer-website.com/awards/abc123",
  "issuer": {
    "id": "did:example:issuer",
    "type": [
      "Profile"
    ],
    "name": "An Example Issuer",
    "image": {
      "id": "https://example.org/logo.png",
      "type": "Image"
    },
    "url": "https://example.org",
    "email": "contact@example.org"
  },
  "issuanceDate": "2022-05-01T19:23:24Z",
  "name": "Cite strong and thorough textual evidence to support analysis of what the text says explicitly as well as inferences drawn from the text, including determining where the text leaves matters uncertain",
  "credentialSubject": {
    "id": "did:example:learner",
    "type": [
      "AchievementSubject"
    ],
    "result": [
      {
        "type": [
          "Result"
        ],
        "alignment": [
          {
            "type": [
              "Alignment"
            ],
            "targetCode": "74f5bb7d-d7cc-11e8-824f-0242ac160002",
            "targetFramework": "Alabama Course of Study: English Language Arts",
            "targetName": "Cite strong and thorough textual evidence to support analysis of what the text says explicitly as well as inferences drawn from the text, including determining where the text leaves matters uncertain",
            "targetType": "CFItem",
            "targetUrl": "https://caseregistry.imsglobal.org/uri/74f5bb7d-d7cc-11e8-824f-0242ac160002"
          }
        ]
      }
    ]
  },
  "proof": [
    {
      "type": "Ed25519Signature2020",
      "created": "2022-06-28T16:28:36Z",
      "verificationMethod": "did:key:z6MkkUD3J14nkYzn46QeuaVSnp7dF85QJKwKvJvfsjx79aXj",
      "proofPurpose": "assertionMethod",
      "proofValue": "z3jb6RqgBA94Ce5aw6eNvjFXYYwEoMk67sMU17J8A3NDqPBdCVG1yx6MRc5WGEdf15BdmYw7dVfC6ZgTgWE5rUuKU"
    }
  ]
}
---------------- JWT header ---------------
{
  "alg": "RS256",
  "typ": "JWT",
  "jwk": {
    "e": "AQAB",
    "kty": "RSA",
    "n": "3HMIoYHPPcTQI92IvkMiHmo-IN0MWRAby2J4eyuv-mG1ZXKxplDlRxWq5airmvPlg6q-VF
ovThTwRRCPfMn3dJsPhNNL5j3pCDY0gHSuaeuIyYouro563G8_cOHbpaersGjYpujCv3DAE2_QcCUjv6
BPYJha-EUNwhVxxM3-yMzeZoDP6LRILgUazilkHS37blgirgA3WHo7cmDQe8sVaP-vfkFJCVG7yDxPwR
4TfGAR0UWxObsCa73mSoQl72JGZ-aFOmuQyNcH9DUKGpXKCt1TW54j9eGK3uBF8kG08vVLnDg3_7Kupw
oi9QT3fGBZ2CKCmqujjUtABZm_mxNBjQ"
  }
}
--------------- JWT payload ---------------
// NOTE: The example below uses a valid VC-JWT serialization
//       that duplicates the iss, nbf, jti, and sub fields in the
//       Verifiable Credential (vc) field.
{
  "vc": {
    "@context": [
      "https://www.w3.org/2018/credentials/v1",
      "https://imsglobal.github.io/openbadges-specification/context.json"
    ],
    "type": [
      "VerifiableCredential",
      "OpenBadgeCredential"
    ],
    "id": "https://issuer-website.com/awards/abc123",
    "issuer": {
      "id": "did:example:issuer",
      "type": [
        "Profile"
      ],
      "name": "An Example Issuer",
      "image": {
        "id": "https://example.org/logo.png",
        "type": "Image"
      },
      "url": "https://example.org",
      "email": "contact@example.org"
    },
    "issuanceDate": "2022-05-01T19:23:24Z",
    "name": "Cite strong and thorough textual evidence to support analysis of wh
at the text says explicitly as well as inferences drawn from the text, including
 determining where the text leaves matters uncertain",
    "credentialSubject": {
      "id": "did:example:learner",
      "type": [
        "AchievementSubject"
      ],
      "result": [
        {
          "type": [
            "Result"
          ],
          "alignment": [
            {
              "type": [
                "Alignment"
              ],
              "targetCode": "74f5bb7d-d7cc-11e8-824f-0242ac160002",
              "targetFramework": "Alabama Course of Study: English Language Arts
",
              "targetName": "Cite strong and thorough textual evidence to suppor
t analysis of what the text says explicitly as well as inferences drawn from the
 text, including determining where the text leaves matters uncertain",
              "targetType": "CFItem",
              "targetUrl": "https://caseregistry.imsglobal.org/uri/74f5bb7d-d7cc
-11e8-824f-0242ac160002"
            }
          ]
        }
      ]
    }
  },
  "iss": "did:example:issuer",
  "nbf": 1651433004,
  "jti": "https://issuer-website.com/awards/abc123",
  "sub": "did:example:learner"
}
--------------- JWT ---------------
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImp3ayI6eyJlIjoiQVFBQiIsImt0eSI6IlJTQSIsIm4i
OiIzSE1Jb1lIUFBjVFFJOTJJdmtNaUhtby1JTjBNV1JBYnkySjRleXV2LW1HMVpYS3hwbERsUnhXcTVh
aXJtdlBsZzZxLVZGb3ZUaFR3UlJDUGZNbjNkSnNQaE5OTDVqM3BDRFkwZ0hTdWFldUl5WW91cm81NjNH
OF9jT0hicGFlcnNHallwdWpDdjNEQUUyX1FjQ1VqdjZCUFlKaGEtRVVOd2hWeHhNMy15TXplWm9EUDZM
UklMZ1Vhemlsa0hTMzdibGdpcmdBM1dIbzdjbURRZThzVmFQLXZma0ZKQ1ZHN3lEeFB3UjRUZkdBUjBV
V3hPYnNDYTczbVNvUWw3MkpHWi1hRk9tdVF5TmNIOURVS0dwWEtDdDFUVzU0ajllR0szdUJGOGtHMDh2
VkxuRGczXzdLdXB3b2k5UVQzZkdCWjJDS0NtcXVqalV0QUJabV9teE5CalEifX0.eyJ2YyI6eyJAY29u
dGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vaW1z
Z2xvYmFsLmdpdGh1Yi5pby9vcGVuYmFkZ2VzLXNwZWNpZmljYXRpb24vY29udGV4dC5qc29uIl0sInR5
cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiLCJPcGVuQmFkZ2VDcmVkZW50aWFsIl0sImlkIjoiaHR0
cHM6Ly9pc3N1ZXItd2Vic2l0ZS5jb20vYXdhcmRzL2FiYzEyMyIsImlzc3VlciI6eyJpZCI6ImRpZDpl
eGFtcGxlOmlzc3VlciIsInR5cGUiOlsiUHJvZmlsZSJdLCJuYW1lIjoiQW4gRXhhbXBsZSBJc3N1ZXIi
LCJpbWFnZSI6eyJpZCI6Imh0dHBzOi8vZXhhbXBsZS5vcmcvbG9nby5wbmciLCJ0eXBlIjoiSW1hZ2Ui
fSwidXJsIjoiaHR0cHM6Ly9leGFtcGxlLm9yZyIsImVtYWlsIjoiY29udGFjdEBleGFtcGxlLm9yZyJ9
LCJpc3N1YW5jZURhdGUiOiIyMDIyLTA1LTAxVDE5OjIzOjI0WiIsIm5hbWUiOiJDaXRlIHN0cm9uZyBh
bmQgdGhvcm91Z2ggdGV4dHVhbCBldmlkZW5jZSB0byBzdXBwb3J0IGFuYWx5c2lzIG9mIHdoYXQgdGhl
IHRleHQgc2F5cyBleHBsaWNpdGx5IGFzIHdlbGwgYXMgaW5mZXJlbmNlcyBkcmF3biBmcm9tIHRoZSB0
ZXh0LCBpbmNsdWRpbmcgZGV0ZXJtaW5pbmcgd2hlcmUgdGhlIHRleHQgbGVhdmVzIG1hdHRlcnMgdW5j
ZXJ0YWluIiwiY3JlZGVudGlhbFN1YmplY3QiOnsiaWQiOiJkaWQ6ZXhhbXBsZTpsZWFybmVyIiwidHlw
ZSI6WyJBY2hpZXZlbWVudFN1YmplY3QiXSwicmVzdWx0IjpbeyJ0eXBlIjpbIlJlc3VsdCJdLCJhbGln
bm1lbnQiOlt7InR5cGUiOlsiQWxpZ25tZW50Il0sInRhcmdldENvZGUiOiI3NGY1YmI3ZC1kN2NjLTEx
ZTgtODI0Zi0wMjQyYWMxNjAwMDIiLCJ0YXJnZXRGcmFtZXdvcmsiOiJBbGFiYW1hIENvdXJzZSBvZiBT
dHVkeTogRW5nbGlzaCBMYW5ndWFnZSBBcnRzIiwidGFyZ2V0TmFtZSI6IkNpdGUgc3Ryb25nIGFuZCB0
aG9yb3VnaCB0ZXh0dWFsIGV2aWRlbmNlIHRvIHN1cHBvcnQgYW5hbHlzaXMgb2Ygd2hhdCB0aGUgdGV4
dCBzYXlzIGV4cGxpY2l0bHkgYXMgd2VsbCBhcyBpbmZlcmVuY2VzIGRyYXduIGZyb20gdGhlIHRleHQs
IGluY2x1ZGluZyBkZXRlcm1pbmluZyB3aGVyZSB0aGUgdGV4dCBsZWF2ZXMgbWF0dGVycyB1bmNlcnRh
aW4iLCJ0YXJnZXRUeXBlIjoiQ0ZJdGVtIiwidGFyZ2V0VXJsIjoiaHR0cHM6Ly9jYXNlcmVnaXN0cnku
aW1zZ2xvYmFsLm9yZy91cmkvNzRmNWJiN2QtZDdjYy0xMWU4LTgyNGYtMDI0MmFjMTYwMDAyIn1dfV19
fSwiaXNzIjoiZGlkOmV4YW1wbGU6aXNzdWVyIiwibmJmIjoxNjUxNDMzMDA0LCJqdGkiOiJodHRwczov
L2lzc3Vlci13ZWJzaXRlLmNvbS9hd2FyZHMvYWJjMTIzIiwic3ViIjoiZGlkOmV4YW1wbGU6bGVhcm5l
ciJ9.EnwNEFDXlXAVL5sLt9wxJZI7cTrRYgcLKI72hQViZySFBOV41guDl9FjK_VYslVpuPG5BBDeTOq
euyJkLKyUjnRyrpsyvzjLLkYGAO70nLwrU6b-GQBYfy9dgb8va_uylt5uxgnZchIAEpAmYaRvBoVPkqJ
4tgnmR9PjJsvF7AIneqFS9YCl_RTZu3wMtvSxrK_aCh2KN8DZltq1LYG97hueQUT-E8ysJ0h-8uoG7jP
A4LD9tc33n-3gdqK0O9zx-iknm8qxiSD1dGsmIyoHRfaeTV27PhCXEaIeIDyaQyNnTthm-RMbWM5LL1P
DA9mOh9y_rl_yPqH50yrnOT1OcA

D.7 Skill Assertion (Credential Engine)

Note
A Skill Assertion credential should only have one Result and one Alignment.
Example 41: Skill Assertion (Credential Registry)
{
  "@context": [
    "https://www.w3.org/2018/credentials/v1",
    "https://imsglobal.github.io/openbadges-specification/context.json"
  ],
  "type": ["VerifiableCredential", "OpenBadgeCredential"],
  "id": "https://issuer-website.com/awards/abc123",
  "issuer": {
    "id": "did:example:issuer",
    "type": ["Profile"],
    "name": "An Example Issuer",
    "image": {
      "id": "https://example.org/logo.png",
      "type": "Image"
    },
    "url": "https://example.org",
    "email": "contact@example.org"
  },
  "issuanceDate": "2022-05-01T19:23:24Z",
  "name": "Solve and graph linear equations and inequalities",
  "credentialSubject": {
    "id": "did:example:learner",
    "type": ["AchievementSubject"],
    "result": [{
      "type": ["Result"],
      "alignment": [{
        "type": ["Alignment"],
        "targetCode": "ce-6369c51f-4d86-4592-a761-8b32ae70a045",
        "targetFramework": "Ivy Tech Community College of Indiana, MATH 135, FINITE MATH",
        "targetName": "Solve and graph linear equations and inequalities",
        "targetType": "ceasn:Competency",
        "targetUrl": "https://credentialfinder.org/competency/ce-6369c51f-4d86-4592-a761-8b32ae70a045"
      }]
    }]
  }
}
{
  "@context": [
    "https://www.w3.org/2018/credentials/v1",
    "https://imsglobal.github.io/openbadges-specification/context.json",
    "https://w3id.org/security/suites/ed25519-2020/v1"
  ],
  "type": [
    "VerifiableCredential",
    "OpenBadgeCredential"
  ],
  "id": "https://issuer-website.com/awards/abc123",
  "issuer": {
    "id": "did:example:issuer",
    "type": [
      "Profile"
    ],
    "name": "An Example Issuer",
    "image": {
      "id": "https://example.org/logo.png",
      "type": "Image"
    },
    "url": "https://example.org",
    "email": "contact@example.org"
  },
  "issuanceDate": "2022-05-01T19:23:24Z",
  "name": "Solve and graph linear equations and inequalities",
  "credentialSubject": {
    "id": "did:example:learner",
    "type": [
      "AchievementSubject"
    ],
    "result": [
      {
        "type": [
          "Result"
        ],
        "alignment": [
          {
            "type": [
              "Alignment"
            ],
            "targetCode": "ce-6369c51f-4d86-4592-a761-8b32ae70a045",
            "targetFramework": "Ivy Tech Community College of Indiana, MATH 135, FINITE MATH",
            "targetName": "Solve and graph linear equations and inequalities",
            "targetType": "ceasn:Competency",
            "targetUrl": "https://credentialfinder.org/competency/ce-6369c51f-4d86-4592-a761-8b32ae70a045"
          }
        ]
      }
    ]
  },
  "proof": [
    {
      "type": "Ed25519Signature2020",
      "created": "2022-06-28T16:28:36Z",
      "verificationMethod": "did:key:z6MkkUD3J14nkYzn46QeuaVSnp7dF85QJKwKvJvfsjx79aXj",
      "proofPurpose": "assertionMethod",
      "proofValue": "z57rhWHv3q8VWDGEwBJfnn7i74JYQUdNKdatjHZvrGPirr6zK8rS6v4adJyXfA9YhaX1z4Ujo6JD1L4C7pCCxt6tx"
    }
  ]
}
---------------- JWT header ---------------
{
  "alg": "RS256",
  "typ": "JWT",
  "jwk": {
    "e": "AQAB",
    "kty": "RSA",
    "n": "3HMIoYHPPcTQI92IvkMiHmo-IN0MWRAby2J4eyuv-mG1ZXKxplDlRxWq5airmvPlg6q-VF
ovThTwRRCPfMn3dJsPhNNL5j3pCDY0gHSuaeuIyYouro563G8_cOHbpaersGjYpujCv3DAE2_QcCUjv6
BPYJha-EUNwhVxxM3-yMzeZoDP6LRILgUazilkHS37blgirgA3WHo7cmDQe8sVaP-vfkFJCVG7yDxPwR
4TfGAR0UWxObsCa73mSoQl72JGZ-aFOmuQyNcH9DUKGpXKCt1TW54j9eGK3uBF8kG08vVLnDg3_7Kupw
oi9QT3fGBZ2CKCmqujjUtABZm_mxNBjQ"
  }
}
--------------- JWT payload ---------------
// NOTE: The example below uses a valid VC-JWT serialization
//       that duplicates the iss, nbf, jti, and sub fields in the
//       Verifiable Credential (vc) field.
{
  "vc": {
    "@context": [
      "https://www.w3.org/2018/credentials/v1",
      "https://imsglobal.github.io/openbadges-specification/context.json"
    ],
    "type": [
      "VerifiableCredential",
      "OpenBadgeCredential"
    ],
    "id": "https://issuer-website.com/awards/abc123",
    "issuer": {
      "id": "did:example:issuer",
      "type": [
        "Profile"
      ],
      "name": "An Example Issuer",
      "image": {
        "id": "https://example.org/logo.png",
        "type": "Image"
      },
      "url": "https://example.org",
      "email": "contact@example.org"
    },
    "issuanceDate": "2022-05-01T19:23:24Z",
    "name": "Solve and graph linear equations and inequalities",
    "credentialSubject": {
      "id": "did:example:learner",
      "type": [
        "AchievementSubject"
      ],
      "result": [
        {
          "type": [
            "Result"
          ],
          "alignment": [
            {
              "type": [
                "Alignment"
              ],
              "targetCode": "ce-6369c51f-4d86-4592-a761-8b32ae70a045",
              "targetFramework": "Ivy Tech Community College of Indiana, MATH 13
5, FINITE MATH",
              "targetName": "Solve and graph linear equations and inequalities",
              "targetType": "ceasn:Competency",
              "targetUrl": "https://credentialfinder.org/competency/ce-6369c51f-
4d86-4592-a761-8b32ae70a045"
            }
          ]
        }
      ]
    }
  },
  "iss": "did:example:issuer",
  "nbf": 1651433004,
  "jti": "https://issuer-website.com/awards/abc123",
  "sub": "did:example:learner"
}
--------------- JWT ---------------
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImp3ayI6eyJlIjoiQVFBQiIsImt0eSI6IlJTQSIsIm4i
OiIzSE1Jb1lIUFBjVFFJOTJJdmtNaUhtby1JTjBNV1JBYnkySjRleXV2LW1HMVpYS3hwbERsUnhXcTVh
aXJtdlBsZzZxLVZGb3ZUaFR3UlJDUGZNbjNkSnNQaE5OTDVqM3BDRFkwZ0hTdWFldUl5WW91cm81NjNH
OF9jT0hicGFlcnNHallwdWpDdjNEQUUyX1FjQ1VqdjZCUFlKaGEtRVVOd2hWeHhNMy15TXplWm9EUDZM
UklMZ1Vhemlsa0hTMzdibGdpcmdBM1dIbzdjbURRZThzVmFQLXZma0ZKQ1ZHN3lEeFB3UjRUZkdBUjBV
V3hPYnNDYTczbVNvUWw3MkpHWi1hRk9tdVF5TmNIOURVS0dwWEtDdDFUVzU0ajllR0szdUJGOGtHMDh2
VkxuRGczXzdLdXB3b2k5UVQzZkdCWjJDS0NtcXVqalV0QUJabV9teE5CalEifX0.eyJ2YyI6eyJAY29u
dGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vaW1z
Z2xvYmFsLmdpdGh1Yi5pby9vcGVuYmFkZ2VzLXNwZWNpZmljYXRpb24vY29udGV4dC5qc29uIl0sInR5
cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiLCJPcGVuQmFkZ2VDcmVkZW50aWFsIl0sImlkIjoiaHR0
cHM6Ly9pc3N1ZXItd2Vic2l0ZS5jb20vYXdhcmRzL2FiYzEyMyIsImlzc3VlciI6eyJpZCI6ImRpZDpl
eGFtcGxlOmlzc3VlciIsInR5cGUiOlsiUHJvZmlsZSJdLCJuYW1lIjoiQW4gRXhhbXBsZSBJc3N1ZXIi
LCJpbWFnZSI6eyJpZCI6Imh0dHBzOi8vZXhhbXBsZS5vcmcvbG9nby5wbmciLCJ0eXBlIjoiSW1hZ2Ui
fSwidXJsIjoiaHR0cHM6Ly9leGFtcGxlLm9yZyIsImVtYWlsIjoiY29udGFjdEBleGFtcGxlLm9yZyJ9
LCJpc3N1YW5jZURhdGUiOiIyMDIyLTA1LTAxVDE5OjIzOjI0WiIsIm5hbWUiOiJTb2x2ZSBhbmQgZ3Jh
cGggbGluZWFyIGVxdWF0aW9ucyBhbmQgaW5lcXVhbGl0aWVzIiwiY3JlZGVudGlhbFN1YmplY3QiOnsi
aWQiOiJkaWQ6ZXhhbXBsZTpsZWFybmVyIiwidHlwZSI6WyJBY2hpZXZlbWVudFN1YmplY3QiXSwicmVz
dWx0IjpbeyJ0eXBlIjpbIlJlc3VsdCJdLCJhbGlnbm1lbnQiOlt7InR5cGUiOlsiQWxpZ25tZW50Il0s
InRhcmdldENvZGUiOiJjZS02MzY5YzUxZi00ZDg2LTQ1OTItYTc2MS04YjMyYWU3MGEwNDUiLCJ0YXJn
ZXRGcmFtZXdvcmsiOiJJdnkgVGVjaCBDb21tdW5pdHkgQ29sbGVnZSBvZiBJbmRpYW5hLCBNQVRIIDEz
NSwgRklOSVRFIE1BVEgiLCJ0YXJnZXROYW1lIjoiU29sdmUgYW5kIGdyYXBoIGxpbmVhciBlcXVhdGlv
bnMgYW5kIGluZXF1YWxpdGllcyIsInRhcmdldFR5cGUiOiJjZWFzbjpDb21wZXRlbmN5IiwidGFyZ2V0
VXJsIjoiaHR0cHM6Ly9jcmVkZW50aWFsZmluZGVyLm9yZy9jb21wZXRlbmN5L2NlLTYzNjljNTFmLTRk
ODYtNDU5Mi1hNzYxLThiMzJhZTcwYTA0NSJ9XX1dfX0sImlzcyI6ImRpZDpleGFtcGxlOmlzc3VlciIs
Im5iZiI6MTY1MTQzMzAwNCwianRpIjoiaHR0cHM6Ly9pc3N1ZXItd2Vic2l0ZS5jb20vYXdhcmRzL2Fi
YzEyMyIsInN1YiI6ImRpZDpleGFtcGxlOmxlYXJuZXIifQ.vmPSzy-JaX6pIYOovufX2LWUAtYfOQ7xE
ifdRAAete8amwz803NOQ21SJP_ueAQOi-IVR-xtQDy3A6PpfA5W1vRQcPerVRqkT0ca-TQc7RzgVpR0-
MQ-kcV-vZD8xcaA75cGQ0DZr_CAfxq4wimhfYIQm2n2kLSczQpuOewuZH1FIO8u-xSSXn-McvTx5f31c
AGIpC8raSWxW-S71voMwK4NiUrp86mJacRVKoJMXWZACMRucdGW5n7rLXx4XskBxIbxxo0svCO0jIFjx
7wpfI2AjzhGjKIq4PYH5Y5mRwK-72CJgM_NjlfpQA0Z7nKPD22rJdc20ss0T7Cp6DOWxA

E. Schema

E.1 Context

        
{
  "@context": {
    "id": "@id",
    "type": "@type",

    "xsd": "https://www.w3.org/2001/XMLSchema#",

    "OpenBadgeCredential": {
      "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#OpenBadgeCredential"
    },
    "Achievement": {
      "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#Achievement",
      "@context": {
        "achievementType": {
          "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#achievementType",
          "@type": "xsd:string"
        },
        "alignment": {
          "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#alignment",
          "@type": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#Alignment",
          "@container": "@set"
        },
        "creator": {
          "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#Profile"
        },
        "creditsAvailable": {
          "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#creditsAvailable",
          "@type": "xsd:float"
        },
        "criteria": {
          "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#Criteria", 
          "@type": "@id"
        },
        "fieldOfStudy": {
          "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#fieldOfStudy", 
          "@type": "xsd:string"
        },
        "humanCode": {
          "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#humanCode", 
          "@type": "xsd:string"
        },
        "otherIdentifier": {
          "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#otherIdentifier",
          "@type": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#IdentifierEntry",
          "@container": "@set"
        },
        "related": {
          "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#related", 
          "@type": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#Related", 
          "@container": "@set"
        },
        "resultDescription": {
          "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#resultDescription",
          "@type": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#ResultDescription",
          "@container": "@set"
        },
        "specialization": {
          "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#specialization", 
          "@type": "xsd:string"
        },
        "tag": {
          "@id": "https://schema.org/keywords", 
          "@type": "xsd:string", 
          "@container": "@set"
        },
        "version": {
          "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#version", 
          "@type": "xsd:string"
        }
      }
    },
    "AchievementCredential": {
      "@id": "OpenBadgeCredential"
    },
    "AchievementSubject": {
      "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#AchievementSubject",
      "@context": {
        "achievement": {
          "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#Achievement"
        },
        "activityEndDate": {
          "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#activityEndDate",
          "@type": "xsd:date"
        },
        "activityStartDate": {
          "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#activityStartDate",
          "@type": "xsd:date"
        },
        "creditsEarned": {
          "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#creditsEarned",
          "@type": "xsd:float"
        },
        "identifier": {
          "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#identifier",
          "@type": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#IdentityObject",
          "@container": "@set"
        },
        "licenseNumber": {
          "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#licenseNumber",
          "@type": "xsd:string"
        },
        "result": {
          "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#result",
          "@type": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#Result",
          "@container": "@set"
        },
        "role": {
          "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#role",
          "@type": "xsd:string"
        },
        "source": {
          "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#source",
          "@type": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#Profile"
        },
        "term": {
          "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#term",
          "@type": "xsd:string"
        }
      }
    },
    "Address": {
      "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#Address",
      "@context": {
        "addressCountry": {
          "@id": "https://schema.org/addressCountry", 
          "@type": "xsd:string"
        },
        "addressCountryCode": {
          "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#CountryCode", 
          "@type": "xsd:string"
        },
        "addressLocality": {
          "@id": "https://schema.org/addresLocality", 
          "@type": "xsd:string"
        },
        "addressRegion": {
          "@id": "https://schema.org/addressRegion", 
          "@type": "xsd:string"
        },
        "geo": {
          "@id" : "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#GeoCoordinates"
        },
        "postOfficeBoxNumber": {
          "@id": "https://schema.org/postOfficeBoxNumber", 
          "@type": "xsd:string"
        },
        "postalCode": {
          "@id": "https://schema.org/postalCode", 
          "@type": "xsd:string"
        },
        "streetAddress": {
          "@id": "https://schema.org/streetAddress", 
          "@type": "xsd:string"
        }
      }
    },
    "Alignment": {
      "@id": "https://schema.org/Alignment",
      "@context": {
        "targetCode": {
          "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#targetCode", 
          "@type": "xsd:string"
        },
        "targetDescription": {
          "@id": "https://schema.org/targetDescription", 
          "@type": "xsd:string"
        },
        "targetFramework": {
          "@id": "https://schema.org/targetFramework", 
          "@type": "xsd:string"
        },
        "targetName": {
          "@id": "https://schema.org/targetName", 
          "@type": "xsd:string"
        }, 
        "targetType": {
          "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#targetType",
          "@type": "xsd:string"
        },     
        "targetUrl": {
          "@id": "https://schema.org/targetUrl",
          "@type": "xsd:anyURI"
        }
      }
    },
    "Criteria": {
      "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#Criteria"
    },
    "EndorsementCredential": {
      "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#EndorsementCredential"
    },
    "EndorsementSubject": {
      "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#EndorsementSubject",
      "@context": {
        "endorsementComment": {
          "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#endorsementComment", 
          "@type": "xsd:string"
        }
      }
    },
    "Evidence": {
      "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#Evidence",
      "@context": {
        "audience": {
          "@id": "https://schema.org/audience", 
          "@type": "xsd:string"
        },
        "genre": {
          "@id": "https://schema.org/genre",
          "@type": "xsd:string"
        }
      }
    },
    "GeoCoordinates": {
      "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#GeoCoordinates",
      "@context": {
        "latitude": {
          "@id": "https://schema.org/latitude", 
          "@type": "xsd:string"
        },
        "longitude": {
          "@id": "https://schema.org/longitude", 
          "@type": "xsd:string"
        }
      }
    },
    "IdentifierEntry": {
      "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#IdentifierEntry",
      "@context": {
        "identifier": {
          "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#identifier",
          "@type": "xsd:string"
        },
        "identifierType": {
          "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#identifierType",
          "@type": "xsd:string"
        }
      }
    },
    "IdentityObject": {
      "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#IdentityObject",
      "@context": {
        "hashed": {
          "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#hashed", 
          "@type": "xsd:boolean"
        },
        "identityHash": {
          "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#identityHash", 
          "@type": "xsd:string"
        },
        "identityType": {
          "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#identityType", 
          "@type": "xsd:string"
        },
        "salt":  {
          "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#salt", 
          "@type": "xsd:string"
        }
      }
    },
    "Image": {
      "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#Image",
      "@context": {
        "caption": {
          "@id": "https://schema.org/caption",
          "@type": "xsd:string"
        }
      }
    },
    "Profile": {
      "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#Profile",
      "@context": {
        "additionalName": {
          "@id": "https://schema.org/additionalName",
          "@type": "xsd:string"
        },
        "address": {
          "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#Address"
        },
        "dateOfBirth": {
          "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#dateOfBirth",
          "@type": "xsd:date"
        },
        "email": {
          "@id": "https://schema.org/email", 
          "@type": "xsd:string"
        },
        "familyName": {
          "@id": "https://schema.org/familyName",
          "@type": "xsd:string"
        },
        "familyNamePrefix": {
          "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#familyNamePrefix",
          "@type": "xsd:string"
        },
        "givenName": {
          "@id": "https://schema.org/givenName",
          "@type": "xsd:string"
        },
        "honorificPrefix": {
          "@id": "https://schema.org/honorificPrefix",
          "@type": "xsd:string"
        },
        "honorificSuffix": {
          "@id": "https://schema.org/honorificSuffix",
          "@type": "xsd:string"
        },
        "otherIdentifier": {
          "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#otherIdentifier",
          "@type": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#IdentifierEntry",
          "@container": "@set"
        },
        "parentOrg": {
          "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#parentOrg",
          "@type": "xsd:string"
        },
        "patronymicName": {
          "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#patronymicName",
          "@type": "xsd:string"
        },
        "phone": {
          "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#PhoneNumber", 
          "@type": "xsd:string"
        },
        "official": {
          "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#official",
          "@type": "xsd:string"
        }
      }
    },
    "Related": {
      "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#Related",
      "@context": {
        "version": {
          "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#version",
          "@type": "xsd:string"
        }
      }
    },
    "Result": {
      "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#Result",
      "@context": {
        "achievedLevel": {
          "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#achievedLevel", 
          "@type": "xsd:anyURI"
        },
        "resultDescription": {
          "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#resultDescription",
          "@type": "xsd:anyURI"
        },
        "status": {
          "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#status", 
          "@type": "xsd:string"
        },
        "value": {
          "@id": "https://schema.org/value", 
          "@type": "xsd:string"
        }
      }
    },
    "ResultDescription": {
      "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#ResultDescription",
      "@context": {
        "allowedValue": {
          "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#allowedValue", 
          "@type": "xsd:string",
          "@container": "@set"
        },
        "requiredLevel": {
          "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#requiredLevel", 
          "@type": "xsd:anyURI"
        },
        "requiredValue": {
          "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#requiredValue", 
          "@type": "xsd:string"
        },
        "resultType": {
          "@id":"https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#resultType",  
          "@type": "xsd:string"
        },
        "rubricCriterionLevel": {
          "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#rubricCriterionLevel",
          "@type": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#RubricCriterionLevel",
          "@container": "@set"
        },
        "valueMax": {
          "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#valueMax", 
          "@type": "xsd:string"
        },
        "valueMin": {
          "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#valueMin", 
          "@type": "xsd:string"
        }              
      }
    },
    "RubricCriterionLevel": {
      "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#RubricCriterionLevel",
      "@context": {
        "level": {
          "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#level", 
          "@type": "xsd:string"
        },
        "points": {
          "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#points", 
          "@type": "xsd:string"
        }
      }
    },
    "alignment": {
      "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#alignment", 
      "@type": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#Alignment",
      "@container": "@set"
    },    
    "description": {
      "@id": "https://schema.org/description", 
      "@type": "xsd:string"
    },
    "endorsement": {
      "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#endorsement", 
      "@type": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#EndorsementCredential", 
      "@container": "@set"
    },
    "image": {
      "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#image", 
      "@type": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#Image"
    },
    "name": {
      "@id": "https://schema.org/name", 
      "@type": "xsd:string"
    },
    "narrative": {
      "@id": "https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#narrative", 
      "@type": "xsd:string"
    },
    "url": {
      "@id": "https://schema.org/url", 
      "@type": "xsd:anyURI"
    }
  }
}

E.2 JSON Schema

E.2.1 Open Badges JSON Schema

E.2.1.1 Achievement

A collection of information about the accomplishment recognized by the Assertion. Many assertions may be created corresponding to one Achievement.

{
  "$schema": "https://json-schema.org/draft/2019-09/schema#",
  "$id": "https://example.org/404/ob/achievementv3p0.schema.json",
  "$comment": "This is a dynamically generated schema made available only for testing purposes; it does not have normative status and must not be persisted or served to the public.",
  "title": "JSON Schema for the Achievement class.",
  "description": "A collection of information about the accomplishment recognized by the Assertion. Many assertions may be created corresponding to one Achievement.",
  "type": "object",
  "properties": {
    "id": {
      "description": "Unique URI for the Achievement.",
      "$comment": "Origin: URI (DerivedType); A `NormalizedString` that respresents a Uniform Resource Identifier (URI).",
      "type": "string"
    },
    "type": {
      "description": "No description supplied.",
      "$comment": "Origin: IRI (DerivedType); A `NormalizedString` that represents an Internationalized Resource Identifier (IRI), which extends the ASCII characters subset of the Uniform Resource Identifier (URI).",
      "type": "array",
      "minItems": 1,
      "items": {
        "type": "string"
      }
    },
    "alignment": {
      "description": "An object describing which objectives or educational standards this achievement aligns to, if any.",
      "$comment": "Origin: Alignment (Unordered); Describes an alignment between an achievement and a node in an educational framework.",
      "type": "array",
      "items": {
        "$ref": "#/$defs/Alignment"
      }
    },
    "achievementType": {
      "description": "The type of achievement. This is an extensible vocabulary.",
      "$comment": "Origin: AchievementType (EnumExt); The type of achievement, for example 'Award' or 'Certification'. This is an extensible enumerated vocabulary. Extending the vocabulary makes use of a naming convention.",
      "anyOf": [
        {
          "type": "string",
          "enum": [
            "Achievement",
            "ApprenticeshipCertificate",
            "Assessment",
            "Assignment",
            "AssociateDegree",
            "Award",
            "Badge",
            "BachelorDegree",
            "Certificate",
            "CertificateOfCompletion",
            "Certification",
            "CommunityService",
            "Competency",
            "Course",
            "CoCurricular",
            "Degree",
            "Diploma",
            "DoctoralDegree",
            "Fieldwork",
            "GeneralEducationDevelopment",
            "JourneymanCertificate",
            "LearningProgram",
            "License",
            "Membership",
            "ProfessionalDoctorate",
            "QualityAssuranceCredential",
            "MasterCertificate",
            "MasterDegree",
            "MicroCredential",
            "ResearchDoctorate",
            "SecondarySchoolDiploma"
          ]
        },
        {
          "type": "string",
          "pattern": "(ext:)[a-z|A-Z|0-9|.|-|_]+"
        }
      ]
    },
    "creator": {
      "description": "The person or organization that created the achievement definition.",
      "$comment": "Origin: Profile (Unordered); A Profile is a collection of information that describes the entity or organization using Open Badges. Issuers must be represented as Profiles, and recipients, endorsers, or other entities may also be represented using this vocabulary. Each Profile that represents an Issuer may be referenced in many BadgeClasses that it has defined. Anyone can create and host an Issuer file to start issuing Open Badges. Issuers may also serve as recipients of Open Badges, often identified within an Assertion by specific properties, like their url or contact email address.",
      "$ref": "#/$defs/Profile"
    },
    "creditsAvailable": {
      "description": "Credit hours associated with this entity, or credit hours possible. For example 3.0.",
      "$comment": "Origin: Float (PrimitiveType)",
      "type": "number"
    },
    "criteria": {
      "description": "Criteria describing how to earn the achievement.",
      "$comment": "Origin: Criteria (Unordered); Descriptive metadata about the achievements necessary to be recognized with an assertion of a particular achievement. This data is added to the Achievement class so that it may be rendered when the achievement assertion is displayed, instead of simply a link to human-readable criteria external to the achievement. Embedding criteria allows either enhancement of an external criteria page or increased portability and ease of use by allowing issuers to skip hosting the formerly-required external criteria page altogether. Criteria is used to allow would-be recipients to learn what is required of them to be recognized with an assertion of a particular achievement. It is also used after the assertion is awarded to a recipient to let those inspecting earned achievements know the general requirements that the recipients met in order to earn it.",
      "$ref": "#/$defs/Criteria"
    },
    "description": {
      "description": "A short description of the achievement.",
      "$comment": "Origin: String (PrimitiveType); Character strings.",
      "type": "string"
    },
    "endorsement": {
      "description": "Allows endorsers to make specific claims about the Achievement. These endorsements are signed with a Data Integrity proof format.",
      "$comment": "Origin: EndorsementCredential (Unordered); A verifiable credential that asserts a claim about an entity.",
      "type": "array",
      "items": {
        "$ref": "#/$defs/EndorsementCredential"
      }
    },
    "endorsementJwt": {
      "description": "Allows endorsers to make specific claims about the Achievement. These endorsements are signed with the VC-JWT proof format.",
      "$comment": "Origin: CompactJws (DerivedType); A `String` in Compact JWS format [[RFC7515]].",
      "type": "array",
      "items": {
        "type": "string",
        "pattern": "^[a-zA-Z0-9_-]+\\.[a-zA-Z0-9_-]*\\.[a-zA-Z0-9_-]+$"
      }
    },
    "fieldOfStudy": {
      "description": "Category, subject, area of study, discipline, or general branch of knowledge. Examples include Business, Education, Psychology, and Technology.",
      "$comment": "Origin: String (PrimitiveType); Character strings.",
      "type": "string"
    },
    "humanCode": {
      "description": "The code, generally human readable, associated with an achievement.",
      "$comment": "Origin: String (PrimitiveType); Character strings.",
      "type": "string"
    },
    "image": {
      "description": "An image representing the achievement.",
      "$comment": "Origin: Image (Unordered); Metadata about images that represent assertions, achieve or profiles. These properties can typically be represented as just the id string of the image, but using a fleshed-out document allows for including captions and other applicable metadata.",
      "$ref": "#/$defs/Image"
    },
    "@language": {
      "description": "The language of the achievement.",
      "$comment": "Origin: LanguageCode (DerivedType); A language code [[BCP47]].",
      "type": "string",
      "pattern": "^[a-z]{2,4}(-[A-Z][a-z]{3})?(-([A-Z]{2}|[0-9]{3}))?$"
    },
    "name": {
      "description": "The name of the achievement.",
      "$comment": "Origin: String (PrimitiveType); Character strings.",
      "type": "string"
    },
    "otherIdentifier": {
      "description": "A list of identifiers for the described entity.",
      "$comment": "Origin: IdentifierEntry (Unordered)",
      "type": "array",
      "items": {
        "$ref": "#/$defs/IdentifierEntry"
      }
    },
    "related": {
      "description": "The related property identifies another Achievement that should be considered the same for most purposes. It is primarily intended to identify alternate language editions or previous versions of Achievements.",
      "$comment": "Origin: Related (Unordered); Identifies a related achievement.",
      "type": "array",
      "items": {
        "$ref": "#/$defs/Related"
      }
    },
    "resultDescription": {
      "description": "The set of result descriptions that may be asserted as results with this achievement.",
      "$comment": "Origin: ResultDescription (Unordered); Describes a possible achievement result.",
      "type": "array",
      "items": {
        "$ref": "#/$defs/ResultDescription"
      }
    },
    "specialization": {
      "description": "Name given to the focus, concentration, or specific area of study defined in the achievement. Examples include 'Entrepreneurship', 'Technical Communication', and 'Finance'.",
      "$comment": "Origin: String (PrimitiveType); Character strings.",
      "type": "string"
    },
    "tag": {
      "description": "Tags that describes the type of achievement.",
      "$comment": "Origin: String (PrimitiveType); Character strings.",
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "version": {
      "description": "The version property allows issuers to set a version string for an Achievement. This is particularly useful when replacing a previous version with an update.",
      "$comment": "Origin: String (PrimitiveType); Character strings.",
      "type": "string"
    }
  },
  "required": [
    "id",
    "type",
    "criteria",
    "description",
    "name"
  ],
  "additionalProperties": true,
  "$defs": {
    "Alignment": {
      "description": "Describes an alignment between an achievement and a node in an educational framework.",
      "type": "object",
      "properties": {
        "type": {
          "description": "The value of the type property MUST be an unordered set. One of the items MUST be the IRI 'Alignment'.",
          "$comment": "Origin: IRI (DerivedType); A `NormalizedString` that represents an Internationalized Resource Identifier (IRI), which extends the ASCII characters subset of the Uniform Resource Identifier (URI).",
          "type": "array",
          "minItems": 1,
          "items": {
            "type": "string"
          }
        },
        "targetCode": {
          "description": "If applicable, a locally unique string identifier that identifies the alignment target within its framework and/or targetUrl.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "targetDescription": {
          "description": "Short description of the alignment target.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "targetName": {
          "description": "Name of the alignment.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "targetFramework": {
          "description": "Name of the framework the alignment target.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "targetType": {
          "description": "The type of the alignment target node.",
          "$comment": "Origin: AlignmentTargetType (EnumExt); The type of the alignment target node in the target framework.",
          "anyOf": [
            {
              "type": "string",
              "enum": [
                "ceasn:Competency",
                "ceterms:Credential",
                "CFItem",
                "CFRubric",
                "CFRubricCriterion",
                "CFRubricCriterionLevel",
                "CTDL"
              ]
            },
            {
              "type": "string",
              "pattern": "(ext:)[a-z|A-Z|0-9|.|-|_]+"
            }
          ]
        },
        "targetUrl": {
          "description": "URL linking to the official description of the alignment target, for example an individual standard within an educational framework.",
          "$comment": "Origin: URL (DerivedType); A `URI` that represents a Uniform Resource Locator (URL).",
          "type": "string"
        }
      },
      "required": [
        "type",
        "targetName",
        "targetUrl"
      ],
      "additionalProperties": true
    },
    "Criteria": {
      "description": "Descriptive metadata about the achievements necessary to be recognized with an assertion of a particular achievement. This data is added to the Achievement class so that it may be rendered when the achievement assertion is displayed, instead of simply a link to human-readable criteria external to the achievement. Embedding criteria allows either enhancement of an external criteria page or increased portability and ease of use by allowing issuers to skip hosting the formerly-required external criteria page altogether. Criteria is used to allow would-be recipients to learn what is required of them to be recognized with an assertion of a particular achievement. It is also used after the assertion is awarded to a recipient to let those inspecting earned achievements know the general requirements that the recipients met in order to earn it.",
      "type": "object",
      "properties": {
        "id": {
          "description": "The URI of a webpage that describes in a human-readable format the criteria for the achievement.",
          "$comment": "Origin: URI (DerivedType); A `NormalizedString` that respresents a Uniform Resource Identifier (URI).",
          "type": "string"
        },
        "narrative": {
          "description": "A narrative of what is needed to earn the achievement. Markdown is allowed.",
          "$comment": "Origin: Markdown (DerivedType); A `String` that may contain Markdown.",
          "type": "string"
        }
      },
      "required": [],
      "additionalProperties": true
    },
    "EndorsementCredential": {
      "description": "A verifiable credential that asserts a claim about an entity.",
      "type": "object",
      "properties": {
        "@context": {
          "description": "The value of the `@context` property MUST be an ordered set where the first item is a URI with the value 'https://www.w3.org/2018/credentials/v1', and the second item is a URI with the value 'https://purl.imsglobal.org/spec/ob/v3p0/context/ob_v3p0.jsonld'.",
          "$comment": "Origin: URI (DerivedType); A `NormalizedString` that respresents a Uniform Resource Identifier (URI).",
          "type": "array",
          "minItems": 1,
          "items": {
            "type": "string"
          }
        },
        "type": {
          "description": "The value of the type property MUST be an unordered set. One of the items MUST be the URI 'VerifiableCredential', and one of the items MUST be the URI 'EndorsementCredential'.",
          "$comment": "Origin: IRI (DerivedType); A `NormalizedString` that represents an Internationalized Resource Identifier (IRI), which extends the ASCII characters subset of the Uniform Resource Identifier (URI).",
          "type": "array",
          "minItems": 1,
          "items": {
            "type": "string"
          }
        },
        "credentialSubject": {
          "description": "The individual, entity, organization, assertion, or achievement that is endorsed and the endorsement comment.",
          "$comment": "Origin: EndorsementSubject (Unordered); A collection of information about the subject of the endorsement.",
          "$ref": "#/$defs/EndorsementSubject"
        },
        "id": {
          "description": "Unambiguous reference to the credential.",
          "$comment": "Origin: URI (DerivedType); A `NormalizedString` that respresents a Uniform Resource Identifier (URI).",
          "type": "string"
        },
        "issuer": {
          "description": "A description of the individual, entity, or organization that issued the credential.",
          "$comment": "Origin: Profile (Unordered); A Profile is a collection of information that describes the entity or organization using Open Badges. Issuers must be represented as Profiles, and recipients, endorsers, or other entities may also be represented using this vocabulary. Each Profile that represents an Issuer may be referenced in many BadgeClasses that it has defined. Anyone can create and host an Issuer file to start issuing Open Badges. Issuers may also serve as recipients of Open Badges, often identified within an Assertion by specific properties, like their url or contact email address.",
          "$ref": "#/$defs/Profile"
        },
        "issuanceDate": {
          "description": "Timestamp of when the credential was awarded.",
          "$comment": "Origin: DateTime (PrimitiveType); An [[ISO8601]] time using the syntax YYYY-MM-DDThh:mm:ss.",
          "type": "string",
          "format": "date-time"
        },
        "expirationDate": {
          "description": "If the credential has some notion of expiry, this indicates a timestamp when a credential should no longer be considered valid. After this time, the credential should be considered expired.",
          "$comment": "Origin: DateTime (PrimitiveType); An [[ISO8601]] time using the syntax YYYY-MM-DDThh:mm:ss.",
          "type": "string",
          "format": "date-time"
        },
        "proof": {
          "description": "If present, one or more embedded cryptographic proofs that can be used to detect tampering and verify the authorship of the credential.",
          "$comment": "Origin: Proof (Unordered); A JSON-LD Linked Data proof.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/Proof"
          }
        },
        "credentialSchema": {
          "description": "The value of the `credentialSchema` property MUST be one or more data schemas that provide verifiers with enough information to determine if the provided data conforms to the provided schema.",
          "$comment": "Origin: CredentialSchema (Unordered); Identify the type and location of a data schema.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/CredentialSchema"
          }
        },
        "credentialStatus": {
          "description": "The information in CredentialStatus is used to discover information about the current status of a verifiable credential, such as whether it is suspended or revoked.",
          "$comment": "Origin: CredentialStatus (Unordered); The information in CredentialStatus is used to discover information about the current status of a verifiable credential, such as whether it is suspended or revoked.",
          "$ref": "#/$defs/CredentialStatus"
        },
        "refreshService": {
          "description": "The information in RefreshService is used to refresh the verifiable credential.",
          "$comment": "Origin: RefreshService (Unordered); The information in RefreshService is used to refresh the verifiable credential.",
          "$ref": "#/$defs/RefreshService"
        }
      },
      "required": [
        "@context",
        "type",
        "credentialSubject",
        "issuer",
        "issuanceDate"
      ],
      "additionalProperties": false
    },
    "CredentialStatus": {
      "description": "The information in CredentialStatus is used to discover information about the current status of a verifiable credential, such as whether it is suspended or revoked.",
      "type": "object",
      "properties": {
        "id": {
          "description": "The value MUST be the URL of the issuer's credential status method.",
          "$comment": "Origin: URI (DerivedType); A `NormalizedString` that respresents a Uniform Resource Identifier (URI).",
          "type": "string"
        },
        "type": {
          "description": "The name of the credential status method.",
          "$comment": "Origin: IRI (DerivedType); A `NormalizedString` that represents an Internationalized Resource Identifier (IRI), which extends the ASCII characters subset of the Uniform Resource Identifier (URI).",
          "type": "string"
        }
      },
      "required": [
        "id",
        "type"
      ],
      "additionalProperties": false
    },
    "IdentifierEntry": {
      "description": "No description supplied.",
      "type": "object",
      "properties": {
        "type": {
          "description": "The value of the type property MUST be an unordered set. One of the items MUST be the IRI 'IdentifierEntry'.",
          "$comment": "Origin: IRI (DerivedType); A `NormalizedString` that represents an Internationalized Resource Identifier (IRI), which extends the ASCII characters subset of the Uniform Resource Identifier (URI).",
          "type": "string"
        },
        "identifier": {
          "description": "An identifier.",
          "$comment": "Origin: Identifier (DerivedType); A `NormalizedString` that functions as an identifier.",
          "type": "string"
        },
        "identifierType": {
          "description": "The identifier type.",
          "$comment": "Origin: IdentifierTypeEnum (EnumExt)",
          "anyOf": [
            {
              "type": "string",
              "enum": [
                "sourcedId",
                "systemId",
                "productId",
                "userName",
                "accountId",
                "emailAddress",
                "nationalIdentityNumber",
                "isbn",
                "issn",
                "lisSourcedId",
                "oneRosterSourcedId",
                "sisSourcedId",
                "ltiContextId",
                "ltiDeploymentId",
                "ltiToolId",
                "ltiPlatformId",
                "ltiUserId",
                "identifier"
              ]
            },
            {
              "type": "string",
              "pattern": "(ext:)[a-z|A-Z|0-9|.|-|_]+"
            }
          ]
        }
      },
      "required": [
        "type",
        "identifier",
        "identifierType"
      ],
      "additionalProperties": false
    },
    "Proof": {
      "description": "A JSON-LD Linked Data proof.",
      "type": "object",
      "properties": {
        "type": {
          "description": "Signature suite used to produce proof.",
          "$comment": "Origin: IRI (DerivedType); A `NormalizedString` that represents an Internationalized Resource Identifier (IRI), which extends the ASCII characters subset of the Uniform Resource Identifier (URI).",
          "type": "string"
        },
        "created": {
          "description": "Date the proof was created.",
          "$comment": "Origin: DateTime (PrimitiveType); An [[ISO8601]] time using the syntax YYYY-MM-DDThh:mm:ss.",
          "type": "string",
          "format": "date-time"
        },
        "challenge": {
          "description": "A value chosen by the verifier to mitigate authentication proof replay attacks.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "domain": {
          "description": "The domain of the proof to restrict its use to a particular target.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "nonce": {
          "description": "A value chosen by the creator of proof to randomize proof values for privacy purposes.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "proofPurpose": {
          "description": "The purpose of the proof to be used with `verificationMethod`. MUST be 'assertionMethod'.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "proofValue": {
          "description": "Value of the proof.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "verificationMethod": {
          "description": "The URL of the public key that can verify the signature.",
          "$comment": "Origin: URI (DerivedType); A `NormalizedString` that respresents a Uniform Resource Identifier (URI).",
          "type": "string"
        }
      },
      "required": [
        "type",
        "created",
        "proofPurpose",
        "proofValue",
        "verificationMethod"
      ],
      "additionalProperties": true
    },
    "RefreshService": {
      "description": "The information in RefreshService is used to refresh the verifiable credential.",
      "type": "object",
      "properties": {
        "id": {
          "description": "The value MUST be the URL of the issuer's refresh service.",
          "$comment": "Origin: URI (DerivedType); A `NormalizedString` that respresents a Uniform Resource Identifier (URI).",
          "type": "string"
        },
        "type": {
          "description": "The name of the refresh service method.",
          "$comment": "Origin: IRI (DerivedType); A `NormalizedString` that represents an Internationalized Resource Identifier (IRI), which extends the ASCII characters subset of the Uniform Resource Identifier (URI).",
          "type": "string"
        }
      },
      "required": [
        "id",
        "type"
      ],
      "additionalProperties": true
    },
    "Image": {
      "description": "Metadata about images that represent assertions, achieve or profiles. These properties can typically be represented as just the id string of the image, but using a fleshed-out document allows for including captions and other applicable metadata.",
      "type": "object",
      "properties": {
        "id": {
          "description": "The URI or Data URI of the image.",
          "$comment": "Origin: URI (DerivedType); A `NormalizedString` that respresents a Uniform Resource Identifier (URI).",
          "type": "string"
        },
        "type": {
          "description": "MUST be the IRI 'Image'.",
          "$comment": "Origin: IRI (DerivedType); A `NormalizedString` that represents an Internationalized Resource Identifier (IRI), which extends the ASCII characters subset of the Uniform Resource Identifier (URI).",
          "type": "string"
        },
        "caption": {
          "description": "The caption for the image.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        }
      },
      "required": [
        "id",
        "type"
      ],
      "additionalProperties": false
    },
    "ResultDescription": {
      "description": "Describes a possible achievement result.",
      "type": "object",
      "properties": {
        "id": {
          "description": "The unique URI for this result description. Required so a result can link to this result description.",
          "$comment": "Origin: URI (DerivedType); A `NormalizedString` that respresents a Uniform Resource Identifier (URI).",
          "type": "string"
        },
        "type": {
          "description": "The value of the type property MUST be an unordered set. One of the items MUST be the IRI 'ResultDescription'.",
          "$comment": "Origin: IRI (DerivedType); A `NormalizedString` that represents an Internationalized Resource Identifier (IRI), which extends the ASCII characters subset of the Uniform Resource Identifier (URI).",
          "type": "array",
          "minItems": 1,
          "items": {
            "type": "string"
          }
        },
        "alignment": {
          "description": "Alignments between this result description and nodes in external frameworks.",
          "$comment": "Origin: Alignment (Unordered); Describes an alignment between an achievement and a node in an educational framework.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/Alignment"
          }
        },
        "allowedValue": {
          "description": "An ordered list of allowed values. The values should be ordered from low to high as determined by the achievement creator.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "name": {
          "description": "The name of the result.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "requiredLevel": {
          "description": "The `id` of the rubric criterion level required to pass as determined by the achievement creator.",
          "$comment": "Origin: URI (DerivedType); A `NormalizedString` that respresents a Uniform Resource Identifier (URI).",
          "type": "string"
        },
        "requiredValue": {
          "description": "A value from `allowedValue` or within the range of `valueMin` to `valueMax` required to pass as determined by the achievement creator.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "resultType": {
          "description": "The type of result this description represents. This is an extensible enumerated vocabulary.",
          "$comment": "Origin: ResultType (EnumExt); The type of result. This is an extensible enumerated vocabulary. Extending the vocabulary makes use of a naming convention.",
          "anyOf": [
            {
              "type": "string",
              "enum": [
                "GradePointAverage",
                "LetterGrade",
                "Percent",
                "PerformanceLevel",
                "PredictedScore",
                "RawScore",
                "Result",
                "RubricCriterion",
                "RubricCriterionLevel",
                "RubricScore",
                "ScaledScore",
                "Status"
              ]
            },
            {
              "type": "string",
              "pattern": "(ext:)[a-z|A-Z|0-9|.|-|_]+"
            }
          ]
        },
        "rubricCriterionLevel": {
          "description": "An ordered array of rubric criterion levels that may be asserted in the linked result. The levels should be ordered from low to high as determined by the achievement creator.",
          "$comment": "Origin: RubricCriterionLevel (Unordered); Describes a rubric criterion level.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/RubricCriterionLevel"
          }
        },
        "valueMax": {
          "description": "The maximum possible `value` that may be asserted in a linked result.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "valueMin": {
          "description": "The minimum possible `value` that may be asserted in a linked result.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        }
      },
      "required": [
        "id",
        "type",
        "name",
        "resultType"
      ],
      "additionalProperties": true
    },
    "RubricCriterionLevel": {
      "description": "Describes a rubric criterion level.",
      "type": "object",
      "properties": {
        "id": {
          "description": "The unique URI for this rubric criterion level. Required so a result can link to this rubric criterion level.",
          "$comment": "Origin: URI (DerivedType); A `NormalizedString` that respresents a Uniform Resource Identifier (URI).",
          "type": "string"
        },
        "type": {
          "description": "The value of the type property MUST be an unordered set. One of the items MUST be the IRI 'RubricCriterionLevel'.",
          "$comment": "Origin: IRI (DerivedType); A `NormalizedString` that represents an Internationalized Resource Identifier (IRI), which extends the ASCII characters subset of the Uniform Resource Identifier (URI).",
          "type": "array",
          "minItems": 1,
          "items": {
            "type": "string"
          }
        },
        "alignment": {
          "description": "Alignments between this rubric criterion level and a rubric criterion levels defined in external frameworks.",
          "$comment": "Origin: Alignment (Unordered); Describes an alignment between an achievement and a node in an educational framework.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/Alignment"
          }
        },
        "description": {
          "description": "Description of the rubric criterion level.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "level": {
          "description": "The rubric performance level in terms of success.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "name": {
          "description": "The name of the rubric criterion level.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "points": {
          "description": "The points associated with this rubric criterion level.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        }
      },
      "required": [
        "id",
        "type",
        "name"
      ],
      "additionalProperties": true
    },
    "EndorsementSubject": {
      "description": "A collection of information about the subject of the endorsement.",
      "type": "object",
      "properties": {
        "id": {
          "description": "The identifier of the individual, entity, organization, assertion, or achievement that is endorsed.",
          "$comment": "Origin: URI (DerivedType); A `NormalizedString` that respresents a Uniform Resource Identifier (URI).",
          "type": "string"
        },
        "type": {
          "description": "The value of the type property MUST be an unordered set. One of the items MUST be the URI 'VerifiableCredential', and one of the items MUST be the URI 'EndorsementSubject'.",
          "$comment": "Origin: IRI (DerivedType); A `NormalizedString` that represents an Internationalized Resource Identifier (IRI), which extends the ASCII characters subset of the Uniform Resource Identifier (URI).",
          "type": "array",
          "minItems": 1,
          "items": {
            "type": "string"
          }
        },
        "endorsementComment": {
          "description": "Allows endorsers to make a simple claim in writing about the entity.",
          "$comment": "Origin: Markdown (DerivedType); A `String` that may contain Markdown.",
          "type": "string"
        }
      },
      "required": [
        "id",
        "type"
      ],
      "additionalProperties": false
    },
    "Related": {
      "description": "Identifies a related achievement.",
      "type": "object",
      "properties": {
        "id": {
          "description": "The related achievement.",
          "$comment": "Origin: URI (DerivedType); A `NormalizedString` that respresents a Uniform Resource Identifier (URI).",
          "type": "string"
        },
        "@language": {
          "description": "The language of the related achievement.",
          "$comment": "Origin: LanguageCode (DerivedType); A language code [[BCP47]].",
          "type": "string",
          "pattern": "^[a-z]{2,4}(-[A-Z][a-z]{3})?(-([A-Z]{2}|[0-9]{3}))?$"
        },
        "version": {
          "description": "The version of the related achievement.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        }
      },
      "required": [
        "id"
      ],
      "additionalProperties": false
    },
    "Profile": {
      "description": "A Profile is a collection of information that describes the entity or organization using Open Badges. Issuers must be represented as Profiles, and recipients, endorsers, or other entities may also be represented using this vocabulary. Each Profile that represents an Issuer may be referenced in many BadgeClasses that it has defined. Anyone can create and host an Issuer file to start issuing Open Badges. Issuers may also serve as recipients of Open Badges, often identified within an Assertion by specific properties, like their url or contact email address.",
      "type": "object",
      "properties": {
        "id": {
          "description": "Unique URI for the Issuer/Profile file.",
          "$comment": "Origin: URI (DerivedType); A `NormalizedString` that respresents a Uniform Resource Identifier (URI).",
          "type": "string"
        },
        "type": {
          "description": "The value of the type property MUST be an unordered set. One of the items MUST be the IRI 'Profile'.",
          "$comment": "Origin: IRI (DerivedType); A `NormalizedString` that represents an Internationalized Resource Identifier (IRI), which extends the ASCII characters subset of the Uniform Resource Identifier (URI).",
          "type": "array",
          "minItems": 1,
          "items": {
            "type": "string"
          }
        },
        "name": {
          "description": "The name of the entity or organization.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "url": {
          "description": "The homepage or social media profile of the entity, whether individual or institutional. Should be a URL/URI Accessible via HTTP.",
          "$comment": "Origin: URI (DerivedType); A `NormalizedString` that respresents a Uniform Resource Identifier (URI).",
          "type": "string"
        },
        "phone": {
          "description": "A phone number.",
          "$comment": "Origin: PhoneNumber (DerivedType); A `NormalizedString` representing a phone number.",
          "type": "string"
        },
        "description": {
          "description": "A short description of the issuer entity or organization.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "endorsement": {
          "description": "Allows endorsers to make specific claims about the individual or organization represented by this profile. These endorsements are signed with a Data Integrity proof format.",
          "$comment": "Origin: EndorsementCredential (Unordered); A verifiable credential that asserts a claim about an entity.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/EndorsementCredential"
          }
        },
        "endorsementJwt": {
          "description": "Allows endorsers to make specific claims about the individual or organization represented by this profile. These endorsements are signed with the VC-JWT proof format.",
          "$comment": "Origin: CompactJws (DerivedType); A `String` in Compact JWS format [[RFC7515]].",
          "type": "array",
          "items": {
            "type": "string",
            "pattern": "^[a-zA-Z0-9_-]+\\.[a-zA-Z0-9_-]*\\.[a-zA-Z0-9_-]+$"
          }
        },
        "image": {
          "description": "An image representing the issuer. This must be a PNG or SVG image.",
          "$comment": "Origin: Image (Unordered); Metadata about images that represent assertions, achieve or profiles. These properties can typically be represented as just the id string of the image, but using a fleshed-out document allows for including captions and other applicable metadata.",
          "$ref": "#/$defs/Image"
        },
        "email": {
          "description": "An email address.",
          "$comment": "Origin: EmailAddress (DerivedType); A `NormalizedString` representing an email address.",
          "type": "string"
        },
        "address": {
          "description": "An address for the individual or organization.",
          "$comment": "Origin: Address (Unordered)",
          "$ref": "#/$defs/Address"
        },
        "otherIdentifier": {
          "description": "A list of identifiers for the described entity.",
          "$comment": "Origin: IdentifierEntry (Unordered)",
          "type": "array",
          "items": {
            "$ref": "#/$defs/IdentifierEntry"
          }
        },
        "official": {
          "description": "If the entity is an organization, `official` is the name of an authorized official of the organization.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "parentOrg": {
          "description": "The parent organization of the entity.",
          "$comment": "Origin: Profile (Unordered); A Profile is a collection of information that describes the entity or organization using Open Badges. Issuers must be represented as Profiles, and recipients, endorsers, or other entities may also be represented using this vocabulary. Each Profile that represents an Issuer may be referenced in many BadgeClasses that it has defined. Anyone can create and host an Issuer file to start issuing Open Badges. Issuers may also serve as recipients of Open Badges, often identified within an Assertion by specific properties, like their url or contact email address.",
          "$ref": "#/$defs/Profile"
        },
        "familyName": {
          "description": "Family name. In the western world, often referred to as the 'last name' of a person.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "givenName": {
          "description": "Given name. In the western world, often referred to as the 'first name' of a person.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "additionalName": {
          "description": "Additional name. Includes what is often referred to as 'middle name' in the western world.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "patronymicName": {
          "description": "Patronymic name.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "honorificPrefix": {
          "description": "Honorific prefix(es) preceding a person's name (e.g. 'Dr', 'Mrs' or 'Mr').",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "honorificSuffix": {
          "description": "Honorific suffix(es) following a person's name (e.g. 'M.D, PhD').",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "familyNamePrefix": {
          "description": "Family name prefix. As used in some locales, this is the leading part of a family name (e.g. 'de' in the name 'de Boer').",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "dateOfBirth": {
          "description": "No description supplied.",
          "$comment": "Origin: Date (PrimitiveType); An [[ISO8601]] calendar date using the syntax YYYY-MM-DD.",
          "type": "string",
          "format": "date"
        }
      },
      "required": [
        "id",
        "type"
      ],
      "additionalProperties": true
    },
    "Address": {
      "description": "No description supplied.",
      "type": "object",
      "properties": {
        "type": {
          "description": "The value of the type property MUST be an unordered set. One of the items MUST be the IRI 'Address'.",
          "$comment": "Origin: IRI (DerivedType); A `NormalizedString` that represents an Internationalized Resource Identifier (IRI), which extends the ASCII characters subset of the Uniform Resource Identifier (URI).",
          "type": "array",
          "minItems": 1,
          "items": {
            "type": "string"
          }
        },
        "addressCountry": {
          "description": "A country.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "addressCountryCode": {
          "description": "A country code. The value must be a ISO 3166-1 alpha-2 country code [[ISO3166-1]].",
          "$comment": "Origin: CountryCode (DerivedType); A two-digit ISO 3166-1 alpha-2 country code [[ISO3166-1]].",
          "type": "string"
        },
        "addressRegion": {
          "description": "A region within the country.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "addressLocality": {
          "description": "A locality within the region.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "streetAddress": {
          "description": "A street address within the locality.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "postOfficeBoxNumber": {
          "description": "A post office box number for PO box addresses.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "postalCode": {
          "description": "A postal code.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "geo": {
          "description": "The geographic coordinates of the location.",
          "$comment": "Origin: GeoCoordinates (Unordered); The geographic coordinates of a location.",
          "$ref": "#/$defs/GeoCoordinates"
        }
      },
      "required": [
        "type"
      ],
      "additionalProperties": false
    },
    "GeoCoordinates": {
      "description": "The geographic coordinates of a location.",
      "type": "object",
      "properties": {
        "type": {
          "description": "The value of the type property MUST be an unordered set. One of the items MUST be the IRI 'GeoCoordinates'.",
          "$comment": "Origin: IRI (DerivedType); A `NormalizedString` that represents an Internationalized Resource Identifier (IRI), which extends the ASCII characters subset of the Uniform Resource Identifier (URI).",
          "type": "string"
        },
        "latitude": {
          "description": "The latitude of the location [[WGS84]].",
          "$comment": "Origin: Float (PrimitiveType)",
          "type": "number"
        },
        "longitude": {
          "description": "The longitude of the location [[WGS84]].",
          "$comment": "Origin: Float (PrimitiveType)",
          "type": "number"
        }
      },
      "required": [
        "type",
        "latitude",
        "longitude"
      ],
      "additionalProperties": false
    },
    "CredentialSchema": {
      "description": "Identify the type and location of a data schema.",
      "type": "object",
      "properties": {
        "id": {
          "description": "The value MUST be a URI identifying the schema file. One instance of `CredentialSchema` MUST have an `id` that is the URL of the JSON Schema for this credential defined by this specification.",
          "$comment": "Origin: URI (DerivedType); A `NormalizedString` that respresents a Uniform Resource Identifier (URI).",
          "type": "string"
        },
        "type": {
          "description": "The value MUST identify the type of data schema validation. One instance of `CredentialSchema` MUST have a `type` of 'JsonSchemaValidator2019'.",
          "$comment": "Origin: IRI (DerivedType); A `NormalizedString` that represents an Internationalized Resource Identifier (IRI), which extends the ASCII characters subset of the Uniform Resource Identifier (URI).",
          "type": "string"
        }
      },
      "required": [
        "id",
        "type"
      ],
      "additionalProperties": false
    }
  }
}
E.2.1.2 AchievementCredential

AchievementCredentials are representations of an awarded achievement, used to share information about a achievement belonging to one earner. Maps to a Verifiable Credential as defined in the [VC-DATA-MODEL].

{
  "$schema": "https://json-schema.org/draft/2019-09/schema#",
  "$id": "https://example.org/404/ob/achievementcredentialv3p0.schema.json",
  "$comment": "This is a dynamically generated schema made available only for testing purposes; it does not have normative status and must not be persisted or served to the public.",
  "title": "JSON Schema for the AchievementCredential class.",
  "description": "AchievementCredentials are representations of an awarded achievement, used to share information about a achievement belonging to one earner. Maps to a Verifiable Credential as defined in the [[VC-DATA-MODEL]].",
  "type": "object",
  "properties": {
    "@context": {
      "description": "The value of the `@context` property MUST be an ordered set where the first item is a URI with the value 'https://www.w3.org/2018/credentials/v1', and the second item is a URI with the value 'https://purl.imsglobal.org/spec/ob/v3p0/context/ob_v3p0.jsonld'.",
      "$comment": "Origin: URI (DerivedType); A `NormalizedString` that respresents a Uniform Resource Identifier (URI).",
      "type": "array",
      "minItems": 1,
      "items": {
        "type": "string"
      }
    },
    "id": {
      "description": "Unambiguous reference to the credential.",
      "$comment": "Origin: URI (DerivedType); A `NormalizedString` that respresents a Uniform Resource Identifier (URI).",
      "type": "string"
    },
    "type": {
      "description": "The value of the type property MUST be an unordered set. One of the items MUST be the URI 'VerifiableCredential', and one of the items MUST be the URI 'AchievementCredential' or the URI 'OpenBadgeCredential'.",
      "$comment": "Origin: IRI (DerivedType); A `NormalizedString` that represents an Internationalized Resource Identifier (IRI), which extends the ASCII characters subset of the Uniform Resource Identifier (URI).",
      "type": "array",
      "minItems": 1,
      "items": {
        "type": "string"
      }
    },
    "name": {
      "description": "The name of the credential for display purposes in wallets. For example, in a list of credentials and in detail views.",
      "$comment": "Origin: String (PrimitiveType); Character strings.",
      "type": "string"
    },
    "description": {
      "description": "The short description of the credential for display purposes in wallets.",
      "$comment": "Origin: String (PrimitiveType); Character strings.",
      "type": "string"
    },
    "image": {
      "description": "The image representing the credential for display purposes in wallets.",
      "$comment": "Origin: Image (Unordered); Metadata about images that represent assertions, achieve or profiles. These properties can typically be represented as just the id string of the image, but using a fleshed-out document allows for including captions and other applicable metadata.",
      "$ref": "#/$defs/Image"
    },
    "credentialSubject": {
      "description": "The recipient of the achievement.",
      "$comment": "Origin: AchievementSubject (Unordered); A collection of information about the recipient of an achievement. Maps to Credential Subject in [[VC-DATA-MODEL]].",
      "$ref": "#/$defs/AchievementSubject"
    },
    "endorsement": {
      "description": "Allows endorsers to make specific claims about the credential, and the achievement and profiles in the credential. These endorsements are signed with a Data Integrity proof format.",
      "$comment": "Origin: EndorsementCredential (Unordered); A verifiable credential that asserts a claim about an entity.",
      "type": "array",
      "items": {
        "$ref": "#/$defs/EndorsementCredential"
      }
    },
    "endorsementJwt": {
      "description": "Allows endorsers to make specific claims about the credential, and the achievement and profiles in the credential. These endorsements are signed with the VC-JWT proof format.",
      "$comment": "Origin: CompactJws (DerivedType); A `String` in Compact JWS format [[RFC7515]].",
      "type": "array",
      "items": {
        "type": "string",
        "pattern": "^[a-zA-Z0-9_-]+\\.[a-zA-Z0-9_-]*\\.[a-zA-Z0-9_-]+$"
      }
    },
    "evidence": {
      "description": "A description of the work that the recipient did to earn the achievement. This can be a page that links out to other pages if linking directly to the work is infeasible.",
      "$comment": "Origin: Evidence (Unordered); Descriptive metadata about evidence related to the achievement assertion. Each instance of the evidence class present in an assertion corresponds to one entity, though a single entry can describe a set of items collectively. There may be multiple evidence entries referenced from an assertion. The narrative property is also in scope of the assertion class to provide an overall description of the achievement related to the assertion in rich text. It is used here to provide a narrative of achievement of the specific entity described. If both the description and narrative properties are present, displayers can assume the narrative value goes into more detail and is not simply a recapitulation of description.",
      "type": "array",
      "items": {
        "$ref": "#/$defs/Evidence"
      }
    },
    "issuer": {
      "description": "A description of the individual, entity, or organization that issued the credential.",
      "$comment": "Origin: Profile (Unordered); A Profile is a collection of information that describes the entity or organization using Open Badges. Issuers must be represented as Profiles, and recipients, endorsers, or other entities may also be represented using this vocabulary. Each Profile that represents an Issuer may be referenced in many BadgeClasses that it has defined. Anyone can create and host an Issuer file to start issuing Open Badges. Issuers may also serve as recipients of Open Badges, often identified within an Assertion by specific properties, like their url or contact email address.",
      "$ref": "#/$defs/Profile"
    },
    "issuanceDate": {
      "description": "Timestamp of when the credential was awarded.",
      "$comment": "Origin: DateTime (PrimitiveType); An [[ISO8601]] time using the syntax YYYY-MM-DDThh:mm:ss.",
      "type": "string",
      "format": "date-time"
    },
    "expirationDate": {
      "description": "If the credential has some notion of expiry, this indicates a timestamp when a credential should no longer be considered valid. After this time, the credential should be considered expired.",
      "$comment": "Origin: DateTime (PrimitiveType); An [[ISO8601]] time using the syntax YYYY-MM-DDThh:mm:ss.",
      "type": "string",
      "format": "date-time"
    },
    "proof": {
      "description": "If present, one or more embedded cryptographic proofs that can be used to detect tampering and verify the authorship of the credential.",
      "$comment": "Origin: Proof (Unordered); A JSON-LD Linked Data proof.",
      "type": "array",
      "items": {
        "$ref": "#/$defs/Proof"
      }
    },
    "credentialSchema": {
      "description": "The value of the `credentialSchema` property MUST be one or more data schemas that provide verifiers with enough information to determine if the provided data conforms to the provided schema.",
      "$comment": "Origin: CredentialSchema (Unordered); Identify the type and location of a data schema.",
      "type": "array",
      "items": {
        "$ref": "#/$defs/CredentialSchema"
      }
    },
    "credentialStatus": {
      "description": "The information in CredentialStatus is used to discover information about the current status of a verifiable credential, such as whether it is suspended or revoked.",
      "$comment": "Origin: CredentialStatus (Unordered); The information in CredentialStatus is used to discover information about the current status of a verifiable credential, such as whether it is suspended or revoked.",
      "$ref": "#/$defs/CredentialStatus"
    },
    "refreshService": {
      "description": "The information in RefreshService is used to refresh the verifiable credential.",
      "$comment": "Origin: RefreshService (Unordered); The information in RefreshService is used to refresh the verifiable credential.",
      "$ref": "#/$defs/RefreshService"
    }
  },
  "required": [
    "@context",
    "id",
    "type",
    "name",
    "credentialSubject",
    "issuer",
    "issuanceDate"
  ],
  "additionalProperties": true,
  "$defs": {
    "CredentialStatus": {
      "description": "The information in CredentialStatus is used to discover information about the current status of a verifiable credential, such as whether it is suspended or revoked.",
      "type": "object",
      "properties": {
        "id": {
          "description": "The value MUST be the URL of the issuer's credential status method.",
          "$comment": "Origin: URI (DerivedType); A `NormalizedString` that respresents a Uniform Resource Identifier (URI).",
          "type": "string"
        },
        "type": {
          "description": "The name of the credential status method.",
          "$comment": "Origin: IRI (DerivedType); A `NormalizedString` that represents an Internationalized Resource Identifier (IRI), which extends the ASCII characters subset of the Uniform Resource Identifier (URI).",
          "type": "string"
        }
      },
      "required": [
        "id",
        "type"
      ],
      "additionalProperties": false
    },
    "AchievementSubject": {
      "description": "A collection of information about the recipient of an achievement. Maps to Credential Subject in [[VC-DATA-MODEL]].",
      "type": "object",
      "properties": {
        "id": {
          "description": "An identifier for the Credential Subject. Either `id` or at least one `identifier` MUST be supplied.",
          "$comment": "Origin: URI (DerivedType); A `NormalizedString` that respresents a Uniform Resource Identifier (URI).",
          "type": "string"
        },
        "type": {
          "description": "The value of the type property MUST be an unordered set. One of the items MUST be the IRI 'AchievementSubject'.",
          "$comment": "Origin: IRI (DerivedType); A `NormalizedString` that represents an Internationalized Resource Identifier (IRI), which extends the ASCII characters subset of the Uniform Resource Identifier (URI).",
          "type": "array",
          "minItems": 1,
          "items": {
            "type": "string"
          }
        },
        "activityEndDate": {
          "description": "The datetime the activity ended.",
          "$comment": "Origin: DateTime (PrimitiveType); An [[ISO8601]] time using the syntax YYYY-MM-DDThh:mm:ss.",
          "type": "string",
          "format": "date-time"
        },
        "activityStartDate": {
          "description": "The datetime the activity started.",
          "$comment": "Origin: DateTime (PrimitiveType); An [[ISO8601]] time using the syntax YYYY-MM-DDThh:mm:ss.",
          "type": "string",
          "format": "date-time"
        },
        "creditsEarned": {
          "description": "The number of credits earned, generally in semester or quarter credit hours. This field correlates with the Achievement `creditsAvailable` field.",
          "$comment": "Origin: Float (PrimitiveType)",
          "type": "number"
        },
        "achievement": {
          "description": "The achievement being awarded.",
          "$comment": "Origin: Achievement (Unordered); A collection of information about the accomplishment recognized by the Assertion. Many assertions may be created corresponding to one Achievement.",
          "$ref": "#/$defs/Achievement"
        },
        "identifier": {
          "description": "Other identifiers for the recipient of the achievement. Either `id` or at least one `identifier` MUST be supplied.",
          "$comment": "Origin: IdentityObject (Unordered); A collection of information about the recipient of an achievement.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/IdentityObject"
          }
        },
        "image": {
          "description": "An image representing this user's achievement. If present, this must be a PNG or SVG image, and should be prepared via the 'baking' instructions. An 'unbaked' image for the achievement is defined in the Achievement class and should not be duplicated here.",
          "$comment": "Origin: Image (Unordered); Metadata about images that represent assertions, achieve or profiles. These properties can typically be represented as just the id string of the image, but using a fleshed-out document allows for including captions and other applicable metadata.",
          "$ref": "#/$defs/Image"
        },
        "licenseNumber": {
          "description": "The license number that was issued with this credential.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "narrative": {
          "description": "A narrative that connects multiple pieces of evidence. Likely only present at this location if evidence is a multi-value array.",
          "$comment": "Origin: Markdown (DerivedType); A `String` that may contain Markdown.",
          "type": "string"
        },
        "result": {
          "description": "The set of results being asserted.",
          "$comment": "Origin: Result (Unordered); Describes a result that was achieved.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/Result"
          }
        },
        "role": {
          "description": "Role, position, or title of the learner when demonstrating or performing the achievement or evidence of learning being asserted. Examples include 'Student President', 'Intern', 'Captain', etc.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "source": {
          "description": "The person, organization, or system that assessed the achievement on behalf of the issuer. For example, a school may assess the achievement, while the school district issues the credential.",
          "$comment": "Origin: Profile (Unordered); A Profile is a collection of information that describes the entity or organization using Open Badges. Issuers must be represented as Profiles, and recipients, endorsers, or other entities may also be represented using this vocabulary. Each Profile that represents an Issuer may be referenced in many BadgeClasses that it has defined. Anyone can create and host an Issuer file to start issuing Open Badges. Issuers may also serve as recipients of Open Badges, often identified within an Assertion by specific properties, like their url or contact email address.",
          "$ref": "#/$defs/Profile"
        },
        "term": {
          "description": "The academic term in which this assertion was achieved.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        }
      },
      "required": [
        "type"
      ],
      "additionalProperties": false
    },
    "IdentityObject": {
      "description": "A collection of information about the recipient of an achievement.",
      "type": "object",
      "properties": {
        "type": {
          "description": "MUST be the IRI 'IdentityObject'.",
          "$comment": "Origin: IRI (DerivedType); A `NormalizedString` that represents an Internationalized Resource Identifier (IRI), which extends the ASCII characters subset of the Uniform Resource Identifier (URI).",
          "type": "string"
        },
        "hashed": {
          "description": "Whether or not the `identityHash` value is hashed.",
          "$comment": "Origin: Boolean (PrimitiveType)",
          "type": "boolean"
        },
        "identityHash": {
          "description": "Either the IdentityHash of the identity or the plaintext value. If it's possible that the plaintext transmission and storage of the identity value would leak personally identifiable information where there is an expectation of privacy, it is strongly recommended that an IdentityHash be used.",
          "$comment": "Origin: IdentityHash (DerivedType); A hash string containing an algorithm identifier and a resulting hash of an identifier, separated by a dollar sign ('$') and the algorithm used to generate the hash. The only supported algorithms are MD5 [[RFC1321]] and SHA-256 [[FIPS-180-4]], identified by the strings md5 and sha256 respectively. Resulting hash for each of these algorithms MUST be expressed in hexadecimal using uppercase (A-F, 0-9) or lowercase character (a-f, 0-9) sets. For example: sha256$7a1a1b3f7d40552e4299180e346e3add12bf9a751a43d9c4ca4518febc2c60c6 represents the result of calculating a SHA-256 hash on the string 'mayze'.",
          "type": "string"
        },
        "identityType": {
          "description": "The identity type.",
          "$comment": "Origin: IdentifierTypeEnum (EnumExt)",
          "anyOf": [
            {
              "type": "string",
              "enum": [
                "sourcedId",
                "systemId",
                "productId",
                "userName",
                "accountId",
                "emailAddress",
                "nationalIdentityNumber",
                "isbn",
                "issn",
                "lisSourcedId",
                "oneRosterSourcedId",
                "sisSourcedId",
                "ltiContextId",
                "ltiDeploymentId",
                "ltiToolId",
                "ltiPlatformId",
                "ltiUserId",
                "identifier"
              ]
            },
            {
              "type": "string",
              "pattern": "(ext:)[a-z|A-Z|0-9|.|-|_]+"
            }
          ]
        },
        "salt": {
          "description": "If the `identityHash` is hashed, this should contain the string used to salt the hash. If this value is not provided, it should be assumed that the hash was not salted.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        }
      },
      "required": [
        "type",
        "hashed",
        "identityHash",
        "identityType"
      ],
      "additionalProperties": false
    },
    "Evidence": {
      "description": "Descriptive metadata about evidence related to the achievement assertion. Each instance of the evidence class present in an assertion corresponds to one entity, though a single entry can describe a set of items collectively. There may be multiple evidence entries referenced from an assertion. The narrative property is also in scope of the assertion class to provide an overall description of the achievement related to the assertion in rich text. It is used here to provide a narrative of achievement of the specific entity described. If both the description and narrative properties are present, displayers can assume the narrative value goes into more detail and is not simply a recapitulation of description.",
      "type": "object",
      "properties": {
        "id": {
          "description": "The URL of a webpage presenting evidence of achievement or the evidence encoded as a Data URI. The schema of the webpage is undefined.",
          "$comment": "Origin: URI (DerivedType); A `NormalizedString` that respresents a Uniform Resource Identifier (URI).",
          "type": "string"
        },
        "type": {
          "description": "The value of the type property MUST be an unordered set. One of the items MUST be the IRI 'Evidence'.",
          "$comment": "Origin: IRI (DerivedType); A `NormalizedString` that represents an Internationalized Resource Identifier (IRI), which extends the ASCII characters subset of the Uniform Resource Identifier (URI).",
          "type": "array",
          "minItems": 1,
          "items": {
            "type": "string"
          }
        },
        "narrative": {
          "description": "A narrative that describes the evidence and process of achievement that led to an assertion.",
          "$comment": "Origin: Markdown (DerivedType); A `String` that may contain Markdown.",
          "type": "string"
        },
        "name": {
          "description": "A descriptive title of the evidence.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "description": {
          "description": "A longer description of the evidence.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "genre": {
          "description": "A string that describes the type of evidence. For example, Poetry, Prose, Film.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "audience": {
          "description": "A description of the intended audience for a piece of evidence.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        }
      },
      "required": [
        "type"
      ],
      "additionalProperties": true
    },
    "EndorsementCredential": {
      "description": "A verifiable credential that asserts a claim about an entity.",
      "type": "object",
      "properties": {
        "@context": {
          "description": "The value of the `@context` property MUST be an ordered set where the first item is a URI with the value 'https://www.w3.org/2018/credentials/v1', and the second item is a URI with the value 'https://purl.imsglobal.org/spec/ob/v3p0/context/ob_v3p0.jsonld'.",
          "$comment": "Origin: URI (DerivedType); A `NormalizedString` that respresents a Uniform Resource Identifier (URI).",
          "type": "array",
          "minItems": 1,
          "items": {
            "type": "string"
          }
        },
        "type": {
          "description": "The value of the type property MUST be an unordered set. One of the items MUST be the URI 'VerifiableCredential', and one of the items MUST be the URI 'EndorsementCredential'.",
          "$comment": "Origin: IRI (DerivedType); A `NormalizedString` that represents an Internationalized Resource Identifier (IRI), which extends the ASCII characters subset of the Uniform Resource Identifier (URI).",
          "type": "array",
          "minItems": 1,
          "items": {
            "type": "string"
          }
        },
        "credentialSubject": {
          "description": "The individual, entity, organization, assertion, or achievement that is endorsed and the endorsement comment.",
          "$comment": "Origin: EndorsementSubject (Unordered); A collection of information about the subject of the endorsement.",
          "$ref": "#/$defs/EndorsementSubject"
        },
        "id": {
          "description": "Unambiguous reference to the credential.",
          "$comment": "Origin: URI (DerivedType); A `NormalizedString` that respresents a Uniform Resource Identifier (URI).",
          "type": "string"
        },
        "issuer": {
          "description": "A description of the individual, entity, or organization that issued the credential.",
          "$comment": "Origin: Profile (Unordered); A Profile is a collection of information that describes the entity or organization using Open Badges. Issuers must be represented as Profiles, and recipients, endorsers, or other entities may also be represented using this vocabulary. Each Profile that represents an Issuer may be referenced in many BadgeClasses that it has defined. Anyone can create and host an Issuer file to start issuing Open Badges. Issuers may also serve as recipients of Open Badges, often identified within an Assertion by specific properties, like their url or contact email address.",
          "$ref": "#/$defs/Profile"
        },
        "issuanceDate": {
          "description": "Timestamp of when the credential was awarded.",
          "$comment": "Origin: DateTime (PrimitiveType); An [[ISO8601]] time using the syntax YYYY-MM-DDThh:mm:ss.",
          "type": "string",
          "format": "date-time"
        },
        "expirationDate": {
          "description": "If the credential has some notion of expiry, this indicates a timestamp when a credential should no longer be considered valid. After this time, the credential should be considered expired.",
          "$comment": "Origin: DateTime (PrimitiveType); An [[ISO8601]] time using the syntax YYYY-MM-DDThh:mm:ss.",
          "type": "string",
          "format": "date-time"
        },
        "proof": {
          "description": "If present, one or more embedded cryptographic proofs that can be used to detect tampering and verify the authorship of the credential.",
          "$comment": "Origin: Proof (Unordered); A JSON-LD Linked Data proof.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/Proof"
          }
        },
        "credentialSchema": {
          "description": "The value of the `credentialSchema` property MUST be one or more data schemas that provide verifiers with enough information to determine if the provided data conforms to the provided schema.",
          "$comment": "Origin: CredentialSchema (Unordered); Identify the type and location of a data schema.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/CredentialSchema"
          }
        },
        "credentialStatus": {
          "description": "The information in CredentialStatus is used to discover information about the current status of a verifiable credential, such as whether it is suspended or revoked.",
          "$comment": "Origin: CredentialStatus (Unordered); The information in CredentialStatus is used to discover information about the current status of a verifiable credential, such as whether it is suspended or revoked.",
          "$ref": "#/$defs/CredentialStatus"
        },
        "refreshService": {
          "description": "The information in RefreshService is used to refresh the verifiable credential.",
          "$comment": "Origin: RefreshService (Unordered); The information in RefreshService is used to refresh the verifiable credential.",
          "$ref": "#/$defs/RefreshService"
        }
      },
      "required": [
        "@context",
        "type",
        "credentialSubject",
        "issuer",
        "issuanceDate"
      ],
      "additionalProperties": false
    },
    "Achievement": {
      "description": "A collection of information about the accomplishment recognized by the Assertion. Many assertions may be created corresponding to one Achievement.",
      "type": "object",
      "properties": {
        "id": {
          "description": "Unique URI for the Achievement.",
          "$comment": "Origin: URI (DerivedType); A `NormalizedString` that respresents a Uniform Resource Identifier (URI).",
          "type": "string"
        },
        "type": {
          "description": "No description supplied.",
          "$comment": "Origin: IRI (DerivedType); A `NormalizedString` that represents an Internationalized Resource Identifier (IRI), which extends the ASCII characters subset of the Uniform Resource Identifier (URI).",
          "type": "array",
          "minItems": 1,
          "items": {
            "type": "string"
          }
        },
        "alignment": {
          "description": "An object describing which objectives or educational standards this achievement aligns to, if any.",
          "$comment": "Origin: Alignment (Unordered); Describes an alignment between an achievement and a node in an educational framework.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/Alignment"
          }
        },
        "achievementType": {
          "description": "The type of achievement. This is an extensible vocabulary.",
          "$comment": "Origin: AchievementType (EnumExt); The type of achievement, for example 'Award' or 'Certification'. This is an extensible enumerated vocabulary. Extending the vocabulary makes use of a naming convention.",
          "anyOf": [
            {
              "type": "string",
              "enum": [
                "Achievement",
                "ApprenticeshipCertificate",
                "Assessment",
                "Assignment",
                "AssociateDegree",
                "Award",
                "Badge",
                "BachelorDegree",
                "Certificate",
                "CertificateOfCompletion",
                "Certification",
                "CommunityService",
                "Competency",
                "Course",
                "CoCurricular",
                "Degree",
                "Diploma",
                "DoctoralDegree",
                "Fieldwork",
                "GeneralEducationDevelopment",
                "JourneymanCertificate",
                "LearningProgram",
                "License",
                "Membership",
                "ProfessionalDoctorate",
                "QualityAssuranceCredential",
                "MasterCertificate",
                "MasterDegree",
                "MicroCredential",
                "ResearchDoctorate",
                "SecondarySchoolDiploma"
              ]
            },
            {
              "type": "string",
              "pattern": "(ext:)[a-z|A-Z|0-9|.|-|_]+"
            }
          ]
        },
        "creator": {
          "description": "The person or organization that created the achievement definition.",
          "$comment": "Origin: Profile (Unordered); A Profile is a collection of information that describes the entity or organization using Open Badges. Issuers must be represented as Profiles, and recipients, endorsers, or other entities may also be represented using this vocabulary. Each Profile that represents an Issuer may be referenced in many BadgeClasses that it has defined. Anyone can create and host an Issuer file to start issuing Open Badges. Issuers may also serve as recipients of Open Badges, often identified within an Assertion by specific properties, like their url or contact email address.",
          "$ref": "#/$defs/Profile"
        },
        "creditsAvailable": {
          "description": "Credit hours associated with this entity, or credit hours possible. For example 3.0.",
          "$comment": "Origin: Float (PrimitiveType)",
          "type": "number"
        },
        "criteria": {
          "description": "Criteria describing how to earn the achievement.",
          "$comment": "Origin: Criteria (Unordered); Descriptive metadata about the achievements necessary to be recognized with an assertion of a particular achievement. This data is added to the Achievement class so that it may be rendered when the achievement assertion is displayed, instead of simply a link to human-readable criteria external to the achievement. Embedding criteria allows either enhancement of an external criteria page or increased portability and ease of use by allowing issuers to skip hosting the formerly-required external criteria page altogether. Criteria is used to allow would-be recipients to learn what is required of them to be recognized with an assertion of a particular achievement. It is also used after the assertion is awarded to a recipient to let those inspecting earned achievements know the general requirements that the recipients met in order to earn it.",
          "$ref": "#/$defs/Criteria"
        },
        "description": {
          "description": "A short description of the achievement.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "endorsement": {
          "description": "Allows endorsers to make specific claims about the Achievement. These endorsements are signed with a Data Integrity proof format.",
          "$comment": "Origin: EndorsementCredential (Unordered); A verifiable credential that asserts a claim about an entity.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/EndorsementCredential"
          }
        },
        "endorsementJwt": {
          "description": "Allows endorsers to make specific claims about the Achievement. These endorsements are signed with the VC-JWT proof format.",
          "$comment": "Origin: CompactJws (DerivedType); A `String` in Compact JWS format [[RFC7515]].",
          "type": "array",
          "items": {
            "type": "string",
            "pattern": "^[a-zA-Z0-9_-]+\\.[a-zA-Z0-9_-]*\\.[a-zA-Z0-9_-]+$"
          }
        },
        "fieldOfStudy": {
          "description": "Category, subject, area of study, discipline, or general branch of knowledge. Examples include Business, Education, Psychology, and Technology.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "humanCode": {
          "description": "The code, generally human readable, associated with an achievement.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "image": {
          "description": "An image representing the achievement.",
          "$comment": "Origin: Image (Unordered); Metadata about images that represent assertions, achieve or profiles. These properties can typically be represented as just the id string of the image, but using a fleshed-out document allows for including captions and other applicable metadata.",
          "$ref": "#/$defs/Image"
        },
        "@language": {
          "description": "The language of the achievement.",
          "$comment": "Origin: LanguageCode (DerivedType); A language code [[BCP47]].",
          "type": "string",
          "pattern": "^[a-z]{2,4}(-[A-Z][a-z]{3})?(-([A-Z]{2}|[0-9]{3}))?$"
        },
        "name": {
          "description": "The name of the achievement.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "otherIdentifier": {
          "description": "A list of identifiers for the described entity.",
          "$comment": "Origin: IdentifierEntry (Unordered)",
          "type": "array",
          "items": {
            "$ref": "#/$defs/IdentifierEntry"
          }
        },
        "related": {
          "description": "The related property identifies another Achievement that should be considered the same for most purposes. It is primarily intended to identify alternate language editions or previous versions of Achievements.",
          "$comment": "Origin: Related (Unordered); Identifies a related achievement.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/Related"
          }
        },
        "resultDescription": {
          "description": "The set of result descriptions that may be asserted as results with this achievement.",
          "$comment": "Origin: ResultDescription (Unordered); Describes a possible achievement result.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/ResultDescription"
          }
        },
        "specialization": {
          "description": "Name given to the focus, concentration, or specific area of study defined in the achievement. Examples include 'Entrepreneurship', 'Technical Communication', and 'Finance'.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "tag": {
          "description": "Tags that describes the type of achievement.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "version": {
          "description": "The version property allows issuers to set a version string for an Achievement. This is particularly useful when replacing a previous version with an update.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        }
      },
      "required": [
        "id",
        "type",
        "criteria",
        "description",
        "name"
      ],
      "additionalProperties": true
    },
    "Alignment": {
      "description": "Describes an alignment between an achievement and a node in an educational framework.",
      "type": "object",
      "properties": {
        "type": {
          "description": "The value of the type property MUST be an unordered set. One of the items MUST be the IRI 'Alignment'.",
          "$comment": "Origin: IRI (DerivedType); A `NormalizedString` that represents an Internationalized Resource Identifier (IRI), which extends the ASCII characters subset of the Uniform Resource Identifier (URI).",
          "type": "array",
          "minItems": 1,
          "items": {
            "type": "string"
          }
        },
        "targetCode": {
          "description": "If applicable, a locally unique string identifier that identifies the alignment target within its framework and/or targetUrl.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "targetDescription": {
          "description": "Short description of the alignment target.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "targetName": {
          "description": "Name of the alignment.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "targetFramework": {
          "description": "Name of the framework the alignment target.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "targetType": {
          "description": "The type of the alignment target node.",
          "$comment": "Origin: AlignmentTargetType (EnumExt); The type of the alignment target node in the target framework.",
          "anyOf": [
            {
              "type": "string",
              "enum": [
                "ceasn:Competency",
                "ceterms:Credential",
                "CFItem",
                "CFRubric",
                "CFRubricCriterion",
                "CFRubricCriterionLevel",
                "CTDL"
              ]
            },
            {
              "type": "string",
              "pattern": "(ext:)[a-z|A-Z|0-9|.|-|_]+"
            }
          ]
        },
        "targetUrl": {
          "description": "URL linking to the official description of the alignment target, for example an individual standard within an educational framework.",
          "$comment": "Origin: URL (DerivedType); A `URI` that represents a Uniform Resource Locator (URL).",
          "type": "string"
        }
      },
      "required": [
        "type",
        "targetName",
        "targetUrl"
      ],
      "additionalProperties": true
    },
    "Criteria": {
      "description": "Descriptive metadata about the achievements necessary to be recognized with an assertion of a particular achievement. This data is added to the Achievement class so that it may be rendered when the achievement assertion is displayed, instead of simply a link to human-readable criteria external to the achievement. Embedding criteria allows either enhancement of an external criteria page or increased portability and ease of use by allowing issuers to skip hosting the formerly-required external criteria page altogether. Criteria is used to allow would-be recipients to learn what is required of them to be recognized with an assertion of a particular achievement. It is also used after the assertion is awarded to a recipient to let those inspecting earned achievements know the general requirements that the recipients met in order to earn it.",
      "type": "object",
      "properties": {
        "id": {
          "description": "The URI of a webpage that describes in a human-readable format the criteria for the achievement.",
          "$comment": "Origin: URI (DerivedType); A `NormalizedString` that respresents a Uniform Resource Identifier (URI).",
          "type": "string"
        },
        "narrative": {
          "description": "A narrative of what is needed to earn the achievement. Markdown is allowed.",
          "$comment": "Origin: Markdown (DerivedType); A `String` that may contain Markdown.",
          "type": "string"
        }
      },
      "required": [],
      "additionalProperties": true
    },
    "IdentifierEntry": {
      "description": "No description supplied.",
      "type": "object",
      "properties": {
        "type": {
          "description": "The value of the type property MUST be an unordered set. One of the items MUST be the IRI 'IdentifierEntry'.",
          "$comment": "Origin: IRI (DerivedType); A `NormalizedString` that represents an Internationalized Resource Identifier (IRI), which extends the ASCII characters subset of the Uniform Resource Identifier (URI).",
          "type": "string"
        },
        "identifier": {
          "description": "An identifier.",
          "$comment": "Origin: Identifier (DerivedType); A `NormalizedString` that functions as an identifier.",
          "type": "string"
        },
        "identifierType": {
          "description": "The identifier type.",
          "$comment": "Origin: IdentifierTypeEnum (EnumExt)",
          "anyOf": [
            {
              "type": "string",
              "enum": [
                "sourcedId",
                "systemId",
                "productId",
                "userName",
                "accountId",
                "emailAddress",
                "nationalIdentityNumber",
                "isbn",
                "issn",
                "lisSourcedId",
                "oneRosterSourcedId",
                "sisSourcedId",
                "ltiContextId",
                "ltiDeploymentId",
                "ltiToolId",
                "ltiPlatformId",
                "ltiUserId",
                "identifier"
              ]
            },
            {
              "type": "string",
              "pattern": "(ext:)[a-z|A-Z|0-9|.|-|_]+"
            }
          ]
        }
      },
      "required": [
        "type",
        "identifier",
        "identifierType"
      ],
      "additionalProperties": false
    },
    "Proof": {
      "description": "A JSON-LD Linked Data proof.",
      "type": "object",
      "properties": {
        "type": {
          "description": "Signature suite used to produce proof.",
          "$comment": "Origin: IRI (DerivedType); A `NormalizedString` that represents an Internationalized Resource Identifier (IRI), which extends the ASCII characters subset of the Uniform Resource Identifier (URI).",
          "type": "string"
        },
        "created": {
          "description": "Date the proof was created.",
          "$comment": "Origin: DateTime (PrimitiveType); An [[ISO8601]] time using the syntax YYYY-MM-DDThh:mm:ss.",
          "type": "string",
          "format": "date-time"
        },
        "challenge": {
          "description": "A value chosen by the verifier to mitigate authentication proof replay attacks.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "domain": {
          "description": "The domain of the proof to restrict its use to a particular target.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "nonce": {
          "description": "A value chosen by the creator of proof to randomize proof values for privacy purposes.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "proofPurpose": {
          "description": "The purpose of the proof to be used with `verificationMethod`. MUST be 'assertionMethod'.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "proofValue": {
          "description": "Value of the proof.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "verificationMethod": {
          "description": "The URL of the public key that can verify the signature.",
          "$comment": "Origin: URI (DerivedType); A `NormalizedString` that respresents a Uniform Resource Identifier (URI).",
          "type": "string"
        }
      },
      "required": [
        "type",
        "created",
        "proofPurpose",
        "proofValue",
        "verificationMethod"
      ],
      "additionalProperties": true
    },
    "RefreshService": {
      "description": "The information in RefreshService is used to refresh the verifiable credential.",
      "type": "object",
      "properties": {
        "id": {
          "description": "The value MUST be the URL of the issuer's refresh service.",
          "$comment": "Origin: URI (DerivedType); A `NormalizedString` that respresents a Uniform Resource Identifier (URI).",
          "type": "string"
        },
        "type": {
          "description": "The name of the refresh service method.",
          "$comment": "Origin: IRI (DerivedType); A `NormalizedString` that represents an Internationalized Resource Identifier (IRI), which extends the ASCII characters subset of the Uniform Resource Identifier (URI).",
          "type": "string"
        }
      },
      "required": [
        "id",
        "type"
      ],
      "additionalProperties": true
    },
    "Image": {
      "description": "Metadata about images that represent assertions, achieve or profiles. These properties can typically be represented as just the id string of the image, but using a fleshed-out document allows for including captions and other applicable metadata.",
      "type": "object",
      "properties": {
        "id": {
          "description": "The URI or Data URI of the image.",
          "$comment": "Origin: URI (DerivedType); A `NormalizedString` that respresents a Uniform Resource Identifier (URI).",
          "type": "string"
        },
        "type": {
          "description": "MUST be the IRI 'Image'.",
          "$comment": "Origin: IRI (DerivedType); A `NormalizedString` that represents an Internationalized Resource Identifier (IRI), which extends the ASCII characters subset of the Uniform Resource Identifier (URI).",
          "type": "string"
        },
        "caption": {
          "description": "The caption for the image.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        }
      },
      "required": [
        "id",
        "type"
      ],
      "additionalProperties": false
    },
    "EndorsementSubject": {
      "description": "A collection of information about the subject of the endorsement.",
      "type": "object",
      "properties": {
        "id": {
          "description": "The identifier of the individual, entity, organization, assertion, or achievement that is endorsed.",
          "$comment": "Origin: URI (DerivedType); A `NormalizedString` that respresents a Uniform Resource Identifier (URI).",
          "type": "string"
        },
        "type": {
          "description": "The value of the type property MUST be an unordered set. One of the items MUST be the URI 'VerifiableCredential', and one of the items MUST be the URI 'EndorsementSubject'.",
          "$comment": "Origin: IRI (DerivedType); A `NormalizedString` that represents an Internationalized Resource Identifier (IRI), which extends the ASCII characters subset of the Uniform Resource Identifier (URI).",
          "type": "array",
          "minItems": 1,
          "items": {
            "type": "string"
          }
        },
        "endorsementComment": {
          "description": "Allows endorsers to make a simple claim in writing about the entity.",
          "$comment": "Origin: Markdown (DerivedType); A `String` that may contain Markdown.",
          "type": "string"
        }
      },
      "required": [
        "id",
        "type"
      ],
      "additionalProperties": false
    },
    "Result": {
      "description": "Describes a result that was achieved.",
      "type": "object",
      "properties": {
        "type": {
          "description": "The value of the type property MUST be an unordered set. One of the items MUST be the IRI 'Result'.",
          "$comment": "Origin: IRI (DerivedType); A `NormalizedString` that represents an Internationalized Resource Identifier (IRI), which extends the ASCII characters subset of the Uniform Resource Identifier (URI).",
          "type": "array",
          "minItems": 1,
          "items": {
            "type": "string"
          }
        },
        "achievedLevel": {
          "description": "If the result represents an achieved rubric criterion level (e.g. Mastered), the value is the `id` of the RubricCriterionLevel in linked ResultDescription.",
          "$comment": "Origin: URI (DerivedType); A `NormalizedString` that respresents a Uniform Resource Identifier (URI).",
          "type": "string"
        },
        "alignment": {
          "description": "The alignments between this result and nodes in external frameworks. This set of alignments are in addition to the set of alignments defined in the corresponding ResultDescription object.",
          "$comment": "Origin: Alignment (Unordered); Describes an alignment between an achievement and a node in an educational framework.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/Alignment"
          }
        },
        "resultDescription": {
          "description": "An achievement can have many result descriptions describing possible results. The value of `resultDescription` is the `id` of the result description linked to this result. The linked result description must be in the achievement that is being asserted.",
          "$comment": "Origin: URI (DerivedType); A `NormalizedString` that respresents a Uniform Resource Identifier (URI).",
          "type": "string"
        },
        "status": {
          "description": "The status of the achievement. Required if `resultType` of the linked ResultDescription is Status.",
          "$comment": "Origin: ResultStatusType (Enumeration); Defined vocabulary to convey the status of an achievement.",
          "type": "string",
          "enum": [
            "Completed",
            "Enrolled",
            "Failed",
            "InProgress",
            "OnHold",
            "Withdrew"
          ]
        },
        "value": {
          "description": "A string representing the result of the performance, or demonstration, of the achievement. For example, 'A' if the recipient received an A grade in class.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        }
      },
      "required": [
        "type"
      ],
      "additionalProperties": true
    },
    "ResultDescription": {
      "description": "Describes a possible achievement result.",
      "type": "object",
      "properties": {
        "id": {
          "description": "The unique URI for this result description. Required so a result can link to this result description.",
          "$comment": "Origin: URI (DerivedType); A `NormalizedString` that respresents a Uniform Resource Identifier (URI).",
          "type": "string"
        },
        "type": {
          "description": "The value of the type property MUST be an unordered set. One of the items MUST be the IRI 'ResultDescription'.",
          "$comment": "Origin: IRI (DerivedType); A `NormalizedString` that represents an Internationalized Resource Identifier (IRI), which extends the ASCII characters subset of the Uniform Resource Identifier (URI).",
          "type": "array",
          "minItems": 1,
          "items": {
            "type": "string"
          }
        },
        "alignment": {
          "description": "Alignments between this result description and nodes in external frameworks.",
          "$comment": "Origin: Alignment (Unordered); Describes an alignment between an achievement and a node in an educational framework.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/Alignment"
          }
        },
        "allowedValue": {
          "description": "An ordered list of allowed values. The values should be ordered from low to high as determined by the achievement creator.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "name": {
          "description": "The name of the result.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "requiredLevel": {
          "description": "The `id` of the rubric criterion level required to pass as determined by the achievement creator.",
          "$comment": "Origin: URI (DerivedType); A `NormalizedString` that respresents a Uniform Resource Identifier (URI).",
          "type": "string"
        },
        "requiredValue": {
          "description": "A value from `allowedValue` or within the range of `valueMin` to `valueMax` required to pass as determined by the achievement creator.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "resultType": {
          "description": "The type of result this description represents. This is an extensible enumerated vocabulary.",
          "$comment": "Origin: ResultType (EnumExt); The type of result. This is an extensible enumerated vocabulary. Extending the vocabulary makes use of a naming convention.",
          "anyOf": [
            {
              "type": "string",
              "enum": [
                "GradePointAverage",
                "LetterGrade",
                "Percent",
                "PerformanceLevel",
                "PredictedScore",
                "RawScore",
                "Result",
                "RubricCriterion",
                "RubricCriterionLevel",
                "RubricScore",
                "ScaledScore",
                "Status"
              ]
            },
            {
              "type": "string",
              "pattern": "(ext:)[a-z|A-Z|0-9|.|-|_]+"
            }
          ]
        },
        "rubricCriterionLevel": {
          "description": "An ordered array of rubric criterion levels that may be asserted in the linked result. The levels should be ordered from low to high as determined by the achievement creator.",
          "$comment": "Origin: RubricCriterionLevel (Unordered); Describes a rubric criterion level.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/RubricCriterionLevel"
          }
        },
        "valueMax": {
          "description": "The maximum possible `value` that may be asserted in a linked result.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "valueMin": {
          "description": "The minimum possible `value` that may be asserted in a linked result.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        }
      },
      "required": [
        "id",
        "type",
        "name",
        "resultType"
      ],
      "additionalProperties": true
    },
    "RubricCriterionLevel": {
      "description": "Describes a rubric criterion level.",
      "type": "object",
      "properties": {
        "id": {
          "description": "The unique URI for this rubric criterion level. Required so a result can link to this rubric criterion level.",
          "$comment": "Origin: URI (DerivedType); A `NormalizedString` that respresents a Uniform Resource Identifier (URI).",
          "type": "string"
        },
        "type": {
          "description": "The value of the type property MUST be an unordered set. One of the items MUST be the IRI 'RubricCriterionLevel'.",
          "$comment": "Origin: IRI (DerivedType); A `NormalizedString` that represents an Internationalized Resource Identifier (IRI), which extends the ASCII characters subset of the Uniform Resource Identifier (URI).",
          "type": "array",
          "minItems": 1,
          "items": {
            "type": "string"
          }
        },
        "alignment": {
          "description": "Alignments between this rubric criterion level and a rubric criterion levels defined in external frameworks.",
          "$comment": "Origin: Alignment (Unordered); Describes an alignment between an achievement and a node in an educational framework.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/Alignment"
          }
        },
        "description": {
          "description": "Description of the rubric criterion level.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "level": {
          "description": "The rubric performance level in terms of success.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "name": {
          "description": "The name of the rubric criterion level.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "points": {
          "description": "The points associated with this rubric criterion level.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        }
      },
      "required": [
        "id",
        "type",
        "name"
      ],
      "additionalProperties": true
    },
    "Related": {
      "description": "Identifies a related achievement.",
      "type": "object",
      "properties": {
        "id": {
          "description": "The related achievement.",
          "$comment": "Origin: URI (DerivedType); A `NormalizedString` that respresents a Uniform Resource Identifier (URI).",
          "type": "string"
        },
        "@language": {
          "description": "The language of the related achievement.",
          "$comment": "Origin: LanguageCode (DerivedType); A language code [[BCP47]].",
          "type": "string",
          "pattern": "^[a-z]{2,4}(-[A-Z][a-z]{3})?(-([A-Z]{2}|[0-9]{3}))?$"
        },
        "version": {
          "description": "The version of the related achievement.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        }
      },
      "required": [
        "id"
      ],
      "additionalProperties": false
    },
    "Profile": {
      "description": "A Profile is a collection of information that describes the entity or organization using Open Badges. Issuers must be represented as Profiles, and recipients, endorsers, or other entities may also be represented using this vocabulary. Each Profile that represents an Issuer may be referenced in many BadgeClasses that it has defined. Anyone can create and host an Issuer file to start issuing Open Badges. Issuers may also serve as recipients of Open Badges, often identified within an Assertion by specific properties, like their url or contact email address.",
      "type": "object",
      "properties": {
        "id": {
          "description": "Unique URI for the Issuer/Profile file.",
          "$comment": "Origin: URI (DerivedType); A `NormalizedString` that respresents a Uniform Resource Identifier (URI).",
          "type": "string"
        },
        "type": {
          "description": "The value of the type property MUST be an unordered set. One of the items MUST be the IRI 'Profile'.",
          "$comment": "Origin: IRI (DerivedType); A `NormalizedString` that represents an Internationalized Resource Identifier (IRI), which extends the ASCII characters subset of the Uniform Resource Identifier (URI).",
          "type": "array",
          "minItems": 1,
          "items": {
            "type": "string"
          }
        },
        "name": {
          "description": "The name of the entity or organization.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "url": {
          "description": "The homepage or social media profile of the entity, whether individual or institutional. Should be a URL/URI Accessible via HTTP.",
          "$comment": "Origin: URI (DerivedType); A `NormalizedString` that respresents a Uniform Resource Identifier (URI).",
          "type": "string"
        },
        "phone": {
          "description": "A phone number.",
          "$comment": "Origin: PhoneNumber (DerivedType); A `NormalizedString` representing a phone number.",
          "type": "string"
        },
        "description": {
          "description": "A short description of the issuer entity or organization.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "endorsement": {
          "description": "Allows endorsers to make specific claims about the individual or organization represented by this profile. These endorsements are signed with a Data Integrity proof format.",
          "$comment": "Origin: EndorsementCredential (Unordered); A verifiable credential that asserts a claim about an entity.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/EndorsementCredential"
          }
        },
        "endorsementJwt": {
          "description": "Allows endorsers to make specific claims about the individual or organization represented by this profile. These endorsements are signed with the VC-JWT proof format.",
          "$comment": "Origin: CompactJws (DerivedType); A `String` in Compact JWS format [[RFC7515]].",
          "type": "array",
          "items": {
            "type": "string",
            "pattern": "^[a-zA-Z0-9_-]+\\.[a-zA-Z0-9_-]*\\.[a-zA-Z0-9_-]+$"
          }
        },
        "image": {
          "description": "An image representing the issuer. This must be a PNG or SVG image.",
          "$comment": "Origin: Image (Unordered); Metadata about images that represent assertions, achieve or profiles. These properties can typically be represented as just the id string of the image, but using a fleshed-out document allows for including captions and other applicable metadata.",
          "$ref": "#/$defs/Image"
        },
        "email": {
          "description": "An email address.",
          "$comment": "Origin: EmailAddress (DerivedType); A `NormalizedString` representing an email address.",
          "type": "string"
        },
        "address": {
          "description": "An address for the individual or organization.",
          "$comment": "Origin: Address (Unordered)",
          "$ref": "#/$defs/Address"
        },
        "otherIdentifier": {
          "description": "A list of identifiers for the described entity.",
          "$comment": "Origin: IdentifierEntry (Unordered)",
          "type": "array",
          "items": {
            "$ref": "#/$defs/IdentifierEntry"
          }
        },
        "official": {
          "description": "If the entity is an organization, `official` is the name of an authorized official of the organization.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "parentOrg": {
          "description": "The parent organization of the entity.",
          "$comment": "Origin: Profile (Unordered); A Profile is a collection of information that describes the entity or organization using Open Badges. Issuers must be represented as Profiles, and recipients, endorsers, or other entities may also be represented using this vocabulary. Each Profile that represents an Issuer may be referenced in many BadgeClasses that it has defined. Anyone can create and host an Issuer file to start issuing Open Badges. Issuers may also serve as recipients of Open Badges, often identified within an Assertion by specific properties, like their url or contact email address.",
          "$ref": "#/$defs/Profile"
        },
        "familyName": {
          "description": "Family name. In the western world, often referred to as the 'last name' of a person.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "givenName": {
          "description": "Given name. In the western world, often referred to as the 'first name' of a person.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "additionalName": {
          "description": "Additional name. Includes what is often referred to as 'middle name' in the western world.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "patronymicName": {
          "description": "Patronymic name.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "honorificPrefix": {
          "description": "Honorific prefix(es) preceding a person's name (e.g. 'Dr', 'Mrs' or 'Mr').",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "honorificSuffix": {
          "description": "Honorific suffix(es) following a person's name (e.g. 'M.D, PhD').",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "familyNamePrefix": {
          "description": "Family name prefix. As used in some locales, this is the leading part of a family name (e.g. 'de' in the name 'de Boer').",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "dateOfBirth": {
          "description": "No description supplied.",
          "$comment": "Origin: Date (PrimitiveType); An [[ISO8601]] calendar date using the syntax YYYY-MM-DD.",
          "type": "string",
          "format": "date"
        }
      },
      "required": [
        "id",
        "type"
      ],
      "additionalProperties": true
    },
    "Address": {
      "description": "No description supplied.",
      "type": "object",
      "properties": {
        "type": {
          "description": "The value of the type property MUST be an unordered set. One of the items MUST be the IRI 'Address'.",
          "$comment": "Origin: IRI (DerivedType); A `NormalizedString` that represents an Internationalized Resource Identifier (IRI), which extends the ASCII characters subset of the Uniform Resource Identifier (URI).",
          "type": "array",
          "minItems": 1,
          "items": {
            "type": "string"
          }
        },
        "addressCountry": {
          "description": "A country.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "addressCountryCode": {
          "description": "A country code. The value must be a ISO 3166-1 alpha-2 country code [[ISO3166-1]].",
          "$comment": "Origin: CountryCode (DerivedType); A two-digit ISO 3166-1 alpha-2 country code [[ISO3166-1]].",
          "type": "string"
        },
        "addressRegion": {
          "description": "A region within the country.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "addressLocality": {
          "description": "A locality within the region.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "streetAddress": {
          "description": "A street address within the locality.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "postOfficeBoxNumber": {
          "description": "A post office box number for PO box addresses.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "postalCode": {
          "description": "A postal code.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "geo": {
          "description": "The geographic coordinates of the location.",
          "$comment": "Origin: GeoCoordinates (Unordered); The geographic coordinates of a location.",
          "$ref": "#/$defs/GeoCoordinates"
        }
      },
      "required": [
        "type"
      ],
      "additionalProperties": false
    },
    "GeoCoordinates": {
      "description": "The geographic coordinates of a location.",
      "type": "object",
      "properties": {
        "type": {
          "description": "The value of the type property MUST be an unordered set. One of the items MUST be the IRI 'GeoCoordinates'.",
          "$comment": "Origin: IRI (DerivedType); A `NormalizedString` that represents an Internationalized Resource Identifier (IRI), which extends the ASCII characters subset of the Uniform Resource Identifier (URI).",
          "type": "string"
        },
        "latitude": {
          "description": "The latitude of the location [[WGS84]].",
          "$comment": "Origin: Float (PrimitiveType)",
          "type": "number"
        },
        "longitude": {
          "description": "The longitude of the location [[WGS84]].",
          "$comment": "Origin: Float (PrimitiveType)",
          "type": "number"
        }
      },
      "required": [
        "type",
        "latitude",
        "longitude"
      ],
      "additionalProperties": false
    },
    "CredentialSchema": {
      "description": "Identify the type and location of a data schema.",
      "type": "object",
      "properties": {
        "id": {
          "description": "The value MUST be a URI identifying the schema file. One instance of `CredentialSchema` MUST have an `id` that is the URL of the JSON Schema for this credential defined by this specification.",
          "$comment": "Origin: URI (DerivedType); A `NormalizedString` that respresents a Uniform Resource Identifier (URI).",
          "type": "string"
        },
        "type": {
          "description": "The value MUST identify the type of data schema validation. One instance of `CredentialSchema` MUST have a `type` of 'JsonSchemaValidator2019'.",
          "$comment": "Origin: IRI (DerivedType); A `NormalizedString` that represents an Internationalized Resource Identifier (IRI), which extends the ASCII characters subset of the Uniform Resource Identifier (URI).",
          "type": "string"
        }
      },
      "required": [
        "id",
        "type"
      ],
      "additionalProperties": false
    }
  }
}
E.2.1.3 AchievementSubject

A collection of information about the recipient of an achievement. Maps to Credential Subject in [VC-DATA-MODEL].

{
  "$schema": "https://json-schema.org/draft/2019-09/schema#",
  "$id": "https://example.org/404/ob/achievementsubjectv3p0.schema.json",
  "$comment": "This is a dynamically generated schema made available only for testing purposes; it does not have normative status and must not be persisted or served to the public.",
  "title": "JSON Schema for the AchievementSubject class.",
  "description": "A collection of information about the recipient of an achievement. Maps to Credential Subject in [[VC-DATA-MODEL]].",
  "type": "object",
  "properties": {
    "id": {
      "description": "An identifier for the Credential Subject. Either `id` or at least one `identifier` MUST be supplied.",
      "$comment": "Origin: URI (DerivedType); A `NormalizedString` that respresents a Uniform Resource Identifier (URI).",
      "type": "string"
    },
    "type": {
      "description": "The value of the type property MUST be an unordered set. One of the items MUST be the IRI 'AchievementSubject'.",
      "$comment": "Origin: IRI (DerivedType); A `NormalizedString` that represents an Internationalized Resource Identifier (IRI), which extends the ASCII characters subset of the Uniform Resource Identifier (URI).",
      "type": "array",
      "minItems": 1,
      "items": {
        "type": "string"
      }
    },
    "activityEndDate": {
      "description": "The datetime the activity ended.",
      "$comment": "Origin: DateTime (PrimitiveType); An [[ISO8601]] time using the syntax YYYY-MM-DDThh:mm:ss.",
      "type": "string",
      "format": "date-time"
    },
    "activityStartDate": {
      "description": "The datetime the activity started.",
      "$comment": "Origin: DateTime (PrimitiveType); An [[ISO8601]] time using the syntax YYYY-MM-DDThh:mm:ss.",
      "type": "string",
      "format": "date-time"
    },
    "creditsEarned": {
      "description": "The number of credits earned, generally in semester or quarter credit hours. This field correlates with the Achievement `creditsAvailable` field.",
      "$comment": "Origin: Float (PrimitiveType)",
      "type": "number"
    },
    "achievement": {
      "description": "The achievement being awarded.",
      "$comment": "Origin: Achievement (Unordered); A collection of information about the accomplishment recognized by the Assertion. Many assertions may be created corresponding to one Achievement.",
      "$ref": "#/$defs/Achievement"
    },
    "identifier": {
      "description": "Other identifiers for the recipient of the achievement. Either `id` or at least one `identifier` MUST be supplied.",
      "$comment": "Origin: IdentityObject (Unordered); A collection of information about the recipient of an achievement.",
      "type": "array",
      "items": {
        "$ref": "#/$defs/IdentityObject"
      }
    },
    "image": {
      "description": "An image representing this user's achievement. If present, this must be a PNG or SVG image, and should be prepared via the 'baking' instructions. An 'unbaked' image for the achievement is defined in the Achievement class and should not be duplicated here.",
      "$comment": "Origin: Image (Unordered); Metadata about images that represent assertions, achieve or profiles. These properties can typically be represented as just the id string of the image, but using a fleshed-out document allows for including captions and other applicable metadata.",
      "$ref": "#/$defs/Image"
    },
    "licenseNumber": {
      "description": "The license number that was issued with this credential.",
      "$comment": "Origin: String (PrimitiveType); Character strings.",
      "type": "string"
    },
    "narrative": {
      "description": "A narrative that connects multiple pieces of evidence. Likely only present at this location if evidence is a multi-value array.",
      "$comment": "Origin: Markdown (DerivedType); A `String` that may contain Markdown.",
      "type": "string"
    },
    "result": {
      "description": "The set of results being asserted.",
      "$comment": "Origin: Result (Unordered); Describes a result that was achieved.",
      "type": "array",
      "items": {
        "$ref": "#/$defs/Result"
      }
    },
    "role": {
      "description": "Role, position, or title of the learner when demonstrating or performing the achievement or evidence of learning being asserted. Examples include 'Student President', 'Intern', 'Captain', etc.",
      "$comment": "Origin: String (PrimitiveType); Character strings.",
      "type": "string"
    },
    "source": {
      "description": "The person, organization, or system that assessed the achievement on behalf of the issuer. For example, a school may assess the achievement, while the school district issues the credential.",
      "$comment": "Origin: Profile (Unordered); A Profile is a collection of information that describes the entity or organization using Open Badges. Issuers must be represented as Profiles, and recipients, endorsers, or other entities may also be represented using this vocabulary. Each Profile that represents an Issuer may be referenced in many BadgeClasses that it has defined. Anyone can create and host an Issuer file to start issuing Open Badges. Issuers may also serve as recipients of Open Badges, often identified within an Assertion by specific properties, like their url or contact email address.",
      "$ref": "#/$defs/Profile"
    },
    "term": {
      "description": "The academic term in which this assertion was achieved.",
      "$comment": "Origin: String (PrimitiveType); Character strings.",
      "type": "string"
    }
  },
  "required": [
    "type"
  ],
  "additionalProperties": false,
  "$defs": {
    "IdentityObject": {
      "description": "A collection of information about the recipient of an achievement.",
      "type": "object",
      "properties": {
        "type": {
          "description": "MUST be the IRI 'IdentityObject'.",
          "$comment": "Origin: IRI (DerivedType); A `NormalizedString` that represents an Internationalized Resource Identifier (IRI), which extends the ASCII characters subset of the Uniform Resource Identifier (URI).",
          "type": "string"
        },
        "hashed": {
          "description": "Whether or not the `identityHash` value is hashed.",
          "$comment": "Origin: Boolean (PrimitiveType)",
          "type": "boolean"
        },
        "identityHash": {
          "description": "Either the IdentityHash of the identity or the plaintext value. If it's possible that the plaintext transmission and storage of the identity value would leak personally identifiable information where there is an expectation of privacy, it is strongly recommended that an IdentityHash be used.",
          "$comment": "Origin: IdentityHash (DerivedType); A hash string containing an algorithm identifier and a resulting hash of an identifier, separated by a dollar sign ('$') and the algorithm used to generate the hash. The only supported algorithms are MD5 [[RFC1321]] and SHA-256 [[FIPS-180-4]], identified by the strings md5 and sha256 respectively. Resulting hash for each of these algorithms MUST be expressed in hexadecimal using uppercase (A-F, 0-9) or lowercase character (a-f, 0-9) sets. For example: sha256$7a1a1b3f7d40552e4299180e346e3add12bf9a751a43d9c4ca4518febc2c60c6 represents the result of calculating a SHA-256 hash on the string 'mayze'.",
          "type": "string"
        },
        "identityType": {
          "description": "The identity type.",
          "$comment": "Origin: IdentifierTypeEnum (EnumExt)",
          "anyOf": [
            {
              "type": "string",
              "enum": [
                "sourcedId",
                "systemId",
                "productId",
                "userName",
                "accountId",
                "emailAddress",
                "nationalIdentityNumber",
                "isbn",
                "issn",
                "lisSourcedId",
                "oneRosterSourcedId",
                "sisSourcedId",
                "ltiContextId",
                "ltiDeploymentId",
                "ltiToolId",
                "ltiPlatformId",
                "ltiUserId",
                "identifier"
              ]
            },
            {
              "type": "string",
              "pattern": "(ext:)[a-z|A-Z|0-9|.|-|_]+"
            }
          ]
        },
        "salt": {
          "description": "If the `identityHash` is hashed, this should contain the string used to salt the hash. If this value is not provided, it should be assumed that the hash was not salted.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        }
      },
      "required": [
        "type",
        "hashed",
        "identityHash",
        "identityType"
      ],
      "additionalProperties": false
    },
    "Achievement": {
      "description": "A collection of information about the accomplishment recognized by the Assertion. Many assertions may be created corresponding to one Achievement.",
      "type": "object",
      "properties": {
        "id": {
          "description": "Unique URI for the Achievement.",
          "$comment": "Origin: URI (DerivedType); A `NormalizedString` that respresents a Uniform Resource Identifier (URI).",
          "type": "string"
        },
        "type": {
          "description": "No description supplied.",
          "$comment": "Origin: IRI (DerivedType); A `NormalizedString` that represents an Internationalized Resource Identifier (IRI), which extends the ASCII characters subset of the Uniform Resource Identifier (URI).",
          "type": "array",
          "minItems": 1,
          "items": {
            "type": "string"
          }
        },
        "alignment": {
          "description": "An object describing which objectives or educational standards this achievement aligns to, if any.",
          "$comment": "Origin: Alignment (Unordered); Describes an alignment between an achievement and a node in an educational framework.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/Alignment"
          }
        },
        "achievementType": {
          "description": "The type of achievement. This is an extensible vocabulary.",
          "$comment": "Origin: AchievementType (EnumExt); The type of achievement, for example 'Award' or 'Certification'. This is an extensible enumerated vocabulary. Extending the vocabulary makes use of a naming convention.",
          "anyOf": [
            {
              "type": "string",
              "enum": [
                "Achievement",
                "ApprenticeshipCertificate",
                "Assessment",
                "Assignment",
                "AssociateDegree",
                "Award",
                "Badge",
                "BachelorDegree",
                "Certificate",
                "CertificateOfCompletion",
                "Certification",
                "CommunityService",
                "Competency",
                "Course",
                "CoCurricular",
                "Degree",
                "Diploma",
                "DoctoralDegree",
                "Fieldwork",
                "GeneralEducationDevelopment",
                "JourneymanCertificate",
                "LearningProgram",
                "License",
                "Membership",
                "ProfessionalDoctorate",
                "QualityAssuranceCredential",
                "MasterCertificate",
                "MasterDegree",
                "MicroCredential",
                "ResearchDoctorate",
                "SecondarySchoolDiploma"
              ]
            },
            {
              "type": "string",
              "pattern": "(ext:)[a-z|A-Z|0-9|.|-|_]+"
            }
          ]
        },
        "creator": {
          "description": "The person or organization that created the achievement definition.",
          "$comment": "Origin: Profile (Unordered); A Profile is a collection of information that describes the entity or organization using Open Badges. Issuers must be represented as Profiles, and recipients, endorsers, or other entities may also be represented using this vocabulary. Each Profile that represents an Issuer may be referenced in many BadgeClasses that it has defined. Anyone can create and host an Issuer file to start issuing Open Badges. Issuers may also serve as recipients of Open Badges, often identified within an Assertion by specific properties, like their url or contact email address.",
          "$ref": "#/$defs/Profile"
        },
        "creditsAvailable": {
          "description": "Credit hours associated with this entity, or credit hours possible. For example 3.0.",
          "$comment": "Origin: Float (PrimitiveType)",
          "type": "number"
        },
        "criteria": {
          "description": "Criteria describing how to earn the achievement.",
          "$comment": "Origin: Criteria (Unordered); Descriptive metadata about the achievements necessary to be recognized with an assertion of a particular achievement. This data is added to the Achievement class so that it may be rendered when the achievement assertion is displayed, instead of simply a link to human-readable criteria external to the achievement. Embedding criteria allows either enhancement of an external criteria page or increased portability and ease of use by allowing issuers to skip hosting the formerly-required external criteria page altogether. Criteria is used to allow would-be recipients to learn what is required of them to be recognized with an assertion of a particular achievement. It is also used after the assertion is awarded to a recipient to let those inspecting earned achievements know the general requirements that the recipients met in order to earn it.",
          "$ref": "#/$defs/Criteria"
        },
        "description": {
          "description": "A short description of the achievement.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "endorsement": {
          "description": "Allows endorsers to make specific claims about the Achievement. These endorsements are signed with a Data Integrity proof format.",
          "$comment": "Origin: EndorsementCredential (Unordered); A verifiable credential that asserts a claim about an entity.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/EndorsementCredential"
          }
        },
        "endorsementJwt": {
          "description": "Allows endorsers to make specific claims about the Achievement. These endorsements are signed with the VC-JWT proof format.",
          "$comment": "Origin: CompactJws (DerivedType); A `String` in Compact JWS format [[RFC7515]].",
          "type": "array",
          "items": {
            "type": "string",
            "pattern": "^[a-zA-Z0-9_-]+\\.[a-zA-Z0-9_-]*\\.[a-zA-Z0-9_-]+$"
          }
        },
        "fieldOfStudy": {
          "description": "Category, subject, area of study, discipline, or general branch of knowledge. Examples include Business, Education, Psychology, and Technology.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "humanCode": {
          "description": "The code, generally human readable, associated with an achievement.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "image": {
          "description": "An image representing the achievement.",
          "$comment": "Origin: Image (Unordered); Metadata about images that represent assertions, achieve or profiles. These properties can typically be represented as just the id string of the image, but using a fleshed-out document allows for including captions and other applicable metadata.",
          "$ref": "#/$defs/Image"
        },
        "@language": {
          "description": "The language of the achievement.",
          "$comment": "Origin: LanguageCode (DerivedType); A language code [[BCP47]].",
          "type": "string",
          "pattern": "^[a-z]{2,4}(-[A-Z][a-z]{3})?(-([A-Z]{2}|[0-9]{3}))?$"
        },
        "name": {
          "description": "The name of the achievement.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "otherIdentifier": {
          "description": "A list of identifiers for the described entity.",
          "$comment": "Origin: IdentifierEntry (Unordered)",
          "type": "array",
          "items": {
            "$ref": "#/$defs/IdentifierEntry"
          }
        },
        "related": {
          "description": "The related property identifies another Achievement that should be considered the same for most purposes. It is primarily intended to identify alternate language editions or previous versions of Achievements.",
          "$comment": "Origin: Related (Unordered); Identifies a related achievement.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/Related"
          }
        },
        "resultDescription": {
          "description": "The set of result descriptions that may be asserted as results with this achievement.",
          "$comment": "Origin: ResultDescription (Unordered); Describes a possible achievement result.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/ResultDescription"
          }
        },
        "specialization": {
          "description": "Name given to the focus, concentration, or specific area of study defined in the achievement. Examples include 'Entrepreneurship', 'Technical Communication', and 'Finance'.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "tag": {
          "description": "Tags that describes the type of achievement.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "version": {
          "description": "The version property allows issuers to set a version string for an Achievement. This is particularly useful when replacing a previous version with an update.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        }
      },
      "required": [
        "id",
        "type",
        "criteria",
        "description",
        "name"
      ],
      "additionalProperties": true
    },
    "Alignment": {
      "description": "Describes an alignment between an achievement and a node in an educational framework.",
      "type": "object",
      "properties": {
        "type": {
          "description": "The value of the type property MUST be an unordered set. One of the items MUST be the IRI 'Alignment'.",
          "$comment": "Origin: IRI (DerivedType); A `NormalizedString` that represents an Internationalized Resource Identifier (IRI), which extends the ASCII characters subset of the Uniform Resource Identifier (URI).",
          "type": "array",
          "minItems": 1,
          "items": {
            "type": "string"
          }
        },
        "targetCode": {
          "description": "If applicable, a locally unique string identifier that identifies the alignment target within its framework and/or targetUrl.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "targetDescription": {
          "description": "Short description of the alignment target.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "targetName": {
          "description": "Name of the alignment.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "targetFramework": {
          "description": "Name of the framework the alignment target.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "targetType": {
          "description": "The type of the alignment target node.",
          "$comment": "Origin: AlignmentTargetType (EnumExt); The type of the alignment target node in the target framework.",
          "anyOf": [
            {
              "type": "string",
              "enum": [
                "ceasn:Competency",
                "ceterms:Credential",
                "CFItem",
                "CFRubric",
                "CFRubricCriterion",
                "CFRubricCriterionLevel",
                "CTDL"
              ]
            },
            {
              "type": "string",
              "pattern": "(ext:)[a-z|A-Z|0-9|.|-|_]+"
            }
          ]
        },
        "targetUrl": {
          "description": "URL linking to the official description of the alignment target, for example an individual standard within an educational framework.",
          "$comment": "Origin: URL (DerivedType); A `URI` that represents a Uniform Resource Locator (URL).",
          "type": "string"
        }
      },
      "required": [
        "type",
        "targetName",
        "targetUrl"
      ],
      "additionalProperties": true
    },
    "Criteria": {
      "description": "Descriptive metadata about the achievements necessary to be recognized with an assertion of a particular achievement. This data is added to the Achievement class so that it may be rendered when the achievement assertion is displayed, instead of simply a link to human-readable criteria external to the achievement. Embedding criteria allows either enhancement of an external criteria page or increased portability and ease of use by allowing issuers to skip hosting the formerly-required external criteria page altogether. Criteria is used to allow would-be recipients to learn what is required of them to be recognized with an assertion of a particular achievement. It is also used after the assertion is awarded to a recipient to let those inspecting earned achievements know the general requirements that the recipients met in order to earn it.",
      "type": "object",
      "properties": {
        "id": {
          "description": "The URI of a webpage that describes in a human-readable format the criteria for the achievement.",
          "$comment": "Origin: URI (DerivedType); A `NormalizedString` that respresents a Uniform Resource Identifier (URI).",
          "type": "string"
        },
        "narrative": {
          "description": "A narrative of what is needed to earn the achievement. Markdown is allowed.",
          "$comment": "Origin: Markdown (DerivedType); A `String` that may contain Markdown.",
          "type": "string"
        }
      },
      "required": [],
      "additionalProperties": true
    },
    "EndorsementCredential": {
      "description": "A verifiable credential that asserts a claim about an entity.",
      "type": "object",
      "properties": {
        "@context": {
          "description": "The value of the `@context` property MUST be an ordered set where the first item is a URI with the value 'https://www.w3.org/2018/credentials/v1', and the second item is a URI with the value 'https://purl.imsglobal.org/spec/ob/v3p0/context/ob_v3p0.jsonld'.",
          "$comment": "Origin: URI (DerivedType); A `NormalizedString` that respresents a Uniform Resource Identifier (URI).",
          "type": "array",
          "minItems": 1,
          "items": {
            "type": "string"
          }
        },
        "type": {
          "description": "The value of the type property MUST be an unordered set. One of the items MUST be the URI 'VerifiableCredential', and one of the items MUST be the URI 'EndorsementCredential'.",
          "$comment": "Origin: IRI (DerivedType); A `NormalizedString` that represents an Internationalized Resource Identifier (IRI), which extends the ASCII characters subset of the Uniform Resource Identifier (URI).",
          "type": "array",
          "minItems": 1,
          "items": {
            "type": "string"
          }
        },
        "credentialSubject": {
          "description": "The individual, entity, organization, assertion, or achievement that is endorsed and the endorsement comment.",
          "$comment": "Origin: EndorsementSubject (Unordered); A collection of information about the subject of the endorsement.",
          "$ref": "#/$defs/EndorsementSubject"
        },
        "id": {
          "description": "Unambiguous reference to the credential.",
          "$comment": "Origin: URI (DerivedType); A `NormalizedString` that respresents a Uniform Resource Identifier (URI).",
          "type": "string"
        },
        "issuer": {
          "description": "A description of the individual, entity, or organization that issued the credential.",
          "$comment": "Origin: Profile (Unordered); A Profile is a collection of information that describes the entity or organization using Open Badges. Issuers must be represented as Profiles, and recipients, endorsers, or other entities may also be represented using this vocabulary. Each Profile that represents an Issuer may be referenced in many BadgeClasses that it has defined. Anyone can create and host an Issuer file to start issuing Open Badges. Issuers may also serve as recipients of Open Badges, often identified within an Assertion by specific properties, like their url or contact email address.",
          "$ref": "#/$defs/Profile"
        },
        "issuanceDate": {
          "description": "Timestamp of when the credential was awarded.",
          "$comment": "Origin: DateTime (PrimitiveType); An [[ISO8601]] time using the syntax YYYY-MM-DDThh:mm:ss.",
          "type": "string",
          "format": "date-time"
        },
        "expirationDate": {
          "description": "If the credential has some notion of expiry, this indicates a timestamp when a credential should no longer be considered valid. After this time, the credential should be considered expired.",
          "$comment": "Origin: DateTime (PrimitiveType); An [[ISO8601]] time using the syntax YYYY-MM-DDThh:mm:ss.",
          "type": "string",
          "format": "date-time"
        },
        "proof": {
          "description": "If present, one or more embedded cryptographic proofs that can be used to detect tampering and verify the authorship of the credential.",
          "$comment": "Origin: Proof (Unordered); A JSON-LD Linked Data proof.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/Proof"
          }
        },
        "credentialSchema": {
          "description": "The value of the `credentialSchema` property MUST be one or more data schemas that provide verifiers with enough information to determine if the provided data conforms to the provided schema.",
          "$comment": "Origin: CredentialSchema (Unordered); Identify the type and location of a data schema.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/CredentialSchema"
          }
        },
        "credentialStatus": {
          "description": "The information in CredentialStatus is used to discover information about the current status of a verifiable credential, such as whether it is suspended or revoked.",
          "$comment": "Origin: CredentialStatus (Unordered); The information in CredentialStatus is used to discover information about the current status of a verifiable credential, such as whether it is suspended or revoked.",
          "$ref": "#/$defs/CredentialStatus"
        },
        "refreshService": {
          "description": "The information in RefreshService is used to refresh the verifiable credential.",
          "$comment": "Origin: RefreshService (Unordered); The information in RefreshService is used to refresh the verifiable credential.",
          "$ref": "#/$defs/RefreshService"
        }
      },
      "required": [
        "@context",
        "type",
        "credentialSubject",
        "issuer",
        "issuanceDate"
      ],
      "additionalProperties": false
    },
    "CredentialStatus": {
      "description": "The information in CredentialStatus is used to discover information about the current status of a verifiable credential, such as whether it is suspended or revoked.",
      "type": "object",
      "properties": {
        "id": {
          "description": "The value MUST be the URL of the issuer's credential status method.",
          "$comment": "Origin: URI (DerivedType); A `NormalizedString` that respresents a Uniform Resource Identifier (URI).",
          "type": "string"
        },
        "type": {
          "description": "The name of the credential status method.",
          "$comment": "Origin: IRI (DerivedType); A `NormalizedString` that represents an Internationalized Resource Identifier (IRI), which extends the ASCII characters subset of the Uniform Resource Identifier (URI).",
          "type": "string"
        }
      },
      "required": [
        "id",
        "type"
      ],
      "additionalProperties": false
    },
    "IdentifierEntry": {
      "description": "No description supplied.",
      "type": "object",
      "properties": {
        "type": {
          "description": "The value of the type property MUST be an unordered set. One of the items MUST be the IRI 'IdentifierEntry'.",
          "$comment": "Origin: IRI (DerivedType); A `NormalizedString` that represents an Internationalized Resource Identifier (IRI), which extends the ASCII characters subset of the Uniform Resource Identifier (URI).",
          "type": "string"
        },
        "identifier": {
          "description": "An identifier.",
          "$comment": "Origin: Identifier (DerivedType); A `NormalizedString` that functions as an identifier.",
          "type": "string"
        },
        "identifierType": {
          "description": "The identifier type.",
          "$comment": "Origin: IdentifierTypeEnum (EnumExt)",
          "anyOf": [
            {
              "type": "string",
              "enum": [
                "sourcedId",
                "systemId",
                "productId",
                "userName",
                "accountId",
                "emailAddress",
                "nationalIdentityNumber",
                "isbn",
                "issn",
                "lisSourcedId",
                "oneRosterSourcedId",
                "sisSourcedId",
                "ltiContextId",
                "ltiDeploymentId",
                "ltiToolId",
                "ltiPlatformId",
                "ltiUserId",
                "identifier"
              ]
            },
            {
              "type": "string",
              "pattern": "(ext:)[a-z|A-Z|0-9|.|-|_]+"
            }
          ]
        }
      },
      "required": [
        "type",
        "identifier",
        "identifierType"
      ],
      "additionalProperties": false
    },
    "Proof": {
      "description": "A JSON-LD Linked Data proof.",
      "type": "object",
      "properties": {
        "type": {
          "description": "Signature suite used to produce proof.",
          "$comment": "Origin: IRI (DerivedType); A `NormalizedString` that represents an Internationalized Resource Identifier (IRI), which extends the ASCII characters subset of the Uniform Resource Identifier (URI).",
          "type": "string"
        },
        "created": {
          "description": "Date the proof was created.",
          "$comment": "Origin: DateTime (PrimitiveType); An [[ISO8601]] time using the syntax YYYY-MM-DDThh:mm:ss.",
          "type": "string",
          "format": "date-time"
        },
        "challenge": {
          "description": "A value chosen by the verifier to mitigate authentication proof replay attacks.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "domain": {
          "description": "The domain of the proof to restrict its use to a particular target.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "nonce": {
          "description": "A value chosen by the creator of proof to randomize proof values for privacy purposes.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "proofPurpose": {
          "description": "The purpose of the proof to be used with `verificationMethod`. MUST be 'assertionMethod'.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "proofValue": {
          "description": "Value of the proof.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "verificationMethod": {
          "description": "The URL of the public key that can verify the signature.",
          "$comment": "Origin: URI (DerivedType); A `NormalizedString` that respresents a Uniform Resource Identifier (URI).",
          "type": "string"
        }
      },
      "required": [
        "type",
        "created",
        "proofPurpose",
        "proofValue",
        "verificationMethod"
      ],
      "additionalProperties": true
    },
    "RefreshService": {
      "description": "The information in RefreshService is used to refresh the verifiable credential.",
      "type": "object",
      "properties": {
        "id": {
          "description": "The value MUST be the URL of the issuer's refresh service.",
          "$comment": "Origin: URI (DerivedType); A `NormalizedString` that respresents a Uniform Resource Identifier (URI).",
          "type": "string"
        },
        "type": {
          "description": "The name of the refresh service method.",
          "$comment": "Origin: IRI (DerivedType); A `NormalizedString` that represents an Internationalized Resource Identifier (IRI), which extends the ASCII characters subset of the Uniform Resource Identifier (URI).",
          "type": "string"
        }
      },
      "required": [
        "id",
        "type"
      ],
      "additionalProperties": true
    },
    "Image": {
      "description": "Metadata about images that represent assertions, achieve or profiles. These properties can typically be represented as just the id string of the image, but using a fleshed-out document allows for including captions and other applicable metadata.",
      "type": "object",
      "properties": {
        "id": {
          "description": "The URI or Data URI of the image.",
          "$comment": "Origin: URI (DerivedType); A `NormalizedString` that respresents a Uniform Resource Identifier (URI).",
          "type": "string"
        },
        "type": {
          "description": "MUST be the IRI 'Image'.",
          "$comment": "Origin: IRI (DerivedType); A `NormalizedString` that represents an Internationalized Resource Identifier (IRI), which extends the ASCII characters subset of the Uniform Resource Identifier (URI).",
          "type": "string"
        },
        "caption": {
          "description": "The caption for the image.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        }
      },
      "required": [
        "id",
        "type"
      ],
      "additionalProperties": false
    },
    "ResultDescription": {
      "description": "Describes a possible achievement result.",
      "type": "object",
      "properties": {
        "id": {
          "description": "The unique URI for this result description. Required so a result can link to this result description.",
          "$comment": "Origin: URI (DerivedType); A `NormalizedString` that respresents a Uniform Resource Identifier (URI).",
          "type": "string"
        },
        "type": {
          "description": "The value of the type property MUST be an unordered set. One of the items MUST be the IRI 'ResultDescription'.",
          "$comment": "Origin: IRI (DerivedType); A `NormalizedString` that represents an Internationalized Resource Identifier (IRI), which extends the ASCII characters subset of the Uniform Resource Identifier (URI).",
          "type": "array",
          "minItems": 1,
          "items": {
            "type": "string"
          }
        },
        "alignment": {
          "description": "Alignments between this result description and nodes in external frameworks.",
          "$comment": "Origin: Alignment (Unordered); Describes an alignment between an achievement and a node in an educational framework.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/Alignment"
          }
        },
        "allowedValue": {
          "description": "An ordered list of allowed values. The values should be ordered from low to high as determined by the achievement creator.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "name": {
          "description": "The name of the result.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "requiredLevel": {
          "description": "The `id` of the rubric criterion level required to pass as determined by the achievement creator.",
          "$comment": "Origin: URI (DerivedType); A `NormalizedString` that respresents a Uniform Resource Identifier (URI).",
          "type": "string"
        },
        "requiredValue": {
          "description": "A value from `allowedValue` or within the range of `valueMin` to `valueMax` required to pass as determined by the achievement creator.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "resultType": {
          "description": "The type of result this description represents. This is an extensible enumerated vocabulary.",
          "$comment": "Origin: ResultType (EnumExt); The type of result. This is an extensible enumerated vocabulary. Extending the vocabulary makes use of a naming convention.",
          "anyOf": [
            {
              "type": "string",
              "enum": [
                "GradePointAverage",
                "LetterGrade",
                "Percent",
                "PerformanceLevel",
                "PredictedScore",
                "RawScore",
                "Result",
                "RubricCriterion",
                "RubricCriterionLevel",
                "RubricScore",
                "ScaledScore",
                "Status"
              ]
            },
            {
              "type": "string",
              "pattern": "(ext:)[a-z|A-Z|0-9|.|-|_]+"
            }
          ]
        },
        "rubricCriterionLevel": {
          "description": "An ordered array of rubric criterion levels that may be asserted in the linked result. The levels should be ordered from low to high as determined by the achievement creator.",
          "$comment": "Origin: RubricCriterionLevel (Unordered); Describes a rubric criterion level.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/RubricCriterionLevel"
          }
        },
        "valueMax": {
          "description": "The maximum possible `value` that may be asserted in a linked result.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "valueMin": {
          "description": "The minimum possible `value` that may be asserted in a linked result.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        }
      },
      "required": [
        "id",
        "type",
        "name",
        "resultType"
      ],
      "additionalProperties": true
    },
    "RubricCriterionLevel": {
      "description": "Describes a rubric criterion level.",
      "type": "object",
      "properties": {
        "id": {
          "description": "The unique URI for this rubric criterion level. Required so a result can link to this rubric criterion level.",
          "$comment": "Origin: URI (DerivedType); A `NormalizedString` that respresents a Uniform Resource Identifier (URI).",
          "type": "string"
        },
        "type": {
          "description": "The value of the type property MUST be an unordered set. One of the items MUST be the IRI 'RubricCriterionLevel'.",
          "$comment": "Origin: IRI (DerivedType); A `NormalizedString` that represents an Internationalized Resource Identifier (IRI), which extends the ASCII characters subset of the Uniform Resource Identifier (URI).",
          "type": "array",
          "minItems": 1,
          "items": {
            "type": "string"
          }
        },
        "alignment": {
          "description": "Alignments between this rubric criterion level and a rubric criterion levels defined in external frameworks.",
          "$comment": "Origin: Alignment (Unordered); Describes an alignment between an achievement and a node in an educational framework.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/Alignment"
          }
        },
        "description": {
          "description": "Description of the rubric criterion level.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "level": {
          "description": "The rubric performance level in terms of success.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "name": {
          "description": "The name of the rubric criterion level.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "points": {
          "description": "The points associated with this rubric criterion level.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        }
      },
      "required": [
        "id",
        "type",
        "name"
      ],
      "additionalProperties": true
    },
    "EndorsementSubject": {
      "description": "A collection of information about the subject of the endorsement.",
      "type": "object",
      "properties": {
        "id": {
          "description": "The identifier of the individual, entity, organization, assertion, or achievement that is endorsed.",
          "$comment": "Origin: URI (DerivedType); A `NormalizedString` that respresents a Uniform Resource Identifier (URI).",
          "type": "string"
        },
        "type": {
          "description": "The value of the type property MUST be an unordered set. One of the items MUST be the URI 'VerifiableCredential', and one of the items MUST be the URI 'EndorsementSubject'.",
          "$comment": "Origin: IRI (DerivedType); A `NormalizedString` that represents an Internationalized Resource Identifier (IRI), which extends the ASCII characters subset of the Uniform Resource Identifier (URI).",
          "type": "array",
          "minItems": 1,
          "items": {
            "type": "string"
          }
        },
        "endorsementComment": {
          "description": "Allows endorsers to make a simple claim in writing about the entity.",
          "$comment": "Origin: Markdown (DerivedType); A `String` that may contain Markdown.",
          "type": "string"
        }
      },
      "required": [
        "id",
        "type"
      ],
      "additionalProperties": false
    },
    "Related": {
      "description": "Identifies a related achievement.",
      "type": "object",
      "properties": {
        "id": {
          "description": "The related achievement.",
          "$comment": "Origin: URI (DerivedType); A `NormalizedString` that respresents a Uniform Resource Identifier (URI).",
          "type": "string"
        },
        "@language": {
          "description": "The language of the related achievement.",
          "$comment": "Origin: LanguageCode (DerivedType); A language code [[BCP47]].",
          "type": "string",
          "pattern": "^[a-z]{2,4}(-[A-Z][a-z]{3})?(-([A-Z]{2}|[0-9]{3}))?$"
        },
        "version": {
          "description": "The version of the related achievement.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        }
      },
      "required": [
        "id"
      ],
      "additionalProperties": false
    },
    "Profile": {
      "description": "A Profile is a collection of information that describes the entity or organization using Open Badges. Issuers must be represented as Profiles, and recipients, endorsers, or other entities may also be represented using this vocabulary. Each Profile that represents an Issuer may be referenced in many BadgeClasses that it has defined. Anyone can create and host an Issuer file to start issuing Open Badges. Issuers may also serve as recipients of Open Badges, often identified within an Assertion by specific properties, like their url or contact email address.",
      "type": "object",
      "properties": {
        "id": {
          "description": "Unique URI for the Issuer/Profile file.",
          "$comment": "Origin: URI (DerivedType); A `NormalizedString` that respresents a Uniform Resource Identifier (URI).",
          "type": "string"
        },
        "type": {
          "description": "The value of the type property MUST be an unordered set. One of the items MUST be the IRI 'Profile'.",
          "$comment": "Origin: IRI (DerivedType); A `NormalizedString` that represents an Internationalized Resource Identifier (IRI), which extends the ASCII characters subset of the Uniform Resource Identifier (URI).",
          "type": "array",
          "minItems": 1,
          "items": {
            "type": "string"
          }
        },
        "name": {
          "description": "The name of the entity or organization.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "url": {
          "description": "The homepage or social media profile of the entity, whether individual or institutional. Should be a URL/URI Accessible via HTTP.",
          "$comment": "Origin: URI (DerivedType); A `NormalizedString` that respresents a Uniform Resource Identifier (URI).",
          "type": "string"
        },
        "phone": {
          "description": "A phone number.",
          "$comment": "Origin: PhoneNumber (DerivedType); A `NormalizedString` representing a phone number.",
          "type": "string"
        },
        "description": {
          "description": "A short description of the issuer entity or organization.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "endorsement": {
          "description": "Allows endorsers to make specific claims about the individual or organization represented by this profile. These endorsements are signed with a Data Integrity proof format.",
          "$comment": "Origin: EndorsementCredential (Unordered); A verifiable credential that asserts a claim about an entity.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/EndorsementCredential"
          }
        },
        "endorsementJwt": {
          "description": "Allows endorsers to make specific claims about the individual or organization represented by this profile. These endorsements are signed with the VC-JWT proof format.",
          "$comment": "Origin: CompactJws (DerivedType); A `String` in Compact JWS format [[RFC7515]].",
          "type": "array",
          "items": {
            "type": "string",
            "pattern": "^[a-zA-Z0-9_-]+\\.[a-zA-Z0-9_-]*\\.[a-zA-Z0-9_-]+$"
          }
        },
        "image": {
          "description": "An image representing the issuer. This must be a PNG or SVG image.",
          "$comment": "Origin: Image (Unordered); Metadata about images that represent assertions, achieve or profiles. These properties can typically be represented as just the id string of the image, but using a fleshed-out document allows for including captions and other applicable metadata.",
          "$ref": "#/$defs/Image"
        },
        "email": {
          "description": "An email address.",
          "$comment": "Origin: EmailAddress (DerivedType); A `NormalizedString` representing an email address.",
          "type": "string"
        },
        "address": {
          "description": "An address for the individual or organization.",
          "$comment": "Origin: Address (Unordered)",
          "$ref": "#/$defs/Address"
        },
        "otherIdentifier": {
          "description": "A list of identifiers for the described entity.",
          "$comment": "Origin: IdentifierEntry (Unordered)",
          "type": "array",
          "items": {
            "$ref": "#/$defs/IdentifierEntry"
          }
        },
        "official": {
          "description": "If the entity is an organization, `official` is the name of an authorized official of the organization.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "parentOrg": {
          "description": "The parent organization of the entity.",
          "$comment": "Origin: Profile (Unordered); A Profile is a collection of information that describes the entity or organization using Open Badges. Issuers must be represented as Profiles, and recipients, endorsers, or other entities may also be represented using this vocabulary. Each Profile that represents an Issuer may be referenced in many BadgeClasses that it has defined. Anyone can create and host an Issuer file to start issuing Open Badges. Issuers may also serve as recipients of Open Badges, often identified within an Assertion by specific properties, like their url or contact email address.",
          "$ref": "#/$defs/Profile"
        },
        "familyName": {
          "description": "Family name. In the western world, often referred to as the 'last name' of a person.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "givenName": {
          "description": "Given name. In the western world, often referred to as the 'first name' of a person.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "additionalName": {
          "description": "Additional name. Includes what is often referred to as 'middle name' in the western world.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "patronymicName": {
          "description": "Patronymic name.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "honorificPrefix": {
          "description": "Honorific prefix(es) preceding a person's name (e.g. 'Dr', 'Mrs' or 'Mr').",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "honorificSuffix": {
          "description": "Honorific suffix(es) following a person's name (e.g. 'M.D, PhD').",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "familyNamePrefix": {
          "description": "Family name prefix. As used in some locales, this is the leading part of a family name (e.g. 'de' in the name 'de Boer').",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "dateOfBirth": {
          "description": "No description supplied.",
          "$comment": "Origin: Date (PrimitiveType); An [[ISO8601]] calendar date using the syntax YYYY-MM-DD.",
          "type": "string",
          "format": "date"
        }
      },
      "required": [
        "id",
        "type"
      ],
      "additionalProperties": true
    },
    "Address": {
      "description": "No description supplied.",
      "type": "object",
      "properties": {
        "type": {
          "description": "The value of the type property MUST be an unordered set. One of the items MUST be the IRI 'Address'.",
          "$comment": "Origin: IRI (DerivedType); A `NormalizedString` that represents an Internationalized Resource Identifier (IRI), which extends the ASCII characters subset of the Uniform Resource Identifier (URI).",
          "type": "array",
          "minItems": 1,
          "items": {
            "type": "string"
          }
        },
        "addressCountry": {
          "description": "A country.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "addressCountryCode": {
          "description": "A country code. The value must be a ISO 3166-1 alpha-2 country code [[ISO3166-1]].",
          "$comment": "Origin: CountryCode (DerivedType); A two-digit ISO 3166-1 alpha-2 country code [[ISO3166-1]].",
          "type": "string"
        },
        "addressRegion": {
          "description": "A region within the country.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "addressLocality": {
          "description": "A locality within the region.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "streetAddress": {
          "description": "A street address within the locality.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "postOfficeBoxNumber": {
          "description": "A post office box number for PO box addresses.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "postalCode": {
          "description": "A postal code.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        },
        "geo": {
          "description": "The geographic coordinates of the location.",
          "$comment": "Origin: GeoCoordinates (Unordered); The geographic coordinates of a location.",
          "$ref": "#/$defs/GeoCoordinates"
        }
      },
      "required": [
        "type"
      ],
      "additionalProperties": false
    },
    "GeoCoordinates": {
      "description": "The geographic coordinates of a location.",
      "type": "object",
      "properties": {
        "type": {
          "description": "The value of the type property MUST be an unordered set. One of the items MUST be the IRI 'GeoCoordinates'.",
          "$comment": "Origin: IRI (DerivedType); A `NormalizedString` that represents an Internationalized Resource Identifier (IRI), which extends the ASCII characters subset of the Uniform Resource Identifier (URI).",
          "type": "string"
        },
        "latitude": {
          "description": "The latitude of the location [[WGS84]].",
          "$comment": "Origin: Float (PrimitiveType)",
          "type": "number"
        },
        "longitude": {
          "description": "The longitude of the location [[WGS84]].",
          "$comment": "Origin: Float (PrimitiveType)",
          "type": "number"
        }
      },
      "required": [
        "type",
        "latitude",
        "longitude"
      ],
      "additionalProperties": false
    },
    "Result": {
      "description": "Describes a result that was achieved.",
      "type": "object",
      "properties": {
        "type": {
          "description": "The value of the type property MUST be an unordered set. One of the items MUST be the IRI 'Result'.",
          "$comment": "Origin: IRI (DerivedType); A `NormalizedString` that represents an Internationalized Resource Identifier (IRI), which extends the ASCII characters subset of the Uniform Resource Identifier (URI).",
          "type": "array",
          "minItems": 1,
          "items": {
            "type": "string"
          }
        },
        "achievedLevel": {
          "description": "If the result represents an achieved rubric criterion level (e.g. Mastered), the value is the `id` of the RubricCriterionLevel in linked ResultDescription.",
          "$comment": "Origin: URI (DerivedType); A `NormalizedString` that respresents a Uniform Resource Identifier (URI).",
          "type": "string"
        },
        "alignment": {
          "description": "The alignments between this result and nodes in external frameworks. This set of alignments are in addition to the set of alignments defined in the corresponding ResultDescription object.",
          "$comment": "Origin: Alignment (Unordered); Describes an alignment between an achievement and a node in an educational framework.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/Alignment"
          }
        },
        "resultDescription": {
          "description": "An achievement can have many result descriptions describing possible results. The value of `resultDescription` is the `id` of the result description linked to this result. The linked result description must be in the achievement that is being asserted.",
          "$comment": "Origin: URI (DerivedType); A `NormalizedString` that respresents a Uniform Resource Identifier (URI).",
          "type": "string"
        },
        "status": {
          "description": "The status of the achievement. Required if `resultType` of the linked ResultDescription is Status.",
          "$comment": "Origin: ResultStatusType (Enumeration); Defined vocabulary to convey the status of an achievement.",
          "type": "string",
          "enum": [
            "Completed",
            "Enrolled",
            "Failed",
            "InProgress",
            "OnHold",
            "Withdrew"
          ]
        },
        "value": {
          "description": "A string representing the result of the performance, or demonstration, of the achievement. For example, 'A' if the recipient received an A grade in class.",
          "$comment": "Origin: String (PrimitiveType); Character strings.",
          "type": "string"
        }
      },
      "required": [
        "type"
      ],
      "additionalProperties": true
    },
    "CredentialSchema": {
      "description": "Identify the type and location of a data schema.",
      "type": "object",
      "properties": {
        "id": {
          "description": "The value MUST be a URI identifying the schema file. One instance of `CredentialSchema` MUST have an `id` that is the URL of the JSON Schema for this credential defined by this specification.",
          "$comment": "Origin: URI (DerivedType); A `NormalizedString` that respresents a Uniform Resource Identifier (URI).",
          "type": "string"
        },
        "type": {
          "description": "The value MUST identify the type of data schema validation. One instance of `CredentialSchema` MUST have a `type` of 'JsonSchemaValidator2019'.",
          "$comment": "Origin: IRI (DerivedType); A `NormalizedString` that represents an Internationalized Resource Identifier (IRI), which extends the ASCII characters subset of the Uniform Resource Identifier (URI).",
          "type": "string"
        }
      },
      "required": [
        "id",
        "type"
      ],
      "additionalProperties": false
    }
  }
}
E.2.1.4 Address

{
  "$schema": "https://json-schema.org/draft/2019-09/schema#",
  "$id": "https://example.org/404/ob/addressv3p0.schema.json",
  "$comment": "This is a dynamically generated schema made available only for testing purposes; it does not have normative status and must not be persisted or served to the public.",
  "title": "JSON Schema for the Address class.",
  "description": "No description supplied.",
  "type": "object",
  "properties": {
    "type": {
      "description": "The value of the type property MUST be an unordered set. One of the items MUST be the IRI 'Address'.",
      "$comment": "Origin: IRI (DerivedType); A `NormalizedString` that represents an Internationalized Resource Identifier (IRI), which extends the ASCII characters subset of the Uniform Resource Identifier (URI).",
      "type": "array",
      "minItems": 1,
      "items": {
        "type": "string"
      }
    },
    "addressCountry": {
      "description": "A country.",
      "$comment": "Origin: String (PrimitiveType); Character strings.",
      "type": "string"
    },
    "addressCountryCode": {
      "description": "A country code. The value must be a ISO 3166-1 alpha-2 country code [[ISO3166-1]].",
      "$comment": "Origin: CountryCode (DerivedType); A two-digit ISO 3166-1 alpha-2 country code [[ISO3166-1]].",
      "type": "string"
    },
    "addressRegion": {
      "description": "A region within the country.",
      "$comment": "Origin: String (PrimitiveType); Character strings.",
      "type": "string"
    },
    "addressLocality": {
      "description": "A locality within the region.",
      "$comment": "Origin: String (PrimitiveType); Character strings.",
      "type": "string"
    },
    "streetAddress": {
      "description": "A street address within the locality.",
      "$comment": "Origin: String (PrimitiveType); Character strings.",
      "type": "string"
    },
    "postOfficeBoxNumber": {
      "description": "A post office box number for PO box addresses.",
      "$comment": "Origin: String (PrimitiveType); Character strings.",
      "type": "string"
    },
    "postalCode": {
      "description": "A postal code.",
      "$comment": "Origin: String (PrimitiveType); Character strings.",
      "type": "string"
    },
    "geo": {
      "description": "The geographic coordinates of the location.",
      "$comment": "Origin: GeoCoordinates (Unordered); The geographic coordinates of a location.",
      "$ref": "#/$defs/GeoCoordinates"
    }
  },
  "required": [
    "type"
  ],
  "additionalProperties": false,
  "$defs": {
    "GeoCoordinates": {
      "description": "The geographic coordinates of a location.",
      "type": "object",
      "properties": {
        "type": {
          "description": "The value of the type property MUST be an unordered set. One of the items MUST be the IRI 'GeoCoordinates'.",
          "$comment": "Origin: IRI (DerivedType); A `NormalizedString` that represents an Internationalized Resource Identifier (IRI), which extends the ASCII characters subset of the Uniform Resource Identifier (URI).",
          "type": "string"
        },
        "latitude": {
          "description": "The latitude of the location [[WGS84]].",
          "$comment": "Origin: Float (PrimitiveType)",
          "type": "number"
        },
        "longitude": {
          "description": "The longitude of the location [[WGS84]].",
          "$comment": "Origin: Float (PrimitiveType)",
          "type": "number"
        }
      },
      "required": [
        "type",
        "latitude",
        "longitude"
      ],
      "additionalProperties": false
    }
  }
}
E.2.1.5 Alignment

Describes an alignment between an achievement and a node in an educational framework.

{
  "$schema": "https://json-schema.org/draft/2019-09/schema#",
  "$id": "https://example.org/404/ob/alignmentv3p0.schema.json",
  "$comment": "This is a dynamically generated schema made available only for testing purposes; it does not have normative status and must not be persisted or served to the public.",
  "title": "JSON Schema for the Alignment class.",
  "description": "Describes an alignment between an achievement and a node in an educational framework.",
  "type": "object",
  "properties": {
    "type": {
      "description": "The value of the type property MUST be an unordered set. One of the items MUST be the IRI 'Alignment'.",
      "$comment": "Origin: IRI (DerivedType); A `NormalizedString` that represents an Internationalized Resource Identifier (IRI), which extends the ASCII characters subset of the Uniform Resource Identifier (URI).",
      "type": "array",
      "minItems": 1,
      "items": {
        "type": "string"
      }
    },
    "targetCode": {
      "description": "If applicable, a locally unique string identifier that identifies the alignment target within its framework and/or targetUrl.",
      "$comment": "Origin: String (PrimitiveType); Character strings.",
      "type": "string"
    },
    "targetDescription": {
      "description": "Short description of the alignment target.",
      "$comment": "Origin: String (PrimitiveType); Character strings.",
      "type": "string"
    },
    "targetName": {
      "description": "Name of the alignment.",
      "$comment": "Origin: String (PrimitiveType); Character strings.",
      "type": "string"
    },
    "targetFramework": {
      "description": "Name of the framework the alignment target.",
      "$comment": "Origin: String (PrimitiveType); Character strings.",
      "type": "string"
    },
    "targetType": {
      "description": "The type of the alignment target node.",
      "$comment": "Origin: AlignmentTargetType (EnumExt); The type of the alignment target node in the target framework.",
      "anyOf": [
        {
          "type": "string",
          "enum": [
            "ceasn:Competency",
            "ceterms:Credential",
            "CFItem",
            "CFRubric",
            "CFRubricCriterion",
            "CFRubricCriterionLevel",
            "CTDL"
          ]
        },
        {
          "type": "string",
          "pattern": "(ext:)[a-z|A-Z|0-9|.|-|_]+"
        }
      ]
    },
    "targetUrl": {
      "description": "URL linking to the official description of the alignment target, for example an individual standard within an educational framework.",
      "$comment": "Origin: URL (DerivedType); A `URI` that represents a Uniform Resource Locator (URL).",
      "type": "string"
    }
  },
  "required": [
    "type",
    "targetName",
    "targetUrl"
  ],
  "additionalProperties": true
}
E.2.1.6 Criteria

Descriptive metadata about the achievements necessary to be recognized with an assertion of a particular achievement. This data is added to the Achievement class so that it may be rendered when the achievement assertion is displayed, instead of simply a link to human-readable criteria external to the achievement. Embedding criteria allows either enhancement of an external criteria page or increased portability and ease of use by allowing issuers to skip hosting the formerly-required external criteria page altogether. Criteria is used to allow would-be recipients to learn what is required of them to be recognized with an assertion of a particular achievement. It is also used after the assertion is awarded to a recipient to let those inspecting earned achievements know the general requirements that the recipients met in order to earn it.

{
  "$schema": "https://json-schema.org/draft/2019-09/schema#",
  "$id": "https://example.org/404/ob/criteriav3p0.schema.json",
  "$comment": "This is a dynamically generated schema made available only for testing purposes; it does not have normative status and must not be persisted or served to the public.",
  "title": "JSON Schema for the Criteria class.",
  "description": "Descriptive metadata about the achievements necessary to be recognized with an assertion of a particular achievement. This data is added to the Achievement class so that it may be rendered when the achievement assertion is displayed, instead of simply a link to human-readable criteria external to the achievement. Embedding criteria allows either enhancement of an external criteria page or increased portability and ease of use by allowing issuers to skip hosting the formerly-required external criteria page altogether. Criteria is used to allow would-be recipients to learn what is required of them to be recognized with an assertion of a particular achievement. It is also used after the assertion is awarded to a recipient to let those inspecting earned achievements know the general requirements that the recipients met in order to earn it.",
  "type": "object",
  "properties": {
    "id": {
      "description": "The URI of a webpage that describes in a human-readable format the criteria for the achievement.",
      "$comment": "Origin: URI (DerivedType); A `NormalizedString` that respresents a Uniform Resource Identifier (URI).",
      "type": "string"
    },
    "narrative": {
      "description": "A narrative of what is needed to earn the achievement. Markdown is allowed.",
      "$comment": "Origin: Markdown (DerivedType); A `String` that may contain Markdown.",
      "type": "string"
    }
  },
  "required": [],
  "additionalProperties": true
}
E.2.1.7 EndorsementCredential

A verifiable credential that asserts a claim about an entity.

{
  "$schema": "https://json-schema.org/draft/2019-09/schema#",
  "$id": "https://example.org/404/ob/endorsementcredentialv3p0.schema.json",
  "$comment": "This is a dynamically generated schema made available only for testing purposes; it does not have normative status and must not be persisted or served to the public.",
  "title": "JSON Schema for the EndorsementCredential class.",
  "description": "A verifiable credential that asserts a claim about an entity.",
  "type": "object",
  "properties": {
    "@context": {
      "description": "The value of the `@context` property MUST be an ordered set where the first item is a URI with the value 'https://www.w3.org/2018/credentials/v1', and the second item is a URI with the value 'https://purl.imsglobal.org/spec/ob/v3p0/context/ob_v3p0.jsonld'.",
      "$comment": "Origin: URI (DerivedType); A `NormalizedString` that respresents a Uniform Resource Identifier (URI).",
      "type": "array",
      "minItems": 1,
      "items": {
        "type": "string"
      }
    },
    "type": {
      "description": "The value of the type property MUST be an unordered set. One of the items MUST be the URI 'VerifiableCredential', and one of the items MUST be the URI 'EndorsementCredential'.",
      "$comment": "Origin: IRI (DerivedType); A `NormalizedString` that represents an Internationalized Resource Identifier (IRI), which extends the ASCII characters subset of the Uniform Resource Identifier (URI).",
      "type": "array",
      "minItems": 1,
      "items": {
        "type": "string"
      }
    },
    "credentialSubject": {
      "description": "The individual, entity, organization, assertion, or achievement that is endorsed and the endorsement comment.",
      "$comment": "Origin: EndorsementSubject (Unordered); A collection of information about the subject of the endorsement.",
      "$ref": "#/$defs/EndorsementSubject"
    },
    "id": {
      "description": "Unambiguous reference to the credential.",
      "$comment": "Origin: URI (DerivedType); A `NormalizedString` that respresents a Uniform Resource Identifier (URI).",
      "type": "string"
    },
    "issuer": {
      "description": "A description of the individual, entity, or organization that issued the credential.",
      "$comment": "Origin: Profile (Unordered); A Profile is a collection of information that describes the entity or organization using Open Badges. Issuers must be represented as Profiles, and recipients, endorsers, or other entities may also be represented using this vocabulary. Each Profile that represents an Issuer may be referenced in many BadgeClasses that it has defined. Anyone can create and host an Issuer file to start issuing Open Badges. Issuers may also serve as recipients of Open Badges, often identified within an Assertion by specific properties, like their url or contact email address.",
      "$ref": "#/$defs/Profile"
    },
    "issuanceDate": {
      "description": "Timestamp of when the credential was awarded.",
      "$comment": "Origin: DateTime (PrimitiveType); An [[ISO8601]] time using the syntax YYYY-MM-DDThh:mm:ss.",
      "type": "string",
      "format": "date-time"
    },
    "expirationDate": {
      "description": "If the credential has some notion of expiry, this indicates a timestamp when a credential should no longer be considered valid. After this time, the credential should be considered expired.",
      "$comment": "Origin: DateTime (PrimitiveType); An [[ISO8601]] time using the syntax YYYY-MM-DDThh:mm:ss.",
      "type": "string",
      "format": "date-time"
    },
    "proof": {
      "description": "If present, one or more embedded cryptographic proofs that can be used to detect tampering and verify the authorship of the credential.",
      "$comment": "Origin: Proof (Unordered); A JSON-LD Linked Data proof.",
      "type": "array",
      "items": {
        "$ref": "#/$defs/Proof"
      }
    },
    "credentialSchema": {
      "description": "The value of the `credentialSchema` property MUST be one or more data schemas that provide verifiers with enough information to determine if the provided data conforms to the provided schema.",
      "$comment": "Origin: CredentialSchema (Unordered); Identify the type and location of a data schema.",
      "type": "array",
      "items": {
        "$ref": "#/$defs/CredentialSchema"
      }
    },
    "credentialStatus": {
      "description": "The information in CredentialStatus is used to discover information about the current status of a verifiable credential, such as whether it is suspended or revoked.",
      "$comment": "Origin: CredentialStatus (Unordered); The information in CredentialStatus is used to discover information about the current status of a verifiable credential, such as whether it is suspended or revoked.",
      "$ref": "#/$defs/CredentialStatus"
    },
    "refreshService": {
      "description": "The information in RefreshService is used to refresh the verifiable credential.",
      "$comment": "Origin: RefreshService (Unordered); The information in RefreshService is used to refresh the verifiable credential.",
      "$ref": "#/$defs/RefreshService"
    }
  },
  "required": [
    "@context",
    "type",
    "credentialSubject",
    "issuer",
    "issuanceDate"
  ],
  "additionalProperties": false,
  "$defs": {
    "CredentialStatus": {
      "description": "The information in CredentialStatus is used to discover information about the current status of a verifiable credential, such as whether it is suspended or revoked.",
      "type": "object",
      "properties": {
        "id": {
          "description": "The value MUST be the URL of the issuer's credential status method.",
          "$comment": "Origin: URI (DerivedType); A `NormalizedString` that respresents a Uniform Resource Identifier (URI).",
          "type": "string"
        },
        "type": {
          "description": "The name of the credential status method.",
          "$comment": "Origin: IRI (DerivedType); A `NormalizedString` that represents an Internationalized Resource Identifier (IRI), which extends the ASCII ch