Management API
Everything you can configure in the dashboard, your app can also do over HTTPS — useful for automating location setup (e.g. generating one location per chapter from your content pipeline).
Base URL: https://api.link.voshi.com/ltiaas/v1
All management endpoints authenticate with your API key:
Authorization: Bearer ltiaas_<app-id>_<secret>
The app object
Endpoints that return your app use this shape:
{
"id": "I4ppXy",
"name": "My Study Tool",
"description": "Practice and quizzes for CS courses.",
"logo_url": "https://myapp.example.com/logo.png",
"callback_url": "https://myapp.example.com/launch_receiver",
"grades_released": true,
"status": "active",
"api_key_hint": "ltiaas_…cr3t",
"locations": [
{
"id": "Il0c8n",
"is_default": true,
"order": 0,
"type": "content",
"label": "Home",
"params": {}
}
],
"created": "2026-05-01T12:00:00+00:00"
}
grades_released controls whether grades your app submits are immediately visible to students in the LMS gradebook (default true). status is read-only here — see app status.
Get your app
GET /ltiaas/v1/apps/me
Returns the app object above. The API key itself is never included — only api_key_hint.
curl "https://api.link.voshi.com/ltiaas/v1/apps/me" \
-H "Authorization: Bearer ltiaas_myappid_mysecret"
Update your app
PATCH /ltiaas/v1/apps/me
Content-Type: application/json
A partial update — send only the fields you want to change. Returns the updated app object.
namestringCannot be blank.
descriptionstringlogo_urlstringcallback_urlstringValidated on write — see callback URL rules.
grades_releasedbooleancurl -X PATCH "https://api.link.voshi.com/ltiaas/v1/apps/me" \
-H "Authorization: Bearer ltiaas_myappid_mysecret" \
-H "Content-Type: application/json" \
-d '{"callback_url": "https://myapp.example.com/v2/launch_receiver"}'
List locations
GET /ltiaas/v1/apps/me/locations
{
"locations": [
{ "id": "Il0c8n", "is_default": true, "order": 0, "type": "content", "label": "Home", "params": {} },
{ "id": "Il0c8m", "is_default": false, "order": 1, "type": "assessment", "label": "Chapter 3 Quiz", "params": { "chapter": "3" } }
]
}
Create a location
POST /ltiaas/v1/apps/me/locations
Content-Type: application/json
Returns the created location object.
typestringdefault: contentOne of assessment, practice, content, setup. An unrecognized value is rejected with a 422 (not silently coerced).
labelstringdefault: The name shown to instructors in the content picker.
paramsobjectdefault: {}Static string-valued params — see constraints.
orderintegerSort position in the picker. Defaults to the end of the list.
curl -X POST "https://api.link.voshi.com/ltiaas/v1/apps/me/locations" \
-H "Authorization: Bearer ltiaas_myappid_mysecret" \
-H "Content-Type: application/json" \
-d '{"type": "assessment", "label": "Chapter 3 Quiz", "params": {"chapter": "3"}}'
Update a location
PATCH /ltiaas/v1/apps/me/locations/{location_id}
Content-Type: application/json
A partial update — only the fields you send are touched. Accepts the same fields as create. Returns the updated location object.
Sending params replaces the entire param set, not just the keys you include. Read-modify-write if you want to keep existing params.
Changes apply immediately to placements instructors have already made — see how placements work.
Delete a location
DELETE /ltiaas/v1/apps/me/locations/{location_id}
Returns {"deleted": "<location_id>"}. The default ("Home") location cannot be deleted (422). Deleting a location that instructors have already placed breaks those placements — see the warning.
Errors
| Status | Cause |
|---|---|
401 | Missing, malformed, or invalid API key; or the app is suspended. |
404 | Location not found — unknown location ID (or one belonging to another app). |
422 | Validation failure — blank name, invalid callback URL, unknown location type, bad params, or deleting the Home location. |
Error responses use the standard error envelope.