This document regards the Backpack Connect API for pushing earner badges to the Mozilla hosted Backpack. The API allows issuers to manage persistent access to the earner Backpack without requiring their explicit permission each time a new badge is issued. Earners grant permission when issuers first call the connect method, and can revoke this permission within their Backpack settings at any time.
Interaction with the Backpack is implemented using access tokens. Issuers can use the issue endpoint to send badges to the Backpack, the refresh endpoint to retrieve valid access tokens and the identity endpoint to retrieve hashed earner identity information.
The Backpack Connect API contrasts with the Issuer API, with which the earner has to grant permission each time you try to push a badge to their Backpack.
In order to use the Backpack Connect API, you first need to have your badge assertions(s) prepared. If you're new to badge issuing or assertions, see these pages:
- Issuer Onboarding
- Assertion Information for the Uninitiated
- Assertion Specification
- New Issuers: Give Yourself a Badge
- Issuer Checklist
- Badge tutorial
- Earn a Badge Issue a badge
- Assertion Validator
For a detailed guide to using the Backpack Connect API, see the tutorial.
- Accessing the API
- Methods and Endpoints
connectissuetokenidentity
To access the Backpack Connect API in your site, include the following script:
https://backpack.openbadges.org/issuer.js
You can then use the OpenBadges object to call the connect method to retrieve your access token for pushing earner badges to the Backpack.
Request earner permission to push issued badges to their Backpack.
| Parameters | |
|---|---|
callback |
URL for callback the Backpack will return your access token details to. |
scope |
Type of access you are requesting - use issue to push badges to the Backpack. |
OpenBadges.connect({
callback: "http://yoursite.com/callback",
scope: ['issue']
});You will receive a response at your specified callback including your access token details if successful. The earner will be prompted to grant you access and the Backpack will send data to your callback when they do so, returning the earner browser to your callback location.
| Parameter | |
|---|---|
error |
If the user denied the issuer access to their backpack, this will be set to access_denied. |
access_token |
A string you can use to access the user's Backpack. |
refresh_token |
A string that can be used to obtain a new access token whenever yours expires. |
expires |
The number of seconds that the access token is valid before it needs to be refreshed. |
api_root |
The absolute URL pointing to the root of the user's backpack connect API endpoint. Note that this won't necessarily point to the openbadges.org domain, since a user's Backpack may be located anywhere on the Web. |
The response is sent using GET parameters, e.g.
http://yoursite.com/callback?access_token=abcde&refresh_token=fghij&expires=3600&api_root=https%3A%2F%2Fbackpack.openbadges.org%2Fapi
When access_token expires, you can call token to retrieve a new one.
Push a badge you have awarded an earner to their Backpack. The endpoint is /issue appended to the api_root value you received when you called the connect method.
POST <api-root>/issue
Content-Type should be application/json
The issue endpoint expects:
- your Base64 encoded
access_tokenasBearerin theAuthorizationheader of the HTTP request - the URL or signature for the badge assertion you are pushing to the earner Backpack as
badgeparameter
var claimData = querystring.stringify({
badge: 'http://yoursite.com/badge-assertion.json'
});
var requestOptions = {
host : 'backpack.openbadges.org',//adjust for your api root
path : '/api/issue',
method : 'POST',
headers: { 'Authorization': 'Bearer ' + b64enc('your-access-token'),
'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(claimData)
}
};
var postRequest = http.request(requestOptions, function(pushResponse) {
//...
});
postRequest.write(claimData);{
"exists": false,
"badge": {
"uid": "assertion-uid",
"recipient": "sha256$hashed-email",
"badge": {
"name": "Badge Name",
"description": "Badge description.",
"image": "http://yoursite.com/badge-image.png",
"criteria": "http://yoursite.com/criteria.html",
"alignment": [ ],
"issuer": {
"name": "Issuer Name",
"url": "http://yoursite.com",
"_location": "http://yoursite.com/issuer-organization.json",
"origin": "http://yoursite.com"
},
"_location": "http://yoursite.com/badge-class.json"
},
"verify": {
"url": "http://yoursite.com/public.pem",
"type": "signed"
},
"issuedOn": 1403784577,
"_originalRecipient": {
"identity": "sha256$hashed-email",
"type": "email",
"hashed": true
},
"issued_on": 1403784577
}
}{
"message": "issuer origin must be identical to bearer token origin"
}The API may return an error if:
- the assertion is malformed/ invalid
- no assertion URL or signature is passed
- the assertion is for a different earner
- issuer origin does not match access token origin
- the badge has already been added to the earner Backpack
- your access token has expired
- the access token is invalid
Retrieve a new token to replace an expired one. The endpoint is /token appended to the api_root value you received when you called the connect method.
POST <api-root>/token
Content-Type should be application/json
The token endpoint expects:
grant_typewhich should berefresh_tokento retrieve a replacement for an expired tokenrefresh_tokenwhich should be yourrefresh_tokenreceived when you calledconnectortokenpreviously
The Authorization header is not required for this endpoint.
var claimData = querystring.stringify({
grant_type: 'refresh_token',
refresh_token: 'your-refresh-token-value'
});
//where api root is backpack.openbadges.org/api
var requestOptions = {
host : 'backpack.openbadges.org',
path : '/api/token',
method : 'POST',
headers: {'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(claimData)
}
};
var postRequest = http.request(requestOptions, function(refreshResponse) {
//...
});
postRequest.write(claimData);{
"expires": 3600,
"access_token": "new-access-token",
"refresh_token": "new-refresh-token"
}- The new
access_tokenshould be used for any subsequent calls toissue. - The new
refresh_tokenshould be used for any subsequent call totoken.
Retrieve the hashed email for the current Backpack user. You can use this to issue badges without direct access to the earner email address. The endpoint is /identity appended to the api_root value you received when you called the connect method.
GET <api-root>/identity
The identity endpoint expects:
- your Base64 encoded
access_tokenasBearerin theAuthorizationheader of the HTTP request
var requestOptions = {
host : 'backpack.openbadges.org',//adjust for your api root
path : '/api/identity',
method : 'GET',
headers: { 'Authorization': 'Bearer ' + b64enc('your-access-token') }
};
var idRequest = http.request(requestOptions, function(idResponse) {
//...
});{
"recipient": "sha256$hashed-email",
"salt": "_123abc456",
"type": "email"
}These values can be used directly within a new badge assertion with the following fields:
recipientidentityset to the receivedrecipientvaluehashedset totruetypeset toemailsaltset to the recievedsaltvalue