diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/Room.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/Room.kt
index 8031fcaeea..de360c89c6 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/Room.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/Room.kt
@@ -28,6 +28,7 @@ import org.matrix.android.sdk.api.session.room.model.LocalRoomSummary
 import org.matrix.android.sdk.api.session.room.model.RoomSummary
 import org.matrix.android.sdk.api.session.room.model.relation.RelationService
 import org.matrix.android.sdk.api.session.room.notification.RoomPushRuleService
+import org.matrix.android.sdk.api.session.room.poll.PollHistoryService
 import org.matrix.android.sdk.api.session.room.read.ReadService
 import org.matrix.android.sdk.api.session.room.reporting.ReportingService
 import org.matrix.android.sdk.api.session.room.send.DraftService
@@ -181,4 +182,9 @@ interface Room {
      * Get the LocationSharingService associated to this Room.
      */
     fun locationSharingService(): LocationSharingService
+
+    /**
+     * Get the PollHistoryService associated to this Room.
+     */
+    fun pollHistoryService(): PollHistoryService
 }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/poll/LoadedPollsStatus.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/poll/LoadedPollsStatus.kt
new file mode 100644
index 0000000000..d9347ff1d6
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/poll/LoadedPollsStatus.kt
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2023 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.matrix.android.sdk.api.session.room.poll
+
+/**
+ * Status to indicate loading of polls for a room.
+ */
+data class LoadedPollsStatus(
+        val canLoadMore: Boolean,
+        val nbLoadedDays: Int,
+)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/poll/PollHistoryService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/poll/PollHistoryService.kt
new file mode 100644
index 0000000000..e0e1477913
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/poll/PollHistoryService.kt
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2023 The Matrix.org Foundation C.I.C.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.matrix.android.sdk.api.session.room.poll
+
+import androidx.lifecycle.LiveData
+import org.matrix.android.sdk.api.session.room.model.PollResponseAggregatedSummary
+
+/**
+ * Expose methods to get history of polls in rooms.
+ */
+interface PollHistoryService {
+
+    val loadingPeriodInDays: Int
+
+    /**
+     * Ask to load more polls starting from last loaded polls for a period defined by
+     * [loadingPeriodInDays].
+     */
+    suspend fun loadMore(): LoadedPollsStatus
+
+    /**
+     * Indicate whether loading more polls is possible. If not possible,
+     * it indicates the end of the room has been reached in the past.
+     */
+    fun canLoadMore(): Boolean
+
+    /**
+     * Get the current status of the loaded polls.
+     */
+    fun getLoadedPollsStatus(): LoadedPollsStatus
+
+    /**
+     * Sync polls from last loaded polls until now.
+     */
+    suspend fun syncPolls()
+
+    /**
+     * Get currently loaded list of polls. See [loadMore].
+     */
+    fun getPolls(): LiveData<List<PollResponseAggregatedSummary>>
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoom.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoom.kt
index 262c111b73..3252dff0f7 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoom.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoom.kt
@@ -30,6 +30,7 @@ import org.matrix.android.sdk.api.session.room.model.RoomSummary
 import org.matrix.android.sdk.api.session.room.model.RoomType
 import org.matrix.android.sdk.api.session.room.model.relation.RelationService
 import org.matrix.android.sdk.api.session.room.notification.RoomPushRuleService
+import org.matrix.android.sdk.api.session.room.poll.PollHistoryService
 import org.matrix.android.sdk.api.session.room.read.ReadService
 import org.matrix.android.sdk.api.session.room.reporting.ReportingService
 import org.matrix.android.sdk.api.session.room.send.DraftService
@@ -72,6 +73,7 @@ internal class DefaultRoom(
         private val roomVersionService: RoomVersionService,
         private val viaParameterFinder: ViaParameterFinder,
         private val locationSharingService: LocationSharingService,
+        private val pollHistoryService: PollHistoryService,
         override val coroutineDispatchers: MatrixCoroutineDispatchers
 ) : Room {
 
@@ -116,4 +118,5 @@ internal class DefaultRoom(
     override fun roomAccountDataService() = roomAccountDataService
     override fun roomVersionService() = roomVersionService
     override fun locationSharingService() = locationSharingService
+    override fun pollHistoryService() = pollHistoryService
 }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomFactory.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomFactory.kt
index ffe7679575..86c414863d 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomFactory.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomFactory.kt
@@ -28,6 +28,7 @@ import org.matrix.android.sdk.internal.session.room.draft.DefaultDraftService
 import org.matrix.android.sdk.internal.session.room.location.DefaultLocationSharingService
 import org.matrix.android.sdk.internal.session.room.membership.DefaultMembershipService
 import org.matrix.android.sdk.internal.session.room.notification.DefaultRoomPushRuleService
+import org.matrix.android.sdk.internal.session.room.poll.DefaultPollHistoryService
 import org.matrix.android.sdk.internal.session.room.read.DefaultReadService
 import org.matrix.android.sdk.internal.session.room.relation.DefaultRelationService
 import org.matrix.android.sdk.internal.session.room.reporting.DefaultReportingService
@@ -71,6 +72,7 @@ internal class DefaultRoomFactory @Inject constructor(
         private val roomAccountDataServiceFactory: DefaultRoomAccountDataService.Factory,
         private val viaParameterFinder: ViaParameterFinder,
         private val locationSharingServiceFactory: DefaultLocationSharingService.Factory,
+        private val pollHistoryServiceFactory: DefaultPollHistoryService.Factory,
         private val coroutineDispatchers: MatrixCoroutineDispatchers
 ) : RoomFactory {
 
@@ -99,6 +101,7 @@ internal class DefaultRoomFactory @Inject constructor(
                 roomVersionService = roomVersionServiceFactory.create(roomId),
                 viaParameterFinder = viaParameterFinder,
                 locationSharingService = locationSharingServiceFactory.create(roomId),
+                pollHistoryService = pollHistoryServiceFactory.create(roomId),
                 coroutineDispatchers = coroutineDispatchers
         )
     }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/poll/DefaultPollHistoryService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/poll/DefaultPollHistoryService.kt
new file mode 100644
index 0000000000..6779fbc101
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/poll/DefaultPollHistoryService.kt
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2023 The Matrix.org Foundation C.I.C.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.matrix.android.sdk.internal.session.room.poll
+
+import androidx.lifecycle.LiveData
+import dagger.assisted.Assisted
+import dagger.assisted.AssistedFactory
+import dagger.assisted.AssistedInject
+import org.matrix.android.sdk.api.session.room.model.PollResponseAggregatedSummary
+import org.matrix.android.sdk.api.session.room.poll.LoadedPollsStatus
+import org.matrix.android.sdk.api.session.room.poll.PollHistoryService
+import timber.log.Timber
+
+private const val LOADING_PERIOD_IN_DAYS = 30
+
+// TODO add unit tests
+internal class DefaultPollHistoryService @AssistedInject constructor(
+        @Assisted private val roomId: String,
+) : PollHistoryService {
+
+    @AssistedFactory
+    interface Factory {
+        fun create(roomId: String): DefaultPollHistoryService
+    }
+
+    init {
+        Timber.d("init with roomId: $roomId")
+    }
+
+    override val loadingPeriodInDays: Int
+        get() = LOADING_PERIOD_IN_DAYS
+
+    override suspend fun loadMore(): LoadedPollsStatus {
+        TODO("Not yet implemented")
+    }
+
+    override fun canLoadMore(): Boolean {
+        TODO("Not yet implemented")
+    }
+
+    override fun getLoadedPollsStatus(): LoadedPollsStatus {
+        TODO("Not yet implemented")
+    }
+
+    override suspend fun syncPolls() {
+        TODO("Not yet implemented")
+    }
+
+    override fun getPolls(): LiveData<List<PollResponseAggregatedSummary>> {
+        TODO("Not yet implemented")
+    }
+}