diff --git a/apps/dodo/main.go b/apps/dodo/main.go
new file mode 100644
index 0000000..3445b59
--- /dev/null
+++ b/apps/dodo/main.go
@@ -0,0 +1,202 @@
+package main
+
+import (
+	"database/sql"
+	_ "embed"
+	"flag"
+	"fmt"
+	"log"
+	"net/http"
+	"net/url"
+	"strconv"
+	"strings"
+
+	_ "github.com/glebarez/go-sqlite"
+)
+
+var port = flag.Int("port", 8080, "Port to listen on")
+var dbPath = flag.String("db-path", "entries.db", "Path to the sqlite file")
+
+//go:embed index.html
+var indexHtml []byte
+
+//go:embed ok.html
+var okHtml []byte
+
+type entry struct {
+	Email            string
+	InstallationType string
+	NumMembers       int
+	Apps             []string
+	PayPerMonth      float64
+	PrepayFullYear   bool
+	Thoughts         string
+}
+
+func getFormValues(f url.Values, name string) ([]string, error) {
+	return f[name], nil
+}
+
+func getFormValue(f url.Values, name string) (string, error) {
+	if ret, ok := f[name]; ok {
+		switch len(ret) {
+		case 0:
+			return "", fmt.Errorf("%s is required", name)
+		case 1:
+			return ret[0], nil
+		default:
+			return "", fmt.Errorf("%s too many values", name)
+		}
+	}
+	return "", fmt.Errorf("%s is required", name)
+}
+
+func getFormValueInt(f url.Values, name string) (int, error) {
+	v, err := getFormValue(f, name)
+	if err != nil {
+		return 0, err
+	}
+	return strconv.Atoi(v)
+}
+
+func getFormValueBool(f url.Values, name string) (bool, error) {
+	v, err := getFormValue(f, name)
+	if err != nil {
+		return false, err
+	}
+	return strconv.ParseBool(v)
+}
+
+func getFormValueFloat64(f url.Values, name string) (float64, error) {
+	v, err := getFormValue(f, name)
+	if err != nil {
+		return 0, err
+	}
+	return strconv.ParseFloat(v, 64)
+}
+
+func NewEntry(f url.Values) (*entry, error) {
+	var e entry
+	var err error = nil
+	e.Email, err = getFormValue(f, "email")
+	if err != nil {
+		return nil, err
+	}
+	e.InstallationType, err = getFormValue(f, "installation_type")
+	if err != nil {
+		return nil, err
+	}
+	e.NumMembers, err = getFormValueInt(f, "num_members")
+	if err != nil {
+		return nil, err
+	}
+	e.Apps, err = getFormValues(f, "apps")
+	if err != nil {
+		return nil, err
+	}
+	e.PayPerMonth, err = getFormValueFloat64(f, "pay_per_month")
+	if err != nil {
+		return nil, err
+	}
+	e.PrepayFullYear, err = getFormValueBool(f, "pay_full_year")
+	if err != nil {
+		return nil, err
+	}
+	e.Thoughts, err = getFormValue(f, "thoughts")
+	if err != nil {
+		return nil, err
+	}
+	return &e, nil
+}
+
+type AddToWaitlistFn func(e *entry) error
+
+type Server struct {
+	port          int
+	indexHtml     []byte
+	okHtml        []byte
+	addToWaitlist func(e *entry) error
+}
+
+func NewServer(port int, indexHtml, okHtml []byte, addToWaitlist AddToWaitlistFn) *Server {
+	return &Server{
+		port,
+		indexHtml,
+		okHtml,
+		addToWaitlist,
+	}
+}
+
+func (s *Server) Start() {
+	http.HandleFunc("/waitlist", s.waitlist)
+	http.HandleFunc("/", s.index)
+	log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", *port), nil))
+}
+
+func (s *Server) index(w http.ResponseWriter, r *http.Request) {
+	if _, err := w.Write(s.indexHtml); err != nil {
+		http.Error(w, err.Error(), http.StatusInternalServerError)
+		return
+	}
+}
+
+func (s *Server) waitlist(w http.ResponseWriter, r *http.Request) {
+	if r.Method != http.MethodPost {
+		http.Error(w, "Invalid request", http.StatusBadRequest)
+		return
+	}
+	if err := r.ParseForm(); err != nil {
+		http.Error(w, "Invalid request", http.StatusBadRequest)
+		return
+	}
+	e, err := NewEntry(r.PostForm)
+	if err != nil {
+		http.Error(w, fmt.Sprintf("Invalid request: %s", err), http.StatusBadRequest)
+		return
+	}
+	if err := s.addToWaitlist(e); err != nil {
+		http.Error(w, err.Error(), http.StatusInternalServerError)
+		return
+	}
+	w.Write([]byte(s.okHtml))
+}
+
+func NewAddToWaitlist(db *sql.DB) AddToWaitlistFn {
+	return func(e *entry) error {
+		tx, err := db.Begin()
+		if err != nil {
+			return err
+		}
+		stm, err := tx.Prepare(`
+INSERT INTO waitlist (
+  email,
+  installation_type,
+  num_members,
+  apps,
+  pay_per_month,
+  prepay_full_year,
+  thoughts
+) VALUES (
+  ?, ?, ?, ?, ?, ?, ?
+);`)
+		if err != nil {
+			return err
+		}
+		defer stm.Close()
+		if _, err := stm.Exec(e.Email, e.InstallationType, e.NumMembers, strings.Join(e.Apps, ","), e.PayPerMonth, e.PrepayFullYear, e.Thoughts); err != nil {
+			return err
+		}
+		return tx.Commit()
+	}
+}
+
+func main() {
+	flag.Parse()
+	db, err := sql.Open("sqlite", *dbPath)
+	if err != nil {
+		log.Fatal(err)
+	}
+	defer db.Close()
+	s := NewServer(*port, indexHtml, okHtml, NewAddToWaitlist(db))
+	s.Start()
+}
