For the complete documentation index, see llms.txt. This page is also available as Markdown.

Building Verifiable Credentials

A Verifiable Credential (VC) in LearnCard is a JSON document that follows the W3C Verifiable Credentials Data Model. This guide explains how to construct the JSON structure for various types of credentials.

Basic Structure

{
    "@context": [
        "https://www.w3.org/2018/credentials/v1",
        "https://w3id.org/vc/status-list/2021/v1",
        "https://schema.org/"
    ],
    "type": ["VerifiableCredential"],
    "credentialSubject": {
        "id": "did:example:recipient123",
        "name": "Credential Subject Name"
    }
}

Note: LearnCard automatically injects the issuanceDate and issuer fields when you call learnCard.invoke.issueCredential().

Examples by Use Case

1. Basic Educational Achievement

{
    "@context": [
        "https://www.w3.org/2018/credentials/v1",
        "https://w3id.org/vc/status-list/2021/v1",
        "https://purl.imsglobal.org/spec/ob/v3p0/context.json"
    ],
    "type": ["VerifiableCredential", "OpenBadgeCredential"],
    "credentialSubject": {
        "id": "did:example:recipient123",
        "type": ["AchievementSubject"],
        "achievement": {
            "id": "https://example.org/achievements/123",
            "type": ["Achievement"],
            "name": "Introduction to Blockchain",
            "description": "Successfully completed the introduction to blockchain course",
            "criteria": {
                "narrative": "The recipient demonstrated understanding of blockchain fundamentals"
            }
        }
    }
}

2. Professional Certification

3. Digital Badge with Evidence

4. Employment Credential

5. Skill Assessment

6. Learning Pathway Completion

7. Attendance Credential

8. Membership Credential

Fields that make a credential yours

You want to…
Add

Change how it's categorized in the recipient's app

achievement.achievementType — e.g. 'Certificate', 'Course', 'Competency', 'Badge' (all types & categories)

Show proof of the work

credentialSubject.achievement stays the same; add a top-level evidence: [{ id: 'https://…', type: ['Evidence'], name: 'Final project' }]

Make it expire

validUntil: '2027-01-01T00:00:00Z' next to validFrom

Add your own fields (score, cohort, instructor…)

Put them under credentialSubject and add a context that defines them

Control how it displays in LearnCard

Display hint tags (lc: convention)

The OBv3 achievement.alignment array says "this achievement corresponds to entry X in framework Y" — a skills framework, a competency standard, or a credential registry. Verifiers, registries, and hiring tools use it to recognize your credential without a bespoke integration. Each entry names the framework, the target, and where to look it up:

Credential Engine Registry (CTID)

The Credential Engine Registry is a public directory of credential definitions. Registering yours gets it a CTID (Credential Transparency Identifier) — ce- plus a UUID, e.g. ce-12345678-1234-5678-9abc-def012345678 (validated with /^ce-[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i). Find it on your credential's page at credentialfinder.org or in the Registry's publishing tools.

Adding the CTID as an alignment tells verifiers which registered definition each issued credential is an instance of:

No-code path: The Credential Builder in the Developer Portal has a dedicated CTID field. It automatically generates this alignment entry and round-trips it back into the form when editing. See Publish Your App for details.

Best Practices

  1. Start from Open Badges 3.0 (OpenBadgeCredential + AchievementSubject) unless you have a reason not to. Its vocabulary already covers skills (alignment), scores and progress (result), evidence, and validity.

  2. Every field must be defined by a context you list. Signing fails with undefined JSON-LD term otherwise. If you need a field OBv3 doesn't have, add https://schema.org/ (for name, description, startDate…) or https://www.w3.org/2018/credentials/examples/v1 (for VC 1.0 example terms) — or publish your own context and list it.

  3. Prefer alignment over inventing a skills array; prefer result over inventing a score field. Other wallets will understand the first and ignore the second.

  4. Include only what the credential needs. Smaller credentials are easier to display and verify.

  5. issueCredential() fills in issuer and the issuance date if you leave them out.

Last updated

Was this helpful?