Semestra

Files

GET
/courses/{course_id}/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.

Authorization

cookiesemestra_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.

Path Parameters

course_id*Course Id

Course id

Query Parameters

folder_id?|

Only items directly in this folder; omit for the course root

recursive?Recursive

List the items of every folder of the course, not just one

Defaultfalse
search?|

Keep items whose name contains this text (case-insensitive). To search what the files say, use files.document.search instead.

sort?Sort

Sort key

Default"name"
Value in"name""size""updated""created""type"
descending?Descending

Reverse the sort order

Defaultfalse
fields?array<>|

Agent/MCP only: return just these fields of each item (and its id)

cursor?|

next_cursor of the previous page

limit?Limit

Page size

Default200

Response Body

Successful Response

application/json
  1. response
folders*array<>

Every folder of the course

items*array<>
next_cursor*string|null
Example Request
curl -X GET 'https://example.com/courses/string/files'
Example Response
{  "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"}
POST
/courses/{course_id}/files

All or nothing: if one file is refused (too large, over quota) none is kept.

Authorization

cookiesemestra_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.

Path Parameters

course_id*Course Id

Course id

Request Body

multipart/form-data
  1. body
files*array<string>

The files to upload

folder_id?|

Folder to put them in

Response Body

Successful Response

application/json
  1. response
items*array<>
Example Request
curl -X POST 'https://example.com/courses/string/files' \  -F 'files=[  "string"]'
Example Response
{  "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"    }  ]}
GET
/files/{item_id}/content

Authorization

cookiesemestra_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.

Path Parameters

item_id*Item Id

File id

Query Parameters

disposition?Disposition

inline previews, attachment downloads

Match^(inline|attachment)$
Default"attachment"

Response Body

Successful Response

application/octet-stream
Example Request
curl -X GET 'https://example.com/files/string/content'
Example Response
Empty
GET
/files/{item_id}/pages/{page}.png

Authorization

cookiesemestra_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.

Path Parameters

item_id*Item Id

File id

page*Page

Page number, starting at 1

Range1 <= value

Response Body

Successful Response

image/png
Example Request
curl -X GET 'https://example.com/files/string/pages/1.png'
Example Response
Empty
GET
/files/{item_id}/outline

Use to see the structure of a long document before reading parts of it.

Authorization

cookiesemestra_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.

Path Parameters

item_id*Item Id

File or link id, from files.item.list

Response Body

Successful Response

application/json
  1. response
item_id*Item Id
display_name*Display Name
page_count*Page Count
entries*array<>
Example Request
curl -X GET 'https://example.com/files/string/outline'
Example Response
{  "item_id": "string",  "display_name": "string",  "page_count": 0,  "entries": [    {      "level": 0,      "title": "string",      "page": 0    }  ]}
GET
/files/{item_id}/document

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.

Authorization

cookiesemestra_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.

Path Parameters

item_id*Item Id

File id, from files.item.list or files.document.search

Query Parameters

page_from?Page From

First page (1-based)

Default1
page_to?|

Last page; at most 30 pages, and for the assistant about 9000 characters, are returned per call

Response Body

Successful Response

application/json
  1. response
item_id*Item Id
display_name*Display Name
page_count*Page Count
pages*array<>
next_page*|

Call again from this page for the rest

citations*array<>

One per page; cite a page by its citation_id

Example Request
curl -X GET 'https://example.com/files/string/document'
Example Response
{  "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"    }  ]}
POST
/programs/{program_id}/files:search

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.

Authorization

cookiesemestra_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.

Path Parameters

program_id*Program Id

Program id; the search never leaves this Program

Request Body

application/json
  1. body
query*Query

What to look for: words from the document or a question

Length1 <= length <= 500
term_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 K

Results to return

Range1 <= value <= 20
Default8
mode?Mode

hybrid = keywords and meaning together; keyword; semantic (needs an embedding model, else falls back to keyword)

Default"hybrid"
Value in"hybrid""keyword""semantic"

Response Body

Successful Response

application/json
  1. 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
Value in"hybrid""keyword""semantic"
citations*array<>

One per result, by its citation_id

Example Request
curl -X POST 'https://example.com/programs/string/files:search' \  -H 'Content-Type: application/json' \  -d '{  "query": "string"}'
Example Response
{  "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"    }  ]}
POST
/courses/{course_id}/files:delete

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.

Authorization

cookiesemestra_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.

Path Parameters

course_id*Course Id

Course id

Request Body

application/json
  1. body
item_ids?array<>

Files and links to delete

Itemsitems <= 1000
folder_ids?array<>

Folders to delete with everything inside them

Itemsitems <= 1000

Response Body

Successful Response

application/json
  1. response
deleted?Deleted
Defaulttrue
Example Request
curl -X POST 'https://example.com/courses/string/files:delete' \  -H 'Content-Type: application/json' \  -d '{}'
Example Response
{  "deleted": true}
POST
/courses/{course_id}/files:move

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.

Authorization

cookiesemestra_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.

Path Parameters

course_id*Course Id

Course id

Request Body

application/json
  1. body
item_ids?array<>

Files and links to move

Itemsitems <= 1000
folder_ids?array<>

Folders to move, with their contents

Itemsitems <= 1000
to_folder_id*|

Folder to move them into; null moves them to the course root

Response Body

Successful Response

application/json
  1. response
moved*Moved

Files, links and folders moved

Example Request
curl -X POST 'https://example.com/courses/string/files:move' \  -H 'Content-Type: application/json' \  -d '{  "to_folder_id": "string"}'
Example Response
{  "moved": 0}
POST
/courses/{course_id}/folders

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).

Authorization

cookiesemestra_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.

Path Parameters

course_id*Course Id

Course id

Request Body

application/json
  1. body
name*Name

Folder name

Length1 <= length <= 100
parent_id?|

Parent folder (from files.item.list); null = course root

Response Body

Successful Response

application/json
  1. response
id*Id
course_id*Course Id
parent_id*string|null
name*Name
item_count*Item Count

Files and links directly inside the folder

created_at*Created At
Formatdate-time
updated_at*Updated At
Formatdate-time
Example Request
curl -X POST 'https://example.com/courses/string/folders' \  -H 'Content-Type: application/json' \  -d '{  "name": "string"}'
Example Response
{  "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 or move a folder.

PATCH
/folders/{folder_id}

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.

Authorization

cookiesemestra_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.

Path Parameters

folder_id*Folder Id

Folder id

Request Body

application/json
  1. body
name?|

New name

parent_id?|

Move under this folder; null moves it to the course root

Response Body

Successful Response

application/json
  1. response
id*Id
course_id*Course Id
parent_id*string|null
name*Name
item_count*Item Count

Files and links directly inside the folder

created_at*Created At
Formatdate-time
updated_at*Updated At
Formatdate-time
Example Request
curl -X PATCH 'https://example.com/folders/string' \  -H 'Content-Type: application/json' \  -d '{}'
Example Response
{  "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"}
DELETE
/folders/{folder_id}

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.

Authorization

cookiesemestra_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.

Path Parameters

folder_id*Folder Id

Folder id

Query Parameters

recursive?Recursive

Also delete everything inside; required for a non-empty folder

Defaultfalse

Response Body

Successful Response

application/json
  1. response
deleted?Deleted
Defaulttrue
Example Request
curl -X DELETE 'https://example.com/folders/string'
Example Response
{  "deleted": true}
GET
/files/{item_id}

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.

Authorization

cookiesemestra_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.

Path Parameters

item_id*Item Id

File or link id, from files.item.list

Response Body

Successful Response

application/json
  1. response
id*Id
course_id*Course Id
folder_id*string|null
kind*Kind
Value in"file""link"
display_name*Display Name
original_name*string|null
mime_type*string|null
size_bytes*Size Bytes
sha256*string|null
url*string|null
pinned*Pinned
source_kind*|null
source_ref*string|null
doc_status*Doc Status
Value in"none""pending""processing""ready""failed""unsupported"
doc_error_code*string|null
page_count*integer|null
ocr_skipped_pages*Ocr Skipped Pages
job_id*string|null
created_at*Created At
Formatdate-time
updated_at*Updated At
Formatdate-time
Example Request
curl -X GET 'https://example.com/files/string'
Example Response
{  "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"}
PATCH
/files/{item_id}

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.

Authorization

cookiesemestra_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.

Path Parameters

item_id*Item Id

File or link id, from files.item.list

Request Body

application/json
  1. 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

Response Body

Successful Response

application/json
  1. response
id*Id
course_id*Course Id
folder_id*string|null
kind*Kind
Value in"file""link"
display_name*Display Name
original_name*string|null
mime_type*string|null
size_bytes*Size Bytes
sha256*string|null
url*string|null
pinned*Pinned
source_kind*|null
source_ref*string|null
doc_status*Doc Status
Value in"none""pending""processing""ready""failed""unsupported"
doc_error_code*string|null
page_count*integer|null
ocr_skipped_pages*Ocr Skipped Pages
job_id*string|null
created_at*Created At
Formatdate-time
updated_at*Updated At
Formatdate-time
Example Request
curl -X PATCH 'https://example.com/files/string' \  -H 'Content-Type: application/json' \  -d '{}'
Example Response
{  "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"}
DELETE
/files/{item_id}

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.

Authorization

cookiesemestra_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.

Path Parameters

item_id*Item Id

File or link id, from files.item.list

Response Body

Successful Response

application/json
  1. response
deleted?Deleted
Defaulttrue
Example Request
curl -X DELETE 'https://example.com/files/string'
Example Response
{  "deleted": true}
GET
/programs/{program_id}/pinned-files

Files and links the user pinned for quick access, across the Program's courses.

Authorization

cookiesemestra_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.

Path Parameters

program_id*Program Id

Program id

Response Body

Successful Response

application/json
  1. response
items*array<>
Example Request
curl -X GET 'https://example.com/programs/string/pinned-files'
Example Response
{  "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"    }  ]}
POST
/files/{item_id}:reprocess

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.

Authorization

cookiesemestra_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.

Path Parameters

item_id*Item Id

File or link id, from files.item.list

Response Body

Successful Response

application/json
  1. response
id*Id
course_id*Course Id
folder_id*string|null
kind*Kind
Value in"file""link"
display_name*Display Name
original_name*string|null
mime_type*string|null
size_bytes*Size Bytes
sha256*string|null
url*string|null
pinned*Pinned
source_kind*|null
source_ref*string|null
doc_status*Doc Status
Value in"none""pending""processing""ready""failed""unsupported"
doc_error_code*string|null
page_count*integer|null
ocr_skipped_pages*Ocr Skipped Pages
job_id*string|null
created_at*Created At
Formatdate-time
updated_at*Updated At
Formatdate-time
Example Request
curl -X POST 'https://example.com/files/string:reprocess'
Example Response
{  "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"}
POST
/courses/{course_id}/file-links

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.

Authorization

cookiesemestra_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.

Path Parameters

course_id*Course Id

Course id

Request Body

application/json
  1. body
url*Url

http(s) address

Length1 <= length <= 2000
display_name?|

Name to show; defaults to the address' host

folder_id?|

Folder to put it in

Response Body

Successful Response

application/json
  1. response
id*Id
course_id*Course Id
folder_id*string|null
kind*Kind
Value in"file""link"
display_name*Display Name
original_name*string|null
mime_type*string|null
size_bytes*Size Bytes
sha256*string|null
url*string|null
pinned*Pinned
source_kind*|null
source_ref*string|null
doc_status*Doc Status
Value in"none""pending""processing""ready""failed""unsupported"
doc_error_code*string|null
page_count*integer|null
ocr_skipped_pages*Ocr Skipped Pages
job_id*string|null
created_at*Created At
Formatdate-time
updated_at*Updated At
Formatdate-time
Example Request
curl -X POST 'https://example.com/courses/string/file-links' \  -H 'Content-Type: application/json' \  -d '{  "url": "string"}'
Example Response
{  "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"}
GET
/files-usage/breakdown

Bytes and file counts per course and per type (PDF, image, Office, text, other), largest first. Shown on the account's data settings.

Authorization

cookiesemestra_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.

Response Body

Successful Response

application/json
  1. response

Course files by course and by type, largest first; links take no space and are left out.

by_course*array<>
by_type*array<>
Example Request
curl -X GET 'https://example.com/files-usage/breakdown'
Example Response
{  "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    }  ]}
GET
/files-usage

Used and available storage, and the largest file that can be uploaded.

Authorization

cookiesemestra_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.

Response Body

Successful Response

application/json
  1. response
used_bytes*Used Bytes

All the user's stored files, every module

files_bytes*Files Bytes

Of which course files

quota_bytes*Quota Bytes

0 means unlimited

max_upload_bytes*Max Upload Bytes
vector_files*Vector Files

Course files with search vectors; a new embedding model rebuilds them

Example Request
curl -X GET 'https://example.com/files-usage'
Example Response
{  "used_bytes": 0,  "files_bytes": 0,  "quota_bytes": 0,  "max_upload_bytes": 0,  "vector_files": 0}