Skip to content

Latest commit

 

History

History
262 lines (196 loc) · 8.41 KB

File metadata and controls

262 lines (196 loc) · 8.41 KB

untapi

WebUntis JSON-RPC + REST API client for Node.js (ESM, CJS, TypeScript).

Zero runtime dependencies. Requires Node.js 18+.

Install

npm install untapi

Quick Start

1. Find your server and school name

WebUntis URLs look like: https://[prefix].webuntis.com/WebUntis/

  • server = the full hostname — [prefix].webuntis.com
  • school = the subdomain prefix — [prefix] (usually matches)

Pass a full URL and the library parses it automatically:

import { WebUntis } from "untapi";

// Option A: pass server + school separately
const api = new WebUntis("[prefix].webuntis.com", "[prefix]");

// Option B: pass just the URL — school is auto-extracted
const api = new WebUntis("https://[prefix].webuntis.com/WebUntis/");

// Option C: pass server alone — library guesses the school name
const api = new WebUntis("[prefix].webuntis.com");

2. Discovering a school automatically

Don't know the exact server? Use WebUntis.discover() — it probes all known WebUntis domains (.webuntis.com, .webuntis.de, .webuntis.at, .untis.at, etc.):

const info = await WebUntis.discover("[prefix]");
if (info) {
  console.log(`Found: ${info.server} (${info.displayName})`);
  const api = new WebUntis(info.server, info.school);
  // ...
}

3. Authenticate and fetch data

const api = new WebUntis("[prefix].webuntis.com");
await api.login("your-username", "your-password");

// Fetch master data
const teachers = await api.masterData.getTeachers();
console.log(teachers);

// Fetch timetable for a class this week
const mon = WebUntis.thisMonday();
const fri = WebUntis.thisFriday();
const timetable = await api.timetable.forClass(42, mon, fri);

console.log(timetable);
await api.logout();

API

All API modules are accessible as properties on the WebUntis instance:

api.masterData

Method Returns Description
getTeachers() MasterRef[] All teachers
getStudents() MasterRef[] All students
getKlassen() MasterRef[] All classes
getSubjects() MasterRef[] All subjects
getDepartments() Department[] All departments
getRooms() MasterRef[] All rooms
getSchoolyears() Schoolyear[] All school years
getCurrentSchoolyear() Schoolyear Current school year
getSchoolyearByDate(date) Schoolyear School year for a given date
getHolidays() Holiday[] All holidays
getHolidaysForRange(start, end) Holiday[] Holidays in a date range
getTimegrid() Timegrid Lesson time slots
getAll() MasterData All master data in parallel
searchPerson(term) { teachers, students } Search by name
getPersonIds(ids) Person[] Resolve person IDs to names
getClassTeachers(classId?) ClassTeacher[] Class teacher assignments
getSubjectTeachers(subjectId?) SubjectTeacher[] Subject teacher assignments
getStudentGroupMembers(groupId) StudentGroupMember[] Members of a student group

api.timetable

Method Returns Description
getTimetable(element, start, end, opts?) TimetableEntry[] Core timetable query
getTimetableWithAbsences(element, start, end) TimetableEntryWithAbsence[] Includes absence data
getTimetableChanges(start, end, element?) TimetableChange[] Changes since last import
forClass(id, start, end) TimetableEntry[] Shorthand: class timetable
forTeacher(id, start, end) TimetableEntry[] Shorthand: teacher timetable
forStudent(id, start, end) TimetableEntry[] Shorthand: student timetable
forSubject(id, start, end) TimetableEntry[] Shorthand: subject timetable
forRoom(id, start, end) TimetableEntry[] Shorthand: room timetable
thisWeekForClass(id) TimetableEntry[] This week's class timetable
thisWeekForTeacher(id) TimetableEntry[] This week's teacher timetable

Element types (for getTimetable):

import { ElementType } from "untapi";

api.timetable.getTimetable(
  { id: 42, type: ElementType.Class }, // or 1-5
  WebUntis.dateToInt(new Date(2026, 5, 8)),
  WebUntis.dateToInt(new Date(2026, 5, 12)),
);
ElementType Value
ElementType.Class 1
ElementType.Teacher 2
ElementType.Subject 3
ElementType.Student 4
ElementType.Room 5

api.exams

Method Returns Description
getExams() Exam[] All exams
getExamsForRange(start, end, opts?) Exam[] Exams in a date range
forClass(id, start, end) Exam[] Exams for a class
forStudent(id, start, end) Exam[] Exams for a student
forTeacher(id, start, end) Exam[] Exams for a teacher

api.homework

Method Returns Description
getHomeworks(start, end, opts?) Homework[] Homework entries
forClass(id, start, end) Homework[] Homework for a class
forStudent(id, start, end) Homework[] Homework for a student
forTeacher(id, start, end) Homework[] Homework by a teacher
setCompleted(homeworkId, completed) boolean Mark as done/undone

api.absences

Method Returns Description
getAbsences(start, end, opts?) Absence[] Absence records
forStudent(id, start, end) Absence[] Absences for a student
forClass(id, start, end) Absence[] Absences for a class

api.substitutions

Method Returns Description
getSubstitutions(start, end, opts?) Substitution[] Substitution plans

api.classreg

Method Returns Description
getClassregEvents(start, end, opts?) ClassregEvent[] Class register events
forClass(id, start, end) ClassregEvent[] Events for a class

api.status

Method Returns Description
getLatestImportTime() number (unix ms) Last data import timestamp
getStatusData() StatusData Detailed sync status

api.messages

Method Returns Description
getMessages() Message[] All messages
getMessagesSince(timestamp) Message[] Messages after timestamp

Date Helpers

WebUntis uses yyyymmdd integers for dates (e.g. 20260610 = 10 June 2026).

const d = WebUntis.dateToInt(new Date());  // 20260610
const date = WebUntis.intToDate(20260610); // Date object
const mon = WebUntis.thisMonday();          // this week's Monday
const fri = WebUntis.thisFriday();          // this week's Friday
const str = WebUntis.formatDate(20260610);  // "10.6.2026"

Also available as standalone imports:

import { dateToInt, intToDate, thisMonday, thisFriday } from "untapi";

Raw JSON-RPC Access

For methods not covered by the typed API:

const result = await api.client._request("getMethodName", { param: "value" });

REST API (Modern WebUntis)

The library also ships a REST client (used by the WebUntis web app):

const data = await api.client._restRequest("timetable/entries?start=2026-06-08&end=2026-06-12&format=9&resourceType=STUDENT&resources=2627");

Requires authentication via login() first (which captures the REST token).

Error Handling

import { WebUntisError, AuthenticationError, SessionExpiredError } from "untapi";

try {
  await api.login("user", "pass");
} catch (err) {
  if (err instanceof AuthenticationError) {
    console.error("Bad credentials");
  } else if (err instanceof SessionExpiredError) {
    console.error("Session expired, re-login required");
  } else if (err instanceof WebUntisError) {
    console.error(`WebUntis error ${err.code}: ${err.message}`);
  }
}
Error Code When
AuthenticationError -8520 Invalid credentials
SessionExpiredError -8509 / -8510 Session timed out
InvalidRequestError Malformed request
ServerError Server-side failure
WebUntisError varies Base class for all errors

TypeScript

The library is fully typed — import types directly:

import type {
  TimetableEntry, MasterRef, ElementType,
  Schoolyear, Holiday, Exam, Homework, Absence,
  Substitution, Message, StatusData,
} from "untapi";

License

MIT