diff --git a/branding/motd-cli/README.md b/branding/motd-cli/README.md
index cfe8a38ae1d9838ad2427829cb5b44a1f0ff33c6..5d00f1075fece541e63e6c59b3abcb03c7ed7851 100644
--- a/branding/motd-cli/README.md
+++ b/branding/motd-cli/README.md
@@ -19,6 +19,7 @@ The structure of the `motd.json` file is like follows:
         "end":      "Dec 31 2021 23:59:00",
         "type":     "daily",
         "platform": "all",
+        "urgency":  "normal",
         "text": [
           { "lang": "en",
             "str": "This is a <a href='https://leap.se'>test!</a>"},
@@ -33,7 +34,8 @@ Valid values are:
 
 * Begin, End are date strings, like "Jan 1 2021 00:00:00".
 * Type: "once" for a one-shot message, "daily" for a message that is displayed daily during the specified duration.
-* Platform: one of "windows", "linux", "osx" or "all".
+* Platform: one of "windows", "osx", "snap", "linux", or "all".
+* Urgency: either "normal" or "critical".
 
 The text message can contain links.
 
@@ -48,9 +50,12 @@ Message 1 ✓
 -----------
 Type: daily ✓
 Platform: all ✓
+Urgency: normal ✓
 Languages: 2 ✓
 ```
 
+Use `motd-cli -url https://example.com/motd.json` to validate a remote file.
+
 Notes: I'm considering adding an explicit layer of verification of the motd
 payload. Please comment on
 [#554](https://0xacab.org/leap/bitmask-vpn/-/issues/554) if you have an opinion
diff --git a/branding/motd-cli/main.go b/branding/motd-cli/main.go
index 6cfd29ed235b033cbc931c4aed71c97e042b10fd..6828cc9ae1f7d1fd11bf5bfbfffc6ea9c52ed756 100644
--- a/branding/motd-cli/main.go
+++ b/branding/motd-cli/main.go
@@ -4,7 +4,9 @@ import (
 	"encoding/json"
 	"flag"
 	"fmt"
+	"io"
 	"io/ioutil"
+	"net/http"
 	"os"
 )
 
@@ -28,20 +30,24 @@ type Message struct {
 	End      string          `json:"end"`
 	Type     string          `json:"type"`
 	Platform string          `json:"platform"`
+	Urgency  string          `json:"urgency"`
 	Text     []LocalizedText `json:"text"`
 }
 
 func (m *Message) IsValid() bool {
 	valid := (m.IsValidBegin() && m.IsValidEnd() &&
-		m.IsValidType() && m.IsValidPlatform() && m.HasLocalizedText())
+		m.IsValidType() && m.IsValidPlatform() && m.IsValidUrgency() &&
+		m.HasLocalizedText())
 	return valid
 }
 
 func (m *Message) IsValidBegin() bool {
+	// FIXME check that begin is before 1y for instance
 	return true
 }
 
 func (m *Message) IsValidEnd() bool {
+	// FIXME check end is within next year/months
 	return true
 }
 
@@ -63,8 +69,17 @@ func (m *Message) IsValidPlatform() bool {
 	}
 }
 
+func (m *Message) IsValidUrgency() bool {
+	switch m.Urgency {
+	case "normal", "critical":
+		return true
+	default:
+		return false
+	}
+}
+
 func (m *Message) HasLocalizedText() bool {
-	return true
+	return len(m.Text) > 0
 }
 
 type LocalizedText struct {
@@ -73,15 +88,22 @@ type LocalizedText struct {
 }
 
 func main() {
-	// TODO pass url flag too, to fetch and validate remote file
 	file := flag.String("file", "", "file to validate")
+	url := flag.String("url", "", "url to validate")
 	flag.Parse()
+
 	f := *file
-	if f == "" {
-		f = defaultFile
-	}
+	u := *url
 
-	fmt.Println("file:", f)
+	if u != "" {
+		fmt.Println("url:", u)
+		f = downloadToTempFile(u)
+	} else {
+		if f == "" {
+			f = defaultFile
+		}
+		fmt.Println("file:", f)
+	}
 	m := parseFile(f)
 	fmt.Printf("count: %v\n", m.Length())
 	fmt.Println()
@@ -89,6 +111,7 @@ func main() {
 		fmt.Printf("Message %d %v\n-----------\n", i+1, mark(msg.IsValid()))
 		fmt.Printf("Type: %s %v\n", msg.Type, mark(msg.IsValidType()))
 		fmt.Printf("Platform: %s %v\n", msg.Platform, mark(msg.IsValidPlatform()))
+		fmt.Printf("Urgency: %s %v\n", msg.Urgency, mark(msg.IsValidUrgency()))
 		fmt.Printf("Languages: %d %v\n", len(msg.Text), mark(msg.HasLocalizedText()))
 		if !msg.IsValid() {
 			os.Exit(1)
@@ -96,6 +119,24 @@ func main() {
 	}
 }
 
+func downloadToTempFile(url string) string {
+	resp, err := http.Get(url)
+	if err != nil {
+		panic(err)
+	}
+	defer resp.Body.Close()
+
+	out, err := ioutil.TempFile("/tmp/", "motd-linter")
+	if err != nil {
+		panic(err)
+	}
+	defer out.Close()
+
+	_, _ = io.Copy(out, resp.Body)
+	fmt.Println("File downloaded to", out.Name())
+	return out.Name()
+}
+
 func parseFile(f string) Messages {
 	jsonFile, err := os.Open(f)
 	if err != nil {
diff --git a/branding/motd-cli/motd-example.json b/branding/motd-cli/motd-example.json
index 47bf6351bc58cf6ab6a7ed420f35b566a7430a03..9ebb5f5e8f9a13423987a9fdec3b1138e52a9ca8 100644
--- a/branding/motd-cli/motd-example.json
+++ b/branding/motd-cli/motd-example.json
@@ -4,6 +4,7 @@
         "end":      "Dec 31 2021 23:59:00",
         "type":     "daily",
         "platform": "all",
+        "urgency":  "normal",
         "text": [
           { "lang": "en",
             "str": "This is a <a href='https://leap.se'>test!</a>"},