diff --git a/lib/classes/JsonApi/RouteMap.php b/lib/classes/JsonApi/RouteMap.php
index baccc2625696efdee4857cd1fef5b7a41fda2fa2..cc94d16f298c4ef961ba29a1968ff9df9c922578 100644
--- a/lib/classes/JsonApi/RouteMap.php
+++ b/lib/classes/JsonApi/RouteMap.php
@@ -125,6 +125,7 @@ class RouteMap
         $this->addAuthenticatedForumRoutes($group);
         $this->addAuthenticatedInstitutesRoutes($group);
         $this->addAuthenticatedMessagesRoutes($group);
+        $this->addAuthenticatedMVVRoutes($group);
         $this->addAuthenticatedNewsRoutes($group);
         $this->addAuthenticatedStudyAreasRoutes($group);
         $this->addAuthenticatedWikiRoutes($group);
@@ -513,6 +514,12 @@ class RouteMap
         $group->delete('/messages/{id}', Routes\Messages\MessageDelete::class);
     }
 
+    private function addAuthenticatedMVVRoutes(RouteCollectorProxy $group): void
+    {
+        $group->get('/degree/{id}', Routes\MVV\AbschlussShow::class);
+        $group->get('/studycourse/{id}', Routes\MVV\StudiengangShow::class);
+    }
+
     private function addAuthenticatedForumRoutes(RouteCollectorProxy $group): void
     {
         $group->get('/courses/{id}/forum-categories', Routes\Forum\ForumCategoriesIndex::class);
diff --git a/lib/classes/JsonApi/Routes/MVV/AbschlussShow.php b/lib/classes/JsonApi/Routes/MVV/AbschlussShow.php
new file mode 100644
index 0000000000000000000000000000000000000000..efe76e94b5030d3e0b41f1845c96e66838e7a5e3
--- /dev/null
+++ b/lib/classes/JsonApi/Routes/MVV/AbschlussShow.php
@@ -0,0 +1,26 @@
+<?php
+
+namespace JsonApi\Routes\MVV;
+
+use JsonApi\Errors\RecordNotFoundException;
+use JsonApi\JsonApiController;
+use JsonApi\Schemas\MVV\Studiengang;
+use Psr\Http\Message\ResponseInterface as Response;
+use Psr\Http\Message\ServerRequestInterface as Request;
+
+class AbschlussShow extends JsonApiController
+{
+    protected $allowedIncludePaths = [
+        Studiengang::TYPE,
+    ];
+
+    public function __invoke(Request $request, Response $response, $args): Response
+    {
+        $degree = \Abschluss::find($args['id']);
+        if (!$degree) {
+            throw new RecordNotFoundException("No degree with id {$args['id']}");
+        }
+
+        return $this->getContentResponse($degree);
+    }
+}
diff --git a/lib/classes/JsonApi/Routes/MVV/StudiengangShow.php b/lib/classes/JsonApi/Routes/MVV/StudiengangShow.php
new file mode 100644
index 0000000000000000000000000000000000000000..07caa589f57e29b3bd134f8cd1aaa54cca6e8824
--- /dev/null
+++ b/lib/classes/JsonApi/Routes/MVV/StudiengangShow.php
@@ -0,0 +1,29 @@
+<?php
+
+namespace JsonApi\Routes\MVV;
+
+use JsonApi\Errors\AuthorizationFailedException;
+use JsonApi\Errors\BadRequestException;
+use JsonApi\Errors\RecordNotFoundException;
+use JsonApi\JsonApiController;
+use JsonApi\Schemas\MVV\Abschluss;
+use JsonApi\Schemas\User as UserSchema;
+use Psr\Http\Message\ResponseInterface as Response;
+use Psr\Http\Message\ServerRequestInterface as Request;
+
+class StudiengangShow extends JsonApiController
+{
+    protected $allowedIncludePaths = [
+        Abschluss::TYPE,
+    ];
+
+    public function __invoke(Request $request, Response $response, $args): Response
+    {
+        $studycourse = \Studiengang::find($args['id']);
+        if (!$studycourse) {
+            throw new RecordNotFoundException("No study course with id {$args['id']}");
+        }
+
+        return $this->getContentResponse($studycourse);
+    }
+}
diff --git a/lib/classes/JsonApi/SchemaMap.php b/lib/classes/JsonApi/SchemaMap.php
index e7168cd998900a09b7c811cd7a3441e59f08c45f..34eb3c9078d73549ca23b5e798d5005913aaff80 100644
--- a/lib/classes/JsonApi/SchemaMap.php
+++ b/lib/classes/JsonApi/SchemaMap.php
@@ -51,6 +51,9 @@ class SchemaMap
             \FileRef::class => Schemas\FileRef::class,
             \FolderType::class => Schemas\Folder::class,
 
+            \Abschluss::class => Schemas\MVV\Abschluss::class,
+            \Studiengang::class => Schemas\MVV\Studiengang::class,
+
             \Courseware\Block::class => Schemas\Courseware\Block::class,
             \Courseware\BlockComment::class => Schemas\Courseware\BlockComment::class,
             \Courseware\BlockFeedback::class => Schemas\Courseware\BlockFeedback::class,
diff --git a/lib/classes/JsonApi/Schemas/MVV/Abschluss.php b/lib/classes/JsonApi/Schemas/MVV/Abschluss.php
new file mode 100644
index 0000000000000000000000000000000000000000..e857116ce0430b5f86a96f7e13e842d688d9b375
--- /dev/null
+++ b/lib/classes/JsonApi/Schemas/MVV/Abschluss.php
@@ -0,0 +1,72 @@
+<?php
+namespace JsonApi\Schemas\MVV;
+
+use JsonApi\Schemas\SchemaProvider;
+use Neomerx\JsonApi\Contracts\Schema\ContextInterface;
+use Neomerx\JsonApi\Schema\Link;
+
+class Abschluss extends SchemaProvider
+{
+    const TYPE = 'degree';
+
+    const REL_STUDYCOURSES = 'studycourses';
+
+    /**
+     * @param \Abschluss $resource
+     */
+    public function getId($resource): ?string
+    {
+        return $resource->id;
+    }
+
+    /**
+     * @param \Abschluss $resource
+     */
+    public function getAttributes($resource, ContextInterface $context): iterable
+    {
+        return [
+            'name' => (string) $resource->name,
+            'name-short' => (string) $resource->name_kurz,
+            'description' => (string) $resource->beschreibung,
+            'description-formatted' => formatReady($resource->beschreibung),
+            'mkdate' => date('c', $resource->mkdate),
+            'chdate' => date('c', $resource->chdate),
+        ];
+    }
+
+    /**
+     * @param \Abschluss $resource
+     */
+    public function getRelationships($resource, ContextInterface $context): iterable
+    {
+        $relationships = [];
+
+        if ($context->getPosition()->getLevel() === 0) {
+            $relationships = $this->getStudycourseRelationship($relationships, $resource, $this->shouldInclude($context, self::REL_STUDYCOURSES));
+//            $relationships = $this->getBookingsRelationship($relationships, $resource, $this->shouldInclude($context, self::REL_BOOKINGS));
+        }
+
+        return $relationships;
+    }
+
+    private function getStudycourseRelationship(array $relationships, \Abschluss $resource, bool $shouldInclude)
+    {
+        if ($shouldInclude) {
+            $relatedStudycourses = $resource->studiengaenge;
+        } else {
+            $relatedStudycourses = $resource->studiengaenge->map(function (\Studiengang $studycourse) {
+                return \Studiengang::build(['id' => $studycourse->id], false);
+            });
+        }
+
+        $relationships[self::REL_STUDYCOURSES] = [
+            self::RELATIONSHIP_LINKS => [
+                Link::RELATED => $this->getRelationshipRelatedLink($resource, self::REL_STUDYCOURSES),
+            ],
+            self::RELATIONSHIP_DATA => $relatedStudycourses,
+        ];
+
+        return $relationships;
+        return $relationships;
+    }
+}
diff --git a/lib/classes/JsonApi/Schemas/MVV/Fach.php b/lib/classes/JsonApi/Schemas/MVV/Fach.php
new file mode 100644
index 0000000000000000000000000000000000000000..01ba0fa9f18f00ccff7516684a84b452e322aa5f
--- /dev/null
+++ b/lib/classes/JsonApi/Schemas/MVV/Fach.php
@@ -0,0 +1,72 @@
+<?php
+namespace JsonApi\Schemas\MVV;
+
+use JsonApi\Schemas\SchemaProvider;
+use Neomerx\JsonApi\Contracts\Schema\ContextInterface;
+use Neomerx\JsonApi\Schema\Link;
+
+class Fach extends SchemaProvider
+{
+    const TYPE = 'subject';
+
+    const REL_STUDYCOURSES = 'studycourses';
+
+    /**
+     * @param \Fach $resource
+     */
+    public function getId($resource): ?string
+    {
+        return $resource->id;
+    }
+
+    /**
+     * @param \Fach $resource
+     */
+    public function getAttributes($resource, ContextInterface $context): iterable
+    {
+        return [
+            'name' => (string) $resource->name,
+            'name-short' => (string) $resource->name_kurz,
+            'description' => (string) $resource->beschreibung,
+            'description-formatted' => formatReady($resource->beschreibung),
+            'mkdate' => date('c', $resource->mkdate),
+            'chdate' => date('c', $resource->chdate),
+        ];
+    }
+
+    /**
+     * @param \Fach $resource
+     */
+    public function getRelationships($resource, ContextInterface $context): iterable
+    {
+        $relationships = [];
+
+        if ($context->getPosition()->getLevel() === 0) {
+            $relationships = $this->getStudycourseRelationship($relationships, $resource, $this->shouldInclude($context, self::REL_STUDYCOURSES));
+//            $relationships = $this->getBookingsRelationship($relationships, $resource, $this->shouldInclude($context, self::REL_BOOKINGS));
+        }
+
+        return $relationships;
+    }
+
+    private function getStudycourseRelationship(array $relationships, \Fach $resource, bool $shouldInclude)
+    {
+        if ($shouldInclude) {
+            $relatedStudycourses = $resource->studiengaenge;
+        } else {
+            $relatedStudycourses = $resource->studiengaenge->map(function (\Studiengang $studycourse) {
+                return \Studiengang::build(['id' => $studycourse->id], false);
+            });
+        }
+
+        $relationships[self::REL_STUDYCOURSES] = [
+            self::RELATIONSHIP_LINKS => [
+                Link::RELATED => $this->getRelationshipRelatedLink($resource, self::REL_STUDYCOURSES),
+            ],
+            self::RELATIONSHIP_DATA => $relatedStudycourses,
+        ];
+
+        return $relationships;
+        return $relationships;
+    }
+}
diff --git a/lib/classes/JsonApi/Schemas/MVV/Studiengang.php b/lib/classes/JsonApi/Schemas/MVV/Studiengang.php
new file mode 100644
index 0000000000000000000000000000000000000000..d21ee5f55134ad51a2b20b736aad12c1ee81a436
--- /dev/null
+++ b/lib/classes/JsonApi/Schemas/MVV/Studiengang.php
@@ -0,0 +1,88 @@
+<?php
+namespace JsonApi\Schemas\MVV;
+
+use JsonApi\Schemas\SchemaProvider;
+use Neomerx\JsonApi\Contracts\Schema\ContextInterface;
+use Neomerx\JsonApi\Schema\Link;
+
+class Studiengang extends SchemaProvider
+{
+    const TYPE = 'studycourses';
+
+    const REL_DEGREE = 'degree';
+
+    /**
+     * @param \Studiengang $resource
+     */
+    public function getId($resource): ?string
+    {
+        return $resource->id;
+    }
+
+    /**
+     * @param \Studiengang $resource
+     */
+    public function getAttributes($resource, ContextInterface $context): iterable
+    {
+        return [
+            'name' => (string) $resource->getDisplayName(),
+            'name-short' => (string) $resource->name_kurz,
+            'description' => (string) $resource->beschreibung,
+            'description-formatted' => formatReady($resource->beschreibung),
+            'mkdate' => date('c', $resource->mkdate),
+            'chdate' => date('c', $resource->chdate),
+        ];
+    }
+
+//   `studiengang_id` char(32) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL,
+//  `abschluss_id` char(32) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+//  `typ` enum('einfach','mehrfach') CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+//  `institut_id` char(32) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+//  `start` char(32) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+//  `end` char(32) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+//  `beschlussdatum` int(11) unsigned DEFAULT NULL,
+//  `fassung_nr` int(2) DEFAULT NULL,
+//  `fassung_typ` varchar(32) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+//  `stat` varchar(32) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+//  `kommentar_status` text COLLATE utf8mb4_unicode_ci DEFAULT NULL,
+//  `schlagworte` text COLLATE utf8mb4_unicode_ci DEFAULT NULL,
+//  `studienzeit` tinyint(3) unsigned DEFAULT NULL,
+//  `studienplaetze` int(10) unsigned DEFAULT NULL,
+//  `abschlussgrad` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
+//  `enroll` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
+//  `author_id` char(32) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL,
+//  `editor_id` char(32) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL,
+
+    /**
+     * @param \Studiengang $resource
+     */
+    public function getRelationships($resource, ContextInterface $context): iterable
+    {
+        $relationships = [];
+
+        if ($context->getPosition()->getLevel() === 0) {
+            $relationships = $this->getDegreeRelationship($relationships, $resource, $this->shouldInclude($context, self::REL_DEGREE));
+        }
+
+        return $relationships;
+    }
+
+    private function getDegreeRelationship(array $relationships, \Studiengang $studycourse, bool $shouldInclude): array
+    {
+        $degree = $studycourse->abschluss;
+
+        if ($degree) {
+            $data = $shouldInclude ? $degree : \Abschluss::build(['id' => $degree->id], false);
+
+            $relationships[self::REL_DEGREE] = [
+                self::RELATIONSHIP_LINKS => [
+                    Link::RELATED => $this->createLinkToResource($data),
+                ],
+                self::RELATIONSHIP_DATA => $data,
+            ];
+        }
+
+        return $relationships;
+    }
+
+}