diff --git a/scipost_django/edadmin/templates/edadmin/_hx_submission_tab_contents_edadmin.html b/scipost_django/edadmin/templates/edadmin/_hx_submission_tab_contents_edadmin.html
index 9aff7d372cb6115a4f52406cefd0a2d3516eb327..afd9e3910f2ec341be4598370284f3430dbd2b87 100644
--- a/scipost_django/edadmin/templates/edadmin/_hx_submission_tab_contents_edadmin.html
+++ b/scipost_django/edadmin/templates/edadmin/_hx_submission_tab_contents_edadmin.html
@@ -1,4 +1,6 @@
 <h1>Editorial administration</h1>
 {% if submission.in_stage_incoming %}
   {% include "edadmin/incoming/_submission_incoming.html" with submission=submission %}
+{% elif submission.in_stage_preassignment %}
+  {% include "edadmin/preassignment/_submission_preassignment.html" with submission=submission %}
 {% endif %}
diff --git a/scipost_django/edadmin/templates/edadmin/preassignment/_hx_author_profile_row.html b/scipost_django/edadmin/templates/edadmin/preassignment/_hx_author_profile_row.html
new file mode 100644
index 0000000000000000000000000000000000000000..847b1a1e45ea0cad38374f6dd4d25446c9532774
--- /dev/null
+++ b/scipost_django/edadmin/templates/edadmin/preassignment/_hx_author_profile_row.html
@@ -0,0 +1,58 @@
+<tr id="submission-{{ submission.pk }}-author-profile-row-{{ order }}"
+    class="{% if profile %}bg-success{% else %}bg-warning{% endif %} bg-opacity-10"
+>
+  <td>{{ author_string }}</td>
+  <td>{{ order }}</td>
+  <td>
+    {{ profile }}
+  </td>
+  <td>
+    {% if profile %}
+      <button class="ms-4 px-1 py-0 btn btn-small btn-danger text-white"
+	      hx-get="{% url 'edadmin:preassignment:_hx_author_profile_action' identifier_w_vn_nr=submission.preprint.identifier_w_vn_nr order=order profile_id=profile.pk action='unmatch' %}"
+	      hx-target="#submission-{{ submission.pk }}-author-profile-row-{{ order }}"
+	      hx-swap="outerHTML"
+      >
+	{% include 'bi/trash-fill.html' %}
+      </button>
+    {% else %}
+      {% load crispy_forms_tags %}
+      <div class="row mb-0">
+	<div class="col-9">
+	  <form
+	      hx-post="{% url 'profiles:_hx_profile_dynsel_list' %}"
+	      hx-trigger="load, keyup delay:200ms, change"
+	      hx-target="#submission-{{ submission.id }}-profile-{{ order }}-dynsel-results"
+	      hx-swap="innerHTML"
+	      hx-indicator="#submission-{{ submission.id }}-profile-{{ order }}-dynsel-results-indicator"
+	  >
+	    <div id="profile_{{ order }}_dynsel_form">{% crispy profile_dynsel_form %}</div>
+	  </form>
+	</div>
+	<div class="col-3">
+	  <div id="submission-{{ submission.id }}-profile-{{ order }}-dynsel-results-indicator" class="htmx-indicator">
+	    <button class="btn btn-sm btn-warning" type="button" disabled>
+	      <strong>Loading results...</strong>
+	      <div class="spinner-grow spinner-grow-sm ms-2" role="status" aria-hidden="true"></div>
+	    </button>
+	  </div>
+	</div>
+      </div>
+      <div class="row mb-0">
+	<div class="col-9">
+	  <div id="submission-{{ submission.id }}-profile-{{ order }}-dynsel-results" class="border border-light m-0 p-1"></div>
+	</div>
+	<div class="col-3">
+	  <div id="submission-{{ submission.pk }}-author-profile-row-{{ order }}-indicator"
+	       class="htmx-indicator"
+	  >
+	    <button class="btn btn-sm btn-warning" type="button" disabled>
+	      <strong>Loading...</strong>
+	      <div class="spinner-grow spinner-grow-sm ms-2" role="status" aria-hidden="true"></div>
+	    </button>
+	  </div>
+	</div>
+      </div>
+    {% endif %}
+  </td>
+</tr>
diff --git a/scipost_django/edadmin/templates/edadmin/preassignment/_hx_author_profiles_details_contents.html b/scipost_django/edadmin/templates/edadmin/preassignment/_hx_author_profiles_details_contents.html
new file mode 100644
index 0000000000000000000000000000000000000000..48f888c61b211cb88a5d55500d3e007cc5782e36
--- /dev/null
+++ b/scipost_django/edadmin/templates/edadmin/preassignment/_hx_author_profiles_details_contents.html
@@ -0,0 +1,28 @@
+<table class="table table-bordered">
+  <thead>
+    <tr>
+      <th>Name (from author list)</th>
+      <th>Order</th>
+      <th>Matched Profile</th>
+      <th>Candidate Profiles</th>
+    </tr>
+  </thead>
+  <tbody>
+    {% for item in matches_list %}
+      <tr id="submission-{{ submission.pk }}-author-profile-row-{{ item.1 }}"
+	  class="{% if item.2 %}bg-success{% else %}bg-warning{% endif %} bg-opacity-10"
+	  hx-get="{% url 'edadmin:preassignment:_hx_author_profile_row' identifier_w_vn_nr=submission.preprint.identifier_w_vn_nr order=item.1 %}"
+	  hx-swap="outerHTML"
+	  hx-trigger="revealed"
+      >
+      </tr>
+    {% empty %}
+      <tr>
+	<td colspan="4">None found</td>
+      </tr>
+    {% endfor %}
+  </tbody>
+</table>
+
+<h3 class="mb-2">Needed Profiles not found?</h3>
+<p>Then add to our database by <a href="{% url 'profiles:profile_create' %}" target="_blank">creating a new Profile</a> (opens in new window).</p>
diff --git a/scipost_django/edadmin/templates/edadmin/preassignment/_hx_author_profiles_details_summary.html b/scipost_django/edadmin/templates/edadmin/preassignment/_hx_author_profiles_details_summary.html
new file mode 100644
index 0000000000000000000000000000000000000000..dd88f1db18f538bbc248137c652c392d67b5c317
--- /dev/null
+++ b/scipost_django/edadmin/templates/edadmin/preassignment/_hx_author_profiles_details_summary.html
@@ -0,0 +1,3 @@
+{% with submission.authors_as_list|length as nr_authors %}
+  <h2>Author Profiles <small class="{% if matches == nr_authors %}bg-success{% else %}bg-warning{% endif %} ms-4 p-1 text-white">matched: {{ matches }} out of {{ nr_authors }}</small></h2>
+{% endwith %}
diff --git a/scipost_django/edadmin/templates/edadmin/preassignment/_submission_preassignment.html b/scipost_django/edadmin/templates/edadmin/preassignment/_submission_preassignment.html
new file mode 100644
index 0000000000000000000000000000000000000000..4cf353aefdd00b6e2652c198efd618c8200ce934
--- /dev/null
+++ b/scipost_django/edadmin/templates/edadmin/preassignment/_submission_preassignment.html
@@ -0,0 +1,27 @@
+<details id="submission-{{ submission.id }}-author-profiles-details"
+	 class="border border-2"
+>
+  <summary class="bg-primary bg-opacity-10 p-2">
+    <span id="submission-{{ submission.pk }}-author-profiles-details-summary"
+	  hx-get="{% url 'edadmin:preassignment:_hx_author_profiles_details_summary' identifier_w_vn_nr=submission.preprint.identifier_w_vn_nr %}"
+	  hx-trigger="load, submission-{{ submission.pk }}-author-profiles-details-updated from:body"
+    >
+    </span>
+  </summary>
+
+  <div id="submission-{{ submission.pk }}-author-profiles-details-contents"
+       class="p-2"
+       hx-get="{% url 'edadmin:preassignment:_hx_author_profiles_details_contents' identifier_w_vn_nr=submission.preprint.identifier_w_vn_nr %}"
+       hx-trigger="toggle once from:#submission-{{ submission.pk }}-author-profiles-details"
+  >
+  </div>
+  <div id="submission-{{ submission.pk }}-author-profiles-details-contents-indicator"
+       class="htmx-indicator"
+  >
+    <button class="btn btn-sm btn-warning" type="button" disabled>
+      <strong>Loading form...</strong>
+      <div class="spinner-grow spinner-grow-sm ms-2" role="status" aria-hidden="true"></div>
+    </button>
+  </div>
+
+</details>
diff --git a/scipost_django/edadmin/urls/preassignment.py b/scipost_django/edadmin/urls/preassignment.py
new file mode 100644
index 0000000000000000000000000000000000000000..cb556b86fadf376b52318bc7c24b95b38275d016
--- /dev/null
+++ b/scipost_django/edadmin/urls/preassignment.py
@@ -0,0 +1,38 @@
+__copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)"
+__license__ = "AGPL v3"
+
+
+from django.urls import include, path
+
+from ..views import preassignment
+
+app_name = "preassignment"
+
+
+urlpatterns = [ # building on /edadmin/preassigmnent/
+    path( # <identifier>/
+        "<identifier:identifier_w_vn_nr>/",
+        include([
+            path( # /edadmin/preassignment/<identifier>/author_profiles
+                "author_profiles_details_summary",
+                preassignment._hx_author_profiles_details_summary,
+                name="_hx_author_profiles_details_summary",
+            ),
+            path( # /edadmin/preassignment/<identifier>/author_profiles
+                "author_profiles_details_contents",
+                preassignment._hx_author_profiles_details_contents,
+                name="_hx_author_profiles_details_contents",
+            ),
+            path( # /edadmin/preassignment/<identifier>/author_profile_row/<order>
+                "author_profile_row/<int:order>",
+                preassignment._hx_author_profile_row,
+                name="_hx_author_profile_row",
+            ),
+            path( # /edadmin/preassignment/<identifier>/author_profile_dynsel
+                "author_profile_action/<int:order>/<int:profile_id>/<slug:action>",
+                preassignment._hx_author_profile_action,
+                name="_hx_author_profile_action",
+            ),
+        ])
+    ),
+]
diff --git a/scipost_django/edadmin/views/preassignment.py b/scipost_django/edadmin/views/preassignment.py
new file mode 100644
index 0000000000000000000000000000000000000000..c6785e88d5f0bcfac75ebce433aca7dc8e5db45f
--- /dev/null
+++ b/scipost_django/edadmin/views/preassignment.py
@@ -0,0 +1,136 @@
+__copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)"
+__license__ = "AGPL v3"
+
+
+from django.contrib.auth.decorators import login_required, user_passes_test
+from django.http import HttpResponse
+from django.shortcuts import get_object_or_404, render, redirect
+from django.urls import reverse
+
+from colleges.permissions import is_edadmin
+from profiles.models import Profile
+from profiles.forms import ProfileDynSelForm
+from submissions.models import Submission, SubmissionAuthorProfile
+
+
+###########################
+# Author Profile matching #
+###########################
+@login_required
+@user_passes_test(is_edadmin)
+def _hx_author_profiles_details_summary(request, identifier_w_vn_nr):
+    submission = get_object_or_404(
+        Submission, preprint__identifier_w_vn_nr=identifier_w_vn_nr
+    )
+    matches = submission.author_profiles.exclude(profile__isnull=True).count()
+    context = {
+        "submission": submission,
+        "matches": matches,
+    }
+    return render(
+        request,
+        "edadmin/preassignment/_hx_author_profiles_details_summary.html",
+        context,
+    )
+
+
+@login_required
+@user_passes_test(is_edadmin)
+def _hx_author_profiles_details_contents(request, identifier_w_vn_nr):
+    submission = get_object_or_404(
+        Submission, preprint__identifier_w_vn_nr=identifier_w_vn_nr
+    )
+    matches_list = [ (
+        author_string,
+        index + 1,
+        submission.author_profiles.filter(
+            order=index + 1,
+            profile__isnull=False,
+        ).first(),
+    ) for index, author_string in enumerate(submission.authors_as_list) ]
+
+    context = {
+        "submission": submission,
+        "matches_list": matches_list,
+    }
+    return render(
+        request,
+        "edadmin/preassignment/_hx_author_profiles_details_contents.html",
+        context,
+    )
+
+
+@login_required
+@user_passes_test(is_edadmin)
+def _hx_author_profile_row(request, identifier_w_vn_nr, order: int):
+    submission = get_object_or_404(
+        Submission, preprint__identifier_w_vn_nr=identifier_w_vn_nr
+    )
+    author_string = submission.authors_as_list[order-1]
+    profile = submission.author_profiles.filter(
+            order=order,
+            profile__isnull=False,
+    ).first()
+    context = {
+        "submission": submission,
+        "author_string": author_string,
+        "order": order,
+        "profile": profile,
+    }
+    if profile is None:
+        profile_dynsel_form = ProfileDynSelForm(
+            initial={
+                "q": author_string.rpartition(". ")[2],
+                "action_url_name": "edadmin:preassignment:_hx_author_profile_action",
+                "action_url_base_kwargs": {
+                    "identifier_w_vn_nr": identifier_w_vn_nr,
+                    "order": order,
+                    "action": "match",
+                },
+                "action_target_element_id":
+                f"submission-{submission.pk}-author-profile-row-{order}",
+                "action_target_swap": "outerHTML",
+            }
+        )
+        context["profile_dynsel_form"] = profile_dynsel_form
+    response = render(
+        request,
+        "edadmin/preassignment/_hx_author_profile_row.html",
+        context,
+    )
+    response["HX-Trigger-After-Settle"] = f"submission-{submission.pk}-author-profiles-details-updated"
+    return response
+
+
+@login_required
+@user_passes_test(is_edadmin)
+def _hx_author_profile_action(
+        request,
+        identifier_w_vn_nr,
+        order,
+        profile_id,
+        action: str="match",
+):
+    submission = get_object_or_404(
+        Submission, preprint__identifier_w_vn_nr=identifier_w_vn_nr
+    )
+    profile = get_object_or_404(Profile, pk=profile_id)
+    author_profile, created = SubmissionAuthorProfile.objects.get_or_create(
+        submission=submission,
+        order=order,
+    )
+    if action == "match":
+        author_profile.profile = profile
+    elif action == "unmatch":
+        author_profile.profile = None
+    author_profile.save()
+    response = redirect(
+        reverse(
+            "edadmin:preassignment:_hx_author_profile_row",
+            kwargs={
+                "identifier_w_vn_nr": identifier_w_vn_nr,
+                "order": order,
+            }
+        )
+    )
+    return response
diff --git a/scipost_django/profiles/forms.py b/scipost_django/profiles/forms.py
index d720b08e41c0c2445acfc511dff1c724ac540c0f..c9f2f218300d37986c07c0a8b151da0ada3dcb26 100644
--- a/scipost_django/profiles/forms.py
+++ b/scipost_django/profiles/forms.py
@@ -229,6 +229,7 @@ class ProfileDynSelForm(forms.Form):
     action_url_name = forms.CharField()
     action_url_base_kwargs = forms.JSONField(required=False)
     action_target_element_id = forms.CharField()
+    action_target_swap = forms.CharField()
 
     def __init__(self, *args, **kwargs):
         super().__init__(*args, **kwargs)
@@ -238,6 +239,7 @@ class ProfileDynSelForm(forms.Form):
             Field("action_url_name", type="hidden"),
             Field("action_url_base_kwargs", type="hidden"),
             Field("action_target_element_id", type="hidden"),
+            Field("action_target_swap", type="hidden"),
         )
 
     def search_results(self):
diff --git a/scipost_django/profiles/templates/profiles/_hx_profile_dynsel_list.html b/scipost_django/profiles/templates/profiles/_hx_profile_dynsel_list.html
index 1a850fd67a444afef387ccd5a0d68a9ba27cfb88..a665da83b40d6e91ebb38ab67ecf48fccbd5a19c 100644
--- a/scipost_django/profiles/templates/profiles/_hx_profile_dynsel_list.html
+++ b/scipost_django/profiles/templates/profiles/_hx_profile_dynsel_list.html
@@ -9,6 +9,7 @@
 	<a
 	    hx-get="{% profile_dynsel_action_url profile %}"
 	    hx-target="#{{ action_target_element_id }}"
+	    hx-swap="{{ action_target_swap }}"
 	    hx-indicator="#{{ action_target_element_id }}-indicator"
 	>
 	  {{ profile }}
diff --git a/scipost_django/profiles/views.py b/scipost_django/profiles/views.py
index 810cc72812056448749ec6eb957211bda81bb278..b82026056913a7de13e84f4c89161b6060874118 100644
--- a/scipost_django/profiles/views.py
+++ b/scipost_django/profiles/views.py
@@ -350,6 +350,7 @@ def _hx_profile_dynsel_list(request):
             else {}
         ),
         "action_target_element_id": form.cleaned_data["action_target_element_id"],
+        "action_target_swap": form.cleaned_data["action_target_swap"],
     }
     return render(request, "profiles/_hx_profile_dynsel_list.html", context)
 
diff --git a/scipost_django/submissions/admin.py b/scipost_django/submissions/admin.py
index e7c927af9df588c659d6d683c816e714eba1adab..dd910f0d71e74d52d73287cc558d543231dd889c 100644
--- a/scipost_django/submissions/admin.py
+++ b/scipost_django/submissions/admin.py
@@ -9,6 +9,7 @@ from django import forms
 from guardian.admin import GuardedModelAdmin
 
 from submissions.models import (
+    SubmissionAuthorProfile,
     Submission,
     EditorialAssignment,
     RefereeInvitation,
@@ -73,6 +74,15 @@ class QualificationInline(admin.StackedInline):
     ]
 
 
+class SubmissionAuthorProfileInline(admin.TabularInline):
+    model = SubmissionAuthorProfile
+    extra = 0
+    autocomplete_fields = [
+        "profile",
+        "affiliations",
+    ]
+
+
 class SubmissionTieringInline(admin.StackedInline):
     model = SubmissionTiering
     extra = 0
@@ -123,6 +133,7 @@ class SubmissionAdmin(GuardedModelAdmin):
     inlines = [
         InternalPlagiarismAssessmentInline,
         iThenticatePlagiarismAssessmentInline,
+        SubmissionAuthorProfileInline,
         QualificationInline,
         SubmissionTieringInline,
     ]
diff --git a/scipost_django/submissions/migrations/0135_submissionauthorprofile.py b/scipost_django/submissions/migrations/0135_submissionauthorprofile.py
new file mode 100644
index 0000000000000000000000000000000000000000..fe73d07a3f4f263fa0a73820ca533d56f5c21a97
--- /dev/null
+++ b/scipost_django/submissions/migrations/0135_submissionauthorprofile.py
@@ -0,0 +1,29 @@
+# Generated by Django 3.2.16 on 2023-01-18 08:14
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('profiles', '0035_alter_profile_title'),
+        ('organizations', '0019_auto_20220314_0723'),
+        ('submissions', '0134_rename_status_qualification_expertise_level'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='SubmissionAuthorProfile',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('order', models.PositiveSmallIntegerField()),
+                ('affiliations', models.ManyToManyField(blank=True, to='organizations.Organization')),
+                ('profile', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='profiles.profile')),
+                ('submission', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='author_profiles', to='submissions.submission')),
+            ],
+            options={
+                'ordering': ('submission', 'order'),
+            },
+        ),
+    ]
diff --git a/scipost_django/submissions/migrations/0136_alter_submissionauthorprofile_profile.py b/scipost_django/submissions/migrations/0136_alter_submissionauthorprofile_profile.py
new file mode 100644
index 0000000000000000000000000000000000000000..c69c30493123165b124a2d4ffe56190cea4cd8ba
--- /dev/null
+++ b/scipost_django/submissions/migrations/0136_alter_submissionauthorprofile_profile.py
@@ -0,0 +1,20 @@
+# Generated by Django 3.2.16 on 2023-01-18 08:24
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('profiles', '0035_alter_profile_title'),
+        ('submissions', '0135_submissionauthorprofile'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='submissionauthorprofile',
+            name='profile',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='profiles.profile'),
+        ),
+    ]
diff --git a/scipost_django/submissions/models/__init__.py b/scipost_django/submissions/models/__init__.py
index 0add63fac87c27719056a2298815f4a3694cf203..5963d6b9b2213b5ad1a4c90f49fe5c7720b3195d 100644
--- a/scipost_django/submissions/models/__init__.py
+++ b/scipost_django/submissions/models/__init__.py
@@ -2,7 +2,12 @@ __copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)"
 __license__ = "AGPL v3"
 
 
-from .submission import Submission, SubmissionEvent, SubmissionTiering
+from .submission import (
+    SubmissionAuthorProfile,
+    Submission,
+    SubmissionEvent,
+    SubmissionTiering,
+)
 
 from .plagiarism_assessment import (
     PlagiarismAssessment,
diff --git a/scipost_django/submissions/models/submission.py b/scipost_django/submissions/models/submission.py
index 13cd9f55dca5a0188faed282168c513206c7f6ab..1626d20e9e17fc4e031ce62cc24b20a77db8a766 100644
--- a/scipost_django/submissions/models/submission.py
+++ b/scipost_django/submissions/models/submission.py
@@ -41,6 +41,47 @@ from ..managers import SubmissionQuerySet, SubmissionEventQuerySet
 from ..refereeing_cycles import ShortCycle, DirectCycle, RegularCycle
 
 
+class SubmissionAuthorProfile(models.Model):
+
+    submission = models.ForeignKey(
+        "submissions.Submission",
+        on_delete=models.CASCADE,
+        related_name="author_profiles",
+    )
+    profile = models.ForeignKey(
+        "profiles.Profile", on_delete=models.PROTECT, blank=True, null=True,
+    )
+    affiliations = models.ManyToManyField("organizations.Organization", blank=True)
+    order = models.PositiveSmallIntegerField()
+
+    class Meta:
+        ordering = ("submission", "order",)
+
+    def __str__(self):
+        return str(self.profile)
+
+    def save(self, *args, **kwargs):
+        """Auto increment order number if not explicitly set."""
+        if not self.order:
+            self.order = self.submission.author_profiles.count() + 1
+        return super().save(*args, **kwargs)
+
+    @property
+    def is_registered(self):
+        """Check if author is registered at SciPost."""
+        return self.profile.contributor is not None
+
+    @property
+    def first_name(self):
+        """Return first name of author."""
+        return self.profile.first_name
+
+    @property
+    def last_name(self):
+        """Return last name of author."""
+        return self.profile.last_name
+
+
 class Submission(models.Model):
     """
     A Submission is a preprint sent to SciPost for consideration.