Showing results for 
Search instead for 
Did you mean: 
Community Member

Deep linking LTI External Tool

Jump to solution

So my tool creates bits of user generated content, and it is very handy to be able to provide a url that links directly to one of those pieces of content.  However I can't passes any arguments to the external tool definition that canvas uses to perform the basic lti launch

I want to be able to do something like this

https://canvas/courses/14/external_tools/25?link=/deep/content/link  => https://my.tool.url/lti?link=/deep/content/link

I understand that canvas does not currently repackage GET params, from the launch link back into the basic_lti_launch, however I am looking for a solution that can achieve this same effect.

Is there any other way to accomplish this, where I can pass arbitrary url parameters thru to the external tool launch?


This needs to be a solution that doesn't require any admin rights, i.e. a student can generate the url for sharing etc..

Labels (1)
1 Solution

Accepted Solutions
Community Member

Here is the workaround that I ultimately settled upon .. and it is working well.

I created a page inside my application that acts as a redirector (lets call it deeplink); the code flow works like this

  1. /deeplink?redirect=/path/to/deep/content
  2. the page body for deeplink takes the redirect param and puts it in a cookie and redirects to an LTI app installed inside canvas. i.e.  forward to:  https://canvas/courses/14/external_tools/25
  3. Then that external tool forces an LTI Launch on my application /deeplink
  4. now the page body checks and sees the existence of a redirect cookie and redirects the user to the appropriate page.

View solution in original post

19 Replies
Adventurer III

I'm not an expert with the external tools (I hate them, actually), but I believe I've worked with them enough to be able to answer this (just take it with a grain of salt).

When you configure the "External App", you have to supply a Launch URL. You could add it directly to this. We have to do this for integration of Bookshelf Online and Chalk & Wire Learning Assessment. So, assuming "https://my.tool.url/lti" is your current ​Launch URL​, simply add to the end of it that additional string you want to use. This would also help you to avoid in issues with regards to their new policy of allowing only one Launch URL per access path, assuming you need to load multiple links with a different additional field.

For multiple links off the same base Launch URL, you could alternatively leave the ​Launch URL​ as "https://my.tool.url/lti" and add the additional portion to wherever it is linked. This'll allow you to have the single "External App" while using different additional GET parameters. This is the solution we use for the two scenarios I mentioned, and it's worked fairly well, despite the subtle changes Instructure has made over the last year that seems to be targeted at ending use of multiple external tools from the same source.


Thanks for the reply, unfortunately I need to use something similar to #2 where I can create the urls more dynamically, however I need to be able to pass a launch url that I can trigger from outside canvas, so that it will pass thru the canvas SSO flow.

The problem is I when I append params onto the courses/{id}/external_tools/{id}?myparam=test  and canvas converts that url into an LTI launch with post params, it does not append the additional GET params into the launch post.


Where exactly are you putting the change at? There shouldn't be any point where you're appending it to the end of a Canvas-generated URL.

Here's what I'm referring to with that second scenario:


The Launch URL of the "External App" is "", as shown above. The problem is that we load this external tool multiple times into a course, targeting a different point. To do this, every time that tool is selected, the URL is modified to point to the intended target:


The "External App" is a single configuration, but by modifying the URL where it is used, we use the desired configuration with the desired destination.

At no point is there a modification to a Canvas-generated URL. "/courses/1234/modules/items/12345678" remains unchanged, but it's destination goes to where we wanted it to.

With regards to the GET​ vs ​POST, I did say I'm not an expert with ​external tools​, so what is entered as a ​GET​ in the configuration may be converted to a POST, though that wouldn't make any sense to me.


I understand that I *shouldn't* be appending to the canvas generated url, however that is the very effect that I am trying to achieve, and modifying the launch configs is not an option (I would have to generate 10000s of launch configs for each course).  There ought to be a way to create a deep link to content contained inside a LTI application where you can create a specific reference to it in a canvas wiki page, or in a discussion in such a way that when I click on the wiki link it

1) Launches the LTI application

2) Passes some addtl deep link parameter into the lti application so the app can forward you to a specific piece of content.


With what I described, you only have one "External App" configuration. Here's a short video I just made to demonstrate this:


Again, I fully understand that, but you are missing my key point.

Imagine a scenario where a student uses an LTI tool to author a piece of content, and then wants to send a link to that content to another student/teacher etc..  the most natural way to do this would be via a link.  However you cannot generate a link to a backend lti tool, because you won't be passing thru the canvas SSO process and the backend LTI tool will have no context as to who you are.

This is why I am asking if there is a way to generate links that passes parameters thru the canvas side of the link [thus making them stable, and able to be sent to people who might not have an active sign-in cookie] to the backend lti application.


Ah, you didn't mention it was for use by students. Teachers could just use the process I provided and provide the module link, but student cannot. That's the key difference between what I was demonstrating and what you wanted but didn't mention.

Alright, in that case it is not possible through the external tool. You'd have to make a non-LTI access method to allow this. Modifying a Canvas URL requires Canvas to process that additional data. Any changes not strictly covered by the LMS will be ignored. Any changes covered by the LMS will be handled by Canvas as it sees fit.

Simply put, you should avoid trying the modify "/courses/:course_id/external_tools/:id" to provide your parameters and seek an alternate solution.

VitalSource has a similar issue with its deeplinking. They support deeplinking via a standard anchor, but the user must be authenticated. With an external tool, authentication is automatically done, but a basic hyperlink won't do this. The only solution to making these work for VitalSource (since we're limited to one configuration per Launch URL and deeplinking via LTI requires Custom Parameters) is to instruction the user (student or teacher) to access the LTI if accessing a deeplink doesn't work, then try the deeplink, again.

You'd need a similar process to make something work that would be manipulable by students.


Since apparently it's not possible to have Canvas do it for you, see if you can create a "sharable string". When a user decides to share something, instead of generating a deep link, create something like "aardvark316" or whatever (which is mapped to however you store the necessary state).

Another user can then type that code in to see (and hopefully bookmark somehow) the relevant content.

It is a bit of a kludge, but if you do your UX right, you might be alright.

To make it possible to actually make a deep link, I believe you might need to change the code around here to append any params to the URL. I don't know where that data would come from, since I'm not really familiar with Canvas' inner workings.


I'm not very experienced with Ruby (Canvas is my first real working with the language), so I didn't want to go into the code to supply and answer when I wouldn't be sure of its accuracy. Further, it doesn't do much good for those using Instructure-hosted instances as we're unable to modify the code.

The suggestion of a short url feature is good, but that also adds a requirement to store the short url identifier and it's target destination. If there's already a dynamic data storage method in place on the target system, which is most likely so since the target is an external tool system, this would be a minor thing to accommodate. It, however, the external tool system is actually a static data system the only authenticates access, this could prove more difficult since such a system wouldn't actually require dynamic data storage.

In all, I think it's brilliant, but I wanted to clarify it's requirements. Smiley Happy