Performing Dynamic Registration
Make sure you've read about authenticating API requests before proceeding to the guide below.
The Dynamic Registrations API endpoints only accept the bearer api key based authentication method.
How Dynamic Registration Works
LTI® Dynamic Registration is used to automate the LMS/tool registration process. Several LMSes support it, including Canvas, Moodle, and Brightspace. The default Dynamic Registration process is as follows:
- The LMS administrator enters your dynamic registration URL into their LMS:
https://your.ltiaas.com/lti/register - LTIAAS communicates with the LMS and completes the registration process automatically.
- (optional) The LMS administrator can open the registered tool and modify any pre-defined settings as needed.
Controlling How Much User Data the LMS Sends (Privacy Level)
By default, registrations request the public privacy level, meaning the LMS sends full user information (name and email) on each launch. You can request that the LMS send less personal data by choosing a different privacy level:
| Privacy level | User data sent on launch |
|---|---|
public (default) | Full name and email |
name_only | Name only |
email_only | Email only |
anonymous | No name or email — only the stable, opaque user id (sub) |
There are three ways to set it, in order of precedence (highest first):
Registration completion body (Pre-Approval) — if you use the Pre-Approval flow, pass
privacyLevelin the body of the Complete Registration API call (see below). This overrides everything else.Registration URL — append a
privacyLevelquery parameter to the Dynamic Registration URL the LMS administrator enters:https://your.ltiaas.com/lti/register?privacyLevel=anonymousThis works in both the standard and Pre-Approval flows. In the Pre-Approval flow the value is carried through as the default and can be overridden by the completion body above — you can read it back from the Get Registrations API (
privacyLevelfield).Account-wide default — the default privacy level applied when no per-registration value is given, configured for your account in the LTIAAS Portal.
The privacy level is declared at registration time — changing it afterwards means re-registering the tool. On Canvas, any level other than public also stops Canvas custom fields (such as custom_canvas_user_id) from being sent. If you need the Canvas numeric user id, use public; otherwise the stable LTI sub is available at every privacy level.
In some cases, it is not desirable to allow specific users or LMSes to register your tool. There are two general scenarios that might require approval/intervention while doing dynamic registration:
- Simple Approval: If you want to allow any user to register your tool, but want to manually approve each registration before it can be used, you can simply enable the
Dynamic Registration Auto-Activationfeature in the LTIAAS Portal within the API Settings page. - Account Authentication or Payment: You might want to require the user to login to your service or submit payment before allowing the registration to complete. LTIAAS has APIs that enable this flow that we call Dynamic Registration Pre-Approval.
If all you need is simple approval, you can stop reading here.
The Pre-Approval Flow
The Dynamic Registration Pre-Approval flow is disabled by default. It can be enabled in the LTIAAS Portal under the API Settings page by enabling the Enable Pre-Approval option.
The LTIAAS Dynamic Registration Pre-Approval flow consists of 4 steps:
- Initiate Dynamic Registration
- Pre-Approval Redirection
- Get Registration Data
- Submission of registration approval and/or settings override
Initiate Dynamic Registration
Just like in the 'vanilla' dynamic registration described above, the LMS administrator initiates Dynamic Registration by entering the Dynamic Registration URL into their LMS: https://your.ltiaas.com/lti/register.
Pre-Approval Redirection
Because the Enable Pre-Approval option is true, the user is redirected to the URL you entered into the Pre-Approval URL field of the API Settings page. This page will receive a query parameter called registrationId. For example:
https://yoursite.com/intermediateTarget?registrationId=123
You will use the registrationId to get information about the LMS and complete/approve the registration process.
Get Registration Data
Once LTIAAS has redirected to your Pre-Approval URL, you can use the registrationId query parameter to get information about the LMS using the Get Registrations API.
// Building Bearer API authentication header
const authorizationHeader = `Bearer ${API_KEY}`
const headers = { Authorization: authorizationHeader }
// Get the registrationId (from the front-end)
const registrationId = req.query.registrationId
// Making /api/registrations GET request (called in your back-end)
const response = requests.get(`https://your.ltiaas.com/api/registrations/${registrationId}`, { headers })
const url = response['url']
const lmsFamily = response['familyCode']
//... and other data
A successful response will contain details about the LMS and the options it supports.
{
"url": "https://moodle.ltiaas.com",
"familyCode": "moodle",
"version": "4.4.1+ (Build: 20240705)",
"supportedScopes": [
"https://purl.imsglobal.org/spec/lti-bo/scope/basicoutcome",
"https://purl.imsglobal.org/spec/lti-ags/scope/lineitem.readonly",
"https://purl.imsglobal.org/spec/lti-ags/scope/result.readonly",
"https://purl.imsglobal.org/spec/lti-ags/scope/score",
"https://purl.imsglobal.org/spec/lti-ags/scope/lineitem",
"https://purl.imsglobal.org/spec/lti-nrps/scope/contextmembership.readonly",
"https://purl.imsglobal.org/spec/lti-ts/scope/toolsetting",
"openid"
],
"supportedMessages": [
{
"type": "LtiResourceLinkRequest"
},
{
"type": "LtiDeepLinkingRequest",
"placements": [
"ContentArea"
]
}
]
}
The registrationId parameter is not persistent. It can only be used to get information about a potential registration and to complete a registration. Once the registration is completed or abandoned, the registrationId will no longer work.
Submission of Registration Approval and Settings Override
During the dynamic registration process, you are free to redirect to other pages on your site, for example to allow the user to log in. It is important to not leave the context of the dynamic registration iframe, because the iframe is used by LTIAAS to communicate with the LMS.
When you are ready to approve the registration, you can use the Complete Registration API.
// Building Bearer API authentication header
const authorizationHeader = `Bearer ${API_KEY}`
const headers = { Authorization: authorizationHeader }
// Get the registrationId
const registrationId = req.query.registrationId
// build the registration completion message
const body = {
// These are all optional, defaulting to the stored values set in the LTIAAS Portal
platformName: 'Platform name',
autoActivate: true,
privacyLevel: 'public', // 'public' (default), 'name_only', 'email_only', or 'anonymous'
messages: [
// Canvas placements are fully qualified URLs; Brightspace uses the standard bare names
{ type: 'LtiResourceLinkRequest', placements: ['https://canvas.instructure.com/lti/assignment_selection'] },
{ type: 'LtiDeepLinkingRequest', placements: ['ContentArea'] }
// LTIAAS will validate each of these placements, only sending the ones allowed by the LMS
]
}
// Making /api/registrations POST request
const response = requests.post(`https://your.ltiaas.com/api/registrations/${registrationId}/complete`, body, { headers })
const htmlToInject = response['html']
return htmlToInject
Choosing Placements
Placements tell the LMS where your tool should appear. The identifiers are LMS specific, and they must be sent exactly as the LMS advertised them. LTIAAS validates each placement against the list the LMS provided when it started the registration and silently drops anything that doesn't match — so a misspelled or wrongly formatted placement is discarded rather than raising an error.
The safest approach is to read supportedMessages[].placements from the Get Registrations API response and pick from those exact strings. Use familyCode to branch when you need to request different placements per LMS.
| LMS | familyCode | Format | Official list |
|---|---|---|---|
| Canvas | canvas | Fully qualified URLs prefixed with https://canvas.instructure.com/lti/, e.g. https://canvas.instructure.com/lti/course_navigation | Canvas placements overview and the Canvas LTI registration docs |
| Brightspace | desire2learn | Bare, standard names only: ContentArea and RichTextEditor | Brightspace tool registration, deployment, and links and Deep linking extension with LTI 1.3 |
ContentArea and RichTextEditor are the only placements defined by the LTI® Dynamic Registration specification itself, and every other value is a vendor extension. Canvas accepts both — it maps ContentArea onto its link_selection placement and RichTextEditor onto editor_button. If placements is omitted entirely, deep linking defaults to ContentArea.
The full per-placement breakdown, including which message types each Canvas placement supports, is in the Complete Registration API reference.
This will return an html snippet that needs to be appended to the document that is in the active iframe for this registration.
{
platformId: "A2F48n9Ss8Hjpw4gjo0",
html: "<script>(window.opener || window.parent).postMessage({subject:'org.imsglobal.lti.close'}, '*');</script>"
}
The platformId that is returned in this step is persistent. It can be used later on to update, activate, or deactivate the platform registration.
Here's an example of completing the process by appending the html snippet to the active iframe's document body.
// Front-end
// Append returned script to HTML body
$('body').append(htmlToInject)
Platform Registration Management
Once dynamic registration (or manual registration) is complete, you can use the platformId to manipulate the registration via the /admin/platforms API. See our Platforms API reference for more information.
