Overview
LTI (Learning Tools Interoperability) 1.3 is the industry standard for securely connecting external tools to a Learning Management System (LMS). It replaces older LTI versions with modern OAuth 2.0-based authentication, signed JWTs, and a well-defined launch flow.
TutorFlow acts as an LTI Tool (also called a Tool Provider). When configured, students can launch TutorFlow directly from assignments inside Canvas, Moodle, Blackboard, or any LMS that supports LTI 1.3. Grades flow back automatically through the Assignment and Grade Services (AGS) specification.
Why LTI 1.3?
- Single sign-on: Students authenticate through their LMS. No separate TutorFlow login required.
- Grade passback: Evaluation scores sync back to the LMS gradebook automatically.
- Deep linking: Instructors can embed specific TutorFlow activities into course modules.
- Security: All communication uses signed JWTs and HTTPS. No shared secrets in query strings.
Prerequisites
Before setting up LTI, you need:
- A TutorFlow Platform workspace with an active API key. See Quick Start.
- Administrator access to your LMS (Canvas, Moodle, Blackboard, or any LTI 1.3-compatible platform).
- Your TutorFlow API key (
tf_platform_...) for creating the LTI registration.
Step-by-Step Setup
Step 1: Create an LTI Registration
Call the TutorFlow API to register your LMS as an LTI platform. You will need the issuer URL, authorization endpoint, token endpoint, and JWKS URL from your LMS.
curl -X POST https://api.tutorflow.io/v1/platform/lti/registrations \
-H "Authorization: Bearer tf_platform_..." \
-H "Content-Type: application/json" \
-d '{
"name": "Canvas Production",
"platformIssuer": "https://canvas.instructure.com",
"platformAuthorizationEndpoint": "https://canvas.instructure.com/api/lti/authorize_redirect",
"platformTokenEndpoint": "https://canvas.instructure.com/login/oauth2/token",
"platformJwksUrl": "https://canvas.instructure.com/api/lti/security/jwks",
"clientId": "10000000000001",
"deploymentId": "1"
}'The response includes the registration ID and the URLs you need to configure in your LMS:
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"name": "Canvas Production",
"platformIssuer": "https://canvas.instructure.com",
"clientId": "10000000000001",
"deploymentId": "1",
"toolLoginUrl": "https://api.tutorflow.io/v1/platform/lti/login",
"toolLaunchUrl": "https://api.tutorflow.io/v1/platform/lti/launch",
"toolJwksUrl": "https://api.tutorflow.io/v1/platform/lti/.well-known/jwks.json",
"status": "active",
"createdAt": "2026-03-25T12:00:00Z"
}Step 2: Configure Your LMS
Use the URLs from the registration response to configure TutorFlow as an external tool in your LMS.
Canvas
- Go to Admin > Developer Keys > + Developer Key > LTI Key.
- Enter the following values:
| LMS Field | Value |
|---|---|
| Redirect URIs | https://api.tutorflow.io/v1/platform/lti/launch |
| Target Link URI | https://api.tutorflow.io/v1/platform/lti/launch |
| OpenID Connect Initiation URL | https://api.tutorflow.io/v1/platform/lti/login |
| Public JWK URL | https://api.tutorflow.io/v1/platform/lti/.well-known/jwks.json |
- Enable the developer key and add TutorFlow as an external tool in your course settings.
Moodle
- Go to Site Administration > Plugins > Activity Modules > External Tool > Manage Tools.
- Click Configure a tool manually and enter:
| Moodle Field | Value |
|---|---|
| Tool URL | https://api.tutorflow.io/v1/platform/lti/launch |
| LTI version | LTI 1.3 |
| Initiate login URL | https://api.tutorflow.io/v1/platform/lti/login |
| Redirection URI(s) | https://api.tutorflow.io/v1/platform/lti/launch |
| Public keyset URL | https://api.tutorflow.io/v1/platform/lti/.well-known/jwks.json |
- Copy the platform ID, client ID, and deployment ID from Moodle back into your TutorFlow registration using the Update Registration endpoint.
Blackboard
- Go to System Admin > LTI Tool Providers > Register LTI 1.3 Tool.
- Enter the client ID from TutorFlow, then fill in:
| Blackboard Field | Value |
|---|---|
| Tool Provider URL | https://api.tutorflow.io/v1/platform/lti/launch |
| Login Initiation URL | https://api.tutorflow.io/v1/platform/lti/login |
| Tool Provider JWKS URL | https://api.tutorflow.io/v1/platform/lti/.well-known/jwks.json |
Step 3: Test the Launch Flow
- Create an assignment in your LMS that uses TutorFlow as the external tool.
- Open the assignment as a test student.
- Verify that the OIDC login redirect completes and TutorFlow loads inside the LMS iframe.
- Submit a test answer and confirm the evaluation completes.
- Check the LMS gradebook to verify the score was passed back.
OIDC Launch Flow
The LTI 1.3 launch follows the OpenID Connect (OIDC) third-party login flow. Here is how it works step by step:
Student clicks assignment in LMS
|
v
LMS redirects to TutorFlow Login URL
GET /v1/platform/lti/login
(iss, login_hint, target_link_uri, lti_message_hint, client_id)
|
v
TutorFlow validates the request and redirects
back to the LMS authorization endpoint
(state, nonce, redirect_uri, client_id)
|
v
LMS authenticates the user and creates a signed JWT (id_token)
|
v
LMS POSTs to TutorFlow Launch URL
POST /v1/platform/lti/launch
(id_token, state)
|
v
TutorFlow validates the JWT signature using the LMS JWKS
|
v
TutorFlow creates an LTI session and renders the tool UI
|
v
Student completes evaluation, score syncs to LMS gradebook via AGSAll tokens are signed JWTs verified against the LMS public key set. The state parameter
prevents CSRF attacks. TutorFlow never receives the student's LMS password.
Grade Passback (AGS)
The Assignment and Grade Services (AGS) specification allows TutorFlow to send scores back to the LMS gradebook. This happens automatically when an evaluation completes.
How It Works
- When a student launches TutorFlow through LTI, the launch token includes AGS claim data with the line item URL for the assignment.
- TutorFlow stores this AGS context in the LTI launch session.
- When the student submits an answer and the evaluation completes, TutorFlow posts the normalized score (0.0 to 1.0) back to the LMS line item.
- The LMS updates the gradebook with the score.
Triggering Grade Sync from the API
If you are building a custom integration that creates evaluations via the REST API, you can
link an evaluation to an LTI launch session by including the ltiLaunchSessionId in the
clientMetadata field:
curl -X POST https://api.tutorflow.io/v1/platform/evaluations \
-H "Authorization: Bearer tf_platform_..." \
-H "Content-Type: application/json" \
-d '{
"evaluationType": "open_ended",
"questionText": "Explain the water cycle",
"learnerAnswer": "Water evaporates from oceans...",
"clientMetadata": {
"ltiLaunchSessionId": "session_abc123"
}
}'When the evaluation completes, TutorFlow automatically syncs the score to the LMS using the AGS credentials stored in the launch session.
Score Format
TutorFlow sends scores using the AGS score format:
{
"scoreGiven": 8.0,
"scoreMaximum": 10.0,
"activityProgress": "Completed",
"gradingProgress": "FullyGraded",
"userId": "lti-user-id-from-launch",
"timestamp": "2026-03-25T12:05:00Z"
}The activityProgress and gradingProgress fields follow the LTI AGS specification values.
Deep Linking
Deep Linking (LTI-DL) allows instructors to browse and select specific TutorFlow activities when creating assignments. Instead of a generic launch, the instructor picks a particular evaluation type, course module, or pre-configured assessment.
When the LMS initiates a deep link request, TutorFlow presents a selection UI. The instructor picks the desired content, and TutorFlow returns a signed deep link response that the LMS saves as the assignment configuration. Subsequent student launches go directly to that content.
Environment Variables
If you are self-hosting or running TutorFlow in a custom environment, the following environment variables control the LTI integration:
| Variable | Description |
|---|---|
LTI_TOOL_ISSUER | The issuer identifier for TutorFlow as an LTI tool |
LTI_JWKS_PRIVATE_KEY | RSA private key (PEM format) used to sign tool JWTs |
LTI_JWKS_KEY_ID | Key ID (kid) for the JWKS endpoint |
LTI_PLATFORM_BASE_URL | Base URL for the TutorFlow API (e.g., https://api.tutorflow.io) |
For the hosted TutorFlow service, these are already configured. You only need them if running your own deployment.
Troubleshooting
"Invalid issuer" error during launch
The platformIssuer in your TutorFlow registration must exactly match the iss claim
in the JWT sent by your LMS. Common issues:
- Trailing slash mismatch (
https://canvas.instructure.comvshttps://canvas.instructure.com/) - Using the wrong URL (e.g., your institution-specific URL vs the global Canvas URL)
"JWKS validation failed" error
- Verify the
platformJwksUrlis correct and publicly accessible. - Check that the JWKS endpoint returns keys in the expected JWK Set format.
- Ensure the key used to sign the LMS JWT is included in the JWKS response.
Grade not appearing in LMS
- Confirm that the LTI launch token includes the AGS claim (
https://purl.imsglobal.org/spec/lti-ags/claim/endpoint). - Check that the line item URL in the AGS claim is valid.
- Verify that TutorFlow has the
Scorescope for the assignment. - Look at the evaluation response to confirm it completed successfully (status
COMPLETED).
"State mismatch" error
This usually means the student's browser blocked third-party cookies. LTI 1.3 launches happen inside iframes, and some browsers block cookies in that context. Solutions:
- Ensure your LMS domain is trusted in the browser.
- Use the LMS in a non-incognito window.
- Check that TutorFlow cookies use
SameSite=None; Secureattributes.
Launch works but iframe is blank
- Check the browser console for Content Security Policy (CSP) errors.
- Ensure the LMS allows framing TutorFlow's domain.
- Verify that TutorFlow sets the
Content-Security-Policy: frame-ancestorsheader to include your LMS domain.