> ## Documentation Index
> Fetch the complete documentation index at: https://docs.kralis.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Klapp integration

> Protected school data endpoints for Klapp clients.

Kralis provides a protected integration for Klapp clients. Klapp is a Swiss school communication and management platform used by Kralis schools to connect parents, teachers, students, and the school. Kralis supplies Klapp with school master data and academic structure so the communication experience can use the school’s existing records.

[Kralis.app](https://kralis.app) links users to [Klapp Chat](https://klapp.mobi). This page documents the separate server-to-server API that shares Kralis school data with Klapp.

This is a Klapp-compatible pull API: Klapp retrieves school master data from Kralis for synchronization. It does not write students, classes, teachers, or academic years back to Kralis.

## Base URL and authentication

The API is hosted at `https://api.kralis.app`. Every school-scoped data request uses the school acronym in the path:

```text theme={null}
https://api.kralis.app/integrations/klapp/<school_acronym>/
```

For example:

```text theme={null}
https://api.kralis.app/integrations/klapp/demo/
```

Send the API key in the `Authorization` header on every school-scoped request:

```http theme={null}
Authorization: Api-Key <YOUR_SCHOOL_SCOPED_API_KEY>
```

The same header format is used for a global API key where one has been issued. Keep the key server-side. Never place it in a browser URL, client-side bundle, source repository, or log.

The public integration index does not require authentication. The school-scoped router index and all school data endpoints are protected.

The school-scoped API provides:

* school details;
* semesters, represented by Kralis academic years;
* classes;
* students; and
* teachers.

## Route overview

| Route                                   | Authentication | `semester_id` | Academic-year behavior                                                |
| --------------------------------------- | -------------- | ------------- | --------------------------------------------------------------------- |
| `/integrations/klapp/`                  | Public         | No            | Returns integration metadata                                          |
| `/integrations/klapp/<school_acronym>/` | Protected      | No            | Lists school-scoped routes                                            |
| `/school/`                              | Protected      | Optional      | Selects a Year; defaults to the current Year                          |
| `/semesters/`                           | Protected      | No            | Lists all Kralis Years                                                |
| `/classes/`                             | Protected      | Required      | Uses academic-year enrollment records for student membership          |
| `/classes/<class_id>/students/`         | Protected      | Required      | Uses academic-year enrollment records for the selected Year and class |
| `/classes/<class_id>/teachers/`         | Protected      | No            | Returns current teacher-class assignments                             |

In the Klapp contract, a “semester” is the Kralis academic `Year`. A `semester_id` is therefore a Kralis Year UUID, not a Kralis `Term` UUID.

The school-scoped base path also exposes a browsable router index:

```http theme={null}
GET /integrations/klapp/<school_acronym>/
```

## Endpoint details

### Integration index

```text theme={null}
GET /integrations/klapp/
```

This public index returns the API base path, the school-scoped path template, and a demo path example.

```json theme={null}
{
  "integration": "klapp",
  "base_path": "https://api.kralis.app/integrations/klapp/",
  "school_scoped_base_path_template": "https://api.kralis.app/integrations/klapp/{school_acronym}/",
  "example_school_scoped_path_index": "https://api.kralis.app/integrations/klapp/demo/"
}
```

### School master data

```text theme={null}
GET /integrations/klapp/<school_acronym>/school/
GET /integrations/klapp/<school_acronym>/school/?semester_id=<year_uuid>
```

Returns `school_id`, `school_acronym`, `school_name`, the active semester ID, the selected semester ID, and arrays of semesters, classes, teachers, and students. Omitting `semester_id` uses the school’s current year. Students and class `student_ids` are taken from active students’ academic-year enrollment records for the selected year. This master-data bundle is useful when Klapp needs to synchronize a school in one request.

The two semester fields have distinct meanings:

| Field                | Meaning                                                                                                                                         |
| -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| `active_semester_id` | The UUID of the school’s current/active Kralis Year. This remains the same when a historical year is requested.                                 |
| `semester_id`        | The UUID of the Kralis Year used for this response. It is the requested `semester_id`, or the current Year when the query parameter is omitted. |

Example response:

```json theme={null}
{
  "school_id": "f6a46d9a-98f3-48fd-99c0-4b0e167e7f6f",
  "school_acronym": "demo",
  "school_name": "Demo School",
  "active_semester_id": "85c2918b-ffef-4ed4-8796-01e47dac6fa9",
  "semester_id": "85c2918b-ffef-4ed4-8796-01e47dac6fa9",
  "semesters": [
    { "id": "85c2918b-ffef-4ed4-8796-01e47dac6fa9", "name": "2025/2026", "school_year": "2025/2026", "active": true, "last_change": "2026-09-03T08:55:07Z" },
    { "id": "a4b8f8a7-2d8d-4b5d-8d6f-2c1a9f4e6b10", "name": "2024/2025", "school_year": "2024/2025", "active": false, "last_change": "2026-08-20T12:10:00Z" }
  ],
  "classes": [
    {
      "class_id": "b1a46d9a-98f3-48fd-99c0-4b0e167e7f6f",
      "school_year": "2025/2026",
      "name": "JS1",
      "full_name": "Junior Secondary 1",
      "type": ["class"],
      "teacher_ids": ["9f1f4a1c-8a7b-4f49-90a1-27b2d9bb8a2b"],
      "student_ids": ["2d8a2dd1-4f68-4c5d-90f9-44c35e2c08b4"],
      "last_change": "2026-09-03T08:55:07Z"
    }
  ],
  "teachers": [
    {
      "teacher_id": "9f1f4a1c-8a7b-4f49-90a1-27b2d9bb8a2b",
      "first_name": "Samuel",
      "last_name": "Ibrahim",
      "other_names": "David",
      "full_name": "Ibrahim Samuel David",
      "function": "Teacher",
      "email": "samuel.ibrahim@demo.edu",
      "class_ids": ["b1a46d9a-98f3-48fd-99c0-4b0e167e7f6f"],
      "last_change": "2026-09-03T08:55:07Z"
    }
  ],
  "students": [
    {
      "guid": "2d8a2dd1-4f68-4c5d-90f9-44c35e2c08b4",
      "student_id": "2d8a2dd1-4f68-4c5d-90f9-44c35e2c08b4",
      "student_username": "stu123456789@demo",
      "first_name": "Ada",
      "last_name": "Okafor",
      "other_names": null,
      "full_name": "Okafor Ada",
      "date_of_birth": "2012-03-14",
      "current_class_id": "b1a46d9a-98f3-48fd-99c0-4b0e167e7f6f",
      "semester_class_id": "b1a46d9a-98f3-48fd-99c0-4b0e167e7f6f",
      "class_ids": ["b1a46d9a-98f3-48fd-99c0-4b0e167e7f6f"],
      "last_change": "2026-09-03T08:55:07Z"
    }
  ]
}
```

### Semesters

```text theme={null}
GET /integrations/klapp/<school_acronym>/semesters/
```

Returns every Kralis academic year as a Klapp semester. Each record includes `id`, `name`, `school_year`, `active`, and `last_change`:

```json theme={null}
{ "id": "year-uuid", "name": "2025/2026", "school_year": "2025/2026", "active": true, "last_change": "2026-09-03T08:55:07Z" }
```

An example collection response:

```json theme={null}
[
  { "id": "85c2918b-ffef-4ed4-8796-01e47dac6fa9", "name": "2025/2026", "school_year": "2025/2026", "active": true, "last_change": "2026-09-03T08:55:07Z" },
  { "id": "a4b8f8a7-2d8d-4b5d-8d6f-2c1a9f4e6b10", "name": "2024/2025", "school_year": "2024/2025", "active": false, "last_change": "2026-08-20T12:10:00Z" }
]
```

The `id` is the Kralis Year UUID and is used as `semester_id` in other requests.

### Classes

```text theme={null}
GET /integrations/klapp/<school_acronym>/classes/?semester_id=<year_uuid>
```

Returns class records with `class_id`, `school_year`, `name`, `full_name`, `type`, `teacher_ids`, `student_ids`, and `last_change`. Klapp allows a record to be either a class or a group, but Kralis `Classe` records represent academic classes only; Kralis does not currently expose group records through this integration. Therefore, `type` is always `['class']`, represented as an array to match Klapp’s class/group contract. `semester_id` identifies the Year whose academic-year enrollment records supply the active students for each class. Teacher IDs represent the current teacher-class assignments.

```json theme={null}
[
  {
    "class_id": "b1a46d9a-98f3-48fd-99c0-4b0e167e7f6f",
    "school_year": "2025/2026",
    "name": "JS1",
    "full_name": "Junior Secondary 1",
    "type": ["class"],
    "teacher_ids": ["9f1f4a1c-8a7b-4f49-90a1-27b2d9bb8a2b"],
    "student_ids": ["2d8a2dd1-4f68-4c5d-90f9-44c35e2c08b4"],
    "last_change": "2026-09-03T08:55:07Z"
  }
]
```

### Class students

```text theme={null}
GET /integrations/klapp/<school_acronym>/classes/<class_id>/students/?semester_id=<year_uuid>
```

Student rows include `guid`, `student_id`, `student_username`, `first_name`, `last_name`, `other_names`, `full_name`, `date_of_birth`, `current_class_id`, `semester_class_id`, `class_ids`, and `last_change`. The endpoint returns active students with an academic-year enrollment record for the selected Year and class. `current_class_id` identifies the student’s live class, while `semester_class_id` and `class_ids` identify the student’s class membership in the selected academic context. `class_ids` is currently a one-item list because this endpoint represents one selected Year/class membership; it is not a complete historical class list.

Student response:

```json theme={null}
[
  {
    "guid": "2d8a2dd1-4f68-4c5d-90f9-44c35e2c08b4",
    "student_id": "2d8a2dd1-4f68-4c5d-90f9-44c35e2c08b4",
    "student_username": "stu123456789@demo",
    "first_name": "Ada",
    "last_name": "Okafor",
    "other_names": "Grace",
    "full_name": "Okafor Ada Grace",
    "date_of_birth": "2012-03-14",
    "current_class_id": "b1a46d9a-98f3-48fd-99c0-4b0e167e7f6f",
    "semester_class_id": "b1a46d9a-98f3-48fd-99c0-4b0e167e7f6f",
    "class_ids": ["b1a46d9a-98f3-48fd-99c0-4b0e167e7f6f"],
    "last_change": "2026-09-03T08:55:07Z"
  }
]
```

### Class teachers

```text theme={null}
GET /integrations/klapp/<school_acronym>/classes/<class_id>/teachers/
```

No `semester_id` is required because Kralis represents teacher-class assignments as school relationships rather than historical Year-level assignments. Teacher rows include `teacher_id`, name fields, `function`, `email`, `class_ids`, and `last_change`. Extra query parameters are ignored.

Teacher response:

```json theme={null}
[
  {
    "teacher_id": "9f1f4a1c-8a7b-4f49-90a1-27b2d9bb8a2b",
    "first_name": "Samuel",
    "last_name": "Ibrahim",
    "other_names": "David",
    "full_name": "Ibrahim Samuel David",
    "function": "Teacher",
    "email": "samuel.ibrahim@demo.edu",
    "class_ids": ["b1a46d9a-98f3-48fd-99c0-4b0e167e7f6f"],
    "last_change": "2026-09-03T08:55:07Z"
  }
]
```

## Data behavior

* Student and teacher collections include only active users. The `student_ids` and `teacher_ids` included on class records likewise reference active users.
* `guid` and `student_id` are the same stable Kralis Student UUID. `teacher_id` is the stable Kralis Teacher UUID.
* `student_username` is the stable Kralis username. These are Kralis identifiers, not Klapp-generated IDs.
* `semester_id` is a Kralis academic Year UUID, not a Term UUID.
* `last_change` is an ISO 8601 UTC timestamp based on the Kralis record’s most recent update. For students, it also reflects changes to their selected-year academic membership.
* Student `class_ids` contains the selected academic-year class membership, not the student’s complete class history.
* Kralis class records always use `type: ["class"]`; group records are not currently provided.
* Classes and class-students require `semester_id`; class-teachers does not.
* Student membership is year-scoped through academic-year enrollment records. These records store the student’s class placement for that academic year, while the related student profile supplies the stable identity and profile fields.
* Teacher-class membership is current/global because Kralis does not store historical teacher assignments by Year.
* If a student has no date of birth in Kralis, the API returns `2010-10-10` as a compatibility fallback. This fallback is response-only and never updates Kralis.
* API responses are cached for ten minutes.
* The API is read-only. It does not create students, classes, teachers, or academic years in Kralis.

The school-scoped endpoints require a school API key, a global API key, or authorized administration. Keys should be scoped to the intended school and rotated or revoked when no longer needed.

For an initial synchronization, use the school master-data endpoint to retrieve the school structure and its related records in one response. For recurring or targeted synchronization, use the semesters, classes, students, and teachers endpoints independently so Klapp can refresh only the data it needs.
