These requests allows you to initialize a session, upload images and PDF-like files, set instructions, start LLM sessions, analyse files, generate study guides, flashcards, worksheets, mindmaps, and retrieve history.
All communication is done via POST requests to the server endpoint:
https://6q4-meon3oytck2ykijcg-comzfeezo-custom.service.onethingrobot.com/upload
Each request uses FormData with a command key and optional additional fields.
Command: init_session
This command initializes a new study session under a specific user. It verifies both the session ID and username, creates the required folder structure under the user’s directory, and sets up a default conversation history for the LLM.
FormData:
formData.append("command", "init_session");
formData.append("session", "<SESSION_ID>");
formData.append("user", "<USERNAME>");Server Behavior:
- Verifies both
id(session ID) anduser(username) are provided. - Creates the following directory structure:
ROOT_DIR └── <USERNAME>/ └── <SESSION_ID>/ ├── pdfs/ └── imgs/ - Initializes a default message history (
messages.json) in the session folder with a system instruction and a first user prompt:[ { "role": "system", "content": "Your task is to serve as a study tool - given the info that will be provided next, in form of either text or image, you will try your best to understand them. You will be asked to generate a summary in case we have to check your understanding. You will generate a study guide covering the given information. The guide shall contain 1) a descriptive summary of all given materials in the form of a lecture note, 2) a set of flashcard questions, short in form, along with corresponding answers, 3) an organized worksheet served as an exercise, supplied along with an answer sheet. Your responses will be listened by a front end, so answer only what is being asked, and follow the form. Good Luck!" }, { "role": "user", "content": "You will be writing a note and prepare some questions on following materials. Materials will be given" }, { "role": "assistant", "content": "<Assistant’s initial response from Ollama>" } ] - Sends the initial messages to the LLM model via
ollama.chat()and appends the assistant’s first response. - Saves this conversation in
messages.jsonunder the session directory.
Status:
- ✅ Success:
{ "message": "Session '<SESSION_ID>' initialized successfully for user '<USERNAME>'" } - ❌ Failure:
- Missing session ID:
{ "error": "No session ID provided" } - Missing username:
{ "error": "No permission." }
- Missing session ID:
Example Usage:
const formData = new FormData();
formData.append("command", "init_session");
formData.append("id", "session001");
formData.append("user", "jayfeng");
fetch(SERVER_URL, { method: "POST", body: formData })
.then(res => res.json())
.then(console.log);Notes:
- Both
idanduserare required — the session won’t initialize otherwise. - The structure now organizes all sessions under user folders, enabling multiple users and multiple sessions per user.
- Always call
init_sessionbefore any upload, analysis, or generation commands.
Command: append_image
FormData:
formData.append("user", <USER_ID>);
formData.append("session", <SESSION_ID>);
formData.append("command", "append_image");
formData.append("file", <File Object>);Status:
- Success:
{"message": "File saved at: <path>: Success"} - Failure:
{"error": "...error details..."}
Command: append_pdflike
FormData:
formData.append("user", <USER_ID>);
formData.append("session", <SESSION_ID>);
formData.append("command", "append_pdflike");
formData.append("file", <File Object>);Status: Same as Upload Image
Command: remove_img
FormData:
formData.append("user", <USER_ID>);
formData.append("session", <SESSION_ID>);
formData.append("command", "remove_img");
formData.append("filename", "<IMAGE_FILENAME>");Status:
-
Success:
{"message": "File '<IMAGE_FILENAME>' removed successfully."} -
Failure:
- Session not initialized:
{"error": "Session not initialized."} - Filename missing:
{"error": "No filename provided."} - File not found:
{"error": "File not found: <IMAGE_FILENAME>"} - Other errors:
{"error": "...error details..."}
- Session not initialized:
Command: remove_pdf
FormData:
formData.append("user", <USER_ID>);
formData.append("session", <SESSION_ID>);
formData.append("command", "remove_pdf");
formData.append("filename", "<PDF_FILENAME>");Status:
-
Success:
- PDF removed only:
{"message": "PDF '<PDF_FILENAME>' removed successfully."} - PDF and associated image folder removed:
{"message": "PDF '<PDF_FILENAME>' removed successfully. Associated image folder '<BASENAME>' removed."}
- PDF removed only:
-
Failure:
- Session not initialized:
{"error": "Session not initialized."} - Filename missing:
{"error": "No filename provided."} - PDF not found:
{"error": "File not found: <PDF_FILENAME>"} - Other errors:
{"error": "...error details..."}
- Session not initialized:
Command: set_instruct
FormData:
formData.append("user", <USER_ID>);
formData.append("session", <SESSION_ID>);
formData.append("command", "set_instruct");
formData.append("instruction_text", "<INSTRUCTION_TEXT>");Status:
- Success:
{"message": "Instruction Text Reset Successful"} - Failure:
{"error": "...error details..."}
Command: analyse_pdf
FormData:
formData.append("user", <USER_ID>);
formData.append("session", <SESSION_ID>);
formData.append("command", "analyse_pdf");Status:
- Success:
{"message": "Analyse PDFs Successful"} - Failure:
{"error": "...error details..."}
Command: analyse_img
FormData:
formData.append("user", <USER_ID>);
formData.append("session", <SESSION_ID>);
formData.append("command", "analyse_img");Status:
- Success:
{"message": "Analysing Images Successful"} - Failure:
{"error": "...error details..."}
Command: generate_study_guide
FormData:
formData.append("user", <USER_ID>);
formData.append("session", <SESSION_ID>);
formData.append("command", "generate_study_guide");Status:
- Success:
{"markdown": "<generated markdown content>", "mermaid": "<mindmap mermaid source>"} - Failure:
{"error": "...error details..."}
Command: generate_flashcard_questions
FormData:
formData.append("user", <USER_ID>);
formData.append("session", <SESSION_ID>);
formData.append("command", "generate_flashcard_questions");
formData.append("num_questions", "<NUMBER>");
formData.append("difficulty", "<easy|medium|hard>");Status:
- Success:
{"flashcards": "<JSON flashcards>"} - Failure:
{"error": "...error details..."}
Command: generate_worksheet_questions
FormData:
formData.append("user", <USER_ID>);
formData.append("session", <SESSION_ID>);
formData.append("command", "generate_worksheet_questions");
formData.append("num_questions", "<NUMBER>");
formData.append("difficulty", "<easy|medium|hard>");Status:
- Success:
{"worksheet": "<JSON worksheet>"} - Failure:
{"error": "...error details..."}
Command: generate_worksheet_questions
FormData:
formData.append("user", <USER_ID>);
formData.append("session", <SESSION_ID>);
formData.append("command", "mark_worksheet_questions");
formData.append("question", "<THE QUESTION FOR MARKING>");
formData.append("answer", "<USER ANSWER>");
formData.append("mark_scheme", "<MARK SCHEME>"); // This is optional, but `generate_worksheet_questions` will provide mark_scheme.Status:
- Success:
{"marking": "<JSON marking>"} - Failure:
{"error": "...error details..."}
Command: generate_podcast
FormData:
formData.append("user", <USER_ID>);
formData.append("session", <SESSION_ID>);
formData.append("command", "mark_worksheet_questions");
formData.append("prompt", "An optional user prompt if need additional requirements"); // This is optionalAction:
When request is sent, a podcast script (refer to the schema later in the file) will be generated by the LLM, after which audios
are generated via ElevenLabs API, along with a podcast cover image. The latter two will be uploaded to supabase at location
<USER>/<SESSION_ID>/podcasts/<PODCAST_ID>/i, under the media basket (i represents the i-th audio). The script will be returned back
over the POST request (refer to the following Status section).
Status:
- Success:
{"script": "<JSON script>"} - Failure:
{"error": "...error details..."}
Command: generate_mindmap
FormData:
formData.append("user", <USER_ID>);
formData.append("session", <SESSION_ID>);
formData.append("command", "generate_mindmap");Status:
- Success:
{"message": "Generate Mindmap Successful"} - Failure:
{"error": "...error details..."}
Command: retrieve_full_history
FormData:
formData.append("command", "retrieve_full_history");Status:
- Success:
{"message": "Full History Uploaded."} - Failure:
{"error": "...error details..."}
To actually fetch the history, call the separate endpoint:
GET /full_history→{"full_history": [...messages...]}
Command: inference_from_prompt
FormData:
formData.append("user", <USER_ID>);
formData.append("session", <SESSION_ID>);
formData.append("command", "inference_from_prompt");
formData.append("prompt", "<PROMPT_TEXT>");Status:
- Success:
{"last_response": "<generated content>"} - Failure:
{"error": "...error details..."}
- Always run
init_sessionfirst before any other command. - Uploads require valid
Fileobjects. - Errors always come as JSON:
{"error": "...message..."}. generate_flashcard_answersandgenerate_worksheet_answersare not separate commands (handled inside their respective question-generation commands).
workspaceId,
title: 'Some title'`,
description: 'Some description for generated practice problems',
difficulty: 'EASY/MEDIUM/HARD',
estimatedTime: '30 min',
'problems": [
{{
"question": "<Question 1>",
"answer": "<Answer 1>",
"type": "TEXT",
"options": [Keep this empty],
"mark_scheme": {
"points": [
{
"point": 1,
"requirements": "Description of what's needed for this point"
}
],
"totalPoints": <integer value representing total points for this question>
}
}},
{{
"question": "<Question 2>",
"answer": "<Answer 2>",
"type": "TEXT",
"options": [Keep this empty],
"mark_scheme": {
"points": [
{
"point": 1,
"requirements": "Description of what's needed for this point"
}
],
"totalPoints": <integer value representing total points for this question>
}
}},
{{
"question": "<Question 3>",
"answer": "<Answer 3>",
"type": "MULTIPLE_CHOICE",
"options": ["<Option 1>", "<Option 2>", "<Option 3>"],
"mark_scheme": {
"points": [
{
"point": 1,
"requirements": "Answer explanation for this MCQ"
}
],
"totalPoints": <integer value representing total points for this question>
},
"points": <integer value representing total points for this question>
}},
{{
"question": "<Question 4>",
"answer": "<Answer 4>",
"type": "NUMERIC",
"options": [Keep this empty],
"mark_scheme": {
"points": [
{
"point": 1,
"requirements": "Answer explanation for this numeric question"
}
],
"totalPoints": <integer value representing total points for this question>
},
"points": <integer value representing total points for this question>
}},
{{
"question": "<Question 5>",
"answer": "<Answer 5>",
"type": "TRUE_FALSE",
"options": [Keep this empty],
"mark_scheme": {
"points": [
{
"point": 1,
"requirements": "Answer explanation for this true/false question"
}
],
"totalPoints": <integer value representing total points for this question>
},
"points": <integer value representing total points for this question>
}},
{{
"question": "<Question 6>",
"answer": "<Answer 6>",
"type": "MATCHING",
"options": ["Option 1", "Option 2", "Option 3"],
"mark_scheme": {
"points": [
{
"point": 1,
"requirements": "Answer explanation for this matching question"
}
],
"totalPoints": <integer value representing total points for this question>
},
"points": <integer value representing total points for this question>
}}]
{
totalPoints: <sum of all achievedPoints (total points earned by student)>,
points: [
{
point: <max points for this criteria>,
requirements: <requirements text from mark scheme>,
achievedPoints: <points earned for this criteria>,
feedback: <specific feedback for this criteria>
},
... (one object for each marking point in the mark scheme)
]
}
[
<Section One Script (str)>,
<Section Two Script (str)>,
<Section Three Script (str)>,
...
]
- Make sure to initialize a session first (
init_session) before sending any other commands to that session. - All file uploads require a
Fileobject from a<input type="file">element. - All output JSON responses are displayed in
<pre>blocks for readability in the frontend. - Errors will be returned as HTTP errors or caught exceptions.
Returns a listing of all files grouped by session.
A session is represented by a directory in the server’s working directory that contains
at least a pdfs/ or imgs/ subfolder.
GET /session_files
- 200 OK — JSON object containing session data.
- 400/500 — Error response if something went wrong.
{
"user_count": 5,
"users": {
"FantasticJellyFish": {
"61016": {
"counts": {
"all": 1,
"imgs": 0,
"pdfs": 1
},
"imgs": [],
"pdfs": [
{
"modified_iso": "2025-10-11T21:20:50",
"modified_ts": 1760217650,
"name": "AP Lab 04 - Diffusion and Osmosis 2016.pdf",
"path": "Data/FantasticJellyFish/61016/pdfs/AP Lab 04 - Diffusion and Osmosis 2016.pdf",
"size_bytes": 320573,
"type": "pdf"
}
],
"user": "FantasticJellyFish"
}
},
"HappyCat": {
"1": {
"counts": {
"all": 1,
"imgs": 1,
"pdfs": 0
},
"imgs": [
{
"modified_iso": "2025-10-11T20:21:58",
"modified_ts": 1760214118,
"name": "figure-05-02-04.jpeg",
"path": "Data/HappyCat/1/imgs/figure-05-02-04.jpeg",
"size_bytes": 162699,
"type": "img"
}
],
"pdfs": [],
"user": "HappyCat"
},
"100": {
"counts": {
"all": 1,
"imgs": 1,
"pdfs": 0
},
"imgs": [
{
"modified_iso": "2025-10-11T19:26:42",
"modified_ts": 1760210802,
"name": "figure-05-02-04.jpeg",
"path": "Data/HappyCat/100/imgs/figure-05-02-04.jpeg",
"size_bytes": 162699,
"type": "img"
}
],
"pdfs": [],
"user": "HappyCat"
},
"200": {
"counts": {
"all": 1,
"imgs": 1,
"pdfs": 0
},
"imgs": [
{
"modified_iso": "2025-10-11T19:55:12",
"modified_ts": 1760212512,
"name": "figure-05-02-04.jpeg",
"path": "Data/HappyCat/200/imgs/figure-05-02-04.jpeg",
"size_bytes": 162699,
"type": "img"
}
],
"pdfs": [],
"user": "HappyCat"
}
},
"SadDog": {
"100": {
"counts": {
"all": 0,
"imgs": 0,
"pdfs": 0
},
"imgs": [],
"pdfs": [],
"user": "SadDog"
},
"610": {
"counts": {
"all": 0,
"imgs": 0,
"pdfs": 0
},
"imgs": [],
"pdfs": [],
"user": "SadDog"
}
},
"SadPig": {
"101": {
"counts": {
"all": 0,
"imgs": 0,
"pdfs": 0
},
"imgs": [],
"pdfs": [],
"user": "SadPig"
}
},
"cmesjxa2i0000ry9oyjmoasjk": {
"cmesjxwhz0002ry9ozjg0gpvn": {
"counts": {
"all": 0,
"imgs": 0,
"pdfs": 0
},
"imgs": [],
"pdfs": [],
"user": "cmesjxa2i0000ry9oyjmoasjk"
}
}
}
}-
sessionsis a dictionary keyed by session name. -
Each session includes:
counts: number of PDFs, images, and total files.pdfs,imgs,all: arrays of file metadata.
-
File metadata includes:
name: filename only.path: relative path to the file.type:"pdf"or"img".size_bytes: file size.modified_ts: last modified timestamp (epoch).modified_iso: last modified time (ISO format).