diff --git a/routers/api/v1/activitypub/repository.go b/routers/api/v1/activitypub/repository.go
index 9dc84c2ec0..1f2599f0de 100644
--- a/routers/api/v1/activitypub/repository.go
+++ b/routers/api/v1/activitypub/repository.go
@@ -1,4 +1,4 @@
-// Copyright 2022 The Gitea Authors. All rights reserved.
+// Copyright 2023 The Gitea forgejoAuthors. All rights reserved.
 // SPDX-License-Identifier: MIT
 
 package activitypub
diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go
index 58814d3b2e..2043962cc8 100644
--- a/routers/api/v1/api.go
+++ b/routers/api/v1/api.go
@@ -894,6 +894,11 @@ func Routes() *web.Route {
 					m.Get("", activitypub.Person)
 					m.Post("/inbox", activitypub.ReqHTTPSignature(), activitypub.PersonInbox)
 				}, context_service.UserIDAssignmentAPI())
+				// TODO: implement ctx
+				m.Group("/repository-id/{repsitory-id}", func() {
+					m.Get("", activitypub.Repository)
+					m.Post("/inbox", activitypub.ReqHTTPSignature(), activitypub.RepositoryInbox)
+				}, context_service.RepositoryAssignmentAPI())
 			}, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryActivityPub))
 		}
 
@@ -1081,7 +1086,10 @@ func Routes() *web.Route {
 			repo.CreateOrgRepoDeprecated)
 
 		// requires repo scope
-		m.Combo("/repositories/{id}", reqToken(), tokenRequiresScopes(auth_model.AccessTokenScopeCategoryRepository)).Get(repo.GetByID)
+		m.Combo("/repositories/{id}", 
+			reqToken(), 
+			tokenRequiresScopes(auth_model.AccessTokenScopeCategoryRepository)
+		).Get(repo.GetByID)
 
 		// Repos (requires repo scope)
 		m.Group("/repos", func() {
diff --git a/services/context/repository.go b/services/context/repository.go
new file mode 100644
index 0000000000..74c60f4715
--- /dev/null
+++ b/services/context/repository.go
@@ -0,0 +1,32 @@
+// Copyright 2023 The forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package context
+
+import (
+	"net/http"
+
+	repo_model "code.gitea.io/gitea/models/repo"
+	"code.gitea.io/gitea/modules/context"
+)
+
+// RepositoryIDAssignmentAPI returns a middleware to handle context-repo assignment for api routes
+func RepositoryIDAssignmentAPI() func(ctx *context.APIContext) {
+	return func(ctx *context.APIContext) {
+		// TODO: enough validation for security?
+		repositoryID := ctx.ParamsInt64(":repository-id")
+
+		//TODO: check auth here ?
+		if !ctx.Repo.HasAccess() && !ctx.IsUserSiteAdmin() {
+			ctx.Error(http.StatusForbidden, "reqAnyRepoReader", "user should have any permission to read repository or permissions of site admin")
+			return
+		}
+
+		var err error
+		ctx.Repo, err = repo_model.GetRepositoryByID(ctx, repositoryID)
+
+		if err != nil {
+			ctx.Error(http.StatusInternalServerError, "GetRepositoryByID", err)
+		}
+	}
+}