LTI 1.3

EmbayLMS is an LTI 1.3 tool provider. This lets an external learning platform (Canvas, Moodle, Blackboard, or any LTI 1.3-compliant platform) launch EmbayLMS course content directly inside its own UI. Learners click a link in the host platform and are signed straight into the EmbayLMS course player — no separate login.

These endpoints are live. LTI is configured per tenant: an admin registers each platform as an LTI tool under the tenant’s integration settings, and the platform side is registered with the values below.


What LTI 1.3 provider mode does

  • An external platform launches a specific EmbayLMS course for a learner.
  • The launch carries the learner’s identity (signed by the platform). EmbayLMS validates the signature, then finds or just-in-time (JIT) provisions the user before redirecting them into the course.
  • Deep Linking 2.0 lets an instructor on the host platform browse the tenant’s published courses and embed a launch link without leaving the platform.

All four endpoints live under /api/v1/lti/ on the tenant subdomain (https://{tenant}.embaylms.com). The tenant is resolved from the request hostname.


Endpoints

OIDC Login Initiation

GET  /api/v1/lti/login
POST /api/v1/lti/login

Step 1 of the launch. The platform sends the learner here first. EmbayLMS registers a one-time nonce and redirects the browser back to the platform’s authorization endpoint (the target_link_uri) to obtain a signed id_token.

Required parameters (query string for GET, form-encoded for POST):

ParameterDescription
issThe platform’s issuer identifier
login_hintOpaque learner identifier supplied by the platform
target_link_uriThe platform authorization endpoint to redirect back to
client_id(optional) The tool’s client id, echoed back if present

Missing any of iss, login_hint, or target_link_uri returns 400 with { "error": "missing_required_params" }.

The redirect requests response_type=id_token, response_mode=form_post, scope=openid, and sets redirect_uri to the launch endpoint below.

POST /api/v1/lti/launch

Step 2 of the launch. The platform POSTs the signed id_token here (form field id_token). EmbayLMS:

  1. Decodes the token to find the issuer (iss) and audience (aud → client id).
  2. Looks up the matching LTI tool registration in the tenant by client id, and confirms the issuer matches and the tool is active.
  3. Verifies the JWT signature against the tool’s published JWKS.
  4. Validates the nonce (single-use, replay protection).
  5. Requires message_type LtiResourceLink*, version 1.3.0, and a registered deployment_id.
  6. Finds or JIT-provisions the user (see below).
  7. Redirects into the bound course player. If the deployment is bound to a course, the learner lands on /learn/{courseId}; otherwise the catalog.

On any validation failure the learner is redirected to the login page with an error code (e.g. SamlInvalidAssertion, SamlNotConfigured, AccountInactive) — no internal error detail is exposed.

Deep Linking

POST /api/v1/lti/deep-link

Handles a Deep Linking 2.0 (LtiDeepLinkingRequest) from the platform — the flow behind “Add External Tool” / content selection in Canvas and Moodle. EmbayLMS validates the request the same way as a launch (tool lookup, JWKS signature, nonce, message type), then returns a signed LtiDeepLinkingResponse JWT containing one ltiResourceLink content item per published course in the tenant. The response is delivered as an auto-submitting HTML form that POSTs back to the platform’s deep_link_return_url.

Deep linking must be explicitly enabled on the tool registration (deepLinkEnabled); otherwise the request is rejected.

JWKS (public keys)

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

Publishes EmbayLMS’s public RSA key so platforms can verify the JWTs EmbayLMS signs (Deep Linking responses, and any message sent back to the platform). The response is the standard JWKS shape { "keys": [ ... ] } and is cacheable for up to one hour.


Registration reference

Register EmbayLMS as a tool on your platform using these values ({tenant} is your tenant subdomain):

SettingValue
OIDC login / initiation URLhttps://{tenant}.embaylms.com/api/v1/lti/login
Redirect / launch (target link) URIhttps://{tenant}.embaylms.com/api/v1/lti/launch
Deep linking URLhttps://{tenant}.embaylms.com/api/v1/lti/deep-link
Public keyset (JWKS) URLhttps://{tenant}.embaylms.com/api/v1/lti/.well-known/jwks.json
LTI version1.3.0
Signing algorithmRS256

On the EmbayLMS side, the tenant admin registers the platform as an LTI tool and provides the platform’s issuer, client id, and JWKS URL, plus each deployment id (optionally bound to a specific course). The launch only succeeds when the incoming token’s issuer, client id, and deployment id all match an active registration.


JIT provisioning

When a launch carries a learner EmbayLMS has not seen before, the user is provisioned automatically from the LTI claims:

  • Matching: EmbayLMS first looks up an existing user by the email claim (lowercased). If found and active, that account is used; an inactive account returns AccountInactive.
  • Creation: If no match exists, a new user is created. Name comes from given_name / family_name, falling back to the name claim. If the launch carries no email, a synthetic internal address (lti-{sub}@lti.embaylms.internal) is used so the account is still unique.
  • Role mapping: LTI Instructor or Administrator roles map to the EmbayLMS author role; everyone else maps to learner.
  • Re-launch: On subsequent launches the existing account is reused (matched by email), and its role is kept in sync with the incoming claims.

JIT provisioning is per-tenant and isolated by the tenant schema — a launch never crosses tenant boundaries.


Troubleshooting

SymptomLikely cause
Learner bounced to login with SamlNotConfiguredNo active tool/deployment matches the token’s client id + issuer + deployment id. Re-check the registration values.
SamlInvalidAssertion on launchSignature failed, the nonce was already used (replay or a retried POST), or a required LTI claim (message_type, version 1.3.0, deployment_id) is missing.
AccountInactiveThe matched EmbayLMS user is deactivated. Reactivate the user or launch as a different account.
Deep linking returns “Tool not configured for deep linking”deepLinkEnabled is off on the tool registration.
Platform cannot verify EmbayLMS-signed responsesThe platform is not reading the JWKS URL, or is caching a stale key. Re-fetch …/lti/.well-known/jwks.json.