diff --git a/examples/restful_api/index.html b/examples/restful_api/index.html
new file mode 100644
index 0000000000000000000000000000000000000000..9051ff08ceb719ecd6f4c7c4a2b10095a59a86b6
--- /dev/null
+++ b/examples/restful_api/index.html
@@ -0,0 +1,66 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="utf-8" />
+  <title>RESTful API demo</title>
+  <meta name="viewport" content="width=device-width, initial-scale=1" />
+  <style type="text/css">
+    * { outline: none; font: 16px/1.4 Helvetica, Arial, sans-serif; }
+    body {
+      background-color: #cde; margin: 0;
+      padding: 0; font: 16px/1.4 Helvetica, Arial, sans-serif;
+    }
+    div.content {
+      width: 800px; margin: 2em auto; padding: 20px 50px;
+      background-color: #fff; border-radius: 1em;
+    }
+    label { display: inline-block; min-width: 7em; }
+    input { border: 1px solid #ccc; padding: 0.2em; }
+    a:link, a:visited { color: #69c; text-decoration: none; }
+    @media (max-width: 700px) {
+      body { background-color: #fff; }
+      div.content { width: auto; margin: 0 auto; padding: 1em; }
+    }
+</style>
+
+<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
+<script language="javascript" type="text/javascript">
+  jQuery(function() {
+
+    $(document).on('keyup', '#n1, #n2', function() {
+      $.ajax({
+        url: '/api/sum',
+        method: 'POST',
+        dataType: 'json',
+        data: { n1: $('#n1').val(), n2: $('#n2').val() },
+        success: function(json) {
+          $('#result').html(json.result);
+        }
+      });
+    });
+
+  });
+</script>
+</head>
+<body>
+  <div class="content">
+    <h1>RESTful API demo.</h1>
+
+    <p>
+      This page demonstrates how Mongoose web server could be used to implement
+      RESTful APIs. Enter numbers below, and press Submit. Browser will send
+      two numbers to <tt>/api/sum</tt> URI, Mongoose calclulates the sum of
+      two and returns the result.
+    </p>
+
+    <div>
+      <label>Number 1:</label> <input type="text" id="n1" />
+    </div><div>
+      <label>Number 2:</label> <input type="text" id="n2" />
+    </div><div>
+     <label>Result:</label> <span id="result">&nbsp;</span>
+    </div><div>
+
+  </div>
+</body>
+</html>
diff --git a/examples/restful_api/restful_api.c b/examples/restful_api/restful_api.c
index 8884c5c2d7edc7977054094af191122a3f8ee919..ff0ac83a9f30a2f425f02f41fb27eebd498e6e09 100644
--- a/examples/restful_api/restful_api.c
+++ b/examples/restful_api/restful_api.c
@@ -3,62 +3,32 @@
 #include <stdlib.h>
 #include "mongoose.h"
 
-static int static_value = 123;  // Exposed and changeable via the form
+static const char *s_no_cache_header =
+  "Cache-Control: max-age=0, post-check=0, "
+  "pre-check=0, no-store, no-cache, must-revalidate\r\n";
 
-static void print_html_form(struct mg_connection *conn) {
-  mg_send_header(conn, "Content-Type", "text/html");
-  mg_send_header(conn, "Cache-Control", "max-age=0, post-check=0, "
-                 "pre-check=0, no-store, no-cache, must-revalidate");
+static void handle_restful_call(struct mg_connection *conn) {
+  char n1[100], n2[100];
 
-  // Note that all the following normally should reside in static HTML page
-  mg_printf_data(conn, "%s", "<html><head>");
-  // It is better to use local copy though
-  mg_printf_data(conn, "<script src=\"%s\"></script>",
-                 "http://code.jquery.com/jquery-1.11.0.min.js");
-  mg_printf_data(conn, "%s", "<script> jQuery(function() {\n");
-  // Here is the ajax call that fetches data from the device and
-  // updates the form
-  mg_printf_data(conn, "%s", "$.ajax({ url: '/get_value', dataType: 'json', "
-                 "success: function(d) { $('#val').val(d.value); }});\n");
-  // This ajax call is triggered when submit button is pressed. It sends new
-  // value to the device.
-  mg_printf_data(conn, "%s", "$(document).on('click', '#button', function() {"
-                 "  $.ajax({ url: '/set_value', dataType: 'json', "
-                 "  data: { new_value: $('#val').val() } });\n"
-                 "  return false; });\n");
-  mg_printf_data(conn, "%s", "});</script>");
-  mg_printf_data(conn, "%s", "</head><body>");
-  mg_printf_data(conn, "%s", "<h1>Ajax form submission example</h1>");
-  mg_printf_data(conn, "%s", "<form>");
-  mg_printf_data(conn, "%s", "Device value: <input type=text id=val />");
-  mg_printf_data(conn, "%s", "<input type=submit id=button />");
-  mg_printf_data(conn, "%s", "</form>");
-  mg_printf_data(conn, "%s", "</body></html>");
+  // Get form variables
+  mg_get_var(conn, "n1", n1, sizeof(n1));
+  mg_get_var(conn, "n2", n2, sizeof(n2));
+
+  mg_printf_data(conn, "{ \"result\": %lf }", strtod(n1, NULL) + strtod(n2, NULL));
 }
 
 static int ev_handler(struct mg_connection *conn, enum mg_event ev) {
-  if (ev == MG_REQUEST) {
-    if (strcmp(conn->uri, "/get_value") == 0) {
-      mg_printf_data(conn, "{\"value\": %d}", static_value);
-    } else if (strcmp(conn->uri, "/set_value") == 0) {
-      // This Ajax endpoint sets the new value for the device variable
-      char buf[100] = "";
-      mg_get_var(conn, "new_value", buf, sizeof(buf));  // Get form variable
-      static_value = atoi(buf);                         // Set new value
-      mg_printf_data(conn, "%s", "{\"success\": true}");
-      printf("Setting value to [%d]\n", static_value);  // Debug trace
-    } else {
-      // Better way is to set "document_root" option, put "index.html" file
-      // into document_root and return MG_FALSE here. We're printing HTML
-      // page by hands just to keep everything in one C file.
-      print_html_form(conn);
-    }
-    return MG_TRUE;
-  } else if (ev == MG_AUTH) {
-    return MG_TRUE;
+  switch (ev) {
+    case MG_AUTH: return MG_TRUE;
+    case MG_REQUEST:
+      if (!strcmp(conn->uri, "/api/sum")) {
+        handle_restful_call(conn);
+        return MG_TRUE;
+      }
+      mg_send_file(conn, "index.html", s_no_cache_header);
+      return MG_MORE;
+    default: return MG_FALSE;
   }
-
-  return MG_FALSE;
 }
 
 int main(void) {