LTI® Custom Parameters and Variable Substitution
The short answer
Custom parameters are extra key-value pairs an administrator attaches to a placement, delivered with every launch from it. Substitution variables let the value be a placeholder the platform fills in at launch time — a course code, a username, a role.
They are how one tool registration behaves differently in different places.
What they are for
Without them, a tool registration is uniform: every launch looks the same and your tool has to work out the context from the course and resource link alone.
Custom parameters let an administrator say something extra. Typical uses:
- Which part of your product this placement opens — a workspace, a module, a book.
- An identifier from their systems that you need and LTI® does not carry, such as a department or cohort code.
- A mode — read-only, practice, assessed.
They arrive as the custom claim on the ID Token, defined in the LTI® 1.3 specification, alongside everything else:
"custom": {
"workspace": "chemistry-2",
"mode": "assessed"
}
Substitution variables
Rather than a fixed value, the administrator can write a placeholder:
course_id=$Context.id
user_name=$Person.name.full
At launch, the platform replaces each with the real value. This is useful because the administrator configures the placement once and every launch carries the correct, current value.
Support varies a lot. The specification defines a long list; platforms
implement subsets. And the behaviour when a variable is not recognised is to
send the text through unchanged — so your tool receives the literal string
$Context.id rather than an error.
That is the specified behaviour and the usual explanation for "the parameter is arriving wrong". It is not a misconfiguration to debug so much as a variable that platform does not implement. Two defences:
- Check for the literal. If a value still starts with
$, treat it as absent rather than as data. - Prefer what the launch already carries. Course and user identifiers are in the standard claims. Requesting them again through substitution adds a dependency on a feature that varies, for information you already have.
Do not use them for security
The important constraint.
Custom parameters are configured by an administrator and travel through the browser as part of a launch. They are covered by the launch signature, so they are not casually forgeable — but the value is whatever the administrator typed, and the administrator is not necessarily someone you want deciding your authorisation.
A parameter saying role=admin grants nothing that the platform vouches for. Use
the roles claim for
authorisation, and treat custom parameters as configuration.
Where they are set
This differs by platform, and it is the most common reason a parameter does not arrive at all.
Most platforms allow them at more than one level — on the tool registration, so every placement inherits them, and on an individual placement, which overrides. An administrator setting a parameter at the wrong level produces a value that appears on some launches and not others, which reads as intermittent.
When a parameter is missing, ask where it was set before asking whether it was set.
How LTIAAS presents them
They arrive on the launch data as launch.custom, already parsed:
const { launch } = await axios.get('https://your.ltiaas.com/api/idtoken', {
headers: { Authorization: `LTIK-AUTH-V2 ${API_KEY}:${ltik}` }
}).then(r => r.data)
launch.custom.workspace // "chemistry-2"
One normalisation worth knowing: LTI® 1.1 delivered these as top-level fields
prefixed custom_, while 1.3 carries them in a claim of their own. LTIAAS strips
the legacy prefix and presents both the same way, so a tool supporting both
versions reads launch.custom in one place rather than branching on protocol
version.
The full launch structure is in the ID Token guide.
Common questions
What are LTI® custom parameters?
Extra key-value pairs an administrator configures on a placement, sent with every launch from it. They let one tool registration behave differently in different places without a separate registration for each.
What is variable substitution?
A way of writing a placeholder instead of a fixed value, which the platform replaces at launch time with something it knows — a course identifier, a username, a role. Support varies considerably between platforms.
Why is my custom parameter arriving as a literal placeholder?
The platform did not recognise the substitution variable, so it passed the text through unchanged. That is the specified behaviour, and it is the usual sign that the variable is unsupported on that platform.
Should I depend on custom parameters?
For configuration, yes. For identity or authorisation, no. They are set by an administrator and travel through the browser, so treat them as untrusted input rather than as a security control.
Next
- Every LTI® 1.3 configuration field explained
- How LTI® roster access works — roles, for authorisation
- ID Token guide — the whole launch payload
