Found this content helpful? Log in or sign up to leave a like!

LTI 1.3 Lti Deep Linking Response returns 200 but no link appears

DNCAV
Community Member

 

Hi all — I’m implementing LTI 1.3 Deep Linking. When I POST the Deep Linking Response to the deep_link_return_url, Canvas returns 200 OK, but:

  • the selection window stays open, and

  • no assignment/resource appears in the course.

Environment

  • Canvas cloud

  • Tool issuer: <TOOL_ISSUER> (e.g., https://tool.example.com)

  • Client ID: <CLIENT_ID>

  • Deployment ID: <DEPLOYMENT_ID>

  • JWKS URL: <JWKS_URL>

Request I’m sending

 URL (exact): https://<canvas-domain>/courses/<COURSE_ID>/deep_linking_response?data=<OPAQUE_DATA_FROM_LAUNCH>
 Method: POST (application/x-www-form-urlencoded)
 Form fields:id_token=<JWT> (no state present in this DL flow)

Deep Linking Response (JWT)
{

"iss": "<TOOL_ISSUER>", "aud": "<CLIENT_ID>", "azp": "<CLIENT_ID>", "sub": "<TOOL_USER_ID>", "iat": <unix>, "exp": <unix>, "https://purl.imsglobal.org/spec/lti/claim/message_type": "LtiDeepLinkingResponse", "https://purl.imsglobal.org/spec/lti/claim/version": "1.3.0", "https://purl.imsglobal.org/spec/lti/claim/deployment_id": "<DEPLOYMENT_ID>", "https://purl.imsglobal.org/spec/lti-dl/claim/data": "<OPAQUE_DATA_FROM_URL>", "https://purl.imsglobal.org/spec/lti-dl/claim/content_items": [ { "type": "ltiResourceLink", "title":...

Expected

Canvas closes the chooser and adds the LTI link (assignment/resource) to the course.

Actual

POST returns 200, but no UI change and chooser stays open.

Questions

  1. Are there additional required fields for ltiResourceLink in Canvas for the assignment_selection placement?

  2. Must content_items[0].url exactly equal the registered target_link_uri in the Developer Key?

  3. Any course/role/placement settings that could accept the response (200) but not place content?

  4. Known cases where Canvas returns 200 but silently discards the DL response (schema, roles, or deployment mismatch)?

    Checks done

    • RS256 signature verifies; kid matches JWKS at <JWKS_URL>

    • iss = tool issuer; aud = <CLIENT_ID>

    • deployment_id matches the request

    • data round-tripped exactly

    • Single content_item (Canvas sent accept_multiple: false)

    • Posting via form-encoded (not JSON)

      Thanks for any pointers

Labels (1)