Create an Open Badges 3.0 credential
++ {cred.data.achievementType} • Updated {formatRelativeTime(cred.updatedAt)} +
+No saved credentials yet
+ ++ Save your credentials to quickly reuse them later +
+
+ {highlightCode(code)}
+
+
+
- {highlightCode(code)}
-
-
- + The guide you're looking for doesn't exist. +
+ +{subtitle}
+ +{description}
+{subtitle}
+ +{description}
+ ++ Set up a project to start building your integration. +
++ Choose what you want to build. We'll guide you through each step with + ready-to-use code and live setup tools. +
++ Full guided setup for LMS partners. Configure webhooks, build credential templates, + map your data, and go live with automatic credential issuance. +
+Documentation
+Full API reference
+GitHub
+Open source SDKs
+My Apps
+Manage listings
+
+ {highlightCode(currentCode)}
+
+ )}
+ {label}
+ + {description && ( +{description}
+ )} ++ A consent contract defines what data you're requesting and why. Users must accept + the contract before sharing their data. +
++ Consent Redirect Flow: Collect user consent and credentials from your external application. + Users will be redirected to LearnCard to grant permissions, then back to your app with their credentials. +
+Contract Selected
+ +{contractUri}
++ Important: Save this Contract URI — you'll need it to send credentials later. +
++ When users click "Connect with LearnCard" in your app, they'll be redirected to LearnCard to grant consent, + then back to your app with their DID and credentials. +
++ Users will be redirected here after granting consent +
++ Create a button that redirects users to the consent flow: +
+ ++ Create an endpoint to handle the redirect. The user's DID and Delegate VP JWT + will be included in the URL parameters. +
+ +
+ Store the did and{' '}
+ delegateVpJwt to identify and
+ send credentials to this user later.
+
+ Initialize the LearnCard SDK on your backend to send credentials and query consent data. +
+API Token
+ +
+ {apiToken ? (
+
+
No API tokens found.
+ ++ Go to Admin Tools → API Keys to create one, then come back here. +
+{grant.name}
+ ++ Created {new Date(grant.createdAt!).toLocaleDateString()} +
++ Install the LearnCard SDK in your backend application: +
+ ++ Initialize with your API token: +
+ ++ Security: Store your API token in environment variables, never commit it to code. +
++ Now you can issue credentials to users who have connected with your app. +
++ Use the credential builder to create your badge or use the code template below. +
+ +
+ Use the simplified send method
+ to create, sign, and deliver credentials in one call.
+
+ What this does: Creates a credential template, issues it to the user, + and writes it to your consent flow contract — all in one call. +
++ As the contract owner, you can query consent data and transactions: +
+ +Get all consented data for your contract:
+ +Get consent data for a specific user:
+ ++ Users can now securely connect and receive credentials from your application. +
++ Fix the issues above before continuing. See the header examples below. +
+ )} + + {!isChecking && allPassed && ( ++ Your URL passed basic checks. You may still need to configure iframe headers (X-Frame-Options). +
+ )} ++ Set up the Partner Connect SDK in your web app. This takes about 2 minutes. +
++ Your app listing is what users see in the LearnCard app store. +
+ + {!selectedIntegration ? ( ++ Select a project from the header dropdown first. +
++ {listing.display_name} +
+ ++ {listing.tagline || 'No tagline set'} +
+ +No apps yet
+ ++ Create your first app to get started +
+
+ Also works with yarn add or pnpm add
+
+ That's it! Users are already logged in when inside the wallet, so requestIdentity() returns instantly with their profile.
+
+ Select the features you want to add to your app. You can always add more later. +
+{feature.description}
+ + {feature.requiresSetup && !isComingSoon && ( ++ Some features require additional setup. We'll guide you through it. +
+ )} ++ Choose a framework and we'll give you the commands to get started with a pre-configured setup. +
++ When you deploy, you'll need to configure your hosting provider to add these headers. + Most providers (Vercel, Netlify, etc.) support this in their config files. +
++ Your app will run inside an iframe in the LearnCard wallet. Enter your URL and we'll + check if it's ready for embedding. +
++ Enter your URL and click Check to verify requirements +
++ Your server must return these headers to allow iframe embedding: +
+ ++ The Partner Connect SDK lets your embedded app communicate with the LearnCard wallet. +
+Single Sign-On
+Get user identity instantly
+Send Credentials
+Issue VCs to the wallet
+Request Credentials
+Search user's wallet
+Navigation
+Launch wallet features
++ Set up the SDK when your app loads. You can immediately request the user's identity — + no login required since they're already in the wallet. +
++ To create and manage boost templates, select an integration and app listing above. +
++ Create credential templates that your embedded app can issue to users +
++ Create your first boost template to start issuing credentials from your app +
+ +Retrieve templates programmatically from your backend
++ Use this server-side function to dynamically retrieve all boost templates for your app listing. + This is useful for building template pickers or syncing templates to your database. +
+ ++ Complete API for communicating with the LearnCard wallet. Select a method to see detailed documentation and code examples. +
++ {selectedMethod.description} +
+
+ Parameters
+
+ {param.name}
+
+
+
+ {param.type}
+
+
+ {param.required && (
+
+ required
+
+ )}
+ + {param.description} +
+
+ {selectedMethod.returns.type}
+
+
+ + {selectedMethod.returns.description} +
+ ++ Create and manage credential templates for your embedded app +
+No integrations found
+ )} + + {/* Create new integration */} + {isCreatingIntegration ? ( +No app listings for this integration
+ )} + + {/* Create new listing */} + {isCreatingListing ? ( +
+
+ You now have everything you need to build a powerful embedded LearnCard app. + Check out the full documentation for advanced features and best practices. +
+ + ++ Choose how you want to deliver credentials to users in your embedded app. +
++ Important: Step 3 (issuing) must happen on your server with your API key to sign the credential properly. +
+Signing authority ready
+Using: {primarySA.name}
++ A signing authority is needed to cryptographically sign credentials. +
+ ++ Create a consent contract that requests 'write' permission to sync credentials to the user's wallet. +
+ ++ Select an app in Step 1 to create credential templates. +
++ Choose how you want to request credentials from users in your app. +
++ This searches credential titles for matches +
++ A clear reason builds trust and improves sharing rates +
++ Request a specific credential when you already know its ID from a previous interaction: +
+ ++ Ask users for permission to access specific data fields or write data back to their profile via a ConsentFlow contract. +
++ Use the Partner SDK to prompt the user for consent in your embedded app. +
+ ++ On your server, initialize with your API key to read shared credentials and send new ones. +
+ ++ Navigate users to any LearnCard screen directly from your app. Select a category and feature to configure. +
+launchFeature navigates users to any LearnCard screen
+ Create badge templates that users can send to each other using initiateTemplateIssuance.
+
Creating templates for: {selectedListing.display_name}
+You selected this app in Step 1
+initiateTemplateIssuance with a template URI
+ + Please go back to Step 1 and select an app listing first. +
++ Your selected features require different permissions than your app currently has configured. +
+Changes needed:
+ + {configDifferences.map((diff, idx) => ( +{diff.label}
+ ++ Here's your complete integration code with {selectedFeatures.length} feature{selectedFeatures.length !== 1 ? 's' : ''} configured. + Copy this code to get started or share with your development team. +
+{selectedListing.display_name}
+App ID: {selectedListing.listing_id}
+Configured Features
+ +App Configuration
++ {embedUrl ? 'Configured' : 'Set embed URL, permissions & consent'} +
++ The URL that will be loaded in the iframe when users open your app +
++ Based on your selected features, these permissions are required. You can add more if needed. +
+ ++ Request data sharing permissions when users install your app. + {selectedFeatures.includes('request-data-consent') && (requestDataConsentState.contractUri as string) && ( + Auto-filled from your Request Data Consent setup. + )} +
+ ++ Changes will be saved to your app listing +
+ ++ Preview your app and validate partner-connect API calls +
+TODO placeholders with your actual values+ Use this publishable key to authenticate credential claims from your website. + It's safe to expose in client-side code. +
++ This key can only be used to claim credentials. Keep your secret key secure on your server. +
+No Project Selected
+ ++ Select or create a project using the dropdown in the header to continue. +
++ Add a container element to your page where the "Claim Credential" button will appear. +
+You completed the course. Claim your credential below.
+ + + ++ The SDK replaces the target element with a styled button. When clicked, it opens a modal + for the user to verify their email and claim the credential. +
+ ++ Choose how to load the SDK in your project. +
++ The SDK is a single optimized file (~15KB gzipped) with no external dependencies. + It works on any website — no React, Vue, or framework required. +
++ Build your credential and customize branding for the claim experience. +
+
+ {publishableKey}
+
+ + Change your project using the dropdown in the header. +
++ Select or create a project using the dropdown in the header to continue. +
++ {credentialDescription || 'No description set'} +
+ ++ Shown in the claim modal as the issuing organization +
+Button Preview
+ +publishableKey — Required for real claimscredential — Built using the Credential Builder abovebranding — Customize the claim modal appearancerequestBackgroundIssuance — Ask consent for future issuanceonSuccess — Handle post-claim actions+ Here's a checklist and the user flow to verify everything works. +
+User clicks the claim button
+Opens a branded modal
+User enters their email
+A 6-digit code is sent to verify
+User enters the OTP code
+Credential is issued to their wallet
+Success!
+LearnCard wallet opens, onSuccess is called
+ The SDK remembers logged-in users via localStorage. On their next visit, they'll see an + "Accept Credential" button instead of entering email/OTP again. +
++ Users can now claim credentials directly from your website. +
+ + + View full example on GitHub ++ Your server needs an API token to authenticate with LearnCard. This token should be kept secret + and never exposed in client-side code. +
++ {SCOPE_OPTIONS.find(o => o.value === selectedScope)?.description} +
+{grant.name}
+ ++ Created {new Date(grant.createdAt!).toLocaleDateString()} +
++ Security: Never expose your API token in client-side code or commit it to version control. +
++ A signing authority cryptographically signs your credentials, making them verifiable. + This proves the credentials actually came from you. +
++ Design your Open Badges 3.0 credential using our visual builder. The code will update automatically. +
+API Token
+ +
+ {apiToken ? (
+
+
+ No API tokens found. { e.preventDefault(); onBack(); }} className="text-cyan-600 hover:underline">Go back to create one. +
+ ) : ( +{grant.name}
+ ++ Created {new Date(grant.createdAt!).toLocaleDateString()} +
++ {credentialDescription || 'No description set'} +
+ ++ Enter an email to see the send code. The recipient will get a claim link. +
++ Customize branding, webhooks, and delivery options for the Universal Inbox. +
+ + {/* Branding Section */} ++ Receive a POST request when the credential is claimed. +
++ Don't send an email — get the claim URL to use in your own system. +
++ Run your code, then click below to verify the credential was sent successfully. +
+ + {!isPolling && !pollResult?.success && ( +Waiting for new credentials...
+Run your code now. We'll detect when it's sent.
++ {pollResult.message} +
++ ⚠️ Create an API token in step 1 to enable verification. +
+ )} ++ Run your code to issue a credential, then paste it here to verify it works correctly. +
++ Run the code from the previous step in your application to issue your first credential. +
+ +Paste a credential to verify it
++ You'll need an API token to authenticate webhook requests and make API calls from your server. +
+{grant.name}
+ ++ Created {new Date(grant.createdAt!).toLocaleDateString()} +
++ Create an HTTPS endpoint on your server that can receive POST requests from LearnCard. +
++ LearnCard sends different event types. Handle each one based on your needs. +
+
+ {event.type}
+
+
+ {event.description}
+ + Make sure your webhook endpoint is working correctly before going live. +
+{webhookUrl || 'No webhook URL set'}
++ Your server can now receive real-time events from LearnCard. +
++ Verifiable Credentials (VCs) are digital documents that prove something about a person — + like a badge, certificate, or ID — that can be cryptographically verified. +
+
+{`{
+ "@context": ["https://www.w3.org/2018/credentials/v1"],
+ "type": ["VerifiableCredential", "Achievement"],
+ "issuer": "did:web:university.edu",
+ "issuanceDate": "2024-01-15T00:00:00Z",
+ "credentialSubject": {
+ "name": "Bachelor of Computer Science",
+ "achievementType": "Degree"
+ },
+ "proof": {
+ "type": "Ed25519Signature2020",
+ "verificationMethod": "did:web:university.edu#key-1",
+ "proofValue": "z58DAdFfa9SkqZMVPxAQpic..."
+ }
+}`}
+
+ + You can request credentials from users in different ways depending on your integration type. +
++ Accept credentials posted directly to your API endpoint. +
+ ++ Use the LearnCard SDK to cryptographically verify credentials. No API key required for verification. +
+
+ {checksExplanation}
+
+ + Try verifying a credential right here. Paste a credential JSON below. +
++ You can now accept and verify credentials from users. +
+Loading integration...
+{currentStepInfo.description}
+
+ JSON
+ Choose a template to start with
++ {preset.name} +
++ {preset.description} +
++ Missing required fields: {validationErrors.join(', ')} +
+