diff --git a/lib/classes/JsonApi/RouteMap.php b/lib/classes/JsonApi/RouteMap.php
index e779e8b25aee30fd93e362c16153af0205c58317..2eb33a815e2869bf776046c189f7cc93f0b47e91 100644
--- a/lib/classes/JsonApi/RouteMap.php
+++ b/lib/classes/JsonApi/RouteMap.php
@@ -253,6 +253,7 @@ class RouteMap
         $group->get('/institutes/{id}', Routes\Institutes\InstitutesShow::class);
         $group->get('/institutes', Routes\Institutes\InstitutesIndex::class);
 
+        $group->get('/institutes/{id}/memberships', Routes\Institutes\InstituteMembershipsIndex::class);
         $group->get('/institutes/{id}/status-groups', Routes\Institutes\StatusGroupsOfInstitutes::class);
     }
 
diff --git a/lib/classes/JsonApi/Routes/InstituteMemberships/InstituteMembershipsShow.php b/lib/classes/JsonApi/Routes/InstituteMemberships/InstituteMembershipsShow.php
index 7662af34693d8a5e657490583f01b3de234da53f..13e0dd4c41bd18dcdd101b04dcc714385b960dde 100644
--- a/lib/classes/JsonApi/Routes/InstituteMemberships/InstituteMembershipsShow.php
+++ b/lib/classes/JsonApi/Routes/InstituteMemberships/InstituteMembershipsShow.php
@@ -22,7 +22,7 @@ class InstituteMembershipsShow extends JsonApiController
         }
 
         $user = $this->getUser($request);
-        if ($user->id !== $membership->user_id) {
+        if ($user->id !== $membership->user_id && !get_visibility_by_id($membership->user_id)) {
             throw new AuthorizationFailedException();
         }
 
diff --git a/lib/classes/JsonApi/Routes/Institutes/Authority.php b/lib/classes/JsonApi/Routes/Institutes/Authority.php
index b3fe9b13b87914d4f1347d7d357f21cd32069472..c6ee43bee90d6f8b8b519d8ff262faa2f96077ec 100644
--- a/lib/classes/JsonApi/Routes/Institutes/Authority.php
+++ b/lib/classes/JsonApi/Routes/Institutes/Authority.php
@@ -2,10 +2,19 @@
 
 namespace JsonApi\Routes\Institutes;
 
+use Institute;
 use User;
 
 class Authority
 {
+    /**
+     * @SuppressWarnings(PHPMD.Superglobals)
+     */
+    public static function canEditInstitute(User $user, Institute $institute)
+    {
+        return $GLOBALS['perm']->have_studip_perm('admin', $institute->id, $user->id);
+    }
+
     /**
      * @SuppressWarnings(PHPMD.Superglobals)
      */
diff --git a/lib/classes/JsonApi/Routes/Institutes/InstituteMembershipsIndex.php b/lib/classes/JsonApi/Routes/Institutes/InstituteMembershipsIndex.php
new file mode 100644
index 0000000000000000000000000000000000000000..9184fd94d99f29de3579e7abd61e92987badbdc4
--- /dev/null
+++ b/lib/classes/JsonApi/Routes/Institutes/InstituteMembershipsIndex.php
@@ -0,0 +1,80 @@
+<?php
+
+namespace JsonApi\Routes\Institutes;
+
+use Psr\Http\Message\ServerRequestInterface as Request;
+use Psr\Http\Message\ResponseInterface as Response;
+use JsonApi\Errors\AuthorizationFailedException;
+use JsonApi\Errors\BadRequestException;
+use JsonApi\Errors\RecordNotFoundException;
+use JsonApi\JsonApiController;
+use JsonApi\Schemas\InstituteMember;
+
+/**
+ * Returns all institute-memberships of the institute.
+ */
+class InstituteMembershipsIndex extends JsonApiController
+{
+    protected $allowedFilteringParameters = ['permission'];
+
+    protected $allowedIncludePaths = [InstituteMember::REL_INSTITUTE, InstituteMember::REL_USER];
+
+    protected $allowedPagingParameters = ['offset', 'limit'];
+
+    /**
+     * @SuppressWarnings(PHPMD.UnusedFormalParameters)
+     */
+    public function __invoke(Request $request, Response $response, $args)
+    {
+        $institute = \Institute::find($args['id']);
+        if (!$institute) {
+            throw new RecordNotFoundException();
+        }
+
+        $this->validateFilters();
+
+        $user = $this->getUser($request);
+        $memberships = $this->getMemberships($institute, $user, $this->getFilters());
+
+        list($offset, $limit) = $this->getOffsetAndLimit();
+
+        return $this->getPaginatedContentResponse($memberships->limit($offset, $limit), count($memberships));
+    }
+
+    private function getMemberships(\Institute $institute, \User $user, array $filters)
+    {
+        $memberships = $institute->members;
+
+        $visibleMemberships = Authority::canEditInstitute($user, $institute)
+            ? $memberships
+            : $memberships->filter(function ($membership) use ($user) {
+                return $membership->user_id === $user->id || get_visibility_by_id($membership->user_id);
+            });
+
+        return isset($filters['permission'])
+            ? $visibleMemberships->filter(function ($membership) use ($filters) {
+                return $membership->inst_perms === $filters['permission'];
+            })
+            : $visibleMemberships;
+    }
+
+    private function validateFilters()
+    {
+        $filtering = $this->getQueryParameters()->getFilteringParameters() ?? [];
+
+        if (array_key_exists('permission', $filtering)) {
+            if (!in_array($filtering['permission'], ['user', 'autor', 'tutor', 'dozent', 'admin'])) {
+                throw new BadRequestException('Filter `permission` must be one of `user`, `autor`, `tutor`, `dozent`, `admin`.');
+            }
+        }
+    }
+
+    private function getFilters()
+    {
+        $filtering = $this->getQueryParameters()->getFilteringParameters() ?? [];
+
+        $filters['permission'] = $filtering['permission'] ?? null;
+
+        return $filters;
+    }
+}
diff --git a/lib/classes/JsonApi/Schemas/Institute.php b/lib/classes/JsonApi/Schemas/Institute.php
index d3eda4ac133e20d563dff6894a662e4765427422..c1775b1646db204b47f3d8914078cd8167e4da6b 100644
--- a/lib/classes/JsonApi/Schemas/Institute.php
+++ b/lib/classes/JsonApi/Schemas/Institute.php
@@ -12,6 +12,7 @@ class Institute extends SchemaProvider
     const REL_BLUBBER = 'blubber-threads';
     const REL_FILES = 'file-refs';
     const REL_FOLDERS = 'folders';
+    const REL_MEMBERSHIPS = 'memberships';
     const REL_STATUS_GROUPS = 'status-groups';
 
     public function getId($institute): ?string
@@ -60,6 +61,12 @@ class Institute extends SchemaProvider
             ],
         ];
 
+        $relationships[self::REL_MEMBERSHIPS] = [
+            self::RELATIONSHIP_LINKS => [
+                Link::RELATED => $this->getRelationshipRelatedLink($resource, self::REL_MEMBERSHIPS),
+            ],
+        ];
+
         $relationships = $this->addStatusGroupsRelationship(
             $relationships,
             $resource,
diff --git a/tests/jsonapi/InstituteMembershipsIndexTest.php b/tests/jsonapi/InstituteMembershipsIndexTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..f9ddf9defecd78e63ef9f0ab462f24cf84de53af
--- /dev/null
+++ b/tests/jsonapi/InstituteMembershipsIndexTest.php
@@ -0,0 +1,41 @@
+<?php
+
+use JsonApi\Routes\Institutes\InstituteMembershipsIndex;
+
+class InstituteMembershipsIndexTest extends \Codeception\Test\Unit
+{
+    /**
+     * @var \UnitTester
+     */
+    protected $tester;
+
+    protected function _before()
+    {
+        \DBManager::getInstance()->setConnection('studip', $this->getModule('\\Helper\\StudipDb')->dbh);
+    }
+
+    protected function _after()
+    {
+    }
+
+    public function testIndexMemberships()
+    {
+        $credentials = $this->tester->getCredentialsForTestAutor();
+        $instituteId = '2560f7c7674942a7dce8eeb238e15d93';
+
+        $institute = \Institute::find($instituteId);
+
+        $app = $this->tester->createApp($credentials, 'get', '/institutes/{id}/memberships', InstituteMembershipsIndex::class);
+
+        $requestBuilder = $this->tester->createRequestBuilder($credentials);
+        $requestBuilder->setUri('/institutes/'.$instituteId.'/memberships')->fetch();
+
+        $response = $this->tester->sendMockRequest($app, $requestBuilder->getRequest());
+
+        $this->tester->assertTrue($response->isSuccessfulDocument([200]));
+        $document = $response->document();
+        $this->tester->assertTrue($document->isResourceCollectionDocument());
+        $resources = $document->primaryResources();
+        $this->tester->assertCount(count($institute->members), $resources);
+    }
+}