diff --git a/composer.json b/composer.json
index 94f6ceb46f4d10459a533175c84eb8e9b87182bd..1a88b5456621d482dbfa67ddb2ad5ddd4343f37e 100644
--- a/composer.json
+++ b/composer.json
@@ -6,6 +6,7 @@
         "php": ">=7.3",
         "ext-json": "*",
         "api-platform/core": "^2.6",
+        "dbp/relay-base-person-bundle": "dev-main",
         "dbp/relay-core-bundle": "^0.1.11",
         "symfony/framework-bundle": "^5.4"
     },
@@ -34,6 +35,9 @@
         "sort-packages": true,
         "platform": {
             "php": "7.3"
+        },
+        "allow-plugins": {
+            "composer/package-versions-deprecated": true
         }
     },
     "scripts": {
diff --git a/composer.lock b/composer.lock
index aa8268bcf82504d8e1b50811a5f48fa68aeeaeb2..158c78adf0959ea6c5c7a2431f3ef8d131e83cd5 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
         "This file is @generated automatically"
     ],
-    "content-hash": "db61c2249bc8c4ee921893e623472e9a",
+    "content-hash": "c6de62624b6c871ceea7cd39f50c97b9",
     "packages": [
         {
             "name": "api-platform/core",
@@ -167,6 +167,56 @@
             ],
             "time": "2022-01-11T10:29:54+00:00"
         },
+        {
+            "name": "dbp/relay-base-person-bundle",
+            "version": "dev-main",
+            "source": {
+                "type": "git",
+                "url": "https://gitlab.tugraz.at/dbp/relay/dbp-relay-base-person-bundle",
+                "reference": "a7e3c201348fe70841d7e7c031e7a5ca8a007a54"
+            },
+            "require": {
+                "api-platform/core": "^2.6.3",
+                "dbp/relay-core-bundle": "^0.1.25",
+                "ext-json": "*",
+                "guzzlehttp/guzzle": "^7.0",
+                "nelmio/cors-bundle": "^2.1.0",
+                "php": ">=7.3",
+                "phpdocumentor/reflection-docblock": "^3.0 || ^4.0 || ^5.0",
+                "symfony/config": "^5.2",
+                "symfony/expression-language": "^5.2",
+                "symfony/framework-bundle": "^5.2",
+                "symfony/security-bundle": "^5.2",
+                "symfony/security-core": "^5.2",
+                "symfony/security-guard": "^5.2",
+                "symfony/twig-bundle": "^5.2",
+                "symfony/validator": "^5.2",
+                "symfony/yaml": "^5.2"
+            },
+            "require-dev": {
+                "friendsofphp/php-cs-fixer": "^3.0",
+                "phpstan/phpstan": "^1.0.0",
+                "phpstan/phpstan-phpunit": "^1.0.0",
+                "phpunit/phpunit": "^9",
+                "symfony/browser-kit": "^5.2",
+                "symfony/http-client": "^5.2",
+                "symfony/monolog-bundle": "^3.7",
+                "symfony/phpunit-bridge": "^5.2",
+                "vimeo/psalm": "^4.4"
+            },
+            "default-branch": true,
+            "type": "symfony-bundle",
+            "autoload": {
+                "psr-4": {
+                    "Dbp\\Relay\\BasePersonBundle\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "AGPL-3.0-or-later"
+            ],
+            "time": "2022-01-31T11:47:53+00:00"
+        },
         {
             "name": "dbp/relay-core-bundle",
             "version": "v0.1.30",
@@ -9917,7 +9967,9 @@
     ],
     "aliases": [],
     "minimum-stability": "stable",
-    "stability-flags": [],
+    "stability-flags": {
+        "dbp/relay-base-person-bundle": 20
+    },
     "prefer-stable": false,
     "prefer-lowest": false,
     "platform": {
diff --git a/phpstan.neon b/phpstan.neon
index cf03a393954915c79150e1faf19b259a24902341..201f2e7236db14245641ea951ed2f2e3574cd06a 100644
--- a/phpstan.neon
+++ b/phpstan.neon
@@ -6,6 +6,4 @@ parameters:
     level: 3
     paths:
         - src
-    ignoreErrors:
-        - message: '#.*NodeDefinition::children.*#'
-          path: ./src/DependencyInjection
+
diff --git a/src/API/CourseProviderInterface.php b/src/API/CourseProviderInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..a5fc072bf64c5ba8e81377e1bdac1ec347321ad3
--- /dev/null
+++ b/src/API/CourseProviderInterface.php
@@ -0,0 +1,39 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Dbp\Relay\CourseBundle\API;
+
+use Dbp\Relay\BasePersonBundle\Entity\Person;
+use Dbp\Relay\CourseBundle\Entity\Course;
+use Dbp\Relay\CourseBundle\Entity\Exam;
+
+interface CourseProviderInterface
+{
+    public function getCourseById(string $identifier, array $options = []): ?Course;
+
+    /**
+     * @return Course[]
+     */
+    public function getCourses(array $options = []): array;
+
+    /**
+     * @return Course[]
+     */
+    public function getCoursesByOrganization(string $orgUnitId, array $options = []): array;
+
+    /**
+     * @return Course[]
+     */
+    public function getCoursesByPerson(string $personId, array $options = []): array;
+
+    /**
+     * @return Person[]
+     */
+    public function getStudentsByCourse(string $courseId, array $options = []): array;
+
+    /**
+     * @return Exam[]
+     */
+    public function getExamsByCourse(string $courseId, array $options = []): array;
+}
diff --git a/src/Command/TestCommand.php b/src/Command/TestCommand.php
deleted file mode 100644
index ae5c64ba9b06953254aaea4b5b04bb909dea6ea2..0000000000000000000000000000000000000000
--- a/src/Command/TestCommand.php
+++ /dev/null
@@ -1,34 +0,0 @@
-<?php
-
-declare(strict_types=1);
-
-namespace Dbp\Relay\CourseBundle\Command;
-
-use Symfony\Component\Console\Command\Command;
-use Symfony\Component\Console\Input\InputArgument;
-use Symfony\Component\Console\Input\InputInterface;
-use Symfony\Component\Console\Output\OutputInterface;
-
-class TestCommand extends Command
-{
-    protected static $defaultName = 'dbp:my-custom-command';
-
-    public function __construct()
-    {
-        parent::__construct();
-    }
-
-    protected function configure()
-    {
-        $this->addArgument('argument', InputArgument::REQUIRED, 'Example.');
-        $this->setDescription('Hey there!');
-    }
-
-    protected function execute(InputInterface $input, OutputInterface $output): int
-    {
-        $argument = $input->getArgument('argument');
-        $output->writeln($argument);
-
-        return 0;
-    }
-}
diff --git a/src/Controller/GetCoursesByOrganization.php b/src/Controller/GetCoursesByOrganization.php
new file mode 100644
index 0000000000000000000000000000000000000000..4b33c0ee2daae3d53ae885f683cb496df6033279
--- /dev/null
+++ b/src/Controller/GetCoursesByOrganization.php
@@ -0,0 +1,40 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Dbp\Relay\CourseBundle\Controller;
+
+use ApiPlatform\Core\DataProvider\PaginatorInterface;
+use Dbp\Relay\CoreBundle\Helpers\ArrayFullPaginator;
+use Dbp\Relay\CourseBundle\API\CourseProviderInterface;
+use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
+use Symfony\Component\HttpFoundation\Request;
+
+class GetCoursesByOrganization extends AbstractController
+{
+    public const ITEMS_PER_PAGE = 250;
+
+    protected $coursesProvider;
+
+    public function __construct(CourseProviderInterface $coursesProvider)
+    {
+        $this->coursesProvider = $coursesProvider;
+    }
+
+    public function __invoke(string $id, Request $request): PaginatorInterface
+    {
+        $this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
+
+        $page = (int) $request->query->get('page', 1);
+        $perPage = (int) $request->query->get('perPage', self::ITEMS_PER_PAGE);
+
+        $options = [];
+        if ($request->query->has('lang')) {
+            $options['lang'] = (string) $request->query->get('lang');
+        }
+
+        $courses = $this->coursesProvider->getCoursesByOrganization($id, $options);
+
+        return new ArrayFullPaginator($courses, $page, $perPage);
+    }
+}
diff --git a/src/Controller/GetCoursesByPerson.php b/src/Controller/GetCoursesByPerson.php
new file mode 100644
index 0000000000000000000000000000000000000000..b5c13ab6438b034e2feb61b51f2d64d2e40446e9
--- /dev/null
+++ b/src/Controller/GetCoursesByPerson.php
@@ -0,0 +1,40 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Dbp\Relay\CourseBundle\Controller;
+
+use ApiPlatform\Core\DataProvider\PaginatorInterface;
+use Dbp\Relay\CoreBundle\Helpers\ArrayFullPaginator;
+use Dbp\Relay\CourseBundle\API\CourseProviderInterface;
+use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
+use Symfony\Component\HttpFoundation\Request;
+
+class GetCoursesByPerson extends AbstractController
+{
+    public const ITEMS_PER_PAGE = 250;
+
+    protected $coursesProvider;
+
+    public function __construct(CourseProviderInterface $coursesProvider)
+    {
+        $this->coursesProvider = $coursesProvider;
+    }
+
+    public function __invoke(string $id, Request $request): PaginatorInterface
+    {
+        $this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
+
+        $page = (int) $request->query->get('page', 1);
+        $perPage = (int) $request->query->get('perPage', self::ITEMS_PER_PAGE);
+
+        $options = [];
+        if ($request->query->has('lang')) {
+            $options['lang'] = (string) $request->query->get('lang');
+        }
+
+        $courses = $this->coursesProvider->getCoursesByPerson($id, $options);
+
+        return new ArrayFullPaginator($courses, $page, $perPage);
+    }
+}
diff --git a/src/Controller/GetExamsByCourse.php b/src/Controller/GetExamsByCourse.php
new file mode 100644
index 0000000000000000000000000000000000000000..ee2413e802002cad21b7c2ff1e60e3600b24541e
--- /dev/null
+++ b/src/Controller/GetExamsByCourse.php
@@ -0,0 +1,40 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Dbp\Relay\CourseBundle\Controller;
+
+use ApiPlatform\Core\DataProvider\PaginatorInterface;
+use Dbp\Relay\CoreBundle\Helpers\ArrayFullPaginator;
+use Dbp\Relay\CourseBundle\API\CourseProviderInterface;
+use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
+use Symfony\Component\HttpFoundation\Request;
+
+class GetExamsByCourse extends AbstractController
+{
+    public const ITEMS_PER_PAGE = 250;
+
+    protected $coursesProvider;
+
+    public function __construct(CourseProviderInterface $coursesProvider)
+    {
+        $this->coursesProvider = $coursesProvider;
+    }
+
+    public function __invoke(string $id, Request $request): PaginatorInterface
+    {
+        $this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
+
+        $page = (int) $request->query->get('page', 1);
+        $perPage = (int) $request->query->get('perPage', self::ITEMS_PER_PAGE);
+
+        $options = [];
+        if ($request->query->has('lang')) {
+            $options['lang'] = (string) $request->query->get('lang');
+        }
+
+        $courses = $this->coursesProvider->getExamsByCourse($id, $options);
+
+        return new ArrayFullPaginator($courses, $page, $perPage);
+    }
+}
diff --git a/src/Controller/GetStudentsByCourse.php b/src/Controller/GetStudentsByCourse.php
new file mode 100644
index 0000000000000000000000000000000000000000..827e1cfa61d8345423140170f6966f0350e59120
--- /dev/null
+++ b/src/Controller/GetStudentsByCourse.php
@@ -0,0 +1,40 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Dbp\Relay\CourseBundle\Controller;
+
+use ApiPlatform\Core\DataProvider\PaginatorInterface;
+use Dbp\Relay\CoreBundle\Helpers\ArrayFullPaginator;
+use Dbp\Relay\CourseBundle\API\CourseProviderInterface;
+use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
+use Symfony\Component\HttpFoundation\Request;
+
+class GetStudentsByCourse extends AbstractController
+{
+    public const ITEMS_PER_PAGE = 250;
+
+    protected $coursesProvider;
+
+    public function __construct(CourseProviderInterface $coursesProvider)
+    {
+        $this->coursesProvider = $coursesProvider;
+    }
+
+    public function __invoke(string $id, Request $request): PaginatorInterface
+    {
+        $this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
+
+        $page = (int) $request->query->get('page', 1);
+        $perPage = (int) $request->query->get('perPage', self::ITEMS_PER_PAGE);
+
+        $options = [];
+        if ($request->query->has('lang')) {
+            $options['lang'] = (string) $request->query->get('lang');
+        }
+
+        $courses = $this->coursesProvider->getStudentsByCourse($id, $options);
+
+        return new ArrayFullPaginator($courses, $page, $perPage);
+    }
+}
diff --git a/src/Controller/LoggedInOnly.php b/src/Controller/LoggedInOnly.php
deleted file mode 100644
index 8acbb043717dfd749898aa9af7a6044a19d091b1..0000000000000000000000000000000000000000
--- a/src/Controller/LoggedInOnly.php
+++ /dev/null
@@ -1,19 +0,0 @@
-<?php
-
-declare(strict_types=1);
-
-namespace Dbp\Relay\CourseBundle\Controller;
-
-use Dbp\Relay\CourseBundle\Entity\Course;
-use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
-use Symfony\Component\HttpFoundation\Request;
-
-class LoggedInOnly extends AbstractController
-{
-    public function __invoke(Course $data, Request $request): Course
-    {
-        $this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
-
-        return $data;
-    }
-}
diff --git a/src/DataPersister/CourseDataPersister.php b/src/DataPersister/CourseDataPersister.php
deleted file mode 100644
index d44682f8aec520f9c16238ff72a0115cd09756de..0000000000000000000000000000000000000000
--- a/src/DataPersister/CourseDataPersister.php
+++ /dev/null
@@ -1,35 +0,0 @@
-<?php
-
-declare(strict_types=1);
-
-namespace Dbp\Relay\CourseBundle\DataPersister;
-
-use ApiPlatform\Core\DataPersister\DataPersisterInterface;
-use Dbp\Relay\CourseBundle\Entity\Course;
-use Dbp\Relay\CourseBundle\Service\CourseProviderInterface;
-use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
-
-class CourseDataPersister extends AbstractController implements DataPersisterInterface
-{
-    private $api;
-
-    public function __construct(CourseProviderInterface $api)
-    {
-        $this->api = $api;
-    }
-
-    public function supports($data): bool
-    {
-        return $data instanceof Course;
-    }
-
-    public function persist($data): void
-    {
-        // TODO
-    }
-
-    public function remove($data)
-    {
-        // TODO
-    }
-}
diff --git a/src/DataProvider/CourseCollectionDataProvider.php b/src/DataProvider/CourseCollectionDataProvider.php
index 7bb9ec49eea4efd781de2e55d119049ade566b07..5e55ecad7447de4e4e6b3e399f03ce0c3ff8ceb4 100644
--- a/src/DataProvider/CourseCollectionDataProvider.php
+++ b/src/DataProvider/CourseCollectionDataProvider.php
@@ -7,8 +7,8 @@ namespace Dbp\Relay\CourseBundle\DataProvider;
 use ApiPlatform\Core\DataProvider\CollectionDataProviderInterface;
 use ApiPlatform\Core\DataProvider\RestrictedDataProviderInterface;
 use Dbp\Relay\CoreBundle\Helpers\ArrayFullPaginator;
+use Dbp\Relay\CourseBundle\API\CourseProviderInterface;
 use Dbp\Relay\CourseBundle\Entity\Course;
-use Dbp\Relay\CourseBundle\Service\CourseProviderInterface;
 use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
 
 final class CourseCollectionDataProvider extends AbstractController implements CollectionDataProviderInterface, RestrictedDataProviderInterface
diff --git a/src/DataProvider/CourseItemDataProvider.php b/src/DataProvider/CourseItemDataProvider.php
index 1d70f414777cb1556a7b9654a97aaca152660e6d..066fae77c81da0c6c9f5e1de2fef3591c126de90 100644
--- a/src/DataProvider/CourseItemDataProvider.php
+++ b/src/DataProvider/CourseItemDataProvider.php
@@ -6,8 +6,8 @@ namespace Dbp\Relay\CourseBundle\DataProvider;
 
 use ApiPlatform\Core\DataProvider\ItemDataProviderInterface;
 use ApiPlatform\Core\DataProvider\RestrictedDataProviderInterface;
+use Dbp\Relay\CourseBundle\API\CourseProviderInterface;
 use Dbp\Relay\CourseBundle\Entity\Course;
-use Dbp\Relay\CourseBundle\Service\CourseProviderInterface;
 use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
 
 final class CourseItemDataProvider extends AbstractController implements ItemDataProviderInterface, RestrictedDataProviderInterface
diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php
index 2c56a090b499a7197d7c9e2552046a2d980aa233..ea3012b0edcacadaf75a66224d7f6198b2052c58 100644
--- a/src/DependencyInjection/Configuration.php
+++ b/src/DependencyInjection/Configuration.php
@@ -11,15 +11,6 @@ class Configuration implements ConfigurationInterface
 {
     public function getConfigTreeBuilder(): TreeBuilder
     {
-        $treeBuilder = new TreeBuilder('dbp_relay_course');
-
-        $treeBuilder->getRootNode()
-            ->children()
-                ->scalarNode('example_config')
-                    ->defaultValue('42')
-                ->end()
-            ->end();
-
-        return $treeBuilder;
+        return new TreeBuilder('dbp_relay_course');
     }
 }
diff --git a/src/DependencyInjection/DbpRelayCourseExtension.php b/src/DependencyInjection/DbpRelayCourseExtension.php
index d0e4d6aca31bb0dfb4d7ad15809f6a410af30800..36b695836f042acbed9bebfcbcac80191e4e3921 100644
--- a/src/DependencyInjection/DbpRelayCourseExtension.php
+++ b/src/DependencyInjection/DbpRelayCourseExtension.php
@@ -21,10 +21,6 @@ class DbpRelayCourseExtension extends ConfigurableExtension
             new FileLocator(__DIR__.'/../Resources/config')
         );
         $loader->load('services.yaml');
-
-        // Inject the config value into the MyCustomService service
-        $definition = $container->getDefinition('Dbp\Relay\CourseBundle\Service\MyCustomService');
-        $definition->addArgument($mergedConfig['example_config']);
     }
 
     private function extendArrayParameter(ContainerBuilder $container, string $parameter, array $values)
diff --git a/src/Entity/Course.php b/src/Entity/Course.php
index 468686dac78689daba529f211c562d3a5da3d0bf..4d018ad732cba84d1a84f2e7ffe17708a2ecc076 100644
--- a/src/Entity/Course.php
+++ b/src/Entity/Course.php
@@ -6,59 +6,61 @@ namespace Dbp\Relay\CourseBundle\Entity;
 
 use ApiPlatform\Core\Annotation\ApiProperty;
 use ApiPlatform\Core\Annotation\ApiResource;
-use Dbp\Relay\CourseBundle\Controller\LoggedInOnly;
 use Symfony\Component\Serializer\Annotation\Groups;
 
 /**
  * @ApiResource(
  *     collectionOperations={
  *         "get" = {
- *             "path" = "/course/courses",
  *             "openapi_context" = {
- *                 "tags" = {"Course API"},
- *             },
- *         }
- *     },
- *     itemOperations={
- *         "get" = {
- *             "path" = "/course/courses/{identifier}",
- *             "openapi_context" = {
- *                 "tags" = {"Course API"},
- *             },
+ *                 "tags" = {"Courses"},
+ *                 "parameters" = {
+ *                     {"name" = "lang", "in" = "query", "description" = "Language of result", "type" = "string", "enum" = {"de", "en"}, "example" = "de"}
+ *                 }
+ *             }
  *         },
- *         "put" = {
- *             "path" = "/course/courses/{identifier}",
+ *         "get_byorganization" = {
+ *             "method" = "GET",
+ *             "path" = "/base/organizations/{id}/courses",
+ *             "controller" = GetCoursesByOrganization::class,
+ *             "read" = false,
  *             "openapi_context" = {
- *                 "tags" = {"Course API"},
+ *                 "tags" = {"Courses"},
+ *                 "summary" = "Get the Courses related to an organization.",
+ *                 "parameters" = {
+ *                     {"name" = "lang", "in" = "query", "description" = "Language of result", "type" = "string", "enum" = {"de", "en"}, "example" = "de"},
+ *                     {"name" = "id", "in" = "path", "description" = "Id of Organization", "required" = true, "type" = "string", "example" = "123456"}
+ *                 }
  *             },
  *         },
- *         "delete" = {
- *             "path" = "/course/courses/{identifier}",
+ *         "get_byperson" = {
+ *             "method" = "GET",
+ *             "path" = "/base/people/{id}/courses",
+ *             "controller" = GetCoursesByPerson::class,
+ *             "read" = false,
  *             "openapi_context" = {
- *                 "tags" = {"Course API"},
+ *                 "tags" = {"Courses"},
+ *                 "summary" = "Get the Courses related to a person.",
+ *                 "parameters" = {
+ *                     {"name" = "lang", "in" = "query", "description" = "Language of result", "type" = "string", "enum" = {"de", "en"}, "example" = "de"},
+ *                     {"name" = "id", "in" = "path", "description" = "Id of Organization", "required" = true, "type" = "string", "example" = "123456"}
+ *                 }
  *             },
  *         },
- *         "loggedin_only" = {
- *             "security" = "is_granted('IS_AUTHENTICATED_FULLY')",
- *             "method" = "GET",
- *             "path" = "/course/courses/{identifier}/loggedin-only",
- *             "controller" = LoggedInOnly::class,
+ *     },
+ *     itemOperations={
+ *         "get" = {
  *             "openapi_context" = {
- *                 "summary" = "Only works when logged in.",
- *                 "tags" = {"Course API"},
- *             },
+ *                 "tags" = {"Courses"},
+ *                 "parameters" = {
+ *                     {"name" = "lang", "in" = "query", "description" = "Language of result", "type" = "string", "enum" = {"de", "en"}, "example" = "de"}
+ *                 }
+ *             }
  *         }
  *     },
  *     iri="https://schema.org/Course",
- *     shortName="CourseCourse",
- *     normalizationContext={
- *         "groups" = {"CourseCourse:output"},
- *         "jsonld_embed_context" = true
- *     },
- *     denormalizationContext={
- *         "groups" = {"CourseCourse:input"},
- *         "jsonld_embed_context" = true
- *     }
+ *     normalizationContext={"groups" = {"Course:output"}, "jsonld_embed_context" = true},
+ *     denormalizationContext={"groups" = {"Course:input"}, "jsonld_embed_context" = true}
  * )
  */
 class Course
@@ -70,12 +72,38 @@ class Course
 
     /**
      * @ApiProperty(iri="https://schema.org/name")
-     * @Groups({"CourseCourse:output", "CourseCourse:input"})
+     * @Groups({"Course:output"})
      *
      * @var string
      */
     private $name;
 
+    /**
+     * @ApiProperty
+     * @Groups({"Course:output"})
+     *
+     * @var string
+     */
+    private $type;
+
+    /**
+     * @ApiProperty(iri="https://schema.org/description")
+     * @Groups({"Course:output"})
+     *
+     * @var string
+     */
+    private $description;
+
+    public function getIdentifier(): string
+    {
+        return $this->identifier;
+    }
+
+    public function setIdentifier(string $identifier): void
+    {
+        $this->identifier = $identifier;
+    }
+
     public function getName(): string
     {
         return $this->name;
@@ -86,13 +114,23 @@ class Course
         $this->name = $name;
     }
 
-    public function getIdentifier(): string
+    public function getType(): string
     {
-        return $this->identifier;
+        return $this->type;
     }
 
-    public function setIdentifier(string $identifier): void
+    public function setType(string $type): void
     {
-        $this->identifier = $identifier;
+        $this->type = $type;
+    }
+
+    public function getDescription(): string
+    {
+        return $this->description;
+    }
+
+    public function setDescription(string $description): void
+    {
+        $this->description = $description;
     }
 }
diff --git a/src/Entity/CourseAttendee.php b/src/Entity/CourseAttendee.php
new file mode 100644
index 0000000000000000000000000000000000000000..6b375661fc25c25ad176e45d7baf41b9b0a0d6fd
--- /dev/null
+++ b/src/Entity/CourseAttendee.php
@@ -0,0 +1,37 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Dbp\Relay\CourseBundle\Entity;
+
+use ApiPlatform\Core\Annotation\ApiResource;
+use Dbp\Relay\BasePersonBundle\Entity\PersonTrait;
+
+/**
+ * @ApiResource(
+ *     collectionOperations={
+ *         "get_bycourse" = {
+ *             "method" = "GET",
+ *             "path" = "/courses/{id}/attendees",
+ *             "controller" = GetStudentsByCourse::class,
+ *             "read" = false,
+ *             "openapi_context" = {
+ *                 "tags" = {"Courses"},
+ *                 "summary" = "Get the attendees attending to a course.",
+ *                 "parameters" = {
+ *                     {"name" = "lang", "in" = "query", "description" = "Language of result", "type" = "string", "enum" = {"de", "en"}, "example" = "de"},
+ *                     {"name" = "id", "in" = "path", "description" = "Id of Organization", "required" = true, "type" = "string", "example" = "123456"}
+ *                 }
+ *             },
+ *         }
+ *     },
+ *     itemOperations={},
+ *     iri="https://schema.org/EducationEvent",
+ *     normalizationContext={"groups" = {"BasePerson:output"}, "jsonld_embed_context" = true},
+ *     denormalizationContext={"groups" = {"BasePerson:input"}, "jsonld_embed_context" = true}
+ * )
+ */
+class CourseAttendee
+{
+    use PersonTrait;
+}
diff --git a/src/Entity/Exam.php b/src/Entity/Exam.php
new file mode 100644
index 0000000000000000000000000000000000000000..d97cc3782b78e788182971b90c573f12392e3fc0
--- /dev/null
+++ b/src/Entity/Exam.php
@@ -0,0 +1,127 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Dbp\Relay\CourseBundle\Entity;
+
+use ApiPlatform\Core\Annotation\ApiProperty;
+use ApiPlatform\Core\Annotation\ApiResource;
+use DateTime;
+use DBP\API\CourseBundle\Controller\GetExamsByCourse;
+use Symfony\Component\Serializer\Annotation\Groups;
+
+/**
+ * @ApiResource(
+ *     collectionOperations={
+ *         "get_bycourse" = {
+ *             "method" = "GET",
+ *             "path" = "/courses/{id}/exams",
+ *             "controller" = GetExamsByCourse::class,
+ *             "read" = false,
+ *             "openapi_context" = {
+ *                 "tags" = {"Courses"},
+ *                 "summary" = "Get the Exams for a course.",
+ *                 "parameters" = {
+ *                     {"name" = "lang", "in" = "query", "description" = "Language of result", "type" = "string", "enum" = {"de", "en"}, "example" = "de"},
+ *                     {"name" = "id", "in" = "path", "description" = "Id of Organization", "required" = true, "type" = "string", "example" = "123456"}
+ *                 }
+ *             },
+ *         }
+ *     },
+ *     itemOperations={},
+ *     iri="https://schema.org/EducationEvent",
+ *     normalizationContext={"groups" = {"Exam:output"}, "jsonld_embed_context" = true},
+ *     denormalizationContext={"groups" = {"Exam:input"}, "jsonld_embed_context" = true}
+ * )
+ */
+class Exam
+{
+    /**
+     * @ApiProperty(identifier=true)
+     *
+     * @var string
+     */
+    private $identifier;
+
+    /**
+     * @ApiProperty(iri="https://schema.org/description")
+     * @Groups({"Exam:output"})
+     *
+     * @var string
+     */
+    private $description;
+
+    /**
+     * @ApiProperty(iri="https://schema.org/startDate")
+     * @Groups({"Exam:output"})
+     *
+     * @var DateTime
+     */
+    private $startDate;
+
+    /**
+     * @ApiProperty(iri="https://schema.org/endDate")
+     * @Groups({"Exam:output"})
+     *
+     * @var DateTime
+     */
+    private $endDate;
+
+    /**
+     * @ApiProperty(iri="https://schema.org/location")
+     * @Groups({"Exam:output"})
+     *
+     * @var string
+     */
+    private $location;
+
+    public function getIdentifier(): string
+    {
+        return $this->identifier;
+    }
+
+    public function setIdentifier(string $identifier): void
+    {
+        $this->identifier = $identifier;
+    }
+
+    public function getDescription(): string
+    {
+        return $this->description;
+    }
+
+    public function setDescription(string $description): void
+    {
+        $this->description = $description;
+    }
+
+    public function getStartDate(): DateTime
+    {
+        return $this->startDate;
+    }
+
+    public function setStartDate(DateTime $startDate): void
+    {
+        $this->startDate = $startDate;
+    }
+
+    public function getEndDate(): DateTime
+    {
+        return $this->endDate;
+    }
+
+    public function setEndDate(DateTime $endDate): void
+    {
+        $this->endDate = $endDate;
+    }
+
+    public function getLocation(): string
+    {
+        return $this->location;
+    }
+
+    public function setLocation(string $location): void
+    {
+        $this->location = $location;
+    }
+}
diff --git a/src/Service/CourseProviderInterface.php b/src/Service/CourseProviderInterface.php
deleted file mode 100644
index c2e9dfde6db4ef076b3d60325be43f332130d6b3..0000000000000000000000000000000000000000
--- a/src/Service/CourseProviderInterface.php
+++ /dev/null
@@ -1,14 +0,0 @@
-<?php
-
-declare(strict_types=1);
-
-namespace Dbp\Relay\CourseBundle\Service;
-
-use Dbp\Relay\CourseBundle\Entity\Course;
-
-interface CourseProviderInterface
-{
-    public function getCourseById(string $identifier): ?Course;
-
-    public function getCourses(): array;
-}
diff --git a/src/Service/DummyCourseProvider.php b/src/Service/DummyCourseProvider.php
new file mode 100644
index 0000000000000000000000000000000000000000..876ed28612adb73e18e3432d33b53380bcd6c9a2
--- /dev/null
+++ b/src/Service/DummyCourseProvider.php
@@ -0,0 +1,66 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Dbp\Relay\CourseBundle\Service;
+
+use DateTime;
+use Dbp\Relay\BasePersonBundle\Entity\Person;
+use Dbp\Relay\CourseBundle\API\CourseProviderInterface;
+use Dbp\Relay\CourseBundle\Entity\Course;
+use Dbp\Relay\CourseBundle\Entity\Exam;
+
+class DummyCourseProvider implements CourseProviderInterface
+{
+    public function getCourseById(string $identifier, array $options = []): ?Course
+    {
+        $course = new Course();
+        $course->setIdentifier($identifier);
+        $course->setName('Field Theory');
+        $course->setDescription('News from field theory');
+
+        return $course;
+    }
+
+    public function getCourses(array $options = []): array
+    {
+        $course = $this->getCourseById('123', $options);
+        assert($course !== null);
+
+        return [$course];
+    }
+
+    public function getCoursesByOrganization(string $orgUnitId, array $options = []): array
+    {
+        return $this->getCourses($options);
+    }
+
+    public function getCoursesByPerson(string $personId, array $options = []): array
+    {
+        return $this->getCourses($options);
+    }
+
+    public function getStudentsByCourse(string $courseId, array $options = []): array
+    {
+        $person = new Person();
+        $person->setIdentifier('123');
+        $person->setFamilyName('Spencer');
+        $person->setGivenName('Bud');
+        $person->setEmail('bud@spencer.net');
+        $person->setBirthDate('1.1.1950');
+
+        return [$person];
+    }
+
+    public function getExamsByCourse(string $courseId, array $options = []): array
+    {
+        $exam = new Exam();
+        $exam->setIdentifier('123');
+        $exam->setDescription('Oral exam');
+        $exam->setStartDate(new DateTime('25.08.2021 8:00AM'));
+        $exam->setEndDate(new DateTime('25.08.2021 10:00AM'));
+        $exam->setLocation('In a room');
+
+        return [$exam];
+    }
+}
diff --git a/src/Service/ExternalApi.php b/src/Service/ExternalApi.php
deleted file mode 100644
index e72ba4d83982eb6173dab833f8a3414f9da7c3e8..0000000000000000000000000000000000000000
--- a/src/Service/ExternalApi.php
+++ /dev/null
@@ -1,46 +0,0 @@
-<?php
-
-declare(strict_types=1);
-
-namespace Dbp\Relay\CourseBundle\Service;
-
-use Dbp\Relay\CourseBundle\Entity\Course;
-
-class ExternalApi implements CourseProviderInterface
-{
-    private $courses;
-
-    public function __construct(MyCustomService $service)
-    {
-        // Make phpstan happy
-        $service = $service;
-
-        $this->courses = [];
-        $course1 = new Course();
-        $course1->setIdentifier('graz');
-        $course1->setName('Graz');
-
-        $course2 = new Course();
-        $course2->setIdentifier('vienna');
-        $course2->setName('Vienna');
-
-        $this->courses[] = $course1;
-        $this->courses[] = $course2;
-    }
-
-    public function getCourseById(string $identifier): ?Course
-    {
-        foreach ($this->courses as $course) {
-            if ($course->getIdentifier() === $identifier) {
-                return $course;
-            }
-        }
-
-        return null;
-    }
-
-    public function getCourses(): array
-    {
-        return $this->courses;
-    }
-}
diff --git a/src/Service/MyCustomService.php b/src/Service/MyCustomService.php
deleted file mode 100644
index d08550e34c8529646aaac1c88b0b9eda70a108fc..0000000000000000000000000000000000000000
--- a/src/Service/MyCustomService.php
+++ /dev/null
@@ -1,15 +0,0 @@
-<?php
-
-declare(strict_types=1);
-
-namespace Dbp\Relay\CourseBundle\Service;
-
-class MyCustomService
-{
-    private $someConfig;
-
-    public function __construct(string $someConfig)
-    {
-        $this->$someConfig = $someConfig;
-    }
-}
diff --git a/tests/Service/ExternalApiTest.php b/tests/Service/ExternalApiTest.php
index d3e4ab62b84d47c5e8bb48795912ead583937346..13f1f9b10ff8ff3f0bacd67aa38f236d782ccb2d 100644
--- a/tests/Service/ExternalApiTest.php
+++ b/tests/Service/ExternalApiTest.php
@@ -4,23 +4,15 @@ declare(strict_types=1);
 
 namespace Dbp\Relay\CourseBundle\Tests\Service;
 
-use Dbp\Relay\CourseBundle\Service\ExternalApi;
-use Dbp\Relay\CourseBundle\Service\MyCustomService;
 use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
 
 class ExternalApiTest extends WebTestCase
 {
-    private $api;
-
     protected function setUp(): void
     {
-        $service = new MyCustomService('test-42');
-        $this->api = new ExternalApi($service);
     }
 
     public function test()
     {
-        $this->assertTrue(true);
-        $this->assertNotNull($this->api);
     }
 }