SETUP GUIDE · CANVAS ADMIN

How do I install Lectora in Canvas with LTI 1.3?

This guide is for Canvas administrators installing Lectora institution-wide via LTI 1.3 Dynamic Registration — about fifteen minutes of work that ends with every teacher in your Canvas instance launching Lectora directly from a course's left navigation, no per-teacher tokens to manage. The install creates two Canvas Developer Keys: an LTI Registration key (created automatically by Dynamic Registration) and a separate API Key for Canvas REST API access that lets Lectora read submissions and post back the grades and feedback a teacher has approved. Lectora drafts; the teacher approves and publishes; nothing reaches Canvas on its own. Both are required — Canvas's LTI keys can't perform the OAuth authorization_code grant Lectora needs for API access, so the API Key is a second key you create manually before confirming the LTI registration. If you only want a single teacher to try Lectora on their own courses before involving IT, the personal access token quickstart is the lighter path. For multi-teacher deployments, LTI 1.3 is the only compliant option — Canvas's API Policy restricts personal access tokens to single-user use.

Why LTI 1.3 (and not per-teacher tokens)?

For multi-teacher deployments, LTI 1.3 is the only compliant integration path. The Canvas API Policy and Canvas's OAuth2 manual-token-generation docs restrict personal access tokens to personal, single-user use; a third-party app that asks each teacher to generate and hand over a token isn't a compliant integration.

Beyond compliance, the LTI install also gives you one-click teacher onboarding (teachers just open Lectora from a course's left navigation, no signup or token to copy), centralised lifecycle control (toggle the LTI Developer Key OFF and Lectora stops working everywhere instantly), stable identity (Canvas issues signed JWTs on every launch, with no long-lived secrets sitting in user accounts that can leak or get forgotten when a teacher leaves), and a single institution-level OAuth Developer Key — separate from the LTI key, created during the install — that handles Lectora's Canvas API access for every teacher in one place, so teacher-approved grades pass back to Canvas without per-teacher tokens.

What gets installed?

Two Canvas Developer Keys with two distinct roles. The API Key lets Lectora call the Canvas REST API on each teacher's behalf — reading submissions, and posting back the grades and feedback that teacher has approved — using the OAuth 2.0 authorization_code grant. You create it manually in Step 2 by clicking + Developer Key → API Key and copying its Client ID and Secret out. The LTI Registration key handles "click Lectora in the course sidebar and get logged in" — it implements the LTI 1.3 launch handshake, signed JWTs, and the course-navigation placement. Canvas creates it automatically when you run Dynamic Registration in Step 3 (+ Developer Key → LTI Registration).

Both keys are required. Canvas LTI keys can't perform the OAuth authorization_code grant, so the API Key is not something the LTI Registration can replace — they're two complementary keys for two different protocols. The only manual paste anywhere in the flow is the API Key's Client ID and Secret from Step 2 into the Dynamic Registration confirmation iframe in Step 4. No JSON, no config files, no manual key generation.

One quietly useful detail: when you run Dynamic Registration at the Admin level (the default for institution-wide installs), Canvas automatically creates the External App entry for Lectora at that account too. By the time you finish Step 5, Lectora is available in every course under the account where you registered. The per-course manual install step is only needed for narrow, single-course pilots — see Step 6 for the verification and the narrow-rollout path.

What do you need before starting?

Three things. Canvas admin access at the Site Admin or root account level — without that you won't see Developer Keys in the admin menu. Your Lectora URL — https://www.lectora.app. We run it and patch it; your team operates no infrastructure. If your institution has strict data-residency requirements, Lectora runs entirely in the EU/EEA — see what Lectora accesses and where data lives. The registration endpoint is always your Lectora URL plus /api/lti/register. And network reachability in both directions. Your Canvas and your users' browsers must reach https://www.lectora.app over HTTPS. If your Canvas sits behind a firewall, VPN gate or web application firewall that blocks requests from outside your network, Lectora's servers also need an exception to reach it. The network access section below says what to allow; arrange it with your network team before the install.

A note on the two Developer Keys you'll create. The LTI Registration Developer Key is created automatically when you complete Dynamic Registration in Step 3 — it handles teacher launches from the course sidebar. A separate API Developer Key for Canvas REST API OAuth is created manually in Step 2 below and pasted into the Dynamic Registration confirmation page — it lets Lectora read submissions, and — once the teacher has approved a draft and chosen to publish it — post that grade and feedback back to Canvas under that teacher's own Canvas identity. The API Key is a separate key because Canvas LTI keys don't support the authorization_code OAuth grant; this is a Canvas constraint, not a Lectora one. Without the API Key, Canvas will reject the Dynamic Registration submission, so we create it first.

Step 1 — Open Developer Keys

  1. In Canvas, click Admin in the left sidebar.
  2. Choose Developer Keys from the admin menu.

You'll land on the Developer Keys list — usually empty for new installs, or showing any existing third-party tools.

Step 1 — Canvas Admin sidebar → Developer Keys

Step 2 — Create the Canvas API Developer Key

A separate Developer Key — distinct from the LTI Registration key — that lets Lectora call the Canvas API to post back the grades a teacher has approved. The Dynamic Registration confirmation iframe in Step 4 has required fields for this key's Client ID and Secret, so create it now to have those values ready.

  1. On the Developer Keys page, click + Developer Key in the top-right.
  2. Choose + API Key from the dropdown (the top option of three).
  3. Fill in the Key Settings form. Leave everything else at its defaults:
    • Key Name — Lectora API Access
    • Owner Email — your admin email (Canvas sends rotation and maintenance notifications here)
    • Redirect URIs — paste both Lectora OAuth callback URLs below, one per line
    • Icon URL — https://www.lectora.app/icon.svg
  4. Set Enforce Scopes to OFF. Newer Canvas instances default it to ON. With it on, Canvas rejects every teacher's authorization until Lectora holds your institution's scope list, so leave it off for the install.
  5. Click Save.
  6. On the Developer Keys list, toggle the new key's State to ON.
  7. Copy the Client ID from the Details column (a long numeric string like 10000000000040).
  8. Click Show Key to reveal the Secret, copy it, and paste both Client ID and Secret into a temporary scratch pad. You'll need them in Step 4.

Scoping the key is worth doing once the install works, because a leaked token with unrestricted scopes can do more than a scoped one. It takes one coordinated step with us, described in the Enforce Scopes section below. Don't switch it on alone.

OAuth callback URL — first line of the API Key's Redirect URIs field.

https://www.lectora.app/api/auth/canvas/callback

Second line. Canvas compares redirect URIs exactly, so list both hosts.

https://lectora.app/api/auth/canvas/callback

Step 2 — + Developer Key dropdown, API Key option highlighted

Step 2 — Key Settings form, fields filled in

Step 2 — Show Key modal. Canvas only shows the secret once; copy it now.

Step 3 — Start a Dynamic Registration

With the API Key credentials safely copied, you're ready to register Lectora as an LTI tool.

  1. Back on the Developer Keys list, click + Developer Key again in the top-right.
  2. Choose + LTI Registration from the dropdown (the third option).
  3. In the modal that opens, choose Dynamic Registration (the first option).
  4. Enter your Lectora registration endpoint in the URL field (below).
  5. Click Continue.

Lectora's LTI registration URL.

https://www.lectora.app/api/lti/register

Step 3 — + Developer Key dropdown again, this time choose LTI Registration

Step 3 — Dynamic Registration dialog with the URL entered

Step 4 — Confirm the installation

Canvas opens Lectora's confirmation page inside an iframe. It shows the Canvas instance Lectora detected, the placements Lectora will request (course navigation), and two required OAuth credential fields.

  1. Paste the Client ID you copied in Step 2 into the OAuth Client ID field.
  2. Paste the Secret you copied in Step 2 into the OAuth Client Secret field.
  3. Review the placements (course navigation should be checked).
  4. Click Confirm Installation.

The iframe closes automatically on success.

Step 4 — Confirmation page with the OAuth Client ID and Secret pasted in from Step 2

Step 5 — Enable the LTI Developer Key

Back on the Developer Keys list, you'll now see two Lectora rows — the API Key from Step 2 (already ON) and the new LTI Registration key (starts OFF).

  1. Find the new LTI Registration row.
  2. Toggle its State to ON — new keys start OFF.
  3. Copy the Client ID of the LTI Registration key from the Details column. You'll need it in Step 6 (a long number, typically 10000000000123 or similar).

Step 5 — Both keys ON. Two keys, both green — the install is complete on the Canvas side.

Step 6 — Verify Lectora is installed (and optionally narrow the scope)

Good news: the tool is already installed. When you ran Dynamic Registration in Step 3 at the Admin level, Canvas automatically created an External App entry for Lectora, and toggling the LTI key ON in Step 5 activated it across every course beneath that account.

  1. Go to Admin → Settings → Apps tab → View App Configurations.
  2. Look for a Lectora row in the list — that confirms the account-level install landed.

If you ran Dynamic Registration at the root account, every course in your Canvas instance can now show Lectora — jump to Step 7 to verify a teacher-side launch.

Optional — narrow-rollout path. Use this only when you want to pilot Lectora with one department, school, or course before rolling out wider. If the tool is already installed account-wide, skip this step; Lectora's already available everywhere.

  1. Open the course → Settings → Apps tab → View App Configurations.
  2. Click + App in the top-right.
  3. Set Configuration Type to By Client ID.
  4. Paste the LTI Registration key's Client ID from Step 5.
  5. Click Submit, then confirm when Canvas asks Tool found, install?.

Rare fallback. If Lectora isn't listed in Admin → Settings → Apps after Step 5, the auto-install didn't happen. Install it manually using the same flow as the narrow-rollout path above, but at the admin level (Admin → Settings → Apps → + App → By Client ID → paste → Submit).

Step 6 (narrow rollout only) — per-course install via By Client ID

Step 6 fallback — drag Lectora from hidden to visible in the course's nav order

Step 7 — Verify it works

Fastest end-to-end test:

  1. Open a course where Lectora is installed.
  2. Click Lectora in the left sidebar.
  3. Confirm the Lectora course view loads inside Canvas with your courses listed.

If you got here, installation is complete. Teachers in any installed course can now use Lectora without any additional setup — send them a one-liner: "Open any course where Lectora is installed and click Lectora in the left sidebar; it'll log you in automatically."

Step 7 — successful launch from a teacher's perspective

Does your Canvas sit behind a firewall or VPN gate?

Skip this section if your Canvas is reachable from the internet, for example an Instructure-hosted *.instructure.com address with no gate of your own in front of it. It matters when your Canvas domain sits behind a firewall, a VPN gate or a web application firewall (for example Azure Front Door) that blocks or redirects requests from outside your network.

Lectora's servers call your Canvas on behalf of teachers: the Canvas API, the OAuth token endpoint and, when your Canvas issues its own LTI identity, the LTI endpoints. Those requests come from outside your network, so they need an exception. What teachers do in their browsers (the LTI launch, the Canvas consent page, Canvas itself) comes from their own devices, which are already on your network or VPN, and needs nothing extra.

WhatValue
Source addresses155.121.236.3, 155.121.236.4, 155.121.236.5 (fixed; Frankfurt, EU)
ProtocolHTTPS on TCP 443, to your Canvas host
User-AgentLectora/<version> (+https://lectora.app): match the prefix Lectora/
DirectionFrom Lectora's servers to your Canvas. Browser traffic needs no exception.

The paths Lectora's servers call on your Canvas host:

PathMethodWhat it is
/api/v1/**, /api/quiz/v1/**GET, POST, PUT, DELETEThe Canvas REST API: courses, rosters, assignments, submissions, grade and comment write-back, files, rubrics, quizzes
/login/oauth2/tokenPOST, DELETEIssuing, refreshing and revoking teachers' Canvas tokens
/files/:id/download, /courses/:id/files/:id/downloadGETThe first step of a file download; Canvas then redirects to its file storage
/api/lti/security/openid-configuration, /api/lti/registrations, /api/lti/security/jwksGET, POSTLTI registration and the key set that verifies launches, when your Canvas issues its own LTI identity
/api/lti/courses/:id/names_and_rolesGETThe LTI roster, only if roster sync is switched on

How to write the exception:

  • Match the IP address of the connection. On Azure Front Door that is SocketAddr ("Socket address"), not RemoteAddr, which is read from X-Forwarded-For and can be set by any client.
  • Optionally, also match the User-Agent prefix. A second condition, User-Agent begins with Lectora/, narrows the exception and makes Lectora's traffic easy to find in your logs. Anyone can send that header, so it identifies our traffic but doesn't authenticate it. Never match the full string, because the version changes with every release.
  • Allow, early. Evaluate the rule before your VPN redirect and before any geo, rate-limit, JavaScript-challenge or CAPTCHA rule. A server can't solve a challenge.
  • Check the enforcement mode. On Azure Front Door, the WAF policy must be in Prevention mode. In Detection mode nothing is enforced, this Allow included.
  • Treat it as a filter. The three addresses belong to a pool our hosting provider shares with a small number of other customers. Every request still needs a valid Canvas token or signature; the exception only lets it past the gate.

An Azure Front Door WAF custom rule, as the rule object to merge into your policy's custom rules:

{  "name": "AllowLectora",  "priority": 5,  "enabledState": "Enabled",  "ruleType": "MatchRule",  "action": "Allow",  "matchConditions": [    {      "matchVariable": "SocketAddr",      "operator": "IPMatch",      "negateCondition": false,      "matchValue": ["155.121.236.3/32", "155.121.236.4/32", "155.121.236.5/32"]    },    {      "matchVariable": "RequestHeader",      "selector": "User-Agent",      "operator": "BeginsWith",      "negateCondition": false,      "matchValue": ["Lectora/"],      "transforms": []    }  ]}

Pick a priority number that is free and lower than your VPN rule's. On a network firewall, allow TCP 443 from the three addresses to whatever terminates your Canvas domain.

When the addresses change. Only if we change our hosting setup. We tell your IT contact at least 14 days before a planned change, and immediately if a change is forced on us.

The other direction. Your Canvas server and your users' browsers must reach https://www.lectora.app over HTTPS. Canvas fetches Lectora's public keys from https://www.lectora.app/api/lti/jwks. https://lectora.app redirects to https://www.lectora.app.

Can we turn on Enforce Scopes?

Yes, in one coordinated step with us. With Enforce Scopes on, Canvas refuses an authorization request that doesn't name its scopes (invalid_scope), and it limits each token to the scopes it was issued with. Lectora therefore has to ask for exactly the scopes ticked on your API Key, and we store that list for your institution.

  1. Contact us. We confirm the scope list below for the Lectora version you run and store the same list for your institution. Nothing changes while your key still has Enforce Scopes off; new teacher tokens simply carry the listed scopes.
  2. Switch on in one save. On the API Key, turn Enforce Scopes on, tick exactly the listed scopes, and tick Allow Include Parameters. Without Allow Include Parameters, Canvas silently drops extra data Lectora asks for, such as submission comments and attachments, and grading goes wrong without an error.
  3. Teachers authorize once more. We clear the Canvas tokens issued before step 1, so those teachers authorize Lectora once on their next visit.

The scope list for Lectora 2.19. In the key form, Canvas shows scopes as endpoints grouped by resource. We confirm the list with you in step 1, because a new Lectora feature can need a new scope.

Core scopes, needed by every institution (28):

url:GET|/api/v1/users/:idurl:GET|/api/v1/users/:user_id/enrollmentsurl:GET|/api/v1/accounts/:account_id/admins/selfurl:GET|/api/v1/courses/:idurl:GET|/api/v1/accounts/:account_id/termsurl:GET|/api/v1/courses/:course_id/enrollmentsurl:GET|/api/v1/courses/:course_id/usersurl:GET|/api/v1/users/:user_id/profileurl:GET|/api/v1/users/:user_id/communication_channelsurl:GET|/api/v1/courses/:course_id/groupsurl:GET|/api/v1/groups/:group_id/usersurl:GET|/api/v1/courses/:course_id/assignmentsurl:GET|/api/v1/courses/:course_id/assignments/:idurl:GET|/api/v1/courses/:course_id/assignment_groupsurl:GET|/api/v1/courses/:course_id/assignments/:assignment_id/submissionsurl:GET|/api/v1/courses/:course_id/assignments/:assignment_id/submissions/:user_idurl:GET|/api/v1/courses/:course_id/students/submissionsurl:PUT|/api/v1/courses/:course_id/assignments/:assignment_id/submissions/:user_idurl:POST|/api/v1/courses/:course_id/assignments/:assignment_id/submissions/:user_id/comments/filesurl:DELETE|/api/v1/courses/:course_id/assignments/:assignment_id/submissions/:user_id/comments/:idurl:GET|/api/v1/courses/:course_id/rubrics/:idurl:GET|/api/v1/courses/:course_id/grading_standardsurl:GET|/api/v1/accounts/:account_id/grading_standardsurl:GET|/api/v1/accounts/:idurl:GET|/api/v1/courses/:course_id/filesurl:GET|/api/v1/courses/:course_id/files/:idurl:GET|/api/v1/courses/:course_id/foldersurl:GET|/files/:file_id/download

Scopes for optional features (23). Leave a group out only if you don't use that feature, because the feature stops working without it.

# Publishing course and assignment details back to Canvasurl:PUT|/api/v1/courses/:idurl:PUT|/api/v1/courses/:course_id/assignments/:id
# Classic Quizzes: grading, question sync and score publishingurl:GET|/api/v1/courses/:course_id/quizzes/:idurl:GET|/api/v1/courses/:course_id/quizzes/:quiz_id/submissionsurl:GET|/api/v1/quiz_submissions/:quiz_submission_id/questionsurl:GET|/api/v1/courses/:course_id/quizzes/:quiz_id/questionsurl:GET|/api/v1/courses/:course_id/quizzes/:quiz_id/submissions/:id/eventsurl:POST|/api/v1/courses/:course_id/quizzes/:quiz_id/reportsurl:GET|/api/v1/courses/:course_id/quizzes/:quiz_id/reports/:idurl:PUT|/api/v1/courses/:course_id/quizzes/:quiz_id/submissions/:id
# Quiz Studio: publishing quizzes and reading results (with the Classic Quizzes group)url:POST|/api/v1/courses/:course_id/quizzesurl:POST|/api/v1/courses/:course_id/quizzes/:quiz_id/questionsurl:PUT|/api/v1/courses/:course_id/quizzes/:idurl:GET|/api/v1/courses/:course_id/quizzes/assignment_overridesurl:GET|/api/v1/courses/:course_id/quizzes/:quiz_id/statistics
# Knowledge base: uploading files to Canvas and setting file accessurl:POST|/api/v1/courses/:course_id/filesurl:PUT|/api/v1/files/:idurl:DELETE|/api/v1/files/:id
# Learning goals: the upload folderurl:POST|/api/v1/courses/:course_id/folders
# Outcomes importurl:GET|/api/v1/courses/:course_id/root_outcome_groupurl:GET|/api/v1/courses/:course_id/outcome_groups/:idurl:GET|/api/v1/courses/:course_id/outcome_groupsurl:GET|/api/v1/courses/:course_id/outcome_groups/:id/outcomes

Enforce Scopes limits only tokens issued through the API Key. Personal access tokens are not affected.

The LTI Registration key needs no action: Dynamic Registration requests the one LTI scope Lectora uses (Names and Role Provisioning, for the roster) automatically.

Updating or removing the installation

To change Lectora's LTI configuration (for example to update placements or scopes after a Lectora release), go to Admin → Developer Keys, click the pencil edit icon on the LTI Registration key, re-enter the registration URL, and click Save. Canvas re-fetches the configuration; existing course installations continue working without changes. To rotate the API Key's secret, click Show Key on the API Key row to generate a new secret, then re-run Dynamic Registration with the new value (or have your Lectora administrator update the stored credential directly).

To uninstall completely, you need to remove both keys. Either remove the External App from each course (Course Settings → Apps → Lectora → trash icon), or delete the LTI Registration key (Admin → Developer Keys → trash icon on the Lectora LTI row) to disable Lectora launches everywhere at once. Then also delete the API Key (trash icon on the Lectora API Access row) so Lectora can no longer call the Canvas API. Toggling either key OFF instead of deleting it is a safer reversible alternative if you're not sure.

About 15 minutes if you have Canvas admin access and a Lectora URL ready — five for creating the API Developer Key (Step 2), five for Dynamic Registration and toggling the LTI key on (Steps 3–5), and five for making Lectora available in courses and verifying (Steps 6–7). The longest delay is usually scheduling time with your Canvas root account admin, not the install itself.