Chalkmind

Using Chalkmind in an app (Shikhar as the example)

An app that teaches, such as Shikhar, a school's app or a trading academy's site, is a host. It uses Chalkmind through the API alone, with its own key, like any customer. Nothing of the host lives in Chalkmind, and nothing of Chalkmind lives in the host: the host's server keeps the key and calls the API, and the host's app shows the board.

Once: the host's account and teachers

  1. The tenant. The owner makes the host's tenant (POST /v1/tenants {"id": "shikhar", "name": "Shikhar"}). The answer's key manages the tenant; it stays on the host's server, never in the app.
  2. One teacher per class and subject. The host makes them from the templates. Each one gets the class's library by chapter, the shared textbook, and the host's own notes:

`` POST /v1/teachers {"id": "shikhar-std10-science", "from": "std10-science", "name": "Std 10 Science", "names": {"gu": "ધોરણ 10 વિજ્ઞાન"}, "lang": "gu", "record": true, "notes": "GSEB Gujarati medium. Exams in March: board-exam style answers."} ``

A teacher of the host's own (spoken English, a crash course) is made the same way, without from.

  1. Books. If the host has its own notes for a teacher, it adds them as that teacher's book (POST /v1/teachers/ID/book).
  2. The year plan. The host's syllabus with its dates, for every batch of a teacher, or for one batch:

`` PUT /v1/teachers/shikhar-std10-science/plan {"chapters": [{"n": 1, "title": "Chemical reactions and equations", "by": "2026-06-30"}, {"n": 2, "by": "2026-07-15"}, …]} ``

Who is taught: the learner

Every lesson names its learner. The teacher's memory (its journal) is kept per teacher and per learner:

The host chooses its own ids, and they never leave its tenant.

A live class

  1. The host's server starts it, as a teacher, on a channel of its own:

`` POST /v1/board/shikhar-10a-science/command {"text": "Chapter 13: magnetic effects of electric current, the electromagnet", "teacher": "shikhar-std10-science", "learner": "batch-2026-10a", "chapter": 13, "fresh": true} ``

The teacher is told its journal with the batch before it starts: what it taught them, when, how often and how, what was shaky, and what the last lesson left out. With chapter, the batch's year plan counts the chapter as taught, and the teacher hears where the batch is in it.

  1. The host's server makes a viewer token for each student (POST /v1/tokens {"channel": "shikhar-10a-science"}) and gives it to the app.
  2. The app shows the board.
    • The Flutter app uses BoardView(channelUrl: 'https://DOMAIN/board/shikhar-10a-science', token: …).
    • A web page uses https://DOMAIN/board/shikhar-10a-science/display?t=…&name=Ravi.

Students hear the teacher, see the board, answer its questions on their screens, and ask their own, typed or spoken.

  1. Homework. At the end of a full lesson the teacher sets homework, and the students' screens show it. They answer there, or in the host's app (POST /v1/homework/ID/answers, with a photo of the notebook). It is marked, each student's marks become their notes, and the host hears homework.checked. The next lesson starts from how the batch did. A chapter test is given the same way ("kind": "test", or "give a chapter test"): timed on the screens, or on paper, with photos of the answer sheets, and a paper to print (GET /v1/homework/ID/paper).
  2. Recording. A teacher with "record": true is recorded. So is any class whose record button is pressed: the host's own console, or POST /v1/board/CH/record. After the class, GET /v1/lessons/ID/recording gives the video, for students who missed it.

Recordings in the host's own storage (Shikhar's R2)

Chalkmind makes the video; the host keeps it, in its own storage, and shows it in its own app.

  1. Record. "record": true on the class (or on its teacher), or the record button (POST /v1/board/CH/record {"on": true}; {"on": false} stops it).
  2. Ready. When the class ends, the video is made (only the parts recorded). The host's server hears recording.ready: {lesson, channel, title, teacher, learner, started_at, duration_s, seconds, bytes, url}.
  3. Copy. The host's server fetches url with its key (GET /v1/lessons/ID/recording: an MP4, in byte ranges if it likes), and puts it into its own storage (Shikhar: its R2 bucket), under a name of its own.
  4. Delete here. DELETE /v1/lessons/ID/recording: Chalkmind keeps no copy.
  5. Show. The host's app lists its class recordings from its own storage, with the title, teacher, batch, date and length the webhook gave.
// the host's server, on Chalkmind's webhook (check X-Chalkmind-Signature first)
if (event === 'recording.ready') {
  const video = await fetch(`${CHALKMIND}${data.url}`, { headers: { Authorization: `Bearer ${KEY}` } });
  await myR2.put(`class-recordings/${data.learner}/${data.lesson}.mp4`, video.body);   // your own R2 client
  await fetch(`${CHALKMIND}/v1/lessons/${data.lesson}/recording`, { method: 'DELETE', headers: { Authorization: `Bearer ${KEY}` } });
  // and keep {title, teacher, learner, started_at, seconds} in your database, for the app's list of recordings
}

The element and the client

``html <script type="module" src="https://DOMAIN/web/embed.js"></script> <chalk-board channel="shikhar-10a-science" token="v1.…" learner="student-17" name="Ravi"></chalk-board> ``

It sends these events: chalk-lesson, chalk-ended, chalk-expired, chalk-answered {ask, choice, right}, chalk-asked, and chalk-recording. Try it at /web/embed-demo.html?channel=…&t=…&name=….

``js import { Chalkmind } from 'https://DOMAIN/web/chalkmind.js'; const cm = new Chalkmind({ key: process.env.CHALKMIND_API_KEY, site: 'https://DOMAIN' }); await cm.classes.start('shikhar-10a-science', { teacher: 'shikhar-std10-science', text: 'Chapter 13', minutes: 40, record: true }); const { token } = await cm.tokens.create('shikhar-10a-science'); ``

Its parts are teachers, classes, tokens, lessons, learners and account. A refusal throws a ChalkmindError with the HTTP status.

What the host can show its own teachers and admins

WhatRoute
The classes taught, with their teacher, batch, length and recordingGET /v1/lessons
What a teacher taught a batch, and how the batch didGET /v1/teachers/ID/journal?learner=batch-2026-10a
Where a batch is in the year plan: chapters taught, next, and behindGET /v1/teachers/ID/plan?learner=batch-2026-10a
Each student of a batch, and how they have done (answers, latest answers, what is shaky)GET /v1/learners/batch-2026-10a?students=1
A batch's homework, and each student's answers and marksGET /v1/homework?class=batch-2026-10a, GET /v1/homework/ID
A batch's week, and each student's (a page for parents: ?format=html); every Sunday by report.weeklyGET /v1/reports/class/batch-2026-10a, GET /v1/reports/student/ID
Questions flagged: not about the lesson, unkind, personal, or a concern (a student who may need help; question.flagged at once)GET /v1/flags?class=batch-2026-10a
A teacher strictly by its syllabus: "scope": "book" on the teacher, "chapter": N on each lesson. Outside the book: one fixed line, flagged off_topicPATCH /v1/teachers/ID {"scope": "book"}
What the teacher noted about a student or a batchGET /v1/learners/ID
Minutes and cost this monthGET /v1/usage
Its teachers, their books and libraryGET /v1/teachers, GET /v1/teachers/ID

A host's admin page (for example, Shikhar's) is made from these: each teacher with its batches, what it has taught, the recordings, and the minutes used.

The rules a host keeps