diff --git a/www/conservancy/apps/assignment/__init__.py b/www/conservancy/apps/assignment/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/www/conservancy/apps/assignment/apps.py b/www/conservancy/apps/assignment/apps.py
new file mode 100644
index 00000000..9fe186c5
--- /dev/null
+++ b/www/conservancy/apps/assignment/apps.py
@@ -0,0 +1,7 @@
+from __future__ import unicode_literals
+
+from django.apps import AppConfig
+
+
+class AssignmentConfig(AppConfig):
+    name = 'assignment'
diff --git a/www/conservancy/apps/assignment/migrations/__init__.py b/www/conservancy/apps/assignment/migrations/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/www/conservancy/apps/assignment/models.py b/www/conservancy/apps/assignment/models.py
new file mode 100644
index 00000000..0b8243a6
--- /dev/null
+++ b/www/conservancy/apps/assignment/models.py
@@ -0,0 +1,28 @@
+from __future__ import unicode_literals
+
+from django.db import models
+
+
+class Assignment(models.Model):
+    full_name = models.CharField(max_length=255)
+    email = models.EmailField()
+    place_of_residence = models.TextField(
+        'Country of citizenship or residential address',
+        blank=True)
+
+    repository = models.URLField(
+        'Code repository',
+        blank=True,
+    )
+    coverage = models.CharField(
+        verbose_name='Time period to assign',
+        max_length=50,
+        choices=[
+            ('up to this year', 'One-off up to and including this year'),
+            ('ongoing', 'All existing and new contributions'),
+        ],
+        default='up to this year',
+    )
+    attestation_of_copyright = models.BooleanField(
+        'I attest that I own the copyright on these works'
+    )
diff --git a/www/conservancy/apps/assignment/urls.py b/www/conservancy/apps/assignment/urls.py
new file mode 100644
index 00000000..435f6b68
--- /dev/null
+++ b/www/conservancy/apps/assignment/urls.py
@@ -0,0 +1,8 @@
+from django.conf.urls import url
+
+from .views import AssignmentCreateView
+
+
+urlpatterns = [
+    url(r'add/', AssignmentCreateView.as_view(), name='assignement-add'),
+]
diff --git a/www/conservancy/apps/assignment/views.py b/www/conservancy/apps/assignment/views.py
new file mode 100644
index 00000000..73aac1d4
--- /dev/null
+++ b/www/conservancy/apps/assignment/views.py
@@ -0,0 +1,18 @@
+from django.shortcuts import render
+
+
+from django.urls import reverse_lazy
+from django.views.generic.edit import CreateView, DeleteView, UpdateView
+from .models import Assignment
+
+
+class AssignmentCreateView(CreateView):
+    model = Assignment
+    fields = [
+        'full_name',
+        'email',
+        'place_of_residence',
+        'repository',
+        'coverage',
+        'attestation_of_copyright',
+    ]
diff --git a/www/conservancy/urls.py b/www/conservancy/urls.py
index 0cd95c48..5c07d2c1 100644
--- a/www/conservancy/urls.py
+++ b/www/conservancy/urls.py
@@ -59,4 +59,5 @@ urlpatterns = [
     url(r'^coming-soon.html', static_views.index),
     url(r'^fundraiser_data', fundgoal_views.view),
     url(r'^ccs-upload/', include('conservancy.apps.ccs_upload.urls', namespace='ccs_upload')),
+    url(r'^assignment', include('conservancy.apps.assignment.urls')),
 ]