diff --git a/arkindex/documents/api/elements.py b/arkindex/documents/api/elements.py
index 88d74b8bd77439b3b7e2e7b5a7a7e0c87ebedb4b..5e2cf1d6ca7b9f14d89fc7aa6be44d84683da738 100644
--- a/arkindex/documents/api/elements.py
+++ b/arkindex/documents/api/elements.py
@@ -656,7 +656,7 @@ class ElementTranscriptions(ListAPIView):
     pagination_class = TranscriptionsPagination
     openapi_overrides = {
         'security': [],
-        'tags': ['elements'],
+        'tags': ['transcriptions'],
         'parameters': [
             {
                 'name': 'type',
diff --git a/arkindex/documents/api/ml.py b/arkindex/documents/api/ml.py
index 4032783b49e092b4e9c8c8b5630a64c44d3c97e6..d225f604b773cec4cac32fd2c50dcc5df5aa68db 100644
--- a/arkindex/documents/api/ml.py
+++ b/arkindex/documents/api/ml.py
@@ -40,8 +40,9 @@ class TranscriptionCreate(CreateAPIView):
     serializer_class = TranscriptionCreateSerializer
     permission_classes = (IsVerified, )
     openapi_overrides = {
+        'description': 'Create a single manual transcription attached to an element',
         'operationId': 'CreateTranscription',
-        'tags': ['elements'],
+        'tags': ['transcriptions'],
     }
 
     def get_object(self):
@@ -101,6 +102,9 @@ class TranscriptionEdit(RetrieveUpdateDestroyAPIView):
     """
     serializer_class = TranscriptionSerializer
     permission_classes = (IsVerified, )
+    openapi_overrides = {
+        'tags': ['transcriptions'],
+    }
 
     def get_queryset(self):
         if not self.request:
@@ -134,7 +138,7 @@ class TranscriptionBulk(CreateAPIView, UpdateAPIView):
     # Force DRF to ignore PATCH
     http_method_names = ['post', 'put', 'head', 'options', 'trace']
     openapi_overrides = {
-        'tags': ['ml'],
+        'tags': ['transcriptions'],
         'responses': {
             '201': {
                 'description': 'All transcriptions have been created.'
@@ -193,7 +197,7 @@ class CorpusMLClassList(CorpusACLMixin, ListAPIView):
             'List all available classes in a corpus with their'
             ' distribution over elements (best classes count)'
         ),
-        'tags': ['ml'],
+        'tags': ['transcriptions'],
     }
     filter_backends = [SafeSearchFilter]
     search_fields = ['name']
@@ -227,7 +231,7 @@ class MLClassList(ListAPIView):
     openapi_overrides = {
         'operationId': 'ListMLClasses',
         'description': 'List available machine learning classes in all corpora.',
-        'tags': ['ml'],
+        'tags': ['classifications'],
     }
 
 
@@ -238,7 +242,7 @@ class ClassificationCreate(CreateAPIView):
     serializer_class = ClassificationCreateSerializer
     queryset = Classification.objects.all()
     openapi_overrides = {
-        'tags': ['ml'],
+        'tags': ['classifications'],
     }
 
     def create(self, request, *args, **kwargs):
@@ -279,7 +283,7 @@ class ClassificationBulk(CreateAPIView):
     serializer_class = ClassificationsSerializer
     permission_classes = (IsVerified, )
     openapi_overrides = {
-        'tags': ['ml'],
+        'tags': ['classifications'],
     }
 
     def perform_create(self, serializer):
@@ -306,7 +310,7 @@ class ManageClassificationsSelection(SelectionMixin, CreateAPIView):
     permission_classes = (IsVerified, )
     openapi_overrides = {
         'description': 'Manage classifications for a list of selected elements for a specific corpus.',
-        'tags': ['ml']
+        'tags': ['classifications']
     }
 
     def post(self, request, *args, **kwargs):
@@ -388,7 +392,7 @@ class ClassificationValidate(ClassificationModerationActionsMixin):
     openapi_overrides = {
         'operationId': 'ValidateClassification',
         'description': 'Validate an existing classification.',
-        'tags': ['ml'],
+        'tags': ['classifications'],
     }
 
 
@@ -400,7 +404,7 @@ class ClassificationReject(ClassificationModerationActionsMixin):
     openapi_overrides = {
         'operationId': 'RejectClassification',
         'description': 'Reject an existing classification. Manual classifications will be deleted.',
-        'tags': ['ml'],
+        'tags': ['classifications'],
     }
 
     def put(self, request, *args, **kwargs):
@@ -423,7 +427,7 @@ class PageXmlTranscriptionsImport(CreateModelMixin, APIView):
     openapi_overrides = {
         'operationId': 'ImportPageXmlTranscriptions',
         'description': 'Import transcriptions into Arkindex from region data in the PAGE XML format.',
-        'tags': ['ml'],
+        'tags': ['transcriptions'],
         'requestBody': {
             'required': True,
             'description': 'A PAGE XML document. TextRegion tags will be imported as Paragraph transcriptions '
diff --git a/arkindex/project/openapi/patch.yml b/arkindex/project/openapi/patch.yml
index 81bce500c667160a3074fbc4f169140a569ff332..045cf942df3de6cf4364f0d6342824e0c5f4060f 100644
--- a/arkindex/project/openapi/patch.yml
+++ b/arkindex/project/openapi/patch.yml
@@ -237,6 +237,15 @@ paths:
                     format: uri
                     description: URL to the authorization endpoint.
                     readOnly: true
+  /api/v1/transcription/{id}/:
+    get:
+      description: Retrieve a single transcription
+    patch:
+      description: Update the text of a manual transcription
+    put:
+      description: Update the text of a manual transcription
+    delete:
+      description: Delete a manual transcription
   /api/v1/transcription/bulk/:
     put:
       description: >-