diff --git a/lib/types/entry-types.js b/lib/types/entry-types.js
--- a/lib/types/entry-types.js
+++ b/lib/types/entry-types.js
@@ -1,5 +1,7 @@
 // @flow
 
+import t, { type TInterface } from 'tcomb';
+
 import { type Platform, isWebPlatform } from './device-types.js';
 import { type CalendarFilter, defaultCalendarFilters } from './filter-types.js';
 import type { RawMessageInfo } from './message-types.js';
@@ -13,6 +15,7 @@
   fifteenDaysLater,
   thisMonthDates,
 } from '../utils/date-utils.js';
+import { tID, tShape } from '../utils/validation-utils.js';
 
 export type RawEntryInfo = {
   id?: string, // null if local copy without ID yet
@@ -26,6 +29,19 @@
   creatorID: string,
   deleted: boolean,
 };
+export const rawEntryInfoValidator: TInterface<RawEntryInfo> =
+  tShape<RawEntryInfo>({
+    id: t.maybe(tID),
+    localID: t.maybe(t.String),
+    threadID: tID,
+    text: t.String,
+    year: t.Number,
+    month: t.Number,
+    day: t.Number,
+    creationTime: t.Number,
+    creatorID: t.String,
+    deleted: t.Boolean,
+  });
 
 export type EntryInfo = {
   id?: string, // null if local copy without ID yet
diff --git a/lib/types/validation.test.js b/lib/types/validation.test.js
--- a/lib/types/validation.test.js
+++ b/lib/types/validation.test.js
@@ -2,6 +2,7 @@
 
 import _findKey from 'lodash/fp/findKey.js';
 
+import { rawEntryInfoValidator } from './entry-types.js';
 import {
   imageValidator,
   videoValidator,
@@ -633,3 +634,24 @@
     ).toBe(false);
   });
 });
+
+describe('entry validation', () => {
+  const entry = {
+    id: '92860',
+    threadID: '85068',
+    text: 'text',
+    year: 2023,
+    month: 4,
+    day: 2,
+    creationTime: 1682082939882,
+    creatorID: '83853',
+    deleted: false,
+  };
+
+  it('should validate correct entry', () => {
+    expect(rawEntryInfoValidator.is(entry)).toBe(true);
+  });
+  it('should not validate incorrect entry', () => {
+    expect(rawEntryInfoValidator.is({ ...entry, threadID: 0 })).toBe(false);
+  });
+});