The Deep Linking Workflow
This page strictly applies to LTI 1.3 based integrations. If you are looking for how to send assignments or grades to the LMS more generally, please visit this guide instead.
The LTI deep linking flow represents a pretty significant deviation from the way Edlink normally handles the assignment creation process. The most obvious difference is that "push" assignments or coursework into the LMS with an LTI-based connection. Instead, the LMS must "pull" resources from the curriculum platform into its own system.
Even though it is possible to "push" grades into the LMS via what the LTI spec calls "Assignment & Grade Services" (AGS), this process typically only creates a column in the gradebook for a given resource - it doesn't create the resource itself. For example, you can inform Canvas (e.g.) that a gradeable item exists and that it is worth 10 points, but you cannot provide Canvas an LTI launch link that points to your resource.
This limitation requires that we provide support for the LTI deep linking flow. The deep linking flow is the only way to get coursework into the LMS when using an LTI 1.3-based integration.
The Deep Linking Flow
- The user signs into their LMS, selects a course, and clicks "Create Assignment" (or similar).
- The user indicates to the LMS that they want to create an assignment that is connected to a piece of external content (i.e. from your platform).
- The LMS opens an iframe window in a modal above the assignment creation screen.
- The iframe LTI launches into Edlink.
- Edlink silently processes the login and forwards the user down the chain to your primary redirect URI (via our typical OAuth 2.0 flow).
- When your platform exchanges the
authorization_code
for anaccess_token
andrefresh_token
you'll also receive an LTI context object. - The context object will contain details about the user's intent (
select
in this case) and the class they're currently viewing. - Your application should display (ideally) a lightweight UI for selecting one of their resources.
- After the user has made a selection, you should send their selection in a payload.
- Edlink will handle the payload and the LMS will close the iframe.
- When the teacher or students subsequently clicks on the assignment link, they will be launched into your application via our typical OAuth 2.0 flow.
- This time, you'll receive a slightly different
context
object. The intent will beassignment
and it will contain the payload that you shared with Edlink in step #9. - You should display the correct resource to the user.
- If your platform produces submissions or grades, you can send them to Edlink via our normal API endpoints (this process is not LTI-specific).
The Initial LTI Launch
When a user wants to select a piece of content from your platform, the LMS opens up an iframe. Typically, this iframe would point to your LTI launch URL, but since LTI is abstracted by Edlink, the LMS opens up the page to Edlink's LTI launch URL. Edlink processes the launch, captures the launch context, and forwards the user to your primary redirect_uri
(the first one on the list on your application settings page).
This launch will come through to your application as a standard OAuth 2.0 launch (as described elsewhere in the docs). When you make the POST request to exchange your temporary authorization_code
for an access_token
, the API response will contain some additional information - the LTI launch context.
The LTI Context Object
The LTI context object contains two key bits of information:
- The launch
intent
. - The class that the user was viewing when they clicked a link to select a resource from your platform.
When the user is trying to select a resource from your platform for LTI Deep Linking, the intent will always be select
. This is the easiest way to determine that the user wants to select an item from your platform.
It is recommended, but not required, that you consider the class
object that gets returned with the OAuth reseponse. Your platform may choose to show resources available to that class, or to otherwise tailor the teacher's experience based on their class.
{
"$data": {
"access_token": "f7a...746",
"refresh_token": "2cc...81d",
"token_type": "Bearer",
"expires_in": 3600,
"context": {
"version": 2,
"intent": "select",
"custom": {
"custom_param_1": "custom_value_1"
},
"class": {
"id": "8b78e591-ca00-4e16-9ac7-2dd9f9e460fa",
"name": "Math 101",
"description": null,
"state": "active",
"picture_url": null,
"created_date": "2023-01-13T05:44:00.217Z",
"updated_date": "2023-01-13T05:50:59.695Z",
"locale": null,
"time_zone": null,
"school_id": "d20a4cf3-fdcc-4f21-b0fc-f2db854ff63d",
"course_id": null,
"session_ids": [],
"subjects": [],
"grade_levels": [],
"periods": [],
"properties": {},
"identifiers": [],
"materialization_id": "c696449b-f254-47fd-9249-1abc8a0beaf0",
"rules": {},
"product_ids": {}
}
}
},
"$request": "caf2da76-002a-4e5f-baab-6c6ff6dbdeca"
}
Resource Selection
There is no specific process for how the user should go about selecting a resource to assign. Your platform gets to control the user experience.
When the user has selected a given resource, your platform will form a "payload".
- This payload can be any arbitrary Javascript object.
- The payload can contain as much information as you need in order to later identify the resource that the user selected.
- The payload should not contain the actual resource metadata (e.g. the title or description).
Once the user has selected a resource and you've constructed your payload, you are going to use window.parent.postMessage
to send your payload to Edlink. For the unfamiliar, postMessage
is a mechanism to send messages to outer iframes. Edlink will be waiting to receive and process your message.
Resource Payload Properties
Property | Type | Description |
---|---|---|
type | string | Must be set to "lti". |
title | string | The lineItem resource title. |
thumbnail | string | URL to the lineItem resource thumbnail. |
custom | object | A map of key/value custom parameters. |
external_id | string | The lineItem resource ID. |
display_date | Date | The lineItem resource available startDateTime. |
end_date | Date | The lineItem resource available endDateTime. |
start_date | Date | The lineItem resource submission startDateTime. |
due_date | Date | The lineItem resource submission endDateTime. |
For more information on LTI resource linking for lineItems please visit the LTI Deep Linking Specification.
Sample Payload
This is an example of how to return a payload to the Edlink parent window via postMessage
. The target origin must be exactly https://ed.link
. Do not change this value to your own domain name or add any additional parameters.
window.parent.postMessage(
{
type: 'lti',
title: 'Title of Your Attachment',
thumbnail: 'https://thubmnail.url',
custom: {
my_custom_property_1: 'my_custom_value_1',
my_custom_property_2: 'my_custom_value_2'
},
external_id: '000000000000', // this will map to LTI lineItem resourceId
display_date: '2024-09-01T07:00:00.0000Z', // this will map to LTI lineItem startDateTime
end_date: '2024-09-05T12:00:00.0000Z', // this will map to LTI lineItem endDateTime
start_date: '2024-09-05T12:00:00.0000Z',
due_date: '2024-09-04T17:00:00.0000Z'
},
'https://ed.link'
);
Assignment Launch
After the assignment has been created by the teacher, students can access it via their LMS. There is no notification to your platform that the assignment has been created successfully in the LMS prior to a student or teacher launching into it. This is not a limitation of Edlink; it is a limitation of the LTI specification.
This launch will come through to your application as a standard OAuth 2.0 launch. Again, when you make the POST request to exchange your temporary authorization_code
for an access_token
, the API response will contain some additional context.
The LTI Context Object
The LTI context object will contain four key bits of information:
- The launch
intent
(alwaysassignment
in this case). - The class that the user was viewing when they clicked a link to select a resource from your platform.
- The assignment that the user is launching into.
- The original payload that you sent to Edlink when the user first selected the resource.
There's no right answer here, but we recommend implementing a lightweight "assignment viewer" where you provide a trimmed-down version of your standard UI that displays the desired assignment in the relevant class.