Open Badges Version 2.1

Open Badges Specification

Final Release
Spec Version 2.1
Final Release
Document Version: 4
Date Issued: November 27, 2023
Status: This document is made available for adoption by the public community at large.
This version: https://www.imsglobal.org/spec/ob/v2p1/
Latest version: https://www.imsglobal.org/spec/ob/latest/
Errata: https://www.imsglobal.org/spec/ob/v2p1/errata/

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 .

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

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

Abstract

Open Badges are visual symbols of accomplishments packed with verifiable metadata according to the Open Badges specification. The Open Badges 2.0 specification [OB-20] defines the properties necessary to define an achievement and award it to a recipient, as well as procedures for verifying badge authenticity and “baking” badge information into portable image files. It includes term definitions for representations of data in Open Badges. The Open Badges 2.1 specification [OB-21] defines an API for exchanging badge information. These term definitions appear in the current context at https://purl.imsglobal.org/spec/ob/v2p1/context/ob_v2p1.jsonld.

1. Introduction

1.1 Design Goals and Rationale

This section is non-normative.

Open Badges 2.1 is a specification that adds the Badge Connect® API to Open Badges that allows badge recipients to easily move their Assertions between platforms to streamline the experience of earning and using Open Badges. The initial scope for this specification will cover Assertions and Profiles, with potential additions in future versions of other types of data held by applications in the various Open Badges ecosystem roles of Issuer, Displayer, and Host.

1.2 Use cases

This section is non-normative.

The following use cases are supported by this specification:

A recipient of an Assertion wants to import historically-issued badges into a chosen Host from an Issuer platform.
A user wishes to authorize an Issuer to push awarded Assertions to their chosen Host upon issue.
A user wishes to connect their Assertions to a recruiting platform.
A user wishes to move their badges from one Host to another Host.
A Consumer wishes to obtain plaintext recipient identifier, to clearly understand the recipient profile in their badges.
An Issuer platform wishes to register a new recipient identifier on a recipient profile to which it would award badges.

1.3 Conformance and Certification

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, 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 Specification Documents

The full set of documents is comprised of the following documents:

  • Open Badges Specification v2.1

  • Open Badges Conformance and Certification Guide v2.1

  • OpenAPI 3.0 Files for the Badge Connect® API

    From the OpenAPI Specification [OPENAPIS],

    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.

    This standard has OpenAPI 3.0 files for the Badge Connect® API in both JSON and YAML format:

  • JSON Schema Files for Open Badges Badge Connect(TM) API v2.1

  • Badge Connect® API JSON-LD Context File

    From the JSON-LD 1.1 Specification [json-ld11],

    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.

    This specification includes this JSON-LD Context file:

1.5 Terminology

The following terms are used throughout this document.

  • Assertion: A representation of an awarded badge, used to share information about a badge belonging to one recipient.
  • Backpack: A term originally used to describe Open Badges services that provide importing, aggregation, and hosting features for recipients. These services match most closely with the role we now define as an Open Badge “Host” application. May also refer to the Mozilla Backpack.
  • BadgeClass: A collection of information about the accomplishment recognized by the Open Badge. Many assertions may be created corresponding to one BadgeClass.
  • Badge Connect® API: Name of the RESTful web service for transfering assertions and profiles between systems.
  • Badge Issuer: A service that allows for the creation of BadgeClasses and the subsequent issuing of Assertions to recipients that conform to the Open Badges specification. Beginning with Open Badges 2.0, the candidate platform must issue a valid baked badge and demonstrate how the badge is retrieved by the recipient.
  • Badge Displayer: An application that displays verified badges to viewers. Beginning with Open Badges 2.0, the candidate platform must display a minimum set of badge metadata and support viewer-initiated verification of a badge.
  • Badge Host: An application that can import, aggregate, and publicly host Assertions for recipients. It also supports export of badges at user request. Beginning with Open Badges 2.0, 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.
  • Baked badge: Badge Assertions may be “baked” into image files as portable credentials.
  • Candidate platform: A platform implementing the Open Badges specification with the intent to obtain certification from IMS. They may be in the process to obtain certification.
  • Criteria: Detailed information about what must be done in order to be recognized with an assertion of a particular BadgeClass. Potential recipients may use criteria to understand what they must do; consumers may use criteria to understand what recipients did in order to earn the badge.
  • Evidence: Links to and descriptions of evidence related to the issuance of an Assertion, such as portfolio items or narratives that describe a badge recipient's work.
  • Extensions: Extensions are a means for issuers to add additional functionality through the use of metadata on Badge Objects beyond what the standard specifies itself.
  • Validation and verification (of badge assertions): Data validation is a procedure that ensures a cluster of data objects that form an Open Badge are appropriately formatted, published, and linked and that each data object conforms to requirements for its class. Validation of all data class instances used in an Open Badge is a part of badge verification. Verification is the process of ensuring the data that makes up an Open Badge is correct. It includes a number of data validation checks as well as procedures to ensure the badge is trustworthy. Verification is distinct from compliance certification for applications and services that implement the specification, though verification is typically a component of certification programs. See Verification in the current specification.

2. API

Badge Connect® defines a JSON API protocol to be implemented by applications serving in the roles of Provider and Consumer. Typically Relying Parties SHOULD be certified Open Badges services in the Open Badges roles of Displayer or Issuer, though Providers may also be relying parties to serve the Host to Host transfer use case. Badge Connect® API uses OAuth 2.0 for authentication, granular resource-based permission scopes, and offers a number of required endpoints that MUST be implemented by Providers and Consumers or both.

2.1 Architecture

Figure 1 Architecture

There are five key components to the Badge Connect® API architecture.

Resource Owner
This is the user that owns the resources (badges) that are on the Provider.
Web Browser
This is the web browser application that the user interacts with.
Consumer
This is the web application that interacts with the Provider on behalf of the resource owner. This component is called the Consumer in the IMS Security Framework [SEC-10].
Authorization Server
This is a server that implements the OAuth 2.0 endpoints on behalf of the Provider. In many systems, the Authorization Server and the Provider are combined.
Provider
This is the resource server that has the protected resources (badges). This component is called the Provider in the IMS Security Framework [SEC-10].

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

2.2 Authentication

A Consumer requests a token scoped for access to Open Badges Assertions on a Provider that belong to a user (resource owner) of that Provider service, using an OAuth 2.0 Authorization Code Grant as described in Section 4.2 of the IMS Security Framework [SEC-10]. Once a Consumer obtains a code, it exchanges the code for an access token and optionally a refresh token. Subsequent API requests are authenticated with the access token until its expiration. If the Provider previously provided a refresh token, the access token can be renewed.

2.2.1 Registration

The user starts on the Consumer application and is offered the chance to connect that application to their chosen Provider. The user supplies the Consumer with the Provider domain authority or selects their Provider from a list.

When presented with a new target Provider by which the Consumer is attempting to gain an access token from, it MUST register itself with the Provider and receive client credentials in order to proceed with the OAuth 2.0 token exchange. The Consumer and Provider MUST implement [RFC7591].

If the Consumer does not know the Provider's registration URL, it MUST request the Manifest as shown this sequence diagram:

Figure 2 Dynamic Client Registration Sequence Diagram

The registration request MUST use HTTPS (TLS 1.2 or 1.3). An example registration request may look like:

POST /o/register HTTP/1.1
Content-Type: application/json
Accept: application/json
Host: badge-host.example.com

{
  "client_name": "Badge Issuer",
  "client_uri": "https://issuer.example.com",
  "logo_uri": "https://issuer.example.com/logo.png",
  "tos_uri": "https://issuer.example.com/terms-of-service",
  "policy_uri": "https://issuer.example.com/privacy-policy",
  "software_id": "13dcdc83-fc0d-4c8d-9159-6461da297388",
  "software_version": "54dfc83-fc0d-4c8d-9159-6461da297388",
  "redirect_uris": [
    "https://issuer.example.com/o/redirect"
  ],
  "token_endpoint_auth_method": "client_secret_basic",
  "grant_types": [
    "authorization_code",
    "refresh_token"
  ],
  "response_types": [
    "code"
  ],
  "scope": "YOUR_REQUESTED_SPACE_SEPARATED_LIST_OF_SCOPES"
}

The properties of the JSON body MUST be implemented as described in the following table. All URLs MUST use HTTPS (e.g. https://example.com/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 Provider.

Name Type Required Description
client_name String Yes The human-readable name of the Consumer.
client_uri URI Yes A page that which describes the Consumer.
logo_uri URI Yes The logo of the Consumer. The logo image uri should resolve to an image file with a square aspect ratio in either PNG or SVG format. Recommended resolution: 512x512px.
tos_uri URI Yes The Terms of Service of the Consumer.
policy_uri URI Yes The Privacy Policy of the Consumer.
software_id String Yes A unique idenfitier assigned by the client developer. As described in [RFC7591], it SHOULD remain the same for all instances of the client software.
software_version String Yes A version identifier string for the client software. The value SHOULD change on any update to the client software.
redirect_uris URI Yes (Array) Array of redirection URI strings for use in the OAuth 2.0 flow.
token_endpoint_auth_method String No String indicator of the requested authentication method for the token endpoint. In this specification only "client_secret_basic" is allowed:
  • "client_secret_basic": The Consumer uses the HTTP Basic authentication method as defined in OAuth 2.0.
If omitted, the default is "client_secret_basic".
grant_types String No (Array) 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 is that the client will use only the "authorization_code" grant type.
response_types String No (Array) 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.
scope String No String containing a space-separated list of scope values that this client is permitted to use when requesting access tokens. Scopes are defined in Scopes. If omitted, the Provider MAY register a client with a default set of scopes.

If the Provider accepts the registration request, it will store the information provided in the request and generate a set of client credentials for the Consumer to use when requesting access tokens.

All the information provided by the Consumer MUST be returned to the Consumer, including modifications to the properties as the Provider deems necessary. This MAY include changes to scopes that the Provider chooses to support. Consumers are encouraged to fail gracefully if a requested scope was not returned by the Provider by either supporting a subset of the intended functionality or by providing messaging to the Resource Owner.

The Provider MAY reject a registration request if the value of one of the Consumer's metadata fields is invalid. The Provider MAY choose to substitute a valid value for any requested parameter of a Consumer's metadata. Implementers should take note that substitution MAY include changes to the permitted scopes.

For the purposes of registering a Consumer, a Provider MAY limit the scopes it supports to those revelant to Badge Connect®.

HTTP/1.1 201 Created
Content-Type: application/json
Cache-Control: no-store
Pragma: no-cache

{
  "client_id": "BADGECONNECT_s6BhdRkqt3",
  "client_secret": "czZCaGRSa3F0Mzo3RmpmcDBaQnIxS3REUmJuZlZkbUl3",
  "client_id_issued_at": 1558280111,
  "client_secret_expires_at": 1558290111,
  "client_name": "Badge Issuer",
  "client_uri": "https://issuer.example.com",
  "logo_uri": "https://issuer.example.com/logo.png",
  "tos_uri": "https://issuer.example.com/terms-of-service",
  "policy_uri": "https://issuer.example.com/privacy-policy",
  "software_id": "13dcdc83-fc0d-4c8d-9159-6461da297388",
  "software_version": "54dfc83-fc0d-4c8d-9159-6461da297388",
  "redirect_uris": [
    "https://issuer.example.com/o/redirect"
  ],
  "token_endpoint_auth_method": "client_secret_basic",
  "grant_types": [
    "authorization_code",
    "refresh_token"
  ],
  "response_types": [
    "code"
  ],
  "scope": "YOUR_REQUESTED_SPACE_SEPARATED_LIST_OF_SCOPES"
}

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 Required Description
client_id String Yes An OAuth 2.0 client identifier string. The value SHOULD NOT be currently valid for any other registered client.
client_secret String Yes An OAuth 2.0 client secret string.
client_id_issued_at Integer Yes 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.
client_secret_expires_at Integer Yes 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.

Implementers are encouraged to use existing libraries as [RFC7591] supports internationalization among other nuances that may not be realized in an in-house solution.

2.2.2 Obtaining Tokens

After the Consumer is registered with the Provider as described in Registration, the Consumer then MAY initiate an authorization request as described in Section 4.2 of the IMS Security Framework [SEC-10] by redirecting the user to the Provider's authorizationUrl as declared in the Provider's Badge Connect® Manifest.

Figure 3 Authorization Sequence Diagram

All required properties must be included in the authorization request.

Name Type Required Description
response_type String Yes Value MUST be set to "code".
client_id String Yes The client identifier. MUST be client_id provided in the Registration response.
redirect_uri URI Yes The Consumer's redirection endpoint. MUST match one of the redirect_uris in the Registration request. Although this is optional in the IMS Security Framework [SEC-10], it is REQUIRED by this specification.
scope String Yes The scope of the authorization request. This is a space delimited list of scopes.
state String Yes An opaque value used by the client to maintain state between the request and callback.
code_challenge String Yes This is BASE64URL-ENCODE(SHA256(ASCII(code_verifier))).
code_challenge_method String Yes This MUST have a value of S256 i.e. the SHA256 code verifier transformation method is used.

An example authorization request (line breaks for display purposes only):

GET /authorize?
response_type=code
&client_id=BADGECONNECT_s6BhdRkqt3
&state=xyzjklabc
&scope=SPACE_SEPARATED_STRING_OF_REQUESTED_SCOPES
&code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM
&code_challange_method=S256
&redirect_uri=https%3A%2F%2Fbadgehost.example.com%2Fo%2Fredirect HTTP/1.1
Host: www.example.com

If the Provider does not recognize the Consumer's redirection endpoint from a prior connection with this Consumer, the Provider SHOULD throw an error specifying that the redirection endpoint is not applicable to any registered client and registration should be made before proceeding. If the redirect_uri matches the known client_id, the Provider MAY honor the request to present the user or resource owner with the option to authorize the request. If the Provider recognizes the Consumer, the Provider MAY skip the need to register the client again. If the user authorizes the Consumer to access their resources with the requested scopes, the Provider MUST redirect the user back to the redirect_uri with a code query string parameter.

With the supplied code, the Consumer SHOULD attempt to exchange the code for a token. The Consumer makes an authorization grant POST request to the Provider's tokenUrl, as declared in the Provider's Badge Connect® Manifest. The HTTP POST request MUST include a Basic authorization header with the client_id and client_secret provided by the response to the registrationUrl endpoint. The body of the request MUST include the following form fields:

Name Type Required Description
grant_type String Yes Value MUST be set to "authorization_code".
code String Yes The authorization code received from the authorization server.
redirect_uri URI Yes The Consumer's redirection endpoint.
scope String Yes The scope of the access request.
code_verifier String Yes The PKCE code verifier.

An example token request:

POST /badge/connect/auth/token HTTP/1.1
Host: www.example.com
Authorization: Basic QkFER0VDT05ORUNUX3M2QmhkUmtxdDM6Y3paQ2FHUlNhM0YwTXpvM1JtcG1jREJhUW5JeFMzUkVVbUp1Wmxaa2JVbDM=
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code
&code=n0esc3NRze7LTCu7iYzS6a5acc3f0ogp4
&redirect_uri=https://badgehost.example.com/o/redirect
&scope=SPACE_SEPARATED_STRING_OF_REQUESTED_SCOPES
&code_verifier=YOUR_GENERATED_CODE_VERIFIER

If the authorization server finds the request to be a valid, it generates and returns an access token and optionally a refresh token.

If the request fails, the Provider SHOULD return a response as described in RFC6749.

2.2.3 Authenticating with Tokens

After obtaining a token using the method above, a Consumer MAY request resources controlled by the resource owner from Provider endpoints using the token in the HTTP Authorization header. An example follows, where 2YotnFZFEjr1zCsicMWpAA is the token:

Authorization: Bearer 2YotnFZFEjr1zCsicMWpAA
Figure 4 Access Protected Resource Sequence Diagram

2.2.4 Revocation by Resource Owner

Provider platforms MUST provide a list of authorized clients to the resource owner for review. The list SHOULD identify the Consumer and when the grant was created. From this list the resource owner MUST be able to revoke the Consumer's access.

Subsequent attempts to use the relevant revoked access or refresh tokens SHOULD result in a 401 UNAUTHENTICATED error.

2.2.5 Revocation by Consumer

Provider platforms MAY provide a mechanism to revoke both types of tokens by providing a token revocation endpoint in their manifest file [RFC7009]. This revocation endpoint allows a Consumer to invalidate its tokens if the end-user logs out, changes identity, or removes the respective Provider.

If token revocation endpoints are implemented they MUST support the revocation of refresh tokens and SHOULD support the revocation of access tokens.

Revocation by Consumer is not part of the IMS Security Framework [SEC-10]. If the implementer decides to implement it, they SHOULD follow [RFC7009].

Revocation Request

The Consumer makes a POST request to the Provider's token revocation URL, as declared in the Provider's Badge Connect® Manifest. The HTTP request entity-body MUST contain a token parameter containing the refresh token or access token.

Relying Parties MAY also pass a token_type_hint parameter with a value of access_token or refresh_token.

An example revocation request:

POST /badge/connect/auth/revoke_token HTTP/1.1
Host: www.example.com
Content-Type: application/x-www-form-urlencoded

token=n0esc3NRze7LTCu7iYzS6a5acc3f0ogp4
&token_type_hint=access_token

2.3 Scopes

Access to resources in the Badge Connect® API require an access token. These access tokens have a permissioned scope when they are created and inform the responding application which resources the entity has access to.

Name Description
https://purl.imsglobal.org/spec/ob/v2p1/scope/assertion.readonly Permission to read assertions for the authenticated entity.
https://purl.imsglobal.org/spec/ob/v2p1/scope/assertion.create Permission to create assertions for the authenticated entity.
https://purl.imsglobal.org/spec/ob/v2p1/scope/profile.readonly Permission to read the profile for the authenticated entity.
https://purl.imsglobal.org/spec/ob/v2p1/scope/profile.update Permission to update the profile for the authenticated entity.
offline_access Permission to issue a refresh_token along with the access_token.

2.4 Manifest

All Providers MUST implement a JSON manifest file which contains configuration information about their implementation, such as scope support, redirect URIs, and branding information.

Providers MUST serve the manifest at the well-known path /.well-known/badgeconnect.json on the relevant service domain compliant with [RFC5785]. The manifest MUST be provided over secure TLS 1.2 or 1.3 protocol e.g. https://YOUR_DOMAIN/.well-known/badgeconnect.json.

Requesting Manifests

Upon requesting a Manifest file from a Provider, the requester 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 requester SHOULD NOT cache the data for future interactions. If directives include max-age or if an Expires header is present, the requester SHOULD cache the manifest file 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 Manifest file response. If so, after a resource's declared expiration, a requester MAY include an If-None-Match header containing the value of the Etag to check if the resource is still fresh. If so the server may return a 304 Not Modified response status code, and a new Expires or Cache-Control header MAY be included, which the requester SHOULD use to update the cache expiration.

Manifest Structure

{
  "@context": "https://purl.imsglobal.org/spec/ob/v2p1/ob_v2p1.jsonld",
  "id": "https://badgehost.example.com/.well-known/badgeconnect.json",
  "badgeConnectAPI": [{
    "name": "A Badge Host",
    "image": "https://badgehost.example.com/logo.png",
    "apiBase": "https://badgehost.example.com/api/ims/ob/v2p1",
    "version": "v2p1",
    "termsOfServiceUrl": "https://badgehost.example.com/terms",
    "privacyPolicyUrl": "https://badgehost.example.com/privacy",
    "scopesOffered": [
      "https://purl.imsglobal.org/spec/ob/v2p1/scope/assertion.readonly",
      "https://purl.imsglobal.org/spec/ob/v2p1/scope/assertion.create",
      "https://purl.imsglobal.org/spec/ob/v2p1/scope/profile.readonly",
      "https://purl.imsglobal.org/spec/ob/v2p1/scope/profile.update"
    ],
    "registrationUrl": "https://badgehost.example.com/o/register",
    "authorizationUrl": "https://badgehost.example.com/o/auth",
    "tokenUrl": "https://badgehost.example.com/o/token",
    "tokenRevocationUrl": "https://badgehost.example.com/o/revoke_token"
  }]
}

Manifest Properties

For the URL properties below, it is not required that the top-level domains match. However, implementors SHOULD use the manifest location's top-level domain whenever possible.

Property Type Required Description
name String Yes The name of the platform supporting the API. This SHOULD reflect the user-facing identity of the platform requesting authorization.
image URI No An image representing the platform. May be a URI to a hosted image or a Data URI. The logo image uri should resolve to an image file with a square aspect ratio in either PNG or SVG format. Recommended resolution: 512x512px.
apiBase URI Yes Fully qualified URL that will be concatenated with the API endpoints. It must end with the path fragment "/ims/ob/v2p1". It SHOULD NOT have a trailing slash "/".
E.g. apiBase + "/assertions"
version String Yes A string representing the implemented version. MUST be in the format of vMAJORpMINOR where MAJOR and MINOR are integers. v2p1 is the correct string for this specification version.
termsOfServiceUrl URI Yes Fully qualified URL to the platform's terms of service. Other platforms SHOULD link to this resource as part of their authorization interface.
privacyPolicyUrl URI Yes Fully qualified URL to the platform's privacy policy. Other platforms SHOULD link to this resource as part of their authorization interface.
scopesOffered String Yes (Array) An array of strings listing the scopes supported by the Provider in the form of fully qualified URLs to the scope descriptors.
registrationUrl URI Yes A fully qualified URL to which the Consumer would make the client registration request to before performing the authorization flow.
authorizationUrl URI Yes A fully qualified URL to the Provider's authorization endpoint.
tokenUrl URI Yes A fully qualified URL to the Provider's token request endpoint for exchanging an authorization code for a bearer token.
tokenRevocationUrl URI No A fully qualified URL to the Provider's token revocation endpoint for invalidating an existing refresh token or access token. When this property is omitted or has a null value, it will be assumed that the Provider does not support token revocation by a Consumer.

2.5 Response Envelope

Responses from all Badge Connect®-specific APIs in this document are wrapped in a JSON envelope. All response envelopes have a status property and one or more result properties. The result property name(s) and data types are defined in the Responses section for each endpoint.

Responses related to standarized OAuth requests should use the prescribed format in their respective RFC.

2.5.1 Status

The "status" property MUST appear on all responses.

Name Type Required Description
error String Yes A nullable string and the human-readable message describing the problem.
statusCode Integer Yes The HTTP status code of the response.
statusText String Yes A string matching one of the enumerated and allowed values for the given endpoint.

2.5.2 Pagination

Pagination of results is controlled by two query string parameters appended to the request.

  • limit - the number of results to return
  • offset - the index of the first record to return (zero indexed)

The HTTP Link header MUST appear when a list response is incomplete and MAY appear for complete responses.

It is RECOMMENDED that Provider implementations honor the limit when forming the response, but MAY use any limit, or no limit.

It is RECOMMENDED that Provider implementations pass the total result count back to the requester. When the total result count is not known, this MUST be omitted. The value MUST be provided in the custom HTTP header: X-Total-Count.

The header MUST support all of the following link relations (rel values):

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

An example of Link header pagination, line breaks added for readability:

Link:
<https://host.example.com/v1/assertions?limit=10&offset=20>; rel="next",
<https://host.example.com/v1/assertions?limit=3&offset=500>; rel="last",
<https://host.example.com/v1/assertions?limit=10&offset=0>; rel="first",
<https://host.example.com/v1/assertions?limit=10&offset=0>; rel="prev"

2.6 Assertion Payload

An Assertion Payload contains either a signed or unsigned Assertion [OB-20]. If both are specified, the unsigned Assertion MUST be ignored. Null values MAY be omitted.

Three examples:

{
  "assertion": { ... },
  "signedAssertion": null
}

{
  "assertion": null,
  "signedAssertion": "abced..."
}

{
  "assertion": { ... }
}
Property Expected Type Required Description
assertion Assertion No An unsigned Assertion [OB-20] object in serialized JSON-LD.
signedAssertion String No A signed Assertion in JWS Compact JWS Serialization format.

2.7 Endpoints

2.7.1 Assertions

GET /assertions
Description Fetch Assertions for the supplied parameters and authentication token. The response envelope contains a list of zero or more matching signed Assertions and a list of zero or more matching unsigned assertions. There SHOULD be only one assertion (signed or unsigned) for any particular assertion ID as the IDs are intended to be globally unique. The Provider SHOULD return Assertions (signed and unsigned) ordered by last update, descending and SHOULD return only Assertions (signed and unsigned) updated after the timestamp requested if supplied.
Query Parameters
Name Type Required Description
limit Integer No Indicate how many results should be retrieved in a single page.
offset Integer No Indicate the index of the first record to return (zero indexed).
since DateTime No Retrieve Assertions that were created or updated after the provided timestamp.
Responses
Name Type Description
200 Assertions Response This is the response when the request has been completed successfully.
400 400 Response An invalid request was made.
401 401 Response The request was not correctly authorized.
404 404 Response The requested resource does not exist.
405 405 Response This method is not allowed on the endpoint.
500 - This code should be used only if there is catastrophic error.
POST /assertions
Description Create or update an Assertion. The posted data MUST be an Assertion Payload. Upon receiving any Assertion, the Provider SHOULD verify the Assertion, whether it is the first time seen or a subsequent update. The data posted by the Consumer SHOULD not be implicitly trusted to be an accurate representation of the Assertion.
Responses
Name Type Description
200 Assertion Response This is the response when the request has been completed successfully.
400 400 Response An invalid request was made.
401 401 Response The request was not correctly authorized.
404 404 Response The requested resource does not exist.
405 405 Response This method is not allowed on the endpoint.
500 - This code should be used only if there is catastrophic error.

2.7.2 Profile

GET /profile
Description Fetch the profile for the supplied authentication token. For a successful result, the Provider MUST return a valid OB Profile instance.

Profiles that are received MAY contain attributes that a Host SHOULD authenticate before using in practice.

Responses
Name Type Description
200 Profile Response This is the response when the request has been completed successfully.
400 400 Response An invalid request was made.
401 401 Response The request was not correctly authorized.
404 404 Response The requested resource does not exist.
405 405 Response This method is not allowed on the endpoint.
500 - This code should be used only if there is catastrophic error.
POST /profile
Description Update the profile for the authenticate entity. The request SHOULD only include profile identifier properties to be added to the profile, not any existing data. Successful request responses will be the same as GET Profile and may not include the patched values (as the Provider may be waiting for asynchronous processes to complete before accepting the value). The value may never become part of the published profile. A Provider 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 Provider cannot validate telephone numbers.
Responses
Name Type Description
200 Profile Response This is the response when the request has been completed successfully.
400 400 Response An invalid request was made.
401 401 Response The request was not correctly authorized.
404 404 Response The requested resource does not exist.
405 405 Response This method is not allowed on the endpoint.
500 - This code should be used only if there is catastrophic error.

2.8 Retry Behavior

Receivers of requests 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 recipient 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).

2.9 Responses

2.9.1 200 GET Assertions Response

Property Type Required Description
status Status Yes The Status object describing the success or failure of the request.
assertions Assertion No (Array) The matching unsigned Assertions. The total number of unsigned and signed assertions should not exceed the pagination limit. Not required if there are no unsigned assertions.
signedAssertions String No (Array) The matching signed Assertions in JWS Compact Serializion format. The total number of unsigned and signed assertions should not exceed the pagination limit. Not required if there are no signed assertions.
{
    "status": {
        "error": null,
        "statusCode": 200,
        "statusText": "OK"
    },
    "assertions": [
        {
          "@context": "https://w3id.org/openbadges/v2",
          "id": "https://issuer.example.com/api/v20/assertion/1234567",
          "type": "Assertion",
          ...
        }
    ],
    "signedAssertions": [
        "eyJhbGciOiJSUzI1NiJ9.ew0KICAiQGNvbnRleHQiOiAiaHR0cHM6Ly93M2lkLm9yZy9vcGVuYmFkZ2VzL3YyIiwNCiAgInR5cGUiOiAiQXNzZXJ0aW9uIiwNCiAgImlkIjogImh0dHBzOi8vZXhhbXBsZS5vcmcvYmV0aHMtcm9ib3RpY3MtYmFkZ2UuanNvbiIsDQogICJyZWNpcGllbnQiOiB7DQogICAgInR5cGUiOiAiZW1haWwiLA0KICAgICJoYXNoZWQiOiB0cnVlLA0KICAgICJzYWx0IjogImRlYWRzZWEiLA0KICAgICJpZGVudGl0eSI6ICJzaGEyNTYkYzdlZjg2NDA1YmE3MWI4NWFjZDhlMmU5NTE2NmM0YjExMTQ0ODA4OWYyZTE1OTlmNDJmZTFiYmE0NmU4NjVjNSINCiAgfSwNCiAgImltYWdlIjogImh0dHBzOi8vZXhhbXBsZS5vcmcvYmV0aHMtcm9ib3QtYmFkZ2UucG5nIiwNCiAgImV2aWRlbmNlIjogImh0dHBzOi8vZXhhbXBsZS5vcmcvYmV0aHMtcm9ib3Qtd29yay5odG1sIiwNCiAgImlzc3VlZE9uIjogIjIwMTYtMTItMzFUMjM6NTk6NTlaIiwNCiAgImJhZGdlIjogImh0dHBzOi8vZXhhbXBsZS5vcmcvcm9ib3RpY3MtYmFkZ2UuanNvbiIsDQogICJ2ZXJpZnkiOiB7DQogICAgInR5cGUiOiAiU2lnbmVkQmFkZ2UiLA0KICAgICJjcmVhdG9yIjogImh0dHBzOi8vZXhhbXBsZS5vcmcvcHVibGljS2V5Ig0KICB9DQp9.Liv4CLviFH20_6RciUWf-jrUvMAecxT4KZ_gLHAeT_chrsCvBEE1uwgtwiarIs9acFfMi0FJzrGye6mhdHf3Kjv_6P7BsG3RPkYgK6-5i9uZv4QAIlvfNclWAoWUt4j0_Kip2ftzzWwc5old01nJRtudZHxo5eGosSPlztGRE9G_g_cTj32tz3fG92E2azPmbt7026G91rq80Mi-9c4bZm2EgrcwNBjO0p1mbKYXLIAAkOMuJZ_8S4Go8S0Sg3xC6ZCn03zWuXCP6bdY_jJx2BpmvqC3H55xWIU8p5c9RxI8YifPMmJq8ZQhjld0pl-L8kHolJx7KGfTjQSegANUPg"
    ]
}

2.9.2 200 POST Assertion Response

Property Type Required Description
status Status Yes The Status object describing the success or failure of the request.
{
    "status": {
        "error": null,
        "statusCode": 200,
        "statusText": "OK"
    }
}

2.9.3 200 GET Profile Response

Property Type Required Description
status Status Yes The Status object describing the success or failure of the request.
profile Profile Yes The matching Profile.
{
    "status": {
        "error": null,
        "statusCode": 200,
        "statusText": "OK"
    },

    "profile": {
        "@context": "https://w3id.org/openbadges/v2",
        "id": "https://host.example.com/profile/12345",
        "type": "Profile",
        "name": "John Appleseed ",
        "url": "https://example.com",
        "email": "john@example.com"
    }
}

2.9.4 200 POST Profile Response

Property Type Required Description
status Status Yes The Status object describing the success or failure of the request.
profile Profile Yes The updated Profile.
{
    "status": {
        "error": null,
        "statusCode": 200,
        "statusText": "OK"
    },

    "profile": {
        "@context": "https://w3id.org/openbadges/v2",
        "id": "https://host.example.com/profile/12345",
        "type": "Profile",
        "name": "John Appleseed ",
        "url": "https://example.com",
        "email": "john@example.com"
    }
}

2.9.5 400 Response

{
    "status": {
        "error": "Additional information regarding the error in human readable format.",
        "statusCode": 400,
        "statusText": "BAD_REQUEST"
    }
}

Allowed values for the statusText property by endpoint:

  • POST /assertions
    • REQUEST_VALIDATION_ERROR (data validation of the request failed)
    • RECIPIENT_PROFILE_MISMATCH (profile match failed)
    • INVALID_BADGE (badge validation failed)
    • BAD_REQUEST (all other errors)
  • GET /assertions
    • REQUEST_VALIDATION_ERROR (data validation of the request failed)
    • BAD_REQUEST (all other errors)
  • POST /profile
    • REQUEST_VALIDATION_ERROR (data validation of the request failed)
    • BAD_REQUEST (all other errors)

2.9.6 401 Response

{
    "status": {
        "error": "Additional information regarding the error in human readable format.",
        "statusCode": 401,
        "statusText": "UNAUTHENTICATED"
    }
}

PERMISSION_DENIED is another acceptable value for statusText in the event that the request was authenticated but the scope does not include the requested resource.

2.9.7 404 Response

{
    "status": {
        "error": null,
        "statusCode": 404,
        "statusText": "NOT_FOUND"
    }
}

2.9.8 405 Response

{
    "status": {
        "error": "Additional information regarding the error in human readable format.",
        "statusCode": 405,
        "statusText": "METHOD_NOT_ALLOWED"
    }
}

A. Handling Null Values

This standard allows the use of the JSON null data type, and empty arrays such as [] in serialized JSON. Your code should be designed to deserialize JSON with null values and empty arrays even if your code does not serialize them.

B. Data Types

The following primitive data types are referenced in this standard.

  • DateTime - the date/time (using the [ISO8601] format
  • Integer - the integer data-type
  • String - normalized string
  • URI - absolute or relative URI

C. Revision History

This section is non-normative.

C.1 Version History

Version No. Document Version Release Date Comments
Version 2.1 IMS Candidate Final Public 4 October 25, 2021 Fixed a number of specification and documentation issues.
Version 2.1 IMS Candidate Final Public 3 October 7, 2020 Releasing as Candidate Final Public.
Version 2.1 IMS Candidate Final 2 January 24, 2020 Second coordinated release.
v2.1 Candidate Final 1 August 29, 2019 First release of the Candidate Final specification.
v2.1 Final 1 November 27, 2023 Open Badges 2.1 Final release.

D. References

D.1 Normative references

[ISO8601]
Representation of dates and times. ISO 8601:2004.. International Organization for Standardization (ISO). 2004. ISO 8601:2004. URL: http://www.iso.org/iso/catalogue_detail?csnumber=40874
[json-ld11]
JSON-LD 1.1. Gregg Kellogg; Pierre-Antoine Champin; Dave Longley. W3C. 16 July 2020. W3C Recommendation. URL: https://www.w3.org/TR/json-ld11/
[OB-20]
Open Badges v2.0. Otto, Nate; Bohrer, Jeff; Cook, Timothy; Gylling, Markus; Hripak, Alexander; Pitcher, Justin. IMS Global Learning Consortium. April 2018. IMS Final Release. URL: https://www.imsglobal.org/spec/ob/v2p0/
[OB-21]
Open Badges Specification v2.1. Jeff Bohrer; Andy Miller. IMS Global Learning Consortium. November 27, 2023. IMS Final Release. URL: https://www.imsglobal.org/spec/ob/v2p1/
[OB-CERT-21]
Open Badges Conformance and Certification Guide v2.1. Jeff Bohrer; Andy Miller. IMS Global Learning Consortium. November 27, 2023. IMS Final Release. URL: https://www.imsglobal.org/spec/ob/v2p1/cert/
[OB-JSON-21]
JSON Schema Files for Open Badges Badge Connect(TM) API v2.1. Jeff Bohrer; Andy Miller. IMS Global Learning Consortium. November 27, 2023. IMS Final Release. URL: https://purl.imsglobal.org/spec/ob/v2p1/schema/json/
[OPENAPIS]
OpenAPI Specification. Darrell Miller; Jeremy Whitlock; Marsh Gardiner; Mike Ralphson; Ron Ratovsky; Uri Sarid; Tony Tam; Jason Harmon. OpenAPI Initiative. URL: https://www.openapis.org/
[RFC2119]
Key words for use in RFCs to Indicate Requirement Levels. S. Bradner. IETF. March 1997. Best Current Practice. URL: https://www.rfc-editor.org/rfc/rfc2119
[RFC5785]
Defining Well-Known Uniform Resource Identifiers (URIs). M. Nottingham; E. Hammer-Lahav. IETF. April 2010. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc5785
[RFC6749]
The OAuth 2.0 Authorization Framework. D. Hardt, Ed.. IETF. October 2012. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc6749
[RFC7009]
OAuth 2.0 Token Revocation. T. Lodderstedt, Ed.; S. Dronia; M. Scurtescu. IETF. August 2013. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc7009
[RFC7515]
JSON Web Signature (JWS). M. Jones; J. Bradley; N. Sakimura. IETF. May 2015. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc7515
[RFC7591]
OAuth 2.0 Dynamic Client Registration Protocol. J. Richer, Ed.; M. Jones; J. Bradley; M. Machulak; P. Hunt. IETF. July 2015. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc7591
[SEC-10]
IMS Global Security Framework v1.0. C. Smythe; C. Vervoort; M. McKell; N. Mills. IMS Global Learning Consortium. April 2019. IMS Final Release. URL: https://www.imsglobal.org/spec/security/v1p0/

E. List of Contributors

The following individuals contributed to the development of this document:

Name Organization Role
Alexander HripakCredlyEditor
Sara ArjonaMoodle
Jeff BohrerIMS Global
Viktor HaagD2L
Takahiro HataDigital Knowledge EdTech Lab
Chris HoustoneLumen
Mark LeubaIMS Global
Andy MillerIMS Global
Omid MufeedDigitalme
Nate OttoConcentric Sky
Justin PitcherCampus Labs
Alex ReisD2L

1EdTech™ Consortium, Inc. ("1EdTech") is publishing the information contained in this document ("Specification") for purposes of scientific, experimental, and scholarly collaboration only.

1EdTech makes no warranty or representation regarding the accuracy or completeness of the Specification.

This material is provided on an "As Is" and "As Available" basis.

The Specification is at all times subject to change and revision without notice.

It is your sole responsibility to evaluate the usefulness, accuracy, and completeness of the Specification as it relates to you.

1EdTech would appreciate receiving your comments and suggestions.

Please contact 1EdTech through our website at www.1edtech.org.

Please refer to Document Name: Open Badges Specification 2.1

Date: November 27, 2023