Files
Use to see what a course has: its files and saved links in one folder (or every folder with recursive=true), with their processing status (doc_status "none" means the file is stored but not indexed because automatic indexing is off; the user can index it from the file list). Do not use to look for what the files say; use files.document.search for that.
semestra_session<token>Set by the sign-in endpoints for the web app. Requests other than GET, HEAD and OPTIONS also need the X-Semestra-CSRF header set to the semestra_csrf cookie.
course_id*Course IdCourse id
folder_id?|Only items directly in this folder; omit for the course root
recursive?RecursiveList the items of every folder of the course, not just one
falsesearch?|Keep items whose name contains this text (case-insensitive). To search what the files say, use files.document.search instead.
sort?SortSort key
"name""name""size""updated""created""type"descending?DescendingReverse the sort order
falsefields?array<>|Agent/MCP only: return just these fields of each item (and its id)
cursor?|next_cursor of the previous page
limit?LimitPage size
200Successful Response
application/json- response
folders*array<>Every folder of the course
items*array<>next_cursor*string|nullcurl -X GET 'https://example.com/courses/string/files'{ "folders": [ { "id": "string", "course_id": "string", "parent_id": "string", "name": "string", "item_count": 0, "created_at": "2019-08-24T14:15:22Z", "updated_at": "2019-08-24T14:15:22Z" } ], "items": [ { "id": "string", "course_id": "string", "folder_id": "string", "kind": "file", "display_name": "string", "original_name": "string", "mime_type": "string", "size_bytes": 0, "sha256": "string", "url": "string", "pinned": true, "source_kind": "upload", "source_ref": "string", "doc_status": "none", "doc_error_code": "string", "page_count": 0, "ocr_skipped_pages": 0, "job_id": "string", "created_at": "2019-08-24T14:15:22Z", "updated_at": "2019-08-24T14:15:22Z" } ], "next_cursor": "string"}All or nothing: if one file is refused (too large, over quota) none is kept.
semestra_session<token>Set by the sign-in endpoints for the web app. Requests other than GET, HEAD and OPTIONS also need the X-Semestra-CSRF header set to the semestra_csrf cookie.
course_id*Course IdCourse id
multipart/form-data- body
files*array<string>The files to upload
folder_id?|Folder to put them in
Successful Response
application/json- response
items*array<>curl -X POST 'https://example.com/courses/string/files' \ -F 'files=[ "string"]'{ "items": [ { "id": "string", "course_id": "string", "folder_id": "string", "kind": "file", "display_name": "string", "original_name": "string", "mime_type": "string", "size_bytes": 0, "sha256": "string", "url": "string", "pinned": true, "source_kind": "upload", "source_ref": "string", "doc_status": "none", "doc_error_code": "string", "page_count": 0, "ocr_skipped_pages": 0, "job_id": "string", "created_at": "2019-08-24T14:15:22Z", "updated_at": "2019-08-24T14:15:22Z" } ]}semestra_session<token>Set by the sign-in endpoints for the web app. Requests other than GET, HEAD and OPTIONS also need the X-Semestra-CSRF header set to the semestra_csrf cookie.
item_id*Item IdFile id
disposition?Dispositioninline previews, attachment downloads
^(inline|attachment)$"attachment"Successful Response
application/octet-streamcurl -X GET 'https://example.com/files/string/content'semestra_session<token>Set by the sign-in endpoints for the web app. Requests other than GET, HEAD and OPTIONS also need the X-Semestra-CSRF header set to the semestra_csrf cookie.
item_id*Item IdFile id
page*PagePage number, starting at 1
1 <= valueSuccessful Response
image/pngcurl -X GET 'https://example.com/files/string/pages/1.png'Use to see the structure of a long document before reading parts of it.
semestra_session<token>Set by the sign-in endpoints for the web app. Requests other than GET, HEAD and OPTIONS also need the X-Semestra-CSRF header set to the semestra_csrf cookie.
item_id*Item IdFile or link id, from files.item.list
Successful Response
application/json- response
item_id*Item Iddisplay_name*Display Namepage_count*Page Countentries*array<>curl -X GET 'https://example.com/files/string/outline'{ "item_id": "string", "display_name": "string", "page_count": 0, "entries": [ { "level": 0, "title": "string", "page": 0 } ]}Returns the markdown of the pages from page_from (a few pages per call, each with its citation_id). When next_page is set, call again from there to continue. Use it to summarise or extract from a whole document; to find something specific use files.document.search first.
semestra_session<token>Set by the sign-in endpoints for the web app. Requests other than GET, HEAD and OPTIONS also need the X-Semestra-CSRF header set to the semestra_csrf cookie.
item_id*Item IdFile id, from files.item.list or files.document.search
page_from?Page FromFirst page (1-based)
1page_to?|Last page; at most 30 pages, and for the assistant about 9000 characters, are returned per call
Successful Response
application/json- response
item_id*Item Iddisplay_name*Display Namepage_count*Page Countpages*array<>next_page*|Call again from this page for the rest
citations*array<>One per page; cite a page by its citation_id
curl -X GET 'https://example.com/files/string/document'{ "item_id": "string", "display_name": "string", "page_count": 0, "pages": [ { "page_no": 0, "markdown": "string", "ocr_used": true, "citation_id": "string" } ], "next_page": 0, "citations": [ { "id": "string", "title": "string", "item_id": "string", "page_from": 0, "page_to": 0, "snippet": "string" } ]}Use to answer questions about course content (syllabus rules, dates, lecture material): finds the passages of the user's files that match, with page numbers. Narrow it with course_ids or term_id. Quote results with their citation_id. If pending_items is not empty, some files are still being processed; if unindexed_items is not empty, those files are not indexed yet (tell the user they can index them with "Index" in the file list); if unreadable_items is not empty, those files could not be read at all. In all these cases tell the user the answer may be incomplete. Do not use to find a file by its name; use files.item.list.
semestra_session<token>Set by the sign-in endpoints for the web app. Requests other than GET, HEAD and OPTIONS also need the X-Semestra-CSRF header set to the semestra_csrf cookie.
program_id*Program IdProgram id; the search never leaves this Program
application/json- body
query*QueryWhat to look for: words from the document or a question
1 <= length <= 500term_id?|Only the courses of this term
course_ids?array<>|Only these courses
item_ids?array<>|Only these files (from files.item.list)
top_k?Top KResults to return
1 <= value <= 208mode?Modehybrid = keywords and meaning together; keyword; semantic (needs an embedding model, else falls back to keyword)
"hybrid""hybrid""keyword""semantic"Successful Response
application/json- response
results*array<>pending_items*array<>Files in scope that are still being processed and are not searchable yet
unindexed_items?array<>Files in scope that are stored but not indexed (automatic indexing is off); the user can index them from the file list
unreadable_items*array<>Files in scope whose text could not be read; search never covers them
mode_used*Mode Used"hybrid""keyword""semantic"citations*array<>One per result, by its citation_id
curl -X POST 'https://example.com/programs/string/files:search' \ -H 'Content-Type: application/json' \ -d '{ "query": "string"}'{ "results": [ { "item_id": "string", "display_name": "string", "course_id": "string", "page_from": 0, "page_to": 0, "heading_path": [ "string" ], "snippet": "string", "score": 0, "citation_id": "string" } ], "pending_items": [ { "item_id": "string", "display_name": "string", "course_id": "string" } ], "unindexed_items": [ { "item_id": "string", "display_name": "string", "course_id": "string" } ], "unreadable_items": [ { "item_id": "string", "display_name": "string", "course_id": "string", "doc_status": "failed", "doc_error_code": "string" } ], "mode_used": "hybrid", "citations": [ { "id": "string", "title": "string", "item_id": "string", "page_from": 0, "page_to": 0, "snippet": "string" } ]}Use only when the user clearly asks to delete these. Folders go with everything inside them; nothing can be restored. All of them are deleted, or none if one is not found.
semestra_session<token>Set by the sign-in endpoints for the web app. Requests other than GET, HEAD and OPTIONS also need the X-Semestra-CSRF header set to the semestra_csrf cookie.
course_id*Course IdCourse id
application/json- body
item_ids?array<>Files and links to delete
items <= 1000folder_ids?array<>Folders to delete with everything inside them
items <= 1000Successful Response
application/json- response
deleted?Deletedtruecurl -X POST 'https://example.com/courses/string/files:delete' \ -H 'Content-Type: application/json' \ -d '{}'{ "deleted": true}Use when the user wants several things of one course in another folder of the same course (to_folder_id null = course root). Folders move with everything inside them. All of them move or, if one cannot (a folder name already taken there, folders nested too deep), none do.
semestra_session<token>Set by the sign-in endpoints for the web app. Requests other than GET, HEAD and OPTIONS also need the X-Semestra-CSRF header set to the semestra_csrf cookie.
course_id*Course IdCourse id
application/json- body
item_ids?array<>Files and links to move
items <= 1000folder_ids?array<>Folders to move, with their contents
items <= 1000to_folder_id*|Folder to move them into; null moves them to the course root
Successful Response
application/json- response
moved*MovedFiles, links and folders moved
curl -X POST 'https://example.com/courses/string/files:move' \ -H 'Content-Type: application/json' \ -d '{ "to_folder_id": "string"}'{ "moved": 0}Use to organise a course's files. Folders can be nested up to three levels. Move
a file into the new folder with files.item.update (folder_id).
semestra_session<token>Set by the sign-in endpoints for the web app. Requests other than GET, HEAD and OPTIONS also need the X-Semestra-CSRF header set to the semestra_csrf cookie.
course_id*Course IdCourse id
application/json- body
name*NameFolder name
1 <= length <= 100parent_id?|Parent folder (from files.item.list); null = course root
Successful Response
application/json- response
id*Idcourse_id*Course Idparent_id*string|nullname*Nameitem_count*Item CountFiles and links directly inside the folder
created_at*Created Atdate-timeupdated_at*Updated Atdate-timecurl -X POST 'https://example.com/courses/string/folders' \ -H 'Content-Type: application/json' \ -d '{ "name": "string"}'{ "id": "string", "course_id": "string", "parent_id": "string", "name": "string", "item_count": 0, "created_at": "2019-08-24T14:15:22Z", "updated_at": "2019-08-24T14:15:22Z"}Rename a folder or move it under another folder (parent_id null = course root). Folders are listed by name. Only send the fields to change.
semestra_session<token>Set by the sign-in endpoints for the web app. Requests other than GET, HEAD and OPTIONS also need the X-Semestra-CSRF header set to the semestra_csrf cookie.
folder_id*Folder IdFolder id
application/json- body
name?|New name
parent_id?|Move under this folder; null moves it to the course root
Successful Response
application/json- response
id*Idcourse_id*Course Idparent_id*string|nullname*Nameitem_count*Item CountFiles and links directly inside the folder
created_at*Created Atdate-timeupdated_at*Updated Atdate-timecurl -X PATCH 'https://example.com/folders/string' \ -H 'Content-Type: application/json' \ -d '{}'{ "id": "string", "course_id": "string", "parent_id": "string", "name": "string", "item_count": 0, "created_at": "2019-08-24T14:15:22Z", "updated_at": "2019-08-24T14:15:22Z"}Use only when the user clearly asks. A folder that is not empty is refused unless recursive=true, which permanently deletes all its files, links and subfolders.
semestra_session<token>Set by the sign-in endpoints for the web app. Requests other than GET, HEAD and OPTIONS also need the X-Semestra-CSRF header set to the semestra_csrf cookie.
folder_id*Folder IdFolder id
recursive?RecursiveAlso delete everything inside; required for a non-empty folder
falseSuccessful Response
application/json- response
deleted?Deletedtruecurl -X DELETE 'https://example.com/folders/string'{ "deleted": true}Use to check a file's name, type, size and whether its text is ready to read (doc_status = ready). Use files.document.read to read the text.
semestra_session<token>Set by the sign-in endpoints for the web app. Requests other than GET, HEAD and OPTIONS also need the X-Semestra-CSRF header set to the semestra_csrf cookie.
item_id*Item IdFile or link id, from files.item.list
Successful Response
application/json- response
id*Idcourse_id*Course Idfolder_id*string|nullkind*Kind"file""link"display_name*Display Nameoriginal_name*string|nullmime_type*string|nullsize_bytes*Size Bytessha256*string|nullurl*string|nullpinned*Pinnedsource_kind*|nullsource_ref*string|nulldoc_status*Doc Status"none""pending""processing""ready""failed""unsupported"doc_error_code*string|nullpage_count*integer|nullocr_skipped_pages*Ocr Skipped Pagesjob_id*string|nullcreated_at*Created Atdate-timeupdated_at*Updated Atdate-timecurl -X GET 'https://example.com/files/string'{ "id": "string", "course_id": "string", "folder_id": "string", "kind": "file", "display_name": "string", "original_name": "string", "mime_type": "string", "size_bytes": 0, "sha256": "string", "url": "string", "pinned": true, "source_kind": "upload", "source_ref": "string", "doc_status": "none", "doc_error_code": "string", "page_count": 0, "ocr_skipped_pages": 0, "job_id": "string", "created_at": "2019-08-24T14:15:22Z", "updated_at": "2019-08-24T14:15:22Z"}Use when the user wants to rename a file, put it in another folder of the same course (folder_id null = course root), or pin it for quick access. Only send the fields to change.
semestra_session<token>Set by the sign-in endpoints for the web app. Requests other than GET, HEAD and OPTIONS also need the X-Semestra-CSRF header set to the semestra_csrf cookie.
item_id*Item IdFile or link id, from files.item.list
application/json- body
display_name?|New name
folder_id?|Move into this folder; null moves it to the course root
pinned?|Pin it to the quick-open cards
Successful Response
application/json- response
id*Idcourse_id*Course Idfolder_id*string|nullkind*Kind"file""link"display_name*Display Nameoriginal_name*string|nullmime_type*string|nullsize_bytes*Size Bytessha256*string|nullurl*string|nullpinned*Pinnedsource_kind*|nullsource_ref*string|nulldoc_status*Doc Status"none""pending""processing""ready""failed""unsupported"doc_error_code*string|nullpage_count*integer|nullocr_skipped_pages*Ocr Skipped Pagesjob_id*string|nullcreated_at*Created Atdate-timeupdated_at*Updated Atdate-timecurl -X PATCH 'https://example.com/files/string' \ -H 'Content-Type: application/json' \ -d '{}'{ "id": "string", "course_id": "string", "folder_id": "string", "kind": "file", "display_name": "string", "original_name": "string", "mime_type": "string", "size_bytes": 0, "sha256": "string", "url": "string", "pinned": true, "source_kind": "upload", "source_ref": "string", "doc_status": "none", "doc_error_code": "string", "page_count": 0, "ocr_skipped_pages": 0, "job_id": "string", "created_at": "2019-08-24T14:15:22Z", "updated_at": "2019-08-24T14:15:22Z"}Use only when the user clearly asks to delete a file or link. The stored file and everything derived from it (text, search index) is removed and cannot be restored.
semestra_session<token>Set by the sign-in endpoints for the web app. Requests other than GET, HEAD and OPTIONS also need the X-Semestra-CSRF header set to the semestra_csrf cookie.
item_id*Item IdFile or link id, from files.item.list
Successful Response
application/json- response
deleted?Deletedtruecurl -X DELETE 'https://example.com/files/string'{ "deleted": true}Files and links the user pinned for quick access, across the Program's courses.
semestra_session<token>Set by the sign-in endpoints for the web app. Requests other than GET, HEAD and OPTIONS also need the X-Semestra-CSRF header set to the semestra_csrf cookie.
program_id*Program IdProgram id
Successful Response
application/json- response
items*array<>curl -X GET 'https://example.com/programs/string/pinned-files'{ "items": [ { "id": "string", "course_id": "string", "folder_id": "string", "kind": "file", "display_name": "string", "original_name": "string", "mime_type": "string", "size_bytes": 0, "sha256": "string", "url": "string", "pinned": true, "source_kind": "upload", "source_ref": "string", "doc_status": "none", "doc_error_code": "string", "page_count": 0, "ocr_skipped_pages": 0, "job_id": "string", "created_at": "2019-08-24T14:15:22Z", "updated_at": "2019-08-24T14:15:22Z" } ]}Starts the document pipeline again for a file, for example after a failure or after an AI model for reading scanned pages was set up.
semestra_session<token>Set by the sign-in endpoints for the web app. Requests other than GET, HEAD and OPTIONS also need the X-Semestra-CSRF header set to the semestra_csrf cookie.
item_id*Item IdFile or link id, from files.item.list
Successful Response
application/json- response
id*Idcourse_id*Course Idfolder_id*string|nullkind*Kind"file""link"display_name*Display Nameoriginal_name*string|nullmime_type*string|nullsize_bytes*Size Bytessha256*string|nullurl*string|nullpinned*Pinnedsource_kind*|nullsource_ref*string|nulldoc_status*Doc Status"none""pending""processing""ready""failed""unsupported"doc_error_code*string|nullpage_count*integer|nullocr_skipped_pages*Ocr Skipped Pagesjob_id*string|nullcreated_at*Created Atdate-timeupdated_at*Updated Atdate-timecurl -X POST 'https://example.com/files/string:reprocess'{ "id": "string", "course_id": "string", "folder_id": "string", "kind": "file", "display_name": "string", "original_name": "string", "mime_type": "string", "size_bytes": 0, "sha256": "string", "url": "string", "pinned": true, "source_kind": "upload", "source_ref": "string", "doc_status": "none", "doc_error_code": "string", "page_count": 0, "ocr_skipped_pages": 0, "job_id": "string", "created_at": "2019-08-24T14:15:22Z", "updated_at": "2019-08-24T14:15:22Z"}Use when the user wants to keep a web page (an http or https address) next to the course files. Do not use to save a file; uploads are done by the user in the app.
semestra_session<token>Set by the sign-in endpoints for the web app. Requests other than GET, HEAD and OPTIONS also need the X-Semestra-CSRF header set to the semestra_csrf cookie.
course_id*Course IdCourse id
application/json- body
url*Urlhttp(s) address
1 <= length <= 2000display_name?|Name to show; defaults to the address' host
folder_id?|Folder to put it in
Successful Response
application/json- response
id*Idcourse_id*Course Idfolder_id*string|nullkind*Kind"file""link"display_name*Display Nameoriginal_name*string|nullmime_type*string|nullsize_bytes*Size Bytessha256*string|nullurl*string|nullpinned*Pinnedsource_kind*|nullsource_ref*string|nulldoc_status*Doc Status"none""pending""processing""ready""failed""unsupported"doc_error_code*string|nullpage_count*integer|nullocr_skipped_pages*Ocr Skipped Pagesjob_id*string|nullcreated_at*Created Atdate-timeupdated_at*Updated Atdate-timecurl -X POST 'https://example.com/courses/string/file-links' \ -H 'Content-Type: application/json' \ -d '{ "url": "string"}'{ "id": "string", "course_id": "string", "folder_id": "string", "kind": "file", "display_name": "string", "original_name": "string", "mime_type": "string", "size_bytes": 0, "sha256": "string", "url": "string", "pinned": true, "source_kind": "upload", "source_ref": "string", "doc_status": "none", "doc_error_code": "string", "page_count": 0, "ocr_skipped_pages": 0, "job_id": "string", "created_at": "2019-08-24T14:15:22Z", "updated_at": "2019-08-24T14:15:22Z"}Bytes and file counts per course and per type (PDF, image, Office, text, other), largest first. Shown on the account's data settings.
semestra_session<token>Set by the sign-in endpoints for the web app. Requests other than GET, HEAD and OPTIONS also need the X-Semestra-CSRF header set to the semestra_csrf cookie.
Successful Response
application/json- response
Course files by course and by type, largest first; links take no space and are left out.
by_course*array<>by_type*array<>curl -X GET 'https://example.com/files-usage/breakdown'{ "by_course": [ { "course_id": "string", "program_id": "string", "program_name": "string", "name": "string", "color": "string", "files": 0, "bytes": 0 } ], "by_type": [ { "type": "pdf", "files": 0, "bytes": 0 } ]}Used and available storage, and the largest file that can be uploaded.
semestra_session<token>Set by the sign-in endpoints for the web app. Requests other than GET, HEAD and OPTIONS also need the X-Semestra-CSRF header set to the semestra_csrf cookie.
Successful Response
application/json- response
used_bytes*Used BytesAll the user's stored files, every module
files_bytes*Files BytesOf which course files
quota_bytes*Quota Bytes0 means unlimited
max_upload_bytes*Max Upload Bytesvector_files*Vector FilesCourse files with search vectors; a new embedding model rebuilds them
curl -X GET 'https://example.com/files-usage'{ "used_bytes": 0, "files_bytes": 0, "quota_bytes": 0, "max_upload_bytes": 0, "vector_files": 0}