LTI Launch Flow

OIDC login initiation, launch callback, and JWKS endpoints used by the LMS during an LTI 1.3 launch.

LTI Launch Endpoints

These endpoints are called by the LMS during an LTI 1.3 launch. They are public endpoints and do not require an API key. The LMS redirects the student's browser to these URLs as part of the OIDC third-party login flow.

For a full walkthrough of the launch process, see the LTI Integration Guide.


GET /v1/platform/lti/login

OIDC login initiation endpoint. The LMS redirects the student's browser here to start the LTI launch. TutorFlow validates the parameters, generates a state and nonce, and redirects the browser back to the LMS authorization endpoint.

Query Parameters

ParameterTypeRequiredDescription
issstringYesIssuer identifier of the LMS (must match a registered platformIssuer)
login_hintstringYesOpaque value from the LMS identifying the user
target_link_uristringYesThe URL the LMS wants to launch (TutorFlow's launch URL)
lti_message_hintstringNoOpaque value from the LMS passed through to the authorization request
client_idstringNoThe client ID of the tool registration. Required when the same issuer has multiple registrations.

Example

The LMS constructs a URL like this and redirects the student's browser to it:

https://api.tutorflow.io/v1/platform/lti/login
  ?iss=https://canvas.instructure.com
  &login_hint=user-id-12345
  &target_link_uri=https://api.tutorflow.io/v1/platform/lti/launch
  &lti_message_hint=assignment-context-hint
  &client_id=10000000000001

Response

This endpoint does not return a JSON body. It responds with an HTTP 302 redirect to the LMS authorization endpoint. The redirect URL includes the following query parameters:

ParameterDescription
scopeAlways openid
response_typeAlways id_token
response_modeAlways form_post
client_idThe registered client ID
redirect_uriTutorFlow's launch URL
stateCSRF protection token (stored server-side)
nonceReplay protection token
login_hintPassed through from the original request
lti_message_hintPassed through from the original request (if provided)
promptAlways none (SSO, no re-authentication)

Error Responses

StatusCause
400Missing required parameters (iss, login_hint, or target_link_uri)
400No LTI registration found for the given iss and client_id

POST /v1/platform/lti/launch

Launch callback endpoint. After the LMS authenticates the user, it POSTs a form to this URL containing the signed id_token (JWT) and the state value. TutorFlow validates the JWT signature, checks the state and nonce, extracts LTI claims, and creates a launch session.

Request Body (form-encoded)

FieldTypeRequiredDescription
id_tokenstringYesThe signed JWT from the LMS containing LTI launch claims
statestringYesThe CSRF state token generated during the login step

Content Type

Content-Type: application/x-www-form-urlencoded

Example

The LMS auto-submits a form to this endpoint:

<form method="POST" action="https://api.tutorflow.io/v1/platform/lti/launch">
  <input type="hidden" name="id_token" value="eyJhbGciOiJSUzI1NiIs..." />
  <input type="hidden" name="state" value="csrf-state-token" />
</form>

JWT Claims

The id_token JWT contains standard LTI 1.3 claims:

ClaimDescription
issLMS issuer
subUser identifier in the LMS
audClient ID (must match the registration)
nonceMust match the nonce from the login step
https://purl.imsglobal.org/spec/lti/claim/message_typeLtiResourceLinkRequest or LtiDeepLinkingRequest
https://purl.imsglobal.org/spec/lti/claim/versionAlways 1.3.0
https://purl.imsglobal.org/spec/lti/claim/rolesArray of LTI role URIs
https://purl.imsglobal.org/spec/lti/claim/resource_linkResource link details (id, title)
https://purl.imsglobal.org/spec/lti-ags/claim/endpointAGS endpoint for grade passback (if available)

Response

On success, TutorFlow creates an LTI launch session and redirects the student's browser to the tool UI. The response is an HTTP 302 redirect (or an HTML page rendered inside the LMS iframe).

Validation Steps

TutorFlow performs the following validation on every launch:

  1. State check: The state parameter must match a valid, unexpired login session.
  2. JWT signature: The id_token is verified against the LMS JWKS (fetched from the registered platformJwksUrl).
  3. Issuer check: The iss claim must match the platformIssuer in the registration.
  4. Audience check: The aud claim must include the registered clientId.
  5. Nonce check: The nonce must match the value generated during the login step.
  6. Expiry check: The token must not be expired (exp claim).
  7. Message type: Must be a supported LTI message type.

Error Responses

StatusCause
400Missing id_token or state
400Invalid or expired state token
401JWT signature verification failed
401Issuer, audience, or nonce mismatch
401Token expired

GET /v1/platform/lti/.well-known/jwks.json

Returns TutorFlow's public JSON Web Key Set (JWKS). The LMS uses this endpoint to retrieve the public keys needed to verify JWTs signed by TutorFlow (used during deep linking responses and other tool-initiated messages).

Authentication

None. This is a public endpoint.

Example Request

curl https://api.tutorflow.io/v1/platform/lti/.well-known/jwks.json

Response

{
  "keys": [
    {
      "kty": "RSA",
      "kid": "tutorflow-lti-key-1",
      "use": "sig",
      "alg": "RS256",
      "n": "0vx7agoebGcQSuu...",
      "e": "AQAB"
    }
  ]
}

Response Fields

FieldTypeDescription
keysarrayArray of JWK objects
keys[].ktystringKey type (always RSA)
keys[].kidstringKey ID used to match the kid header in JWTs
keys[].usestringKey usage (always sig for signature verification)
keys[].algstringAlgorithm (always RS256)
keys[].nstringRSA modulus (Base64url-encoded)
keys[].estringRSA exponent (Base64url-encoded)

Caching

This endpoint supports HTTP caching. The response includes Cache-Control headers. Keys may be rotated periodically. LMS platforms should re-fetch the JWKS if JWT verification fails with a kid mismatch.