diff --git a/server/handlers.go b/server/handlers.go
index 7c3d649d73d9445662516851582d671c96dc7156..83ef53763d8eef561f30105a118d59f2bbf8f296 100644
--- a/server/handlers.go
+++ b/server/handlers.go
@@ -384,8 +384,7 @@ func (s *Server) sendCodeResponse(w http.ResponseWriter, r *http.Request, authRe
 			}
 
 			if authReq.RedirectURI == redirectURIOOB {
-				// TODO(ericchiang): Add a proper template.
-				fmt.Fprintf(w, "Code: %s", code.ID)
+				s.templates.oob(w, code.ID)
 				return
 			}
 			q.Set("code", code.ID)
diff --git a/server/templates.go b/server/templates.go
index 45d75c84cdcfc7d3188ddc4866dd74c0a29bafcd..117d12c55e315073b48a25b2f85c11993709b1e5 100644
--- a/server/templates.go
+++ b/server/templates.go
@@ -15,6 +15,7 @@ const (
 	tmplApproval = "approval.html"
 	tmplLogin    = "login.html"
 	tmplPassword = "password.html"
+	tmplOOB      = "oob.html"
 )
 
 const coreOSLogoURL = "https://coreos.com/assets/images/brand/coreos-wordmark-135x40px.png"
@@ -23,6 +24,7 @@ var requiredTmpls = []string{
 	tmplApproval,
 	tmplLogin,
 	tmplPassword,
+	tmplOOB,
 }
 
 // TemplateConfig describes.
@@ -106,6 +108,7 @@ func loadTemplates(config TemplateConfig) (*templates, error) {
 		loginTmpl:    tmpls.Lookup(tmplLogin),
 		approvalTmpl: tmpls.Lookup(tmplApproval),
 		passwordTmpl: tmpls.Lookup(tmplPassword),
+		oobTmpl:      tmpls.Lookup(tmplOOB),
 	}, nil
 }
 
@@ -120,6 +123,7 @@ type templates struct {
 	loginTmpl    *template.Template
 	approvalTmpl *template.Template
 	passwordTmpl *template.Template
+	oobTmpl      *template.Template
 }
 
 type connectorInfo struct {
@@ -175,6 +179,14 @@ func (t *templates) approval(w http.ResponseWriter, state, username, clientName
 	renderTemplate(w, t.approvalTmpl, data)
 }
 
+func (t *templates) oob(w http.ResponseWriter, code string) {
+	data := struct {
+		TemplateConfig
+		Code string
+	}{t.globalData, code}
+	renderTemplate(w, t.oobTmpl, data)
+}
+
 // small io.Writer utilitiy to determine if executing the template wrote to the underlying response writer.
 type writeRecorder struct {
 	wrote bool
diff --git a/server/templates_default.go b/server/templates_default.go
index 63b5aaa931386b03c1e3a122140921d882825896..3a3d031a2bdec7ab779d66527ece476ba18a3791 100644
--- a/server/templates_default.go
+++ b/server/templates_default.go
@@ -313,6 +313,18 @@ var defaultTemplates = map[string]string{
 </div>
 
 
+{{ template "footer.html" . }}
+`,
+	"oob.html": `{{ template "header.html" . }}
+
+<div class="panel">
+  <h2 class="heading">Login Successful</h2>
+
+  Please copy this code, switch to your application and paste it there:
+  <br/>
+  <input type="text" value="{{ .Code }}" />
+</div>
+
 {{ template "footer.html" . }}
 `,
 	"password.html": `{{ template "header.html" . }}
diff --git a/web/templates/oob.html b/web/templates/oob.html
new file mode 100644
index 0000000000000000000000000000000000000000..09c98e085bf1e520cd19a4ac8ad9161707cea04f
--- /dev/null
+++ b/web/templates/oob.html
@@ -0,0 +1,11 @@
+{{ template "header.html" . }}
+
+<div class="panel">
+  <h2 class="heading">Login Successful</h2>
+
+  Please copy this code, switch to your application and paste it there:
+  <br/>
+  <input type="text" value="{{ .Code }}" />
+</div>
+
+{{ template "footer.html" . }}