Connecting an LMS is a two-sided handshake. First you register TutorFlow as an external tool inside your LMS and collect the values the LMS assigns. Then you register that LMS on your TutorFlow organization so TutorFlow trusts launches from it.
TutorFlow tool endpoints
Give these URLs to your LMS when you create the external tool. They are the same for every organization.
| LMS field | Value |
|---|---|
| OpenID Connect Initiation URL (login) | https://api.tutorflow.io/v1/platform/lti/login |
| Redirect URI / Launch URL / Target Link URI | https://api.tutorflow.io/v1/platform/lti/launch |
| Public keyset URL (JWKS) | https://api.tutorflow.io/v1/platform/lti/.well-known/jwks.json |
TutorFlow requests these LTI Advantage scopes: Deep Linking, Assignment and Grade Services (line items + scores), and Names and Role Provisioning. Enable them when the LMS asks which services the tool may use.
Step 1 — Register TutorFlow in your LMS
Canvas
- As a Canvas admin, open Admin → Developer Keys → + Developer Key → + LTI Key.
- Choose Method: Manual Entry and fill in:
- Target Link URI:
https://api.tutorflow.io/v1/platform/lti/launch - OpenID Connect Initiation Url:
https://api.tutorflow.io/v1/platform/lti/login - JWK Method: Public JWK URL →
https://api.tutorflow.io/v1/platform/lti/.well-known/jwks.json
- Target Link URI:
- Under LTI Advantage Services, turn on line items, scores, results, and membership.
- Add a placement:
Assignment Selectionand/orLink Selection(these enable the content picker). - Save, then set the key's state to ON. Copy the Client ID (a long number).
Moodle
- As a Moodle admin, go to Site administration → Plugins → Activity modules → External tool → Manage tools → configure a tool manually.
- Fill in:
- Tool URL:
https://api.tutorflow.io/v1/platform/lti/launch - LTI version: LTI 1.3
- Public key type: Keyset URL →
https://api.tutorflow.io/v1/platform/lti/.well-known/jwks.json - Initiate login URL:
https://api.tutorflow.io/v1/platform/lti/login - Redirection URI(s):
https://api.tutorflow.io/v1/platform/lti/launch
- Tool URL:
- Under Services, enable IMS LTI Assignment and Grade Services and IMS LTI Names and Role Provisioning. Under Privacy, share the launcher's name and email "Always".
- Enable Supports Deep Linking (Content-Item Message).
- Save. Open the tool's configuration details and copy the Client ID, Platform ID (issuer), Authentication request URL, Access token URL, and Public keyset URL.
Step 2 — Collect the LMS values
To register the LMS on TutorFlow you need five values from the LMS:
| Value | Canvas | Moodle |
|---|---|---|
issuer | https://canvas.instructure.com (your Canvas URL) | Platform ID |
clientId | Developer Key Client ID | Client ID |
authorizationEndpoint | https://<canvas-host>/api/lti/authorize_redirect | Authentication request URL |
tokenEndpoint | https://<canvas-host>/login/oauth2/token | Access token URL |
jwksEndpoint | https://<canvas-host>/api/lti/security/jwks | Public keyset URL |
Step 3 — Register the LMS on your TutorFlow organization
Registration is done with your signed-in TutorFlow admin session (cookie name jwt). A settings screen for this is on the way; today you register through the admin API.
Set the base URL:
export TUTORFLOW_API_BASE_URL="https://api.tutorflow.io"Find your organization ID:
curl "$TUTORFLOW_API_BASE_URL/v1/content/organizations" \
-b tutorflow-admin.cookies[
{ "id": "00000000-0000-4000-8000-000000000001", "name": "Customer Academy", "role": "ADMIN" }
]Register the LMS (organization admins only):
curl -X POST \
"$TUTORFLOW_API_BASE_URL/v1/admin/organizations/00000000-0000-4000-8000-000000000001/lti/registrations" \
-b tutorflow-admin.cookies \
-H "Content-Type: application/json" \
-d '{
"name": "Acme University Canvas",
"issuer": "https://canvas.instructure.com",
"clientId": "10000000000042",
"authorizationEndpoint": "https://acme.instructure.com/api/lti/authorize_redirect",
"tokenEndpoint": "https://acme.instructure.com/login/oauth2/token",
"jwksEndpoint": "https://acme.instructure.com/api/lti/security/jwks"
}'Response:
{
"id": "6f2b7f1e-9c1a-4b2e-8f0d-2b8f6f1a2c3d",
"organizationId": "00000000-0000-4000-8000-000000000001",
"classroomId": null,
"name": "Acme University Canvas",
"issuer": "https://canvas.instructure.com",
"clientId": "10000000000042",
"status": "ACTIVE"
}Optional: scope a registration to one classroom
Pass classroomId to limit what an LMS can deep link and launch to a single classroom. Omit it to let the registration reach every classroom in the organization.
-d '{ "name": "...", "issuer": "...", "clientId": "...", "authorizationEndpoint": "...", "tokenEndpoint": "...", "jwksEndpoint": "...", "classroomId": "<classroom-uuid>" }'Manage registrations
# List
curl "$TUTORFLOW_API_BASE_URL/v1/admin/organizations/<orgId>/lti/registrations" -b tutorflow-admin.cookies
# Update (any subset of fields)
curl -X PATCH "$TUTORFLOW_API_BASE_URL/v1/admin/organizations/<orgId>/lti/registrations/<registrationId>" \
-b tutorflow-admin.cookies -H "Content-Type: application/json" \
-d '{ "name": "Renamed" }'
# Deactivate
curl -X DELETE "$TUTORFLOW_API_BASE_URL/v1/admin/organizations/<orgId>/lti/registrations/<registrationId>" \
-b tutorflow-admin.cookiesStep 4 — Confirm the launch
In your LMS course, add the tool as an external activity, open it as a test student, and confirm you are handed into a TutorFlow classroom. Then continue to Deep Linking to insert specific content.
Troubleshooting registration
- "Multiple LTI registrations match issuer and this client_id" — the same
(issuer, clientId)is registered twice (for example on both a classroom app and the Agent Platform). Use a distinct LMS developer key per registration. - Launch shows "We couldn't verify this LTI session" — the launch expired (sessions last ~10 minutes) or the LMS clock/keys changed. Re-launch from the LMS. If it persists, confirm the
jwksEndpointvalue is correct.