diff --git a/api/v3/issues_servicer.py b/api/v3/issues_servicer.py
new file mode 100644
index 0000000..ebd545b
--- /dev/null
+++ b/api/v3/issues_servicer.py
@@ -0,0 +1,396 @@
+# Copyright 2020 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file or at
+# https://developers.google.com/open-source/licenses/bsd
+
+from __future__ import print_function
+from __future__ import division
+from __future__ import absolute_import
+
+import re
+
+from api import resource_name_converters as rnc
+from api.v3 import api_constants
+from api.v3 import converters
+from api.v3 import monorail_servicer
+from api.v3 import paginator
+from api.v3.api_proto import issues_pb2
+from api.v3.api_proto import issue_objects_pb2
+from api.v3.api_proto import issues_prpc_pb2
+from businesslogic import work_env
+from framework import exceptions
+
+# We accept only the following filter, and only on ListComments.
+# If we accept more complex filters in the future, introduce a library.
+_APPROVAL_DEF_FILTER_RE = re.compile(
+    r'approval = "(?P<approval_name>%s)"$' % rnc.APPROVAL_DEF_NAME_PATTERN)
+
+
+class IssuesServicer(monorail_servicer.MonorailServicer):
+  """Handle API requests related to Issue objects.
+  Each API request is implemented with a method as defined in the
+  .proto file that does any request-specific validation, uses work_env
+  to safely operate on business objects, and returns a response proto.
+  """
+
+  DESCRIPTION = issues_prpc_pb2.IssuesServiceDescription
+
+  @monorail_servicer.PRPCMethod
+  def GetIssue(self, mc, request):
+    # type: (MonorailContext, GetIssueRequest) -> Issue
+    """pRPC API method that implements GetIssue.
+
+    Raises:
+      InputException: the given name does not have a valid format.
+      NoSuchIssueException: the issue is not found.
+      PermissionException the user is not allowed to view the issue.
+    """
+    issue_id = rnc.IngestIssueName(mc.cnxn, request.name, self.services)
+    with work_env.WorkEnv(mc, self.services) as we:
+      # TODO(crbug/monorail/7614): Eliminate the need to do this lookup.
+      project = we.GetProjectByName(rnc.IngestProjectFromIssue(request.name))
+      mc.LookupLoggedInUserPerms(project)
+      issue = we.GetIssue(issue_id, allow_viewing_deleted=True)
+    return self.converter.ConvertIssue(issue)
+
+  @monorail_servicer.PRPCMethod
+  def BatchGetIssues(self, mc, request):
+    # type: (MonorailContext, BatchGetIssuesRequest) -> BatchGetIssuesResponse
+    """pRPC API method that implements BatchGetIssues.
+
+    Raises:
+      InputException: If `names` is formatted incorrectly. Or if a parent
+          collection in `names` does not match the value in `parent`.
+      NoSuchIssueException: If any of the given issues do not exist.
+      PermissionException If the requester does not have permission to view one
+          (or more) of the given issues.
+    """
+    if len(request.names) > api_constants.MAX_BATCH_ISSUES:
+      raise exceptions.InputException(
+          'Requesting %d issues when the allowed maximum is %d issues.' %
+          (len(request.names), api_constants.MAX_BATCH_ISSUES))
+    if request.parent:
+      parent_match = rnc._GetResourceNameMatch(
+          request.parent, rnc.PROJECT_NAME_RE)
+      parent_project = parent_match.group('project_name')
+      with exceptions.ErrorAggregator(exceptions.InputException) as err_agg:
+        for name in request.names:
+          try:
+            name_match = rnc._GetResourceNameMatch(name, rnc.ISSUE_NAME_RE)
+            issue_project = name_match.group('project')
+            if issue_project != parent_project:
+              err_agg.AddErrorMessage(
+                  '%s is not a child issue of %s.' % (name, request.parent))
+          except exceptions.InputException as e:
+            err_agg.AddErrorMessage(e.message)
+    with work_env.WorkEnv(mc, self.services) as we:
+      # NOTE(crbug/monorail/7614): Until the referenced cleanup is complete,
+      # all servicer methods that are scoped to a single Project need to call
+      # mc.LookupLoggedInUserPerms.
+      #  This method does not because it may be scoped to multiple projects.
+      issue_ids = rnc.IngestIssueNames(mc.cnxn, request.names, self.services)
+      issues_by_iid = we.GetIssuesDict(issue_ids)
+    return issues_pb2.BatchGetIssuesResponse(
+        issues=self.converter.ConvertIssues(
+            [issues_by_iid[issue_id] for issue_id in issue_ids]))
+
+  @monorail_servicer.PRPCMethod
+  def SearchIssues(self, mc, request):
+    # type: (MonorailContext, SearchIssuesRequest) -> SearchIssuesResponse
+    """pRPC API method that implements SearchIssue.
+
+    Raises:
+      InputException: if any given names in `projects` are invalid or if the
+        search query uses invalid syntax (ie: unmatched parentheses).
+    """
+    page_size = paginator.CoercePageSize(
+        request.page_size, api_constants.MAX_ISSUES_PER_PAGE)
+    pager = paginator.Paginator(
+        page_size=page_size,
+        order_by=request.order_by,
+        query=request.query,
+        projects=request.projects)
+
+    project_names = []
+    for resource_name in request.projects:
+      match = rnc._GetResourceNameMatch(resource_name, rnc.PROJECT_NAME_RE)
+      project_names.append(match.group('project_name'))
+
+    with work_env.WorkEnv(mc, self.services) as we:
+      # NOTE(crbug/monorail/7614): Until the referenced cleanup is complete,
+      # all servicer methods that are scoped to a single Project need to call
+      # mc.LookupLoggedInUserPerms.
+      #  This method does not because it may be scoped to multiple projects.
+      list_result = we.SearchIssues(
+          request.query, project_names, mc.auth.user_id, page_size,
+          pager.GetStart(request.page_token), request.order_by)
+
+    return issues_pb2.SearchIssuesResponse(
+        issues=self.converter.ConvertIssues(list_result.items),
+        next_page_token=pager.GenerateNextPageToken(list_result.next_start))
+
+  @monorail_servicer.PRPCMethod
+  def ListComments(self, mc, request):
+    # type: (MonorailContext, ListCommentsRequest) -> ListCommentsResponse
+    """pRPC API method that implements ListComments.
+
+    Raises:
+      InputException: the given name format or page_size are not valid.
+      NoSuchIssueException: the parent is not found.
+      PermissionException: the user is not allowed to view the parent.
+    """
+    issue_id = rnc.IngestIssueName(mc.cnxn, request.parent, self.services)
+    page_size = paginator.CoercePageSize(
+        request.page_size, api_constants.MAX_COMMENTS_PER_PAGE)
+    pager = paginator.Paginator(
+      parent=request.parent, page_size=page_size, filter_str=request.filter)
+    approval_id = None
+    if request.filter:
+      match = _APPROVAL_DEF_FILTER_RE.match(request.filter)
+      if match:
+        approval_id = rnc.IngestApprovalDefName(
+            mc.cnxn, match.group('approval_name'), self.services)
+      if not match:
+        raise exceptions.InputException(
+            'Filtering other than approval not supported.')
+
+    with work_env.WorkEnv(mc, self.services) as we:
+      # TODO(crbug/monorail/7614): Eliminate the need to do this lookup.
+      project = we.GetProjectByName(rnc.IngestProjectFromIssue(request.parent))
+      mc.LookupLoggedInUserPerms(project)
+      list_result = we.SafeListIssueComments(
+          issue_id, page_size, pager.GetStart(request.page_token),
+          approval_id=approval_id)
+    return issues_pb2.ListCommentsResponse(
+        comments=self.converter.ConvertComments(issue_id, list_result.items),
+        next_page_token=pager.GenerateNextPageToken(list_result.next_start))
+
+  @monorail_servicer.PRPCMethod
+  def ListApprovalValues(self, mc, request):
+    # type: (MonorailContext, ListApprovalValuesRequest) ->
+    #     ListApprovalValuesResponse
+    """pRPC API method that implements ListApprovalValues.
+
+    Raises:
+      InputException: the given parent does not have a valid format.
+      NoSuchIssueException: the parent issue is not found.
+      PermissionException the user is not allowed to view the parent issue.
+    """
+    issue_id = rnc.IngestIssueName(mc.cnxn, request.parent, self.services)
+    with work_env.WorkEnv(mc, self.services) as we:
+      # TODO(crbug/monorail/7614): Eliminate the need to do this lookup.
+      project = we.GetProjectByName(rnc.IngestProjectFromIssue(request.parent))
+      mc.LookupLoggedInUserPerms(project)
+      issue = we.GetIssue(issue_id)
+
+    api_avs = self.converter.ConvertApprovalValues(issue.approval_values,
+        issue.field_values, issue.phases, issue_id=issue_id)
+
+    return issues_pb2.ListApprovalValuesResponse(approval_values=api_avs)
+
+  @monorail_servicer.PRPCMethod
+  def MakeIssueFromTemplate(self, _mc, _request):
+    # type: (MonorailContext, MakeIssueFromTemplateRequest) -> Issue
+    """pRPC API method that implements MakeIssueFromTemplate.
+
+    Raises:
+      TODO(crbug/monorail/7197): Document errors when implemented
+    """
+    # Phase 1: Gather info
+    #   Get project id and template name from template resource name.
+    #   Get template pb.
+    #   Make tracker_pb2.IssueDelta from request.template_issue_delta, share
+    #   code with v3/ModifyIssue
+
+    # with work_env.WorkEnv(mc, self.services) as we:
+    #   project = ... get project from template.
+    #   mc.LookupLoggedInUserPerms(project)
+    #   created_issue = we.MakeIssueFromTemplate(template, description, delta)
+
+    # Return newly created API issue.
+    # return converters.ConvertIssue(created_issue)
+
+    return issue_objects_pb2.Issue()
+
+  @monorail_servicer.PRPCMethod
+  def MakeIssue(self, mc, request):
+    # type: (MonorailContext, MakeIssueRequest) -> Issue
+    """pRPC API method that implements MakeIssue.
+
+    Raises:
+      InputException if any given names do not have a valid format or if any
+        fields in the requested issue were invalid.
+      NoSuchProjectException if no project exists with the given parent.
+      FilterRuleException if proposed issue values violate any filter rules
+        that shows error.
+      PermissionException if user lacks sufficient permissions.
+    """
+    project_id = rnc.IngestProjectName(mc.cnxn, request.parent, self.services)
+    with work_env.WorkEnv(mc, self.services) as we:
+      # TODO(crbug/monorail/7614): Eliminate the need to do this lookup.
+      project = we.GetProject(project_id)
+      mc.LookupLoggedInUserPerms(project)
+
+    ingested_issue = self.converter.IngestIssue(
+        request.issue, project_id)
+    send_email = self.converter.IngestNotifyType(request.notify_type)
+
+    with work_env.WorkEnv(mc, self.services) as we:
+      created_issue = we.MakeIssue(
+          ingested_issue, request.description, send_email)
+      starred_issue = we.StarIssue(created_issue, True)
+
+    return self.converter.ConvertIssue(starred_issue)
+
+  @monorail_servicer.PRPCMethod
+  def ModifyIssues(self, mc, request):
+    # type: (MonorailContext, ModifyIssuesRequest) -> ModifyIssuesResponse
+    """pRPC API method that implements ModifyIssues.
+
+    Raises:
+      InputException if any given names do not have a valid format or if any
+        fields in the requested issue were invalid.
+      NoSuchIssueException if some issues weren't found.
+      NoSuchProjectException if no project was found for some given issues.
+      FilterRuleException if proposed issue changes violate any filter rules
+        that shows error.
+      PermissionException if user lacks sufficient permissions.
+    """
+    if not request.deltas:
+      return issues_pb2.ModifyIssuesResponse()
+    if len(request.deltas) > api_constants.MAX_MODIFY_ISSUES:
+      raise exceptions.InputException(
+          'Requesting %d updates when the allowed maximum is %d updates.' %
+          (len(request.deltas), api_constants.MAX_MODIFY_ISSUES))
+    impacted_issues_count = 0
+    for delta in request.deltas:
+      impacted_issues_count += (
+          len(delta.blocked_on_issues_remove) +
+          len(delta.blocking_issues_remove) +
+          len(delta.issue.blocking_issue_refs) +
+          len(delta.issue.blocked_on_issue_refs))
+      if 'merged_into_issue_ref' in delta.update_mask.paths:
+        impacted_issues_count += 1
+    if impacted_issues_count > api_constants.MAX_MODIFY_IMPACTED_ISSUES:
+      raise exceptions.InputException(
+          'Updates include %d impacted issues when the allowed maximum is %d.' %
+          (impacted_issues_count, api_constants.MAX_MODIFY_IMPACTED_ISSUES))
+    iid_delta_pairs = self.converter.IngestIssueDeltas(request.deltas)
+    with work_env.WorkEnv(mc, self.services) as we:
+      issues = we.ModifyIssues(
+          iid_delta_pairs,
+          attachment_uploads=self.converter.IngestAttachmentUploads(
+              request.uploads),
+          comment_content=request.comment_content,
+          send_email=self.converter.IngestNotifyType(request.notify_type))
+
+    return issues_pb2.ModifyIssuesResponse(
+        issues=self.converter.ConvertIssues(issues))
+
+  @monorail_servicer.PRPCMethod
+  def ModifyIssueApprovalValues(self, mc, request):
+    # type: (MonorailContext, ModifyIssueApprovalValuesRequest) ->
+    #     ModifyIssueApprovalValuesResponse
+    """pRPC API method that implements ModifyIssueApprovalValues.
+
+    Raises:
+      InputException if any fields in the delta were invalid.
+      NoSuchIssueException: if the issue of any ApprovalValue isn't found.
+      NoSuchProjectException: if the parent project of any ApprovalValue isn't
+          found.
+      NoSuchUserException: if any user value provided isn't found.
+      PermissionException if user lacks sufficient permissions.
+      # TODO(crbug/monorail/7925): Not all of these are yet thrown.
+    """
+    if len(request.deltas) > api_constants.MAX_MODIFY_APPROVAL_VALUES:
+      raise exceptions.InputException(
+          'Requesting %d updates when the allowed maximum is %d updates.' %
+          (len(request.deltas), api_constants.MAX_MODIFY_APPROVAL_VALUES))
+    response = issues_pb2.ModifyIssueApprovalValuesResponse()
+    delta_specifications = self.converter.IngestApprovalDeltas(
+        request.deltas, mc.auth.user_id)
+    send_email = self.converter.IngestNotifyType(request.notify_type)
+    with work_env.WorkEnv(mc, self.services) as we:
+      # NOTE(crbug/monorail/7614): Until the referenced cleanup is complete,
+      # all servicer methods that are scoped to a single Project need to call
+      # mc.LookupLoggedInUserPerms.
+      # This method does not because it may be scoped to multiple projects.
+      issue_approval_values = we.BulkUpdateIssueApprovalsV3(
+          delta_specifications, request.comment_content, send_email=send_email)
+    api_avs = []
+    for issue, approval_value in issue_approval_values:
+      api_avs.extend(
+          self.converter.ConvertApprovalValues(
+              [approval_value],
+              issue.field_values,
+              issue.phases,
+              issue_id=issue.issue_id))
+    response.approval_values.extend(api_avs)
+    return response
+
+  @monorail_servicer.PRPCMethod
+  def ModifyCommentState(self, mc, request):
+    # type: (MonorailContext, ModifyCommentStateRequest) ->
+    #     ModifyCommentStateResponse
+    """pRPC API method that implements ModifyCommentState.
+
+    We do not support changing between DELETED <-> SPAM. User must
+    undelete or unflag-as-spam first.
+
+    Raises:
+      NoSuchProjectException if the parent Project does not exist.
+      NoSuchIssueException: if the issue does not exist.
+      NoSuchCommentException: if the comment does not exist.
+      PermissionException if user lacks sufficient permissions.
+      ActionNotSupported if user requests unsupported state transitions.
+    """
+    (project_id, issue_id,
+     comment_num) = rnc.IngestCommentName(mc.cnxn, request.name, self.services)
+    with work_env.WorkEnv(mc, self.services) as we:
+      # TODO(crbug/monorail/7614): Eliminate the need to do this lookup.
+      project = we.GetProject(project_id)
+      mc.LookupLoggedInUserPerms(project)
+      issue = we.GetIssue(issue_id, use_cache=False)
+      comments_list = we.SafeListIssueComments(issue_id, 1, comment_num).items
+      try:
+        comment = comments_list[0]
+      except IndexError:
+        raise exceptions.NoSuchCommentException()
+
+      if request.state == issue_objects_pb2.IssueContentState.Value('ACTIVE'):
+        if comment.is_spam:
+          we.FlagComment(issue, comment, False)
+        elif comment.deleted_by != 0:
+          we.DeleteComment(issue, comment, delete=False)
+        else:
+          # No-op if already currently active
+          pass
+      elif request.state == issue_objects_pb2.IssueContentState.Value(
+          'DELETED'):
+        if (not comment.deleted_by) and (not comment.is_spam):
+          we.DeleteComment(issue, comment, delete=True)
+        elif comment.deleted_by and not comment.is_spam:
+          # No-op if already deleted
+          pass
+        else:
+          raise exceptions.ActionNotSupported(
+              'Cannot change comment state from spam to deleted.')
+      elif request.state == issue_objects_pb2.IssueContentState.Value('SPAM'):
+        if (not comment.deleted_by) and (not comment.is_spam):
+          we.FlagComment(issue, comment, True)
+        elif comment.is_spam:
+          # No-op if already spam
+          pass
+        else:
+          raise exceptions.ActionNotSupported(
+              'Cannot change comment state from deleted to spam.')
+      else:
+        raise exceptions.ActionNotSupported('Unsupported target comment state.')
+
+      # FlagComment does not have side effect on comment, must refresh.
+      refreshed_comment = we.SafeListIssueComments(issue_id, 1,
+                                                   comment_num).items[0]
+
+    converted_comment = self.converter.ConvertComments(
+        issue_id, [refreshed_comment])[0]
+    return issues_pb2.ModifyCommentStateResponse(comment=converted_comment)
