Send Credentials

How-To Guide: Sending Credentials with LearnCard

This guide provides practical, step-by-step recipes for sending credentials. We'll start with the simplest possible use case and progressively add more powerful configurations.


The send method is the simplest and most ergonomic way to send credentials to recipients. It handles credential issuance, signing, and delivery in a single call.

The send method automatically detects your recipient type:

  • Profile ID β†’ Direct delivery to their LearnCard

  • DID β†’ Direct delivery via DID resolution

  • Email β†’ Routes through Universal Inbox (sends claim email)

  • Phone β†’ Routes through Universal Inbox (sends claim SMS)

Prerequisites

  • LearnCard SDK initialized with network: true

  • A signing authority configured (for server-side signing) OR local key material available (for client-side signing)

Basic Usage

// Send to an existing LearnCard user
const result = await learnCard.invoke.send({
    type: 'boost',
    recipient: 'recipient-profile-id', // or 'did:key:z6Mk...'
    templateUri: 'urn:lc:boost:abc123',
});

console.log(result.credentialUri); // URI of the sent credential
console.log(result.uri);           // URI of the boost template used

How It Works

  1. Detects recipient type - Automatically determines if recipient is email, phone, DID, or profile ID

  2. Routes appropriately - Uses direct send for profiles/DIDs, Universal Inbox for email/phone

  3. Prepares the credential - Uses your template or creates a new boost on-the-fly

  4. Signs the credential - Uses client-side signing if available, otherwise falls back to your registered signing authority

  5. Delivers the credential - Direct delivery or sends claim email/SMS based on recipient type

  6. Auto-delivery for verified users - If the email/phone is already verified and linked to a LearnCard profile, the credential is delivered directly to their wallet without requiring them to click a claim link

Response

circle-check

Options (for Email/Phone Recipients)

When sending to email or phone recipients, you can provide additional options:

circle-info

Contract Integration: When you provide a contractUri, the method automatically:

  • Checks if the recipient has consented to the contract

  • Routes the credential through the consent flow if terms exist

  • Creates a RELATED_TO relationship between new boosts and the contract

circle-info

Email Verification: When a recipient claims a credential via an email claim link, their email address becomes a verified contact method linked to their LearnCard profile. This means:

  • Future credentials sent to that email will be auto-delivered directly to their wallet

  • No claim link is needed for subsequent issuances

  • The issuer receives status: 'ISSUED' instead of status: 'PENDING'


Tracking Boost Recipients

You can track which users have received credentials from a specific boost template using getBoostRecipients:

This is useful for:

  • Auditing: See who has received a specific credential

  • Preventing duplicates: Check if a user already received a boost before sending

  • Analytics: Track issuance metrics for your credentials


Dynamic Templates with templateData

Use Mustache-style templates to personalize credentials with unique data for each recipient. This is perfect for issuing the same type of credential (like course completions) with recipient-specific details.

Creating a Templated Boost

First, create a boost with {{variableName}} placeholders:

Sending with Personalized Data

Provide templateData when sending to substitute the variables:

The issued credential will have all placeholders replaced with the provided values.

Batch Issuance to Multiple Recipients

Special Characters

Template values are automatically escaped for JSON safety. You can safely include:

  • Quotes: "Course with \"quotes\""

  • Newlines: "Line 1\nLine 2"

  • Backslashes: "Path\\to\\file"

  • Unicode: "CafΓ© β˜• ζ—₯本θͺž"

circle-info

Missing Variables: If a variable in the template isn't provided in templateData, it renders as an empty string. This allows for optional fields.

For more details, see Dynamic Templates with Mustache.


Alternative: Universal Inbox API

For advanced use cases requiring full control over the inbox issuance process, you can use the sendCredentialViaInbox method directly. This is useful when you need:

  • Full configuration control (signing authority, expiration, etc.)

  • To send raw credentials (not boost templates)

  • Custom template IDs for email/SMS

This approach assumes you are familiar with the core concepts of the Universal Inbox and have a valid API token & signing authority set up.

1. The Simplest Case: Fire and Forget

Your goal is to send a single, verifiable record to a user. You want our system to handle all the complexity of signing the credential and notifying the user.

This is the most common use case, perfect for one-off issuances like a course completion certificate.

The Recipe: Make a POST request to the /inbox/issue endpoint with only two required fields: recipient and a signed or unsigned credential. An unsigned credential requires a configured signing authority.

Example:

circle-exclamation

Have you configured your default Primary Signing Authority?

What Happens:

  • Our system receives the unsigned credential data.

  • It sends a professionally designed email to [email protected] with a secure link to claim their record.

  • When the student claims their record, it automatically signs it using your default Primary Signing Authority attached to your profile.

You're done. The rest of the user onboarding and claim process is handled for you.

2. Customizing the User Experience

Your goal is to send a credential, but you want the notification email to be branded with your organization's identity to build trust and recognition.

The Recipe: Use the optional configuration.delivery.template.model object to provide your branding details.

Example:

What Happens: The email sent to the student will now feature the State University name and logo prominently, creating a more professional and trustworthy experience.

3. Taking Control of Delivery and Status

You have more advanced needs. You might want to deliver the claim link through your own system (e.g., inside your web portal) or need to know precisely when a user has successfully claimed their record.

Recipe 3a: Suppressing Delivery

Goal: You want to get a claimUrl from our API but prevent us from sending any emails or texts.

The Recipe: Set configuration.delivery.suppress to true.

Example:

Recipe 3b: Tracking Status with Webhooks

Goal: You need your system to be notified when a user successfully claims their credential so you can update your internal database.

The Recipe: Provide a configuration.webhookUrl.

Example:

What Happens: When the user claims their record, our system will send a POST request to your webhook URL with a payload containing the issuanceId, a status of CLAIMED, and the user's permanent recipientDid.

4. Advanced: Building an Ongoing Relationship

circle-exclamation

Goal: You plan to send credentials to the same user repeatedly over time (e.g., skill badges, course completions). You want to ask for their permission once, so future records can be sent directly to their passport without them needing to claim each one individually.

The Recipe: On the first issuance, include the consentRequest object.

Example:

What Happens:

  1. The employee claims their first badge as normal.

  2. Immediately after, a prompt appears asking for their permission based on your description.

  3. If they allow it, your webhook receives a notification that includes a contractId.

  4. For all future issuances to this user, credentials will appear directly in their passport, friction-free.

Last updated

Was this helpful?