Lesson Attachment Upload & Management
Lesson Attachment Upload & Management
Instructors can enrich lessons by attaching downloadable files — PDFs, images, and other documents — directly to any lesson. The platform handles secure upload URL generation, metadata persistence, and deletion through a straightforward API.
Overview
The attachment workflow has four stages:
| Stage | Description |
|---|---|
| 1. Request presigned URL | Ask the API for a short-lived URL scoped to a specific lesson and file. |
| 2. Upload to storage | PUT the file binary directly to the presigned URL (no platform server in the data path). |
| 3. Confirm attachment | Notify the API that the upload is complete; metadata is persisted and the attachment becomes visible to learners. |
| 4. Delete attachment | Remove an attachment; both the stored object and its metadata record are deleted. |
Supported File Types
- PDF documents (
.pdf) - Images (
.png,.jpg,.gif,.webp, etc.) - General downloadable files
Workflow
Step 1 — Request a Presigned Upload URL
Before uploading, request a presigned URL from the platform. Provide the target lesson ID, the intended filename, and the MIME type.
POST /api/lessons/{lessonId}/attachments/presigned-url
Content-Type: application/json
Authorization: Bearer <token>
{
"filename": "module-1-workbook.pdf",
"contentType": "application/pdf",
"fileSize": 204800
}
Response
{
"uploadUrl": "https://storage.example.com/...",
"attachmentId": "att_01HXZ...",
"expiresAt": "2025-01-01T12:05:00Z"
}
uploadUrl— The presigned URL. Use this in Step 2.attachmentId— The pending attachment identifier. Use this in Step 3.expiresAt— The URL expires at this time; request a new one if the upload is delayed.
Step 2 — Upload the File
Send the file binary directly to the presigned URL using an HTTP PUT request. Set the Content-Type header to match the value provided in Step 1.
PUT {uploadUrl}
Content-Type: application/pdf
<binary file content>
A 200 OK response from storage confirms the upload succeeded.
Note: Do not include your platform
Authorizationheader when calling the presigned URL — it is pre-authenticated.
Step 3 — Confirm and Persist the Attachment
Once the upload to storage succeeds, confirm the attachment with the platform API. This persists the metadata and makes the attachment accessible to learners.
POST /api/lessons/{lessonId}/attachments/{attachmentId}/confirm
Authorization: Bearer <token>
Response
{
"id": "att_01HXZ...",
"lessonId": "les_01ABC...",
"filename": "module-1-workbook.pdf",
"contentType": "application/pdf",
"fileSize": 204800,
"createdAt": "2025-01-01T12:01:30Z"
}
Step 4 — Delete an Attachment
To remove an attachment, call the delete endpoint. This deletes both the file from storage and the metadata record.
DELETE /api/lessons/{lessonId}/attachments/{attachmentId}
Authorization: Bearer <token>
Response
204 No Content
Listing Attachments
Retrieve all attachments for a given lesson:
GET /api/lessons/{lessonId}/attachments
Authorization: Bearer <token>
Response
[
{
"id": "att_01HXZ...",
"filename": "module-1-workbook.pdf",
"contentType": "application/pdf",
"fileSize": 204800,
"createdAt": "2025-01-01T12:01:30Z"
}
]
Error Handling
| Status | Meaning |
|---|---|
400 Bad Request | Missing or invalid fields (e.g. no filename or unsupported contentType). |
401 Unauthorized | Missing or invalid bearer token. |
403 Forbidden | Authenticated user does not have instructor access to this lesson. |
404 Not Found | Lesson or attachment ID does not exist. |
410 Gone | Presigned URL has expired — request a new one. |
Notes
- Presigned URLs are short-lived. Complete the upload promptly after requesting the URL.
- Confirming an upload that was never completed will result in a broken attachment record; always verify the storage
PUTsucceeded before calling confirm. - Deleting a lesson also removes all of its attachments.