Overview
The final step in the issuance workflow delivers the credential offer to the youth’s wallet. This endpoint triggers an email to the youth that initiates automatic credential delivery.
Endpoint
POST https://test.didxtech.com/me-wallet/api/orgs/credentials
Request
curl -X POST "https://test.didxtech.com/me-wallet/api/orgs/credentials" \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
"credentialOffer": "https://didx.co.za/invitation?credential_offer_uri=...",
"recipient": "[email protected]"
}'
Request Body
| Field | Type | Description |
|---|
credentialOffer | string | The offerUri returned from Step 3 (not the QR variant) |
recipient | string | The youth’s email address — must match the email used in Step 1 |
Response
HTTP 201 Created — empty body.
This endpoint returns no response body — just the 201 status code. If your code tries to parse the response as JSON (e.g. response.json()), it will throw a parse error. Check the status code only.
What Happens on the Youth’s Side
- An email is sent to the youth’s email address
- The email triggers automatic delivery of the credential to their wallet
- If the youth has activated their wallet: The credential appears as a pending item. They review the attributes and choose to accept or reject.
- If the youth hasn’t activated yet: The credential is held in the custodial wallet. When they eventually sign in and update their temporary password, the credential is already waiting.
This async behaviour is by design. Some partners onboard youth via WhatsApp — those youth may not activate their wallet for days or weeks. The credential pipeline doesn’t break; it queues.
Complete Issuance Example
Here’s the full four-step flow for Umuzi issuing a credential to Thandi:
# Step 1: Create Thandi's account (done once during programme onboarding)
curl -X POST "https://test.didxtech.com/consumer-onboarding/api/users" \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{"email": "[email protected]", "firstName": "Thandi", "lastName": "Molefe"}'
# Step 2: Create the credential template (done once per credential type)
curl -X POST "https://test.didxtech.com/me-creds/api/templates/credentials" \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
"name": "Web Development Completion",
"code": "web-dev-completion",
"description": "Issued to youth who complete the Umuzi web development programme",
"attributes": {
"programmeName": {"type": "string", "name": "Programme Name", "required": true, "alwaysDisclosed": true},
"completionDate": {"type": "string", "name": "Completion Date", "required": true, "alwaysDisclosed": true},
"fullName": {"type": "string", "name": "Full Name", "required": true, "alwaysDisclosed": true},
"skillsCovered": {"type": "string", "name": "Skills Covered", "required": true, "alwaysDisclosed": false},
"assessmentScore": {"type": "string", "name": "Assessment Score", "required": false, "alwaysDisclosed": false}
}
}'
# Step 3: Issue the credential to Thandi
curl -X POST "https://test.didxtech.com/me-creds/api/credentials/issuance" \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
"credentialTemplateId": "tpl_6421a8905c17830c188e2e2f",
"attributes": {
"programmeName": "Umuzi Web Development Programme",
"completionDate": "2025-03-15",
"fullName": "Thandi Molefe",
"skillsCovered": "HTML, CSS, JavaScript, React, Node.js",
"assessmentScore": "87"
}
}'
# Step 4: Deliver to Thandi's wallet
curl -X POST "https://test.didxtech.com/me-wallet/api/orgs/credentials" \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
"credentialOffer": "https://didx.co.za/invitation?credential_offer_uri=...",
"recipient": "[email protected]"
}'
The issuance workflow is complete. Thandi will receive her “Web Development Completion” credential in her wallet. When she’s ready, she can share it with employers like JobJack — see how verification works.
Troubleshooting
| Problem | Likely cause |
|---|
| Credential doesn’t arrive | The recipient email doesn’t match the email used in Step 1 |
| 400 error on delivery | The credentialOffer is the QR variant instead of the offerUri |
| Youth doesn’t see credential | They haven’t changed their temporary password yet — the credential is waiting in custody |