Who launched
When your element is constructed, api already knows who opened the tool, from where, and into which location. These are plain properties — no calls, no waiting.
The person
api.userobjectThe person who launched.
api.groupsstring[]The same list as api.user.groups, always an array.
api.isStaffbooleantrue for an instructor, assistant, or manager launch. Staff can write all four storage scopes and should see your tool's setup and review features.
api.isStudentbooleantrue for a student launch that is not also staff. Students can write only their own two storage scopes.
A mentor (an observer, watching a student's progress) is neither: both flags are false. Show a mentor what a student sees, without the student's actions — and never score one.
api.hasGroup(group)booleanWhether the launched person holds group: api.hasGroup('assistant').
this.$('#setup-button').hidden = !this.api.isStaff
this.$('#submit-button').hidden = !(this.api.isStudent && this.api.canSubmitGrade)
The place
api.locationobjectWhich of your locations this launch is for: { id, extid, type, label }. Switch on extid — it is your own identifier, exactly as you declared it. id is Voshi's; type and label are what was recorded when the link was placed.
api.courseobjectThe course: { id, name, label }. name is its title ("Intro to Computing"), label its short code ("CS101").
api.contextstringThe course's ID, the same as api.course.id.
api.organizationobjectThe school's side: { title, issuer, client, deployment }. title is the institution's name; the other three are Voshi IDs for the LMS installation your tool was launched from. Most tools only ever read title.
api.appstringYour tool's ID — the one on the Settings tab.
api.launchIdstringThis launch's ID, one per visit. It matches the Launches tab in the dashboard.
Grading
api.canSubmitGradebooleanWhether this launch has a gradebook column to report to: an assessment location that was placed through the Voshi deep linking dialog. When it is false, say nothing about grades at all. See Grades.
When a launch ends
A launch is one visit, and it does not last forever. It ends 12 hours after the tool's last call to Voshi — every save or read slides the clock forward, so a learner who is working stays launched for as long as they work — and at once when the tool is suspended, archived, or deleted, when the code the course runs is replaced, or when the learner is no longer in the course. After that no call succeeds: each throws a VoshiAuthenticationError.
Your tool does not have to notice. The first call Voshi refuses ends the launch: the frame is sent to a page that tells the learner the session has ended and to reopen the activity from the course, which closes your tool. What matters is that work is saved as the learner goes, not only at the end, so that nothing is lost when that happens.
To handle the end yourself instead — show your own notice, or keep an unsaved answer on screen — listen for the voshi-session-expired event on your element and prevent it. Every later call still fails, so the tool should stop trying to save:
constructor(api) {
super()
this.addEventListener('voshi-session-expired', event => {
event.preventDefault() // the frame stays on your tool
this.showRelaunchNotice()
})
}
The launch data's api.expires and api.idle say when the token would end if nothing else happened; a tool rarely needs them.
The whole launch
api.launch_dataobjectEverything Voshi sent, as received. The properties above cover what a tool needs; this is the escape hatch. Its fields are documented in the Launch Data reference — the same payload an externally hosted tool receives as a signed token. Your tool never needs the api, storage, files, grade, or version entries in it; those are what the client and the page already use on your behalf.
What a launch does not tell you
- Nothing in advance. Voshi does not announce a school, course, or student before they launch. The first launch is the first your tool hears of any of them.
- No LMS internals. Every ID is Voshi's own. There is no LMS user ID, course ID, or link ID in the launch.
- No history. A repeat launch looks like the first one. Recognize a returning learner by
api.user.memberand resume from what you saved in storage.