diff --git a/src/api/urls.py b/src/api/urls.py
index 3380c8feddd87d2ff933b48ea371b43cdd5e1501..666bda2725bef79cca5a911e64f0e94e23dceee4 100644
--- a/src/api/urls.py
+++ b/src/api/urls.py
@@ -41,6 +41,8 @@ urlpatterns = [
     path('map/assemblies/poi.json', maps.AssembliesPoiExportView.as_view(), name='map-assemblies-poi'),
     path('map/assemblies/areas.json', maps.AssembliesAreasExportView.as_view(), name='map-assemblies-areas'),
     path('badges/redeem_token', badges.redeem_badge_token, name='badge-redeem'),
+    path('badge/<uuid:pk>/award/user', badges.reward_badge_to_username, name='badge-award-username'),
+    path('badge/<uuid:pk>/award/dect', badges.reward_badge_to_dect, name='badge-award-dect'),
     path('rooms', rooms.ConferenceRoomList.as_view(), name='room-list'),
     path('room/<uuid:pk>/', rooms.ConferenceRoomDetail.as_view(), name='room-detail'),
     path('room/<uuid:pk>/schedule', schedule.RoomSchedule.as_view(), name='room-schedule'),
diff --git a/src/api/views/badges.py b/src/api/views/badges.py
index a9d9789ac1f67e03a80319b836dcc9016061c83a..e19fc17f1cdf320195f31537bf6e09d0706f73f7 100644
--- a/src/api/views/badges.py
+++ b/src/api/views/badges.py
@@ -8,9 +8,9 @@ from rest_framework.response import Response
 from django.http import HttpResponse
 from django.shortcuts import get_object_or_404
 
-from core.models.badges import Badge, BadgeToken
+from core.models.badges import Badge, BadgeToken, UserBadge
 from core.models.conference import Conference
-from core.models.users import PlatformUser
+from core.models.users import PlatformUser, UserCommunicationChannel
 
 from api.permissions import HasIssuingToken, IsAssemblyManager, IsSuperUser
 from api.serializers import BadgeSerializer, BadgeTokenSerializer
@@ -79,3 +79,34 @@ def redeem_badge_token(request, conference, **kwargs):
     badge_token.redeem(user, False)
 
     return Response({'badge': f'{badge_token.badge}', 'user': f'{user.username}'})
+
+
+@api_view(['POST'])
+def reward_badge_to_username(request, **kwargs):
+    badge = get_object_or_404(Badge, id=kwargs.get('pk'))
+    if not badge.issuing_assembly.user_can_manage(request.user):
+        return HttpResponse(status=403)
+    username = request.data.get('username', None)
+    user = get_object_or_404(PlatformUser, username__iexact=username, is_active=True)
+    UserBadge.objects.redeem_badge(user=user, badge=badge, issuer=request.user)
+    return Response({'badge': f'{badge.name}', 'rewarded': True})
+
+
+@api_view(['POST'])
+def reward_badge_to_dect(request, **kwargs):
+    badge = get_object_or_404(Badge, pk=kwargs.get('pk'))
+    if not badge.issuing_assembly.user_can_manage(request.user):
+        return HttpResponse(status=403)
+    dect = request.data.get('dect', None)
+    if dect is None:
+        return HttpResponse(status=400)
+    try:
+        dect = int(dect)
+    except ValueError:
+        return HttpResponse(status=400)
+    try:
+        user = get_object_or_404(UserCommunicationChannel, address=dect).user
+    except UserCommunicationChannel.MultipleObjectsReturned:
+        return Response({'error': 'Unique user cannot be found through dect'}, status=400)
+    UserBadge.objects.redeem_badge(user=user, badge=badge, issuer=request.user)
+    return Response({'badge': f'{badge.name}', 'rewarded': True})
diff --git a/src/core/locale/de/LC_MESSAGES/django.po b/src/core/locale/de/LC_MESSAGES/django.po
index 5f859b6dbd58c8f833ba236dd80a63ccaa6c2602..8e142a60abb8524b7f265c0fe8d1fd02acbbfeb1 100644
--- a/src/core/locale/de/LC_MESSAGES/django.po
+++ b/src/core/locale/de/LC_MESSAGES/django.po
@@ -2351,6 +2351,9 @@ msgstr "Adresse öffentlich anzeigen"
 msgid "UserCommunicationChannel__show_public"
 msgstr "öffentlich"
 
+msgid "UserCommunicationChannel__cannot_notify__dect"
+msgstr "Dieser Kanal kann nicht für Benachrichtigungen benutzt werden."
+
 msgid "UserCommunicationChannel__cannot_notify__phone"
 msgstr "Eine Benachrichtigung per Telefon wird nicht unterstützt."
 
diff --git a/src/core/locale/en/LC_MESSAGES/django.po b/src/core/locale/en/LC_MESSAGES/django.po
index a2be9e62b7a53bc5502bfd2de34bbe866affb35d..1703787ba58c3ea7cc8ec4e037041a0b7aa1d8ad 100644
--- a/src/core/locale/en/LC_MESSAGES/django.po
+++ b/src/core/locale/en/LC_MESSAGES/django.po
@@ -2349,6 +2349,9 @@ msgstr "show this address publicly"
 msgid "UserCommunicationChannel__show_public"
 msgstr "public"
 
+msgid "UserCommunicationChannel__cannot_notify__dect"
+msgstr "cannot use this channel for notifications"
+
 msgid "UserCommunicationChannel__cannot_notify__phone"
 msgstr "notifications via phone/mobile are not supported"
 
diff --git a/src/core/models/users.py b/src/core/models/users.py
index 0ab6c716e25656a7d98b1e212303066f19a94872..9b73e9633d196cfb91c0430909d832796d49793e 100644
--- a/src/core/models/users.py
+++ b/src/core/models/users.py
@@ -563,6 +563,17 @@ class UserCommunicationChannel(models.Model):
         if url.host is None or url.path is None:
             raise ValidationError({'address': 'Expected valid URL.'})
 
+    @staticmethod
+    def validate_dect(address):
+        try:
+            if len(str(address)) > 10:
+                raise ValidationError({'address': 'Dect may not be longer than 10 chars.'})
+            if address[0] == '0':
+                raise ValidationError({'address': 'Dect must not start with a 0.'})
+            int(address)
+        except ValueError:
+            raise ValidationError({'address': 'Dect must be a number.'})
+
     @property
     def can_notify(self):
         """Signals whether this channel can be used for notifications."""
@@ -571,19 +582,21 @@ class UserCommunicationChannel(models.Model):
     def clean(self):
         super().clean()
 
-        if self.channel == self.Channel.MAIL:
-            self.validate_email(self.address)
-
-        elif self.channel == self.Channel.MATRIX:
-            self.validate_matrix_room_url(self.address)
-
-        elif self.channel == self.Channel.PHONE:
-            self.validate_phone_number(self.address)
-            if self.use_for_notifications:
-                raise ValidationError({'use_for_notifications': _('UserCommunicationChannel__cannot_notify__phone')})
-
-        elif self.channel == self.Channel.ACTIVITYPUB:
-            self.validate_activitypub_url(self.address)
+        match self.channel:
+            case self.Channel.MAIL:
+                self.validate_email(self.address)
+            case self.Channel.MATRIX:
+                self.validate_matrix_room_url(self.address)
+            case self.Channel.DECT:
+                self.validate_dect(self.address)
+                if self.use_for_notifications:
+                    raise ValidationError({'use_for_notifications': _('UserCommunicationChannel__cannot_notify__dect')})
+            case self.Channel.PHONE:
+                self.validate_phone_number(self.address)
+                if self.use_for_notifications:
+                    raise ValidationError({'use_for_notifications': _('UserCommunicationChannel__cannot_notify__phone')})
+            case self.Channel.ACTIVITYPUB:
+                self.validate_activitypub_url(self.address)
 
         # TODO: verify the other channel types for correct syntax as well
 
diff --git a/src/plainui/forms.py b/src/plainui/forms.py
index 2f62412aabd617da3e5de06bbd872d2510183a48..bb7c18cc802f79fb1564501792e6dc24b9a7629c 100644
--- a/src/plainui/forms.py
+++ b/src/plainui/forms.py
@@ -92,6 +92,8 @@ class ExampleForm(forms.Form):
 
 
 class ProfileEditForm(TranslatedFieldsForm):
+    dect = forms.IntegerField(required=False)
+
     class Meta:
         model = PlatformUser
         fields = [
@@ -99,6 +101,29 @@ class ProfileEditForm(TranslatedFieldsForm):
             'timezone',
         ]
 
+    def __init__(self, *args, instance, **kwargs):
+        super().__init__(*args, instance=instance, **kwargs)
+
+        dect_channel = UserCommunicationChannel.objects.filter(
+            user=instance,
+            channel=UserCommunicationChannel.Channel.DECT,
+        ).first()
+        if dect_channel:
+            self.fields['dect'].initial = dect_channel.address
+
+    def clean_dect(self):
+        dect = self.cleaned_data['dect']
+        # TODO: De-Duplicate with UserCommunicationChannel
+        try:
+            if len(str(dect)) > 10:
+                raise ValidationError('Dect may not be longer than 10 chars.')
+            if str(dect)[0] == '0':
+                raise ValidationError('Dect must not start with a 0.')
+            int(dect)
+        except ValueError:
+            raise ValidationError('Dect must be a number.')
+        return dect
+
 
 class ProfileDescriptionEditForm(TranslatedFieldsForm):
     class Meta:
diff --git a/src/plainui/jinja2/plainui/components/form_elements.html.j2 b/src/plainui/jinja2/plainui/components/form_elements.html.j2
index 6da3b51b269bedaed4a4c2530e6c9b94e09292d1..facb377b6000a23112675155a29cc4dd31ee6a6f 100644
--- a/src/plainui/jinja2/plainui/components/form_elements.html.j2
+++ b/src/plainui/jinja2/plainui/components/form_elements.html.j2
@@ -37,6 +37,9 @@
 {% macro password(form, name) -%}
   {{ input(form, name, 'password') }}
 {%- endmacro %}
+{% macro number(form, name) -%}
+  {{ input(form, name, 'number') }}
+{%- endmacro %}
 {% macro textarea(form, name) -%}
   {% set el = form[name] -%}
   {% set my_id = unique_id() -%}
@@ -132,6 +135,8 @@
     {{ text(form, field_name) }}
   {% elif field.widget_type == 'password' -%}
     {{ password(form, field_name) }}
+  {% elif field.widget_type == 'number' -%}
+    {{ number(form, field_name) }}
   {% elif field.widget_type == 'checkbox' -%}
     {{ checkbox(form, field_name) }}
   {% elif field.widget_type == 'select' -%}
diff --git a/src/plainui/tests/test_views.py b/src/plainui/tests/test_views.py
index 373612288a64e6f8ff33971397c0008aeffa76c6..daef90c5d063f83c0ba48c23a374ea360c708c6f 100644
--- a/src/plainui/tests/test_views.py
+++ b/src/plainui/tests/test_views.py
@@ -47,6 +47,7 @@ from core.models import (
     StaticPageRevision,
     TagItem,
     UserBadge,
+    UserCommunicationChannel,
     UserDereferrerAllowlist,
 )
 from core.templatetags.hub_absolute import hub_absolute
@@ -1297,6 +1298,7 @@ class ViewsTest(ViewsTestBase):
                 'default_badge_visibility': 'private',
                 'pronouns': 'they',
                 'timezone': 'Europe/Berlin',
+                'dect': '1337',
             },
         )
         self.assertRedirects(resp, reverse('plainui:userprofile'))
@@ -1307,6 +1309,7 @@ class ViewsTest(ViewsTestBase):
         self.assertEqual(self.user.pronouns, 'they')
         self.assertEqual(self.user.timezone.key, 'Europe/Berlin')
         self.assertSetsMessage(resp, 'Updated Profile')
+        self.assertTrue(UserCommunicationChannel.objects.filter(user=self.user, channel=UserCommunicationChannel.Channel.DECT, address='1337').exists())
 
     @override_locale('en')
     def test_ModifyThemeView_get(self):
diff --git a/src/plainui/views/user_profile.py b/src/plainui/views/user_profile.py
index 2ba4f6639f95afdd467d5096e9c27499613882b2..cbf955451a7ed6d18c2e22f6fce1f5fe6e397992 100644
--- a/src/plainui/views/user_profile.py
+++ b/src/plainui/views/user_profile.py
@@ -24,6 +24,7 @@ from core.models import (
     Event,
     Project,
     UserBadge,
+    UserCommunicationChannel,
     UserDereferrerAllowlist,
 )
 from core.sso import SSO
@@ -120,6 +121,20 @@ class ProfileView(ConferenceRequiredMixin, UpdateView):
         form1.instance.timezone = form1.cleaned_data['timezone']
         form1.instance.save()
 
+        if form1.cleaned_data['dect']:
+            UserCommunicationChannel.objects.update_or_create(
+                user=self.request.user,
+                channel=UserCommunicationChannel.Channel.DECT,
+                defaults={'address': form1.cleaned_data['dect']},
+            )
+        else:
+            dect_channel = UserCommunicationChannel.objects.filter(
+                user=self.request.user,
+                channel=UserCommunicationChannel.Channel.DECT,
+            )
+            if dect_channel.exists():
+                dect_channel.delete()
+
         # TODO: Update after deciding oh one or more conferences in #648
         cm = form1.instance.conferences.filter(conference=self.conf).first()
         if cm: