diff --git a/arkindex/documents/migrations/0011_auto_20200403_1456.py b/arkindex/documents/migrations/0011_auto_20200403_1456.py
new file mode 100644
index 0000000000000000000000000000000000000000..7795aef534845cfbd49f7e6711bcfe150e19fc35
--- /dev/null
+++ b/arkindex/documents/migrations/0011_auto_20200403_1456.py
@@ -0,0 +1,28 @@
+# Generated by Django 2.2.10 on 2020-04-03 14:56
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('documents', '0010_remove_region'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='transcription',
+            name='text',
+            field=models.TextField(),
+        ),
+        migrations.AlterField(
+            model_name='transcription',
+            name='zone',
+            field=models.ForeignKey(
+                on_delete=django.db.models.deletion.PROTECT,
+                related_name='transcriptions',
+                to='images.Zone',
+            ),
+        ),
+    ]
diff --git a/arkindex/documents/models.py b/arkindex/documents/models.py
index c169988fb092fc1198db26843e9cb653e0ce7308..f8934e37dde6ca4896343f2e2c50858442cfd268 100644
--- a/arkindex/documents/models.py
+++ b/arkindex/documents/models.py
@@ -422,17 +422,15 @@ class Transcription(models.Model):
     )
     zone = models.ForeignKey(
         'images.Zone',
-        on_delete=models.SET_NULL,
+        on_delete=models.PROTECT,
         related_name='transcriptions',
-        null=True,
-        blank=True,
     )
     source = models.ForeignKey(
         DataSource,
         on_delete=models.CASCADE,
         related_name='transcriptions',
     )
-    text = models.TextField(null=True, blank=True)
+    text = models.TextField()
     score = models.FloatField(null=True, blank=True)
     entities = models.ManyToManyField(
         Entity,
diff --git a/arkindex/documents/tests/consumers/test_ml_results_consumer.py b/arkindex/documents/tests/consumers/test_ml_results_consumer.py
index eeb1e4c8203087e864722f50601edabe40626737..329bc03c9ce902af673aa3dcd74adc54da25da06 100644
--- a/arkindex/documents/tests/consumers/test_ml_results_consumer.py
+++ b/arkindex/documents/tests/consumers/test_ml_results_consumer.py
@@ -63,6 +63,7 @@ class TestMLResultsConsumer(FixtureTestCase):
             text='some text',
             type=TranscriptionType.Line,
             source=source,
+            zone=cls.page2.zone,
         ).transcription_entities.create(
             offset=0,
             length=1,
diff --git a/arkindex/documents/tests/consumers/test_reindex_consumer.py b/arkindex/documents/tests/consumers/test_reindex_consumer.py
index 6274f332c2ed5f8801e146c541aef00f156e6caa..b0b16331b3968b337267e5ec2db484d4e84da9e8 100644
--- a/arkindex/documents/tests/consumers/test_reindex_consumer.py
+++ b/arkindex/documents/tests/consumers/test_reindex_consumer.py
@@ -1,6 +1,7 @@
 from unittest.mock import patch
 from django.db.models import Q
 from arkindex_common.enums import TranscriptionType, MetaType, EntityType
+from arkindex.project.polygon import Polygon
 from arkindex.project.tests import FixtureTestCase
 from arkindex.documents.consumers import ReindexConsumer
 from arkindex.documents.models import Corpus, Element, Transcription, Entity, DataSource
@@ -27,15 +28,19 @@ class TestReindexConsumer(FixtureTestCase):
         )
 
         corpus2 = Corpus.objects.create(name='Another corpus')
+        image = cls.imgsrv.images.first()
+        zone, _ = image.zones.get_or_create(polygon=Polygon.from_coords(0, 0, 10, 10))
         element2 = corpus2.elements.create(
             type=corpus2.types.create(display_name='Element'),
             name='An element',
+            zone=zone,
         )
         ts = element2.transcriptions.create(
             score=0.8,
             text='something',
             type=TranscriptionType.Word,
             source=source,
+            zone=zone,
         )
         ts.transcription_entities.create(
             entity=corpus2.entities.create(
diff --git a/arkindex/documents/tests/test_elements_api.py b/arkindex/documents/tests/test_elements_api.py
index a09f6659b95a8fac52d7e8491228052b4eee4efa..2414b68f084da9f869ef0f4f6ab906575016cd84 100644
--- a/arkindex/documents/tests/test_elements_api.py
+++ b/arkindex/documents/tests/test_elements_api.py
@@ -6,8 +6,9 @@ from arkindex_common.enums import MetaType, TranscriptionType, EntityType
 from arkindex.documents.models import \
     Element, DataSource, Corpus, Entity, MLClass, Classification
 from arkindex.images.models import ImageServer
-from arkindex.project.tests import FixtureAPITestCase
 from arkindex.project.aws import S3FileStatus
+from arkindex.project.polygon import Polygon
+from arkindex.project.tests import FixtureAPITestCase
 from arkindex.users.models import User
 
 
@@ -495,9 +496,11 @@ class TestElementsAPI(FixtureAPITestCase):
         self.page.transcriptions.all().delete()
         transcriptions = []
         for i in range(10):
+            zone, _ = self.page.zone.image.zones.get_or_create(polygon=Polygon.from_coords(0, 0, i + 1, i + 1))
             transcriptions.append(self.page.transcriptions.create(
                 source_id=DataSource.objects.get(slug='test').id,
-                type=TranscriptionType.Word
+                type=TranscriptionType.Word,
+                zone=zone,
             ))
         self.client.force_login(self.user)
         response = self.client.get(reverse('api:element-transcriptions', kwargs={'pk': str(self.page.id)}))
diff --git a/arkindex/documents/tests/test_entities_api.py b/arkindex/documents/tests/test_entities_api.py
index f2ca145d7469af6f1c85d89e67b2c14b0555401a..8896b7f32790f35d225203e4e733d640c9db02ec 100644
--- a/arkindex/documents/tests/test_entities_api.py
+++ b/arkindex/documents/tests/test_entities_api.py
@@ -2,9 +2,10 @@ from django.urls import reverse
 from unittest.mock import Mock, patch, call
 from rest_framework import status
 from arkindex_common.enums import MetaType
+from arkindex.project.polygon import Polygon
+from arkindex.project.tests import FixtureAPITestCase
 from arkindex.documents.models import TranscriptionType, DataSource, \
     Corpus, Entity, EntityType, EntityRole, EntityLink, TranscriptionEntity, MLToolType
-from arkindex.project.tests import FixtureAPITestCase
 from elasticsearch.exceptions import NotFoundError
 
 
@@ -46,10 +47,14 @@ class TestEntitiesAPI(FixtureAPITestCase):
             child_type=EntityType.Location,
             corpus=self.corpus
         )
+        zone, _ = self.page.zone.image.zones.get_or_create(
+            polygon=Polygon.from_coords(0, 0, 42, 42),
+        )
         self.transcription = self.page.transcriptions.create(
             text='Some transcribed text',
+            zone=zone,
             source_id=self.source.id,
-            type=TranscriptionType.Line
+            type=TranscriptionType.Line,
         )
         self.metadata = self.page.metadatas.create(
             name='test 1',
@@ -104,11 +109,12 @@ class TestEntitiesAPI(FixtureAPITestCase):
         self.assertListEqual(response.json().get('results'), [])
 
     def test_get_entity_elements_from_transcription(self):
+        zone, _ = self.imgsrv.images.first().zones.get_or_create(polygon=Polygon.from_coords(0, 0, 200, 200))
         elt = self.corpus.elements.create(
             type=self.corpus.types.get(slug='act'),
             name='001',
         )
-        elt_tr = elt.transcriptions.create(source_id=self.source.id, text='goodbye')
+        elt_tr = elt.transcriptions.create(source_id=self.source.id, text='goodbye', zone=zone)
         TranscriptionEntity.objects.create(transcription=elt_tr, entity=self.entity, offset=42, length=7)
         with self.assertNumQueries(9):
             response = self.client.get(reverse('api:entity-elements', kwargs={'pk': str(self.entity.id)}))