Credential Composition#

Each verifiable credential is assembled from an IssuanceLine record and its related UserCredential. The composition process maps Open edX data into the structure required by the chosen data model.

Common fields#

All data models share these root-level fields:

Field

Source

id

urn:uuid:{IssuanceLine.uuid}

issuer.id

Active IssuanceConfiguration DID

issuer.name

Active IssuanceConfiguration name

issuanceDate / issued / validFrom

IssuanceLine.modified timestamp

validUntil

IssuanceLine.expiration_date (optional)

credentialStatus

Status List 2021 entry (see Status List API)

credentialSubject.id

Subject DID provided by the wallet during issuance

Subject DID#

The credentialSubject.id (the learner’s decentralized identifier) is not generated by Open edX. It is provided by the wallet application during the issuance request. When the wallet POSTs to the issuance endpoint, the storage backend’s request serializer extracts and validates the subject DID, then stores it on the IssuanceLine.

Achievement text generation#

The IssuanceLine model builds human-readable text from the underlying Open edX credential. Three text fields are generated: name, description, and narrative. Each uses template variables resolved from the database at issuance time.

Template variables#

Variable

Source

Fallback

credential_type

Mapped from credential class: "program certificate" or "course certificate"

program_title

Program.title

""

course_title

Course.title (looked up via course_id)

""

organizations

Program.authoring_organizations names, comma-joined

""

organization

course_key.org from the course credential

""

platform_name

Site.siteconfiguration.platform_name

""

recipient_name

User.full_name (by UserCredential.username)

"recipient"

course_count

Program.course_runs.count()

0

hours_of_effort

Program.total_hours_of_effort

omitted if not set

Course credential templates#

Name: the course’s configured title; if absent: "Course certificate".

Description:

{credential_type} is granted on course {course_title} completion
offered by {organization}, in collaboration with {platform_name}

Narrative (placed into the achievement criteria field):

{recipient_name} successfully completed a course and received
a passing grade for a Course Certificate in {course_title}
a course offered by {organization}, in collaboration with
{platform_name}.

Program credential templates#

Name: the program’s configured title; if absent, generated as:

Program certificate for passing a program {program_title}

Description:

{credential_type} is granted on program {program_title} completion
offered by {organizations}, in collaboration with {platform_name}.
The {program_title} program includes {course_count} course(s).

If total_hours_of_effort is set, the description appends:

, with total {hours_of_effort} Hours of effort required to complete it

Narrative (placed into the achievement criteria field):

{recipient_name} successfully completed all courses and received
passing grades for a Professional Certificate in {program_title}
a program offered by {organizations}, in collaboration with
{platform_name}.

Data model differences#

Aspect

Open Badges v3.0

VC Data Model v1.1

Extra context

purl.imsglobal.org/.../ob/v3p0

schema.org

Credential type

OpenBadgeCredential

EducationalOccupationalCredential

Subject type

AchievementSubject

(schema.org structures)

Achievement

Nested achievement object with criteria.narrative

hasCredential relationship

Top-level name

Yes (credential name)

No

Open Badges v3.0.1 extends v3.0 with minor context additions but uses the same structure.

Status index assignment#

Each IssuanceLine receives a monotonically increasing status_index scoped to its issuer. The index starts at 0 and increments with each new issuance. This index determines the credential’s position in the issuer’s Status List bitstring. When a credential is revoked, the bit at that index is flipped to 1 and the Status List is regenerated (gzip-compressed, then base64url-encoded).