diff --git a/backend/alembic/versions/cef049467e32_study_info.py b/backend/alembic/versions/cef049467e32_study_info.py
new file mode 100644
index 0000000000000000000000000000000000000000..76a972c9cce2d3c7f9b61606b4ed1db0dce3f228
--- /dev/null
+++ b/backend/alembic/versions/cef049467e32_study_info.py
@@ -0,0 +1,27 @@
+"""Study info
+
+Revision ID: cef049467e32
+Revises: c4ff1cfa66b7
+Create Date: 2025-03-13 00:19:21.655377
+
+"""
+
+from typing import Sequence, Union
+
+from alembic import op
+import sqlalchemy as sa
+
+
+# revision identifiers, used by Alembic.
+revision: str = "cef049467e32"
+down_revision: Union[str, None] = "c4ff1cfa66b7"
+branch_labels: Union[str, Sequence[str], None] = None
+depends_on: Union[str, Sequence[str], None] = None
+
+
+def upgrade() -> None:
+    pass
+
+
+def downgrade() -> None:
+    op.drop_table("study_infos")
diff --git a/backend/app/crud/studies.py b/backend/app/crud/studies.py
index 5848676a762371bbc15532eaa4dfc1ceb4703b19..ce4923c55c3566c4a7ad3b2df2b4c87737ad012f 100644
--- a/backend/app/crud/studies.py
+++ b/backend/app/crud/studies.py
@@ -242,3 +242,15 @@ def download_study_wide(db: Session, study_id: int):
             "Content-Disposition": f"attachment; filename={study_id}-surveys-wide.csv"
         },
     )
+
+
+def create_study_info(
+    db: Session, study_id: int, study_info: schemas.StudyInfoCreate
+) -> models.StudyInfo:
+    db_study_info = models.StudyInfo(
+        study_id=study_id, **study_info.dict(exclude_unset=True)
+    )
+    db.add(db_study_info)
+    db.commit()
+    db.refresh(db_study_info)
+    return db_study_info
diff --git a/backend/app/models/studies.py b/backend/app/models/studies.py
index 4882e1437ed31050376b6da97705dabf263eeca8..89df185a231487905bda032b0be2f5fb01880119 100644
--- a/backend/app/models/studies.py
+++ b/backend/app/models/studies.py
@@ -42,3 +42,15 @@ class StudyTest(Base):
 
     study_id = Column(Integer, ForeignKey("studies.id"), primary_key=True)
     test_id = Column(Integer, ForeignKey("tests.id"), primary_key=True)
+
+
+class StudyInfo(Base):
+    __tablename__ = "study_infos"
+    id = Column(Integer, primary_key=True, index=True)
+    study_id = Column(Integer, ForeignKey("studies.id"))
+    rid = Column(String)
+    birthyear = Column(Integer)
+    gender = Column(String)
+    primary_language = Column(String)
+    other_languages = Column(String)
+    education = Column(String)
diff --git a/backend/app/routes/studies.py b/backend/app/routes/studies.py
index 04411b25ef7a1a6850a6fb65d0efc85379a62fac..d4ce1f466dca0b03771aa8b917440fd2f46b9fc8 100644
--- a/backend/app/routes/studies.py
+++ b/backend/app/routes/studies.py
@@ -75,7 +75,7 @@ def download_study(
 
 @require_admin("You do not have permission to download this study.")
 @studiesRouter.get("/{study_id}/download/surveys-wide")
-def download_study(
+def download_study_wide(
     study_id: int,
     db: Session = Depends(get_db),
 ):
@@ -83,3 +83,12 @@ def download_study(
     if study is None:
         raise HTTPException(status_code=404, detail="Study not found")
     return crud.download_study_wide(db, study_id)
+
+
+@studiesRouter.post("/{study_id}/info", status_code=status.HTTP_201_CREATED)
+def create_study_info(
+    study_id: int,
+    study_info: schemas.StudyInfoCreate,
+    db: Session = Depends(get_db),
+):
+    return crud.create_study_info(db, study_id, study_info)
diff --git a/backend/app/schemas/studies.py b/backend/app/schemas/studies.py
index 6dbeac99f9d72c5711d8919986976ea67348521c..9fbe529fd437df088e9bd56af0fd90feda61caaa 100644
--- a/backend/app/schemas/studies.py
+++ b/backend/app/schemas/studies.py
@@ -39,3 +39,12 @@ class Study(BaseModel):
 
     users: list[User] = []
     tests: list[Test] = []
+
+
+class StudyInfoCreate(BaseModel):
+    rid: str
+    birthyear: int
+    gender: str
+    primary_language: str
+    other_languages: str
+    education: str
diff --git a/frontend/src/lang/fr.json b/frontend/src/lang/fr.json
index 4b2ad4ce880860ae93e5c9d58b230caddf0d49c5..8136121e3ac9a7486fa2913320c466af4a30731c 100644
--- a/frontend/src/lang/fr.json
+++ b/frontend/src/lang/fr.json
@@ -386,6 +386,7 @@
 			"study": "Étude",
 			"code": "Code",
 			"tests": "Tests",
+			"infos": "Informations",
 			"end": "Fin"
 		},
 		"complete": "Merci pour votre participation !",
diff --git a/frontend/src/lib/api/studies.ts b/frontend/src/lib/api/studies.ts
index 8d116735240085b24236b33e788c7db7cfb4f8ea..f69eeb1430a2459d0b798f6b394fe0b555311e53 100644
--- a/frontend/src/lib/api/studies.ts
+++ b/frontend/src/lib/api/studies.ts
@@ -111,3 +111,29 @@ export async function createTestTypingAPI(
 
 	return parseInt(await response.text());
 }
+
+export async function sendStudyResponseInfoAPI(
+	fetch: fetchType,
+	survey_id: number,
+	rid: string,
+	birthyear: number,
+	gender: string,
+	primary_language: string,
+	other_languages: string,
+	education: string
+) {
+	const response = await fetch(`/api/studies/${survey_id}/info`, {
+		method: 'POST',
+		headers: { 'Content-Type': 'application/json' },
+		body: JSON.stringify({
+			rid,
+			birthyear,
+			gender,
+			primary_language,
+			other_languages,
+			education
+		})
+	});
+
+	return response.ok;
+}
diff --git a/frontend/src/lib/api/survey.ts b/frontend/src/lib/api/survey.ts
index cebdca2986c9f9ceaa59e571820896aec0a555ad..f600aacb96b48d4c6371a4054fa12b40d2813053 100644
--- a/frontend/src/lib/api/survey.ts
+++ b/frontend/src/lib/api/survey.ts
@@ -50,29 +50,3 @@ export async function getSurveyScoreAPI(fetch: fetchType, survey_id: number, sid
 
 	return await response.json();
 }
-
-export async function sendSurveyResponseInfoAPI(
-	fetch: fetchType,
-	survey_id: number,
-	sid: string,
-	birthyear: number,
-	gender: string,
-	primary_language: string,
-	other_language: string,
-	education: string
-) {
-	const response = await fetch(`/api/tests/info/${survey_id}`, {
-		method: 'POST',
-		headers: { 'Content-Type': 'application/json' },
-		body: JSON.stringify({
-			sid,
-			birthyear,
-			gender,
-			primary_language,
-			other_language,
-			education
-		})
-	});
-
-	return response.ok;
-}
diff --git a/frontend/src/lib/components/surveys/endQuestions.svelte b/frontend/src/lib/components/surveys/endQuestions.svelte
new file mode 100644
index 0000000000000000000000000000000000000000..b3084a262d7a5e2ecf724c3994979901ef61a8b6
--- /dev/null
+++ b/frontend/src/lib/components/surveys/endQuestions.svelte
@@ -0,0 +1,145 @@
+<script lang="ts">
+	import { sendStudyResponseInfoAPI } from '$lib/api/studies';
+	import config from '$lib/config';
+	import { t } from '$lib/services/i18n';
+	import { toastAlert } from '$lib/utils/toasts';
+	import Dropdown from './dropdown.svelte';
+
+	let {
+		study_id,
+		rid,
+		onFinish = () => {}
+	}: { study_id: number; rid: string; onFinish: Function } = $props();
+
+	let step = $state(0);
+
+	const genderOptions = [
+		{ value: 'male', label: $t('surveys.genders.male') },
+		{ value: 'female', label: $t('surveys.genders.female') },
+		{ value: 'other', label: $t('surveys.genders.other') },
+		{ value: 'na', label: $t('surveys.genders.na') }
+	];
+
+	let birthYear = '';
+	let gender = '';
+	let primaryLanguage = '';
+	let other_language = '';
+	let education = '';
+
+	let selectedOption: any = $state();
+
+	async function send() {
+		if (
+			!(await sendStudyResponseInfoAPI(
+				fetch,
+				study_id,
+				rid,
+				parseInt(birthYear),
+				gender,
+				primaryLanguage,
+				other_language,
+				education
+			))
+		) {
+			toastAlert($t('surveys.info.error'));
+		} else {
+			onFinish();
+		}
+	}
+</script>
+
+{#if step === 0}
+	<div class="mx-auto mt-16 text-center px-4">
+		<p class="text-center font-bold py-4 px-6 m-auto">{$t('surveys.birthYear')}</p>
+		<Dropdown
+			values={Array.from({ length: 82 }, (_, i) => {
+				const year = 1931 + i;
+				return { value: year, display: year };
+			}).reverse()}
+			bind:option={selectedOption}
+			placeholder={$t('surveys.birthYear')}
+			funct={() => {
+				birthYear = selectedOption;
+				step++;
+			}}
+		></Dropdown>
+	</div>
+{:else if step === 1}
+	<div class="mx-auto mt-16 text-center px-4">
+		<p class="text-center font-bold py-4 px-6 m-auto">{$t('surveys.gender')}</p>
+		<div class="flex flex-col items-center space-y-4">
+			{#each genderOptions as { value, label }}
+				<label class="radio-label flex items-center space-x-2">
+					<input
+						type="radio"
+						name="gender"
+						{value}
+						onchange={() => {
+							gender = value;
+							step++;
+						}}
+						required
+						class="radio-button"
+					/>
+					<span>{label}</span>
+				</label>
+			{/each}
+		</div>
+	</div>
+{:else if step === 2}
+	<div class="mx-auto mt-16 text-center px-4">
+		<p class="text-center font-bold py-4 px-6 m-auto">{$t('surveys.homeLanguage')}</p>
+		<Dropdown
+			values={Object.entries(config.PRIMARY_LANGUAGE).map(([code, name]) => ({
+				value: code,
+				display: name
+			}))}
+			bind:option={selectedOption}
+			placeholder={$t('surveys.homeLanguage')}
+			funct={() => {
+				primaryLanguage = selectedOption;
+				step++;
+			}}
+		></Dropdown>
+	</div>
+{:else if step === 3}
+	<div class="mx-auto mt-16 text-center px-4">
+		<p class="text-center font-bold py-4 px-6 m-auto">{$t('surveys.otherLanguage')}</p>
+		<p class="mb-6 text-sm text-gray-600 text-center">{$t('surveys.otherLanguageNote')}</p>
+		<Dropdown
+			values={[
+				{ value: 'none', display: '/' },
+				...Object.entries(config.PRIMARY_LANGUAGE).map(([code, name]) => ({
+					value: code,
+					display: name
+				}))
+			]}
+			bind:option={selectedOption}
+			placeholder={$t('surveys.otherLanguage')}
+			funct={() => {
+				other_language = selectedOption;
+				step++;
+			}}
+		></Dropdown>
+	</div>
+{:else if step === 4}
+	<div class="mx-auto mt-16 text-center px-4">
+		<p class="text-center font-bold py-4 px-6 m-auto">{$t('surveys.education.title')}</p>
+		<Dropdown
+			values={[
+				{ value: 'NoEducation', display: $t('surveys.education.NoEducation') },
+				{ value: 'PrimarySchool', display: $t('surveys.education.PrimarySchool') },
+				{ value: 'SecondarySchool', display: $t('surveys.education.SecondarySchool') },
+				{ value: 'NonUni', display: $t('surveys.education.NonUni') },
+				{ value: 'Bachelor', display: $t('surveys.education.Bachelor') },
+				{ value: 'Master', display: $t('surveys.education.Master') }
+			]}
+			bind:option={selectedOption}
+			placeholder={$t('surveys.education.title')}
+			funct={() => {
+				education = selectedOption;
+				send();
+			}}
+		></Dropdown>
+	</div>
+{/if}
diff --git a/frontend/src/routes/studies/[[id]]/+page.svelte b/frontend/src/routes/studies/[[id]]/+page.svelte
index 81ae73c2e4e51fbb8b6f2ee807f44f09f0aa85de..358954930a8a5e2eebebdc4906cf7e764e181d88 100644
--- a/frontend/src/routes/studies/[[id]]/+page.svelte
+++ b/frontend/src/routes/studies/[[id]]/+page.svelte
@@ -9,6 +9,7 @@
 	import { TestTask, TestTyping } from '$lib/types/tests';
 	import Typingbox from '$lib/components/tests/typingbox.svelte';
 	import { getTestEntriesScoreAPI } from '$lib/api/tests';
+	import EndQuestions from '$lib/components/surveys/endQuestions.svelte';
 
 	let { data, form }: { data: PageData; form: FormData } = $props();
 	let study: Study | undefined = $state(data.study);
@@ -63,6 +64,9 @@
 			</li>
 		{/if}
 		<li class="step" class:step-primary={study && current_step >= study.tests.length + 2}>
+			{$t('studies.tab.infos')}
+		</li>
+		<li class="step" class:step-primary={study && current_step >= study.tests.length + 3}>
 			{$t('studies.tab.end')}
 		</li>
 	</ul>
@@ -158,6 +162,10 @@
 				{/if}
 			{/key}
 		{:else if current_step == study.tests.length + 2}
+			<div class="flex flex-col h-full">
+				<EndQuestions study_id={study.id} {rid} onFinish={() => current_step++} />
+			</div>
+		{:else if current_step == study.tests.length + 3}
 			<div class="flex flex-col h-full">
 				<div class="flex-grow text-center mt-16">
 					<span>{$t('studies.complete')}</span>