diff --git a/PKG-INFO b/PKG-INFO
index ffcee9d004f2b4af0f980d6674255f21c81c3e84..3e99786b989ec81ad312b8d62e9eab98ffafe898 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: swh.model
-Version: 0.0.62
+Version: 0.0.63
 Summary: Software Heritage data model
 Home-page: https://forge.softwareheritage.org/diffusion/DMOD/
 Author: Software Heritage developers
diff --git a/swh.model.egg-info/PKG-INFO b/swh.model.egg-info/PKG-INFO
index ffcee9d004f2b4af0f980d6674255f21c81c3e84..3e99786b989ec81ad312b8d62e9eab98ffafe898 100644
--- a/swh.model.egg-info/PKG-INFO
+++ b/swh.model.egg-info/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: swh.model
-Version: 0.0.62
+Version: 0.0.63
 Summary: Software Heritage data model
 Home-page: https://forge.softwareheritage.org/diffusion/DMOD/
 Author: Software Heritage developers
diff --git a/swh/model/hypothesis_strategies.py b/swh/model/hypothesis_strategies.py
index b6c35933fdfef36ab9d3e8ec5cc2930e6daee159..19c3fd314a2557d7e4ad38813f3445fca5e101f5 100644
--- a/swh/model/hypothesis_strategies.py
+++ b/swh/model/hypothesis_strategies.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2019 The Software Heritage developers
+# Copyright (C) 2019-2020 The Software Heritage developers
 # See the AUTHORS file at the top-level directory of this distribution
 # License: GNU General Public License version 3, or any later version
 # See top-level LICENSE file for more information
@@ -15,8 +15,8 @@ from hypothesis.strategies import (
 from .from_disk import DentryPerms
 from .model import (
     Person, Timestamp, TimestampWithTimezone, Origin, OriginVisit,
-    Snapshot, SnapshotBranch, TargetType, Release, Revision,
-    Directory, DirectoryEntry, Content, SkippedContent
+    OriginVisitUpdate, Snapshot, SnapshotBranch, TargetType, Release,
+    Revision, Directory, DirectoryEntry, Content, SkippedContent
 )
 from .identifiers import snapshot_identifier, identifier_to_bytes
 
@@ -85,7 +85,22 @@ def origin_visits():
         origin=urls(),
         status=sampled_from(['ongoing', 'full', 'partial']),
         type=pgsql_text(),
-        snapshot=optional(sha1_git()))
+        snapshot=optional(sha1_git()),
+    )
+
+
+def metadata_dicts():
+    return dictionaries(pgsql_text(), pgsql_text())
+
+
+def origin_visit_updates():
+    return builds(
+        OriginVisitUpdate,
+        visit=integers(0, 1000),
+        origin=urls(),
+        status=sampled_from(['ongoing', 'full', 'partial']),
+        snapshot=optional(sha1_git()),
+        metadata=one_of(none(), metadata_dicts()))
 
 
 @composite
@@ -104,8 +119,7 @@ def releases(draw):
         author=author)
 
 
-def revision_metadata():
-    return dictionaries(pgsql_text(), pgsql_text())
+revision_metadata = metadata_dicts
 
 
 def revisions():
@@ -238,6 +252,7 @@ def objects():
     return one_of(
         origins().map(lambda x: ('origin', x)),
         origin_visits().map(lambda x: ('origin_visit', x)),
+        origin_visit_updates().map(lambda x: ('origin_visit_update', x)),
         snapshots().map(lambda x: ('snapshot', x)),
         releases().map(lambda x: ('release', x)),
         revisions().map(lambda x: ('revision', x)),
diff --git a/swh/model/model.py b/swh/model/model.py
index 7cfb7e3ce71460abd4795936d62da763b2fced88..b296b227c51dbf5401c11495a78aec20db314bc0 100644
--- a/swh/model/model.py
+++ b/swh/model/model.py
@@ -234,6 +234,23 @@ class OriginVisit(BaseModel):
             **d)
 
 
+@attr.s(frozen=True)
+class OriginVisitUpdate(BaseModel):
+    """Represents a visit update of an origin at a given point in time.
+
+    """
+    origin = attr.ib(type=str)
+    visit = attr.ib(type=int)
+
+    date = attr.ib(type=datetime.datetime)
+    status = attr.ib(
+        type=str,
+        validator=attr.validators.in_(['ongoing', 'full', 'partial']))
+    snapshot = attr.ib(type=Optional[Sha1Git])
+    metadata = attr.ib(type=Optional[Dict[str, object]],
+                       default=None)
+
+
 class TargetType(Enum):
     """The type of content pointed to by a snapshot branch. Usually a
     revision or an alias."""
diff --git a/swh/model/tests/test_model.py b/swh/model/tests/test_model.py
index 5e8e1ee22acf0653f8188f084ff7a00f4c4d0ca6..c5dbc59cfba1f49d96e73dcf144c014ca79d4333 100644
--- a/swh/model/tests/test_model.py
+++ b/swh/model/tests/test_model.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2019 The Software Heritage developers
+# Copyright (C) 2019-2020 The Software Heritage developers
 # See the AUTHORS file at the top-level directory of this distribution
 # License: GNU General Public License version 3, or any later version
 # See top-level LICENSE file for more information
@@ -16,7 +16,9 @@ from swh.model.model import (
     MissingData, Person
 )
 from swh.model.hashutil import hash_to_bytes, MultiHash
-from swh.model.hypothesis_strategies import objects, origins, origin_visits
+from swh.model.hypothesis_strategies import (
+    objects, origins, origin_visits, origin_visit_updates
+)
 from swh.model.identifiers import (
     directory_identifier, revision_identifier, release_identifier,
     snapshot_identifier
@@ -61,6 +63,13 @@ def test_todict_origin_visits(origin_visit):
     assert origin_visit == type(origin_visit).from_dict(obj)
 
 
+@given(origin_visit_updates())
+def test_todict_origin_visit_updates(origin_visit_update):
+    obj = origin_visit_update.to_dict()
+
+    assert origin_visit_update == type(origin_visit_update).from_dict(obj)
+
+
 def test_timestampwithtimezone_from_datetime():
     tz = datetime.timezone(datetime.timedelta(minutes=+60))
     date = datetime.datetime(
diff --git a/version.txt b/version.txt
index eb7e24b8d7e2668da7d581835a78257a098c7cdc..b83c6fd7a6436135b265e3c015ada7ec503aab31 100644
--- a/version.txt
+++ b/version.txt
@@ -1 +1 @@
-v0.0.62-0-g4a2233c
\ No newline at end of file
+v0.0.63-0-ge9a4c75
\ No newline at end of file