diff --git a/httpbin/handlers.go b/httpbin/handlers.go
index fb27c4b489cae252572d3825040e2ffb1ec6b172..29ed07d4067783d19e1c39c99dfbcb897157fbf1 100644
--- a/httpbin/handlers.go
+++ b/httpbin/handlers.go
@@ -293,6 +293,32 @@ func (h *HTTPBin) AbsoluteRedirect(w http.ResponseWriter, r *http.Request) {
 	doRedirect(w, r, false)
 }
 
+// RedirectTo responds with a redirect to a specific URL with an optional
+// status code, which defaults to 302
+func (h *HTTPBin) RedirectTo(w http.ResponseWriter, r *http.Request) {
+	q := r.URL.Query()
+
+	url := q.Get("url")
+	if url == "" {
+		http.Error(w, "Missing URL", http.StatusBadRequest)
+		return
+	}
+
+	var err error
+	statusCode := http.StatusFound
+	rawStatusCode := q.Get("status_code")
+	if rawStatusCode != "" {
+		statusCode, err = strconv.Atoi(q.Get("status_code"))
+		if err != nil || statusCode < 300 || statusCode > 399 {
+			http.Error(w, "Invalid status code", http.StatusBadRequest)
+			return
+		}
+	}
+
+	w.Header().Set("Location", url)
+	w.WriteHeader(statusCode)
+}
+
 // Cookies responds with the cookies in the incoming request
 func (h *HTTPBin) Cookies(w http.ResponseWriter, r *http.Request) {
 	resp := cookiesResponse{}
diff --git a/httpbin/handlers_test.go b/httpbin/handlers_test.go
index d08e38298a64408240ee23d29d6684b862c3d63b..5dd842488e6f08e252de222344b708fcd1e57837 100644
--- a/httpbin/handlers_test.go
+++ b/httpbin/handlers_test.go
@@ -823,6 +823,51 @@ func TestRedirects(t *testing.T) {
 	}
 }
 
+func TestRedirectTo(t *testing.T) {
+	var okTests = []struct {
+		url              string
+		expectedLocation string
+		expectedStatus   int
+	}{
+		{"/redirect-to?url=http://www.example.com/", "http://www.example.com/", http.StatusFound},
+		{"/redirect-to?url=http://www.example.com/&status_code=307", "http://www.example.com/", http.StatusTemporaryRedirect},
+
+		{"/redirect-to?url=/get", "/get", http.StatusFound},
+		{"/redirect-to?url=/get&status_code=307", "/get", http.StatusTemporaryRedirect},
+
+		{"/redirect-to?url=foo", "foo", http.StatusFound},
+	}
+
+	for _, test := range okTests {
+		t.Run("ok"+test.url, func(t *testing.T) {
+			r, _ := http.NewRequest("GET", test.url, nil)
+			w := httptest.NewRecorder()
+			handler.ServeHTTP(w, r)
+
+			assertStatusCode(t, w, test.expectedStatus)
+			assertHeader(t, w, "Location", test.expectedLocation)
+		})
+	}
+
+	var badTests = []struct {
+		url            string
+		expectedStatus int
+	}{
+		{"/redirect-to", http.StatusBadRequest},
+		{"/redirect-to?status_code=302", http.StatusBadRequest},
+		{"/redirect-to?url=foo&status_code=418", http.StatusBadRequest},
+	}
+	for _, test := range badTests {
+		t.Run("bad"+test.url, func(t *testing.T) {
+			r, _ := http.NewRequest("GET", test.url, nil)
+			w := httptest.NewRecorder()
+			handler.ServeHTTP(w, r)
+
+			assertStatusCode(t, w, test.expectedStatus)
+		})
+	}
+}
+
 func TestCookies(t *testing.T) {
 	testCookies := func(t *testing.T, cookies cookiesResponse) {
 		r, _ := http.NewRequest("GET", "/cookies", nil)
diff --git a/httpbin/httpbin.go b/httpbin/httpbin.go
index 8e835cb748403eaf7c0353d9f8936305791129b6..69d38cdb484508697ac9d8683ace7ece816f66e0 100644
--- a/httpbin/httpbin.go
+++ b/httpbin/httpbin.go
@@ -102,9 +102,11 @@ func (h *HTTPBin) Handler() http.Handler {
 	mux.HandleFunc("/response-headers", h.ResponseHeaders)
 
 	mux.HandleFunc("/status/", h.Status)
+
 	mux.HandleFunc("/redirect/", h.Redirect)
 	mux.HandleFunc("/relative-redirect/", h.RelativeRedirect)
 	mux.HandleFunc("/absolute-redirect/", h.AbsoluteRedirect)
+	mux.HandleFunc("/redirect-to", h.RedirectTo)
 
 	mux.HandleFunc("/cookies", h.Cookies)
 	mux.HandleFunc("/cookies/set", h.SetCookies)