From 7bed7ff4829671c95881691181df8c5eba6d3518 Mon Sep 17 00:00:00 2001
From: Dmitry Frank <dmitry.frank@cesanta.com>
Date: Fri, 18 Mar 2016 13:58:07 +0200
Subject: [PATCH] Docs are generated for Mongoose

Comments in headers are changed a bit: removed adoc-specific stuff,
markdown is used instead

PUBLISHED_FROM=9242cce85cc52a47a197d377e7e23804721a6bb5
---
 docs/build-options/disabling-flags.md         |  12 ++
 docs/build-options/enabling-flags.md          |  11 ++
 docs/build-options/intro.md                   |  17 +++
 docs/build-options/items.json                 |   9 ++
 docs/build-options/platform-spec.md           |  10 ++
 docs/build-options/tunables.md                |  11 ++
 docs/c-api/coap.h/intro.md                    |  16 +++
 docs/c-api/coap.h/items.json                  |  44 +++++++
 docs/c-api/coap.h/mg_coap_add_option.md       |  13 ++
 docs/c-api/coap.h/mg_coap_compose.md          |  12 ++
 docs/c-api/coap.h/mg_coap_free_options.md     |  11 ++
 docs/c-api/coap.h/mg_coap_parse.md            |  22 ++++
 docs/c-api/coap.h/mg_coap_send_ack.md         |  12 ++
 docs/c-api/coap.h/mg_coap_send_message.md     |  19 +++
 docs/c-api/coap.h/mg_set_protocol_coap.md     |  10 ++
 docs/c-api/coap.h/struct_mg_coap_message.md   |  20 +++
 docs/c-api/coap.h/struct_mg_coap_option.md    |  16 +++
 docs/c-api/dns-server.h/intro.md              |   8 ++
 docs/c-api/dns-server.h/items.json            |  20 +++
 .../c-api/dns-server.h/mg_dns_create_reply.md |  36 ++++++
 .../c-api/dns-server.h/mg_dns_reply_record.md |  18 +++
 docs/c-api/dns-server.h/mg_dns_send_reply.md  |  19 +++
 docs/c-api/dns.h/intro.md                     |   8 ++
 docs/c-api/dns.h/items.json                   |  48 ++++++++
 docs/c-api/dns.h/mg_dns_copy_body.md          |  15 +++
 docs/c-api/dns.h/mg_dns_encode_record.md      |  25 ++++
 docs/c-api/dns.h/mg_dns_insert_header.md      |  13 ++
 docs/c-api/dns.h/mg_dns_parse_record_data.md  |  20 +++
 docs/c-api/dns.h/mg_dns_uncompress_name.md    |  21 ++++
 docs/c-api/dns.h/mg_parse_dns.md              |  10 ++
 docs/c-api/dns.h/mg_send_dns_query.md         |  11 ++
 docs/c-api/dns.h/mg_set_protocol_dns.md       |  19 +++
 docs/c-api/dns.h/struct_mg_dns_message.md     |  18 +++
 .../dns.h/struct_mg_dns_resource_record.md    |  17 +++
 docs/c-api/http.h/intro.md                    |   8 ++
 docs/c-api/http.h/items.json                  | 108 ++++++++++++++++
 docs/c-api/http.h/mg_connect_http.md          |  35 ++++++
 docs/c-api/http.h/mg_connect_ws.md            |  30 +++++
 docs/c-api/http.h/mg_get_http_header.md       |  13 ++
 docs/c-api/http.h/mg_get_http_var.md          |  16 +++
 .../mg_http_create_digest_auth_header.md      |  13 ++
 docs/c-api/http.h/mg_http_parse_header.md     |  23 ++++
 docs/c-api/http.h/mg_parse_http.md            |  15 +++
 docs/c-api/http.h/mg_parse_multipart.md       |  46 +++++++
 docs/c-api/http.h/mg_printf_html_escape.md    |  10 ++
 docs/c-api/http.h/mg_printf_http_chunk.md     |  11 ++
 .../c-api/http.h/mg_printf_websocket_frame.md |  14 +++
 docs/c-api/http.h/mg_send_head.md             |  21 ++++
 docs/c-api/http.h/mg_send_http_chunk.md       |  25 ++++
 docs/c-api/http.h/mg_send_response_line.md    |  21 ++++
 docs/c-api/http.h/mg_send_websocket_frame.md  |  26 ++++
 docs/c-api/http.h/mg_send_websocket_framev.md |  13 ++
 .../http.h/mg_send_websocket_handshake.md     |  22 ++++
 .../http.h/mg_send_websocket_handshake2.md    |  19 +++
 docs/c-api/http.h/mg_serve_http.md            |  28 +++++
 .../http.h/mg_set_protocol_http_websocket.md  |  50 ++++++++
 docs/c-api/http.h/mg_url_decode.md            |  18 +++
 docs/c-api/http.h/struct_http_message.md      |  38 ++++++
 .../http.h/struct_mg_http_multipart_part.md   |  15 +++
 .../c-api/http.h/struct_mg_serve_http_opts.md | 104 ++++++++++++++++
 docs/c-api/http.h/struct_websocket_message.md |  14 +++
 docs/c-api/items.json                         |  44 +++++++
 docs/c-api/json-rpc.h/intro.md                |   8 ++
 docs/c-api/json-rpc.h/items.json              |  44 +++++++
 docs/c-api/json-rpc.h/mg_rpc_create_error.md  |  16 +++
 docs/c-api/json-rpc.h/mg_rpc_create_reply.md  |  16 +++
 .../c-api/json-rpc.h/mg_rpc_create_request.md |  16 +++
 .../json-rpc.h/mg_rpc_create_std_error.md     |  22 ++++
 docs/c-api/json-rpc.h/mg_rpc_dispatch.md      |  20 +++
 docs/c-api/json-rpc.h/mg_rpc_parse_reply.md   |  24 ++++
 docs/c-api/json-rpc.h/struct_mg_rpc_error.md  |  16 +++
 docs/c-api/json-rpc.h/struct_mg_rpc_reply.md  |  14 +++
 .../c-api/json-rpc.h/struct_mg_rpc_request.md |  15 +++
 docs/c-api/mbuf.h/intro.md                    |  11 ++
 docs/c-api/mbuf.h/items.json                  |  40 ++++++
 docs/c-api/mbuf.h/mbuf_append.md              |  12 ++
 docs/c-api/mbuf.h/mbuf_free.md                |  10 ++
 docs/c-api/mbuf.h/mbuf_init.md                |  11 ++
 docs/c-api/mbuf.h/mbuf_insert.md              |  14 +++
 docs/c-api/mbuf.h/mbuf_remove.md              |  10 ++
 docs/c-api/mbuf.h/mbuf_resize.md              |  13 ++
 docs/c-api/mbuf.h/mbuf_trim.md                |  10 ++
 docs/c-api/mbuf.h/struct_mbuf.md              |  14 +++
 docs/c-api/mqtt-broker.h/intro.md             |   8 ++
 docs/c-api/mqtt-broker.h/items.json           |  28 +++++
 docs/c-api/mqtt-broker.h/mg_mqtt_broker.md    |  32 +++++
 .../mqtt-broker.h/mg_mqtt_broker_init.md      |  10 ++
 docs/c-api/mqtt-broker.h/mg_mqtt_next.md      |  18 +++
 .../mqtt-broker.h/struct_mg_mqtt_broker.md    |  13 ++
 .../mqtt-broker.h/struct_mg_mqtt_session.md   |  17 +++
 docs/c-api/mqtt.h/intro.md                    |   8 ++
 docs/c-api/mqtt.h/items.json                  |  80 ++++++++++++
 docs/c-api/mqtt.h/mg_mqtt_connack.md          |  10 ++
 docs/c-api/mqtt.h/mg_mqtt_disconnect.md       |  10 ++
 .../mqtt.h/mg_mqtt_next_subscribe_topic.md    |  15 +++
 docs/c-api/mqtt.h/mg_mqtt_ping.md             |  10 ++
 docs/c-api/mqtt.h/mg_mqtt_pong.md             |  10 ++
 docs/c-api/mqtt.h/mg_mqtt_puback.md           |  10 ++
 docs/c-api/mqtt.h/mg_mqtt_pubcomp.md          |  10 ++
 docs/c-api/mqtt.h/mg_mqtt_publish.md          |  12 ++
 docs/c-api/mqtt.h/mg_mqtt_pubrec.md           |  10 ++
 docs/c-api/mqtt.h/mg_mqtt_pubrel.md           |  10 ++
 docs/c-api/mqtt.h/mg_mqtt_suback.md           |  12 ++
 docs/c-api/mqtt.h/mg_mqtt_subscribe.md        |  12 ++
 docs/c-api/mqtt.h/mg_mqtt_unsuback.md         |  10 ++
 docs/c-api/mqtt.h/mg_mqtt_unsubscribe.md      |  11 ++
 docs/c-api/mqtt.h/mg_send_mqtt_handshake.md   |  10 ++
 .../mqtt.h/mg_send_mqtt_handshake_opt.md      |  11 ++
 docs/c-api/mqtt.h/mg_set_protocol_mqtt.md     |  20 +++
 .../mqtt.h/struct_mg_mqtt_topic_expression.md |  13 ++
 docs/c-api/net.h/intro.md                     |  12 ++
 docs/c-api/net.h/items.json                   | 116 ++++++++++++++++++
 docs/c-api/net.h/mg_add_sock.md               |  13 ++
 docs/c-api/net.h/mg_add_sock_opt.md           |  15 +++
 docs/c-api/net.h/mg_bind.md                   |  13 ++
 docs/c-api/net.h/mg_bind_opt.md               |  26 ++++
 docs/c-api/net.h/mg_broadcast.md              |  19 +++
 docs/c-api/net.h/mg_check_ip_acl.md           |  27 ++++
 docs/c-api/net.h/mg_connect.md                |  13 ++
 docs/c-api/net.h/mg_connect_opt.md            |  57 +++++++++
 docs/c-api/net.h/mg_enable_javascript.md      |  14 +++
 docs/c-api/net.h/mg_enable_multithreading.md  |  14 +++
 docs/c-api/net.h/mg_mgr_free.md               |  12 ++
 docs/c-api/net.h/mg_mgr_init.md               |  15 +++
 docs/c-api/net.h/mg_mgr_poll.md               |  15 +++
 docs/c-api/net.h/mg_next.md                   |  20 +++
 docs/c-api/net.h/mg_printf.md                 |  12 ++
 docs/c-api/net.h/mg_send.md                   |  14 +++
 docs/c-api/net.h/mg_set_ssl.md                |  19 +++
 docs/c-api/net.h/mg_set_timer.md              |  31 +++++
 docs/c-api/net.h/mg_socketpair.md             |  12 ++
 docs/c-api/net.h/mg_time.md                   |  10 ++
 docs/c-api/net.h/mg_vprintf.md                |  10 ++
 docs/c-api/net.h/struct_mg_add_sock_opts.md   |  17 +++
 docs/c-api/net.h/struct_mg_bind_opts.md       |  22 ++++
 docs/c-api/net.h/struct_mg_connect_opts.md    |  28 +++++
 docs/c-api/net.h/struct_mg_connection.md      |  63 ++++++++++
 docs/c-api/net.h/struct_mg_mgr.md             |  21 ++++
 docs/c-api/net.h/struct_mg_str.md             |  13 ++
 docs/c-api/util.h/intro.md                    |   8 ++
 docs/c-api/util.h/items.json                  |  96 +++++++++++++++
 docs/c-api/util.h/mg_avprintf.md              |  22 ++++
 docs/c-api/util.h/mg_base64_decode.md         |  16 +++
 docs/c-api/util.h/mg_base64_encode.md         |  12 ++
 docs/c-api/util.h/mg_casecmp.md               |  10 ++
 docs/c-api/util.h/mg_conn_addr_to_str.md      |  21 ++++
 docs/c-api/util.h/mg_fopen.md                 |  14 +++
 docs/c-api/util.h/mg_hexdump.md               |  15 +++
 docs/c-api/util.h/mg_hexdump_connection.md    |  15 +++
 docs/c-api/util.h/mg_is_big_endian.md         |  10 ++
 docs/c-api/util.h/mg_match_prefix.md          |  12 ++
 docs/c-api/util.h/mg_mk_str.md                |  10 ++
 docs/c-api/util.h/mg_ncasecmp.md              |  10 ++
 docs/c-api/util.h/mg_next_comma_list_entry.md |  21 ++++
 docs/c-api/util.h/mg_open.md                  |  14 +++
 docs/c-api/util.h/mg_skip.md                  |  17 +++
 docs/c-api/util.h/mg_sock_addr_to_str.md      |  13 ++
 docs/c-api/util.h/mg_sock_to_str.md           |  10 ++
 docs/c-api/util.h/mg_start_thread.md          |  13 ++
 docs/c-api/util.h/mg_stat.md                  |  14 +++
 docs/c-api/util.h/mg_vcasecmp.md              |  11 ++
 docs/c-api/util.h/mg_vcmp.md                  |  11 ++
 docs/design-concept/conn-flags.md             |  32 +++++
 docs/design-concept/event-handler.md          |  31 +++++
 docs/design-concept/events.md                 |  48 ++++++++
 docs/design-concept/intro.md                  |  28 ++---
 docs/design-concept/items.json                |   5 +-
 docs/design-concept/memory-buffers.md         |  21 ++--
 docs/items.json                               |   4 +-
 169 files changed, 3375 insertions(+), 29 deletions(-)
 create mode 100644 docs/build-options/disabling-flags.md
 create mode 100644 docs/build-options/enabling-flags.md
 create mode 100644 docs/build-options/intro.md
 create mode 100644 docs/build-options/items.json
 create mode 100644 docs/build-options/platform-spec.md
 create mode 100644 docs/build-options/tunables.md
 create mode 100644 docs/c-api/coap.h/intro.md
 create mode 100644 docs/c-api/coap.h/items.json
 create mode 100644 docs/c-api/coap.h/mg_coap_add_option.md
 create mode 100644 docs/c-api/coap.h/mg_coap_compose.md
 create mode 100644 docs/c-api/coap.h/mg_coap_free_options.md
 create mode 100644 docs/c-api/coap.h/mg_coap_parse.md
 create mode 100644 docs/c-api/coap.h/mg_coap_send_ack.md
 create mode 100644 docs/c-api/coap.h/mg_coap_send_message.md
 create mode 100644 docs/c-api/coap.h/mg_set_protocol_coap.md
 create mode 100644 docs/c-api/coap.h/struct_mg_coap_message.md
 create mode 100644 docs/c-api/coap.h/struct_mg_coap_option.md
 create mode 100644 docs/c-api/dns-server.h/intro.md
 create mode 100644 docs/c-api/dns-server.h/items.json
 create mode 100644 docs/c-api/dns-server.h/mg_dns_create_reply.md
 create mode 100644 docs/c-api/dns-server.h/mg_dns_reply_record.md
 create mode 100644 docs/c-api/dns-server.h/mg_dns_send_reply.md
 create mode 100644 docs/c-api/dns.h/intro.md
 create mode 100644 docs/c-api/dns.h/items.json
 create mode 100644 docs/c-api/dns.h/mg_dns_copy_body.md
 create mode 100644 docs/c-api/dns.h/mg_dns_encode_record.md
 create mode 100644 docs/c-api/dns.h/mg_dns_insert_header.md
 create mode 100644 docs/c-api/dns.h/mg_dns_parse_record_data.md
 create mode 100644 docs/c-api/dns.h/mg_dns_uncompress_name.md
 create mode 100644 docs/c-api/dns.h/mg_parse_dns.md
 create mode 100644 docs/c-api/dns.h/mg_send_dns_query.md
 create mode 100644 docs/c-api/dns.h/mg_set_protocol_dns.md
 create mode 100644 docs/c-api/dns.h/struct_mg_dns_message.md
 create mode 100644 docs/c-api/dns.h/struct_mg_dns_resource_record.md
 create mode 100644 docs/c-api/http.h/intro.md
 create mode 100644 docs/c-api/http.h/items.json
 create mode 100644 docs/c-api/http.h/mg_connect_http.md
 create mode 100644 docs/c-api/http.h/mg_connect_ws.md
 create mode 100644 docs/c-api/http.h/mg_get_http_header.md
 create mode 100644 docs/c-api/http.h/mg_get_http_var.md
 create mode 100644 docs/c-api/http.h/mg_http_create_digest_auth_header.md
 create mode 100644 docs/c-api/http.h/mg_http_parse_header.md
 create mode 100644 docs/c-api/http.h/mg_parse_http.md
 create mode 100644 docs/c-api/http.h/mg_parse_multipart.md
 create mode 100644 docs/c-api/http.h/mg_printf_html_escape.md
 create mode 100644 docs/c-api/http.h/mg_printf_http_chunk.md
 create mode 100644 docs/c-api/http.h/mg_printf_websocket_frame.md
 create mode 100644 docs/c-api/http.h/mg_send_head.md
 create mode 100644 docs/c-api/http.h/mg_send_http_chunk.md
 create mode 100644 docs/c-api/http.h/mg_send_response_line.md
 create mode 100644 docs/c-api/http.h/mg_send_websocket_frame.md
 create mode 100644 docs/c-api/http.h/mg_send_websocket_framev.md
 create mode 100644 docs/c-api/http.h/mg_send_websocket_handshake.md
 create mode 100644 docs/c-api/http.h/mg_send_websocket_handshake2.md
 create mode 100644 docs/c-api/http.h/mg_serve_http.md
 create mode 100644 docs/c-api/http.h/mg_set_protocol_http_websocket.md
 create mode 100644 docs/c-api/http.h/mg_url_decode.md
 create mode 100644 docs/c-api/http.h/struct_http_message.md
 create mode 100644 docs/c-api/http.h/struct_mg_http_multipart_part.md
 create mode 100644 docs/c-api/http.h/struct_mg_serve_http_opts.md
 create mode 100644 docs/c-api/http.h/struct_websocket_message.md
 create mode 100644 docs/c-api/items.json
 create mode 100644 docs/c-api/json-rpc.h/intro.md
 create mode 100644 docs/c-api/json-rpc.h/items.json
 create mode 100644 docs/c-api/json-rpc.h/mg_rpc_create_error.md
 create mode 100644 docs/c-api/json-rpc.h/mg_rpc_create_reply.md
 create mode 100644 docs/c-api/json-rpc.h/mg_rpc_create_request.md
 create mode 100644 docs/c-api/json-rpc.h/mg_rpc_create_std_error.md
 create mode 100644 docs/c-api/json-rpc.h/mg_rpc_dispatch.md
 create mode 100644 docs/c-api/json-rpc.h/mg_rpc_parse_reply.md
 create mode 100644 docs/c-api/json-rpc.h/struct_mg_rpc_error.md
 create mode 100644 docs/c-api/json-rpc.h/struct_mg_rpc_reply.md
 create mode 100644 docs/c-api/json-rpc.h/struct_mg_rpc_request.md
 create mode 100644 docs/c-api/mbuf.h/intro.md
 create mode 100644 docs/c-api/mbuf.h/items.json
 create mode 100644 docs/c-api/mbuf.h/mbuf_append.md
 create mode 100644 docs/c-api/mbuf.h/mbuf_free.md
 create mode 100644 docs/c-api/mbuf.h/mbuf_init.md
 create mode 100644 docs/c-api/mbuf.h/mbuf_insert.md
 create mode 100644 docs/c-api/mbuf.h/mbuf_remove.md
 create mode 100644 docs/c-api/mbuf.h/mbuf_resize.md
 create mode 100644 docs/c-api/mbuf.h/mbuf_trim.md
 create mode 100644 docs/c-api/mbuf.h/struct_mbuf.md
 create mode 100644 docs/c-api/mqtt-broker.h/intro.md
 create mode 100644 docs/c-api/mqtt-broker.h/items.json
 create mode 100644 docs/c-api/mqtt-broker.h/mg_mqtt_broker.md
 create mode 100644 docs/c-api/mqtt-broker.h/mg_mqtt_broker_init.md
 create mode 100644 docs/c-api/mqtt-broker.h/mg_mqtt_next.md
 create mode 100644 docs/c-api/mqtt-broker.h/struct_mg_mqtt_broker.md
 create mode 100644 docs/c-api/mqtt-broker.h/struct_mg_mqtt_session.md
 create mode 100644 docs/c-api/mqtt.h/intro.md
 create mode 100644 docs/c-api/mqtt.h/items.json
 create mode 100644 docs/c-api/mqtt.h/mg_mqtt_connack.md
 create mode 100644 docs/c-api/mqtt.h/mg_mqtt_disconnect.md
 create mode 100644 docs/c-api/mqtt.h/mg_mqtt_next_subscribe_topic.md
 create mode 100644 docs/c-api/mqtt.h/mg_mqtt_ping.md
 create mode 100644 docs/c-api/mqtt.h/mg_mqtt_pong.md
 create mode 100644 docs/c-api/mqtt.h/mg_mqtt_puback.md
 create mode 100644 docs/c-api/mqtt.h/mg_mqtt_pubcomp.md
 create mode 100644 docs/c-api/mqtt.h/mg_mqtt_publish.md
 create mode 100644 docs/c-api/mqtt.h/mg_mqtt_pubrec.md
 create mode 100644 docs/c-api/mqtt.h/mg_mqtt_pubrel.md
 create mode 100644 docs/c-api/mqtt.h/mg_mqtt_suback.md
 create mode 100644 docs/c-api/mqtt.h/mg_mqtt_subscribe.md
 create mode 100644 docs/c-api/mqtt.h/mg_mqtt_unsuback.md
 create mode 100644 docs/c-api/mqtt.h/mg_mqtt_unsubscribe.md
 create mode 100644 docs/c-api/mqtt.h/mg_send_mqtt_handshake.md
 create mode 100644 docs/c-api/mqtt.h/mg_send_mqtt_handshake_opt.md
 create mode 100644 docs/c-api/mqtt.h/mg_set_protocol_mqtt.md
 create mode 100644 docs/c-api/mqtt.h/struct_mg_mqtt_topic_expression.md
 create mode 100644 docs/c-api/net.h/intro.md
 create mode 100644 docs/c-api/net.h/items.json
 create mode 100644 docs/c-api/net.h/mg_add_sock.md
 create mode 100644 docs/c-api/net.h/mg_add_sock_opt.md
 create mode 100644 docs/c-api/net.h/mg_bind.md
 create mode 100644 docs/c-api/net.h/mg_bind_opt.md
 create mode 100644 docs/c-api/net.h/mg_broadcast.md
 create mode 100644 docs/c-api/net.h/mg_check_ip_acl.md
 create mode 100644 docs/c-api/net.h/mg_connect.md
 create mode 100644 docs/c-api/net.h/mg_connect_opt.md
 create mode 100644 docs/c-api/net.h/mg_enable_javascript.md
 create mode 100644 docs/c-api/net.h/mg_enable_multithreading.md
 create mode 100644 docs/c-api/net.h/mg_mgr_free.md
 create mode 100644 docs/c-api/net.h/mg_mgr_init.md
 create mode 100644 docs/c-api/net.h/mg_mgr_poll.md
 create mode 100644 docs/c-api/net.h/mg_next.md
 create mode 100644 docs/c-api/net.h/mg_printf.md
 create mode 100644 docs/c-api/net.h/mg_send.md
 create mode 100644 docs/c-api/net.h/mg_set_ssl.md
 create mode 100644 docs/c-api/net.h/mg_set_timer.md
 create mode 100644 docs/c-api/net.h/mg_socketpair.md
 create mode 100644 docs/c-api/net.h/mg_time.md
 create mode 100644 docs/c-api/net.h/mg_vprintf.md
 create mode 100644 docs/c-api/net.h/struct_mg_add_sock_opts.md
 create mode 100644 docs/c-api/net.h/struct_mg_bind_opts.md
 create mode 100644 docs/c-api/net.h/struct_mg_connect_opts.md
 create mode 100644 docs/c-api/net.h/struct_mg_connection.md
 create mode 100644 docs/c-api/net.h/struct_mg_mgr.md
 create mode 100644 docs/c-api/net.h/struct_mg_str.md
 create mode 100644 docs/c-api/util.h/intro.md
 create mode 100644 docs/c-api/util.h/items.json
 create mode 100644 docs/c-api/util.h/mg_avprintf.md
 create mode 100644 docs/c-api/util.h/mg_base64_decode.md
 create mode 100644 docs/c-api/util.h/mg_base64_encode.md
 create mode 100644 docs/c-api/util.h/mg_casecmp.md
 create mode 100644 docs/c-api/util.h/mg_conn_addr_to_str.md
 create mode 100644 docs/c-api/util.h/mg_fopen.md
 create mode 100644 docs/c-api/util.h/mg_hexdump.md
 create mode 100644 docs/c-api/util.h/mg_hexdump_connection.md
 create mode 100644 docs/c-api/util.h/mg_is_big_endian.md
 create mode 100644 docs/c-api/util.h/mg_match_prefix.md
 create mode 100644 docs/c-api/util.h/mg_mk_str.md
 create mode 100644 docs/c-api/util.h/mg_ncasecmp.md
 create mode 100644 docs/c-api/util.h/mg_next_comma_list_entry.md
 create mode 100644 docs/c-api/util.h/mg_open.md
 create mode 100644 docs/c-api/util.h/mg_skip.md
 create mode 100644 docs/c-api/util.h/mg_sock_addr_to_str.md
 create mode 100644 docs/c-api/util.h/mg_sock_to_str.md
 create mode 100644 docs/c-api/util.h/mg_start_thread.md
 create mode 100644 docs/c-api/util.h/mg_stat.md
 create mode 100644 docs/c-api/util.h/mg_vcasecmp.md
 create mode 100644 docs/c-api/util.h/mg_vcmp.md
 create mode 100644 docs/design-concept/conn-flags.md
 create mode 100644 docs/design-concept/event-handler.md

diff --git a/docs/build-options/disabling-flags.md b/docs/build-options/disabling-flags.md
new file mode 100644
index 000000000..c88e25b86
--- /dev/null
+++ b/docs/build-options/disabling-flags.md
@@ -0,0 +1,12 @@
+---
+title: Disabling flags
+---
+
+- `MG_DISABLE_HTTP_WEBSOCKET` disable HTTP + Websocket protocol support
+- `MG_DISABLE_HTTP_DIGEST_AUTH` disable HTTP Digest (MD5) authorization support
+- `MG_DISABLE_MQTT` disable MQTT support
+- `MG_DISABLE_SHA1` disable SHA1 support (used by Websocket)
+- `MG_DISABLE_MD5` disable MD5 support (used by HTTP auth)
+- `MG_DISABLE_JSON_RPC` disable JSON-RPC support
+- `MG_DISABLE_SOCKETPAIR` disable `mg_broadcast()` API
+- `MG_DISABLE_HTTP_KEEP_ALIVE` useful for embedded systems to save resources
diff --git a/docs/build-options/enabling-flags.md b/docs/build-options/enabling-flags.md
new file mode 100644
index 000000000..5dfd64595
--- /dev/null
+++ b/docs/build-options/enabling-flags.md
@@ -0,0 +1,11 @@
+---
+title: Enabling flags
+---
+
+- `MG_ENABLE_SSL` Enable OpenSSL support
+- `MG_ENABLE_IPV6` Enable IPV6 support
+- `MG_ENABLE_THREADS` enable `mg_start_thread()` API
+- `MG_ENABLE_MQTT_BROKER` enable MQTT broker
+- `MG_ENABLE_DNS_SERVER` enable DNS server
+- `MG_ENABLE_COAP` enable CoAP protocol
+- `MG_ENABLE_GETADDRINFO` enable `getaddrinfo()` in `mg_resolve2()`
diff --git a/docs/build-options/intro.md b/docs/build-options/intro.md
new file mode 100644
index 000000000..f418a963c
--- /dev/null
+++ b/docs/build-options/intro.md
@@ -0,0 +1,17 @@
+---
+title: Build Options
+---
+
+Mongoose source code ships in a single .c file that contains functionality
+for all supported protocols (modules). Modules can be disabled at compile
+time which reduces executable size. That can be done by setting preprocessor
+flags. Also, some preprocessor flags can be used to tune internal Mongoose
+parameters.
+
+To set a preprocessor flag during compile time, use `-D <PREPROCESSOR_FLAG>`
+compiler option. For example, to disable both MQTT and JSON-RPC,
+compile the application `my_app.c` like this (assumed UNIX system):
+
+```
+  $ cc my_app.c mongoose.c -D MG_DISABLE_MQTT -D MG_DISABLE_JSON_RPC
+```
diff --git a/docs/build-options/items.json b/docs/build-options/items.json
new file mode 100644
index 000000000..2d8c57bdc
--- /dev/null
+++ b/docs/build-options/items.json
@@ -0,0 +1,9 @@
+{
+  "items": [
+    { "type": "markdown", "name": "intro.md" },
+    { "type": "markdown", "name": "enabling-flags.md" },
+    { "type": "markdown", "name": "disabling-flags.md" },
+    { "type": "markdown", "name": "platform-spec.md" },
+    { "type": "markdown", "name": "tunables.md" }
+  ]
+}
diff --git a/docs/build-options/platform-spec.md b/docs/build-options/platform-spec.md
new file mode 100644
index 000000000..408045a89
--- /dev/null
+++ b/docs/build-options/platform-spec.md
@@ -0,0 +1,10 @@
+---
+title: Platform specific
+---
+
+Mongoose tries to detect the target platform whenever possible, but in some cases you have
+to explicitly declare some peculiarities of your target, such as:
+
+- `MG_LWIP`: use LWIP networking stack
+- `MG_CC3200`: enable workarounds for the TI CC3200 target.
+- `MG_ESP8266`: enable workarounds for the ESP8266 target, add `RTOS_SDK` to specify the RTOS SDK flavour.
diff --git a/docs/build-options/tunables.md b/docs/build-options/tunables.md
new file mode 100644
index 000000000..1eeefe427
--- /dev/null
+++ b/docs/build-options/tunables.md
@@ -0,0 +1,11 @@
+---
+title: Tunables
+---
+
+- `MG_MALLOC`, `MG_CALLOC`, `MG_REALLOC`, `MG_FREE` allow to use custom
+  memory allocator, e.g. `-DMG_MALLOC=my_malloc`
+- `MG_USE_READ_WRITE` when set replaces calls to `recv` with `read` and `send` with `write`,
+  thus enabling to add any kind of file descriptor (files, serial devices) to an event manager.
+- `MG_SSL_CRYPTO_MODERN`, `MG_SSL_CRYPTO_OLD` - choose either "Modern" or "Old" ciphers
+  instead of the default "Intermediate" setting.
+  See [this article](https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_configurations) for details.
diff --git a/docs/c-api/coap.h/intro.md b/docs/c-api/coap.h/intro.md
new file mode 100644
index 000000000..764f07775
--- /dev/null
+++ b/docs/c-api/coap.h/intro.md
@@ -0,0 +1,16 @@
+---
+title: "CoAP"
+symbol_kind: "intro"
+decl_name: "coap.h"
+---
+
+CoAP message format:
+
+```
++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
+|Ver| T | TKL | Code | Message ID | Token (if any, TKL bytes) ...
++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
+| Options (if any) ...            |1 1 1 1 1 1 1 1| Payload (if any) ...
++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
+```
+
diff --git a/docs/c-api/coap.h/items.json b/docs/c-api/coap.h/items.json
new file mode 100644
index 000000000..de1889c40
--- /dev/null
+++ b/docs/c-api/coap.h/items.json
@@ -0,0 +1,44 @@
+{
+    "items": [
+        {
+            "type": "markdown",
+            "name": "intro.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_set_protocol_coap.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_coap_add_option.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_coap_free_options.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_coap_send_message.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_coap_send_ack.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_coap_parse.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_coap_compose.md"
+        },
+        {
+            "type": "markdown",
+            "name": "struct_mg_coap_option.md"
+        },
+        {
+            "type": "markdown",
+            "name": "struct_mg_coap_message.md"
+        }
+    ]
+}
diff --git a/docs/c-api/coap.h/mg_coap_add_option.md b/docs/c-api/coap.h/mg_coap_add_option.md
new file mode 100644
index 000000000..f56887e5d
--- /dev/null
+++ b/docs/c-api/coap.h/mg_coap_add_option.md
@@ -0,0 +1,13 @@
+---
+title: "mg_coap_add_option()"
+decl_name: "mg_coap_add_option"
+symbol_kind: "func"
+signature: |
+  struct mg_coap_option *mg_coap_add_option(struct mg_coap_message *cm,
+                                            uint32_t number, char *value,
+                                            size_t len);
+---
+
+Add new option to mg_coap_message structure.
+Returns pointer to the newly created option. 
+
diff --git a/docs/c-api/coap.h/mg_coap_compose.md b/docs/c-api/coap.h/mg_coap_compose.md
new file mode 100644
index 000000000..844c1b61b
--- /dev/null
+++ b/docs/c-api/coap.h/mg_coap_compose.md
@@ -0,0 +1,12 @@
+---
+title: "mg_coap_compose()"
+decl_name: "mg_coap_compose"
+symbol_kind: "func"
+signature: |
+  uint32_t mg_coap_compose(struct mg_coap_message *cm, struct mbuf *io);
+---
+
+Composes CoAP message from mg_coap_message structure.
+This is a helper function.
+Return value: see `mg_coap_send_message()` 
+
diff --git a/docs/c-api/coap.h/mg_coap_free_options.md b/docs/c-api/coap.h/mg_coap_free_options.md
new file mode 100644
index 000000000..39d07d443
--- /dev/null
+++ b/docs/c-api/coap.h/mg_coap_free_options.md
@@ -0,0 +1,11 @@
+---
+title: "mg_coap_free_options()"
+decl_name: "mg_coap_free_options"
+symbol_kind: "func"
+signature: |
+  void mg_coap_free_options(struct mg_coap_message *cm);
+---
+
+Free the memory allocated for options,
+if cm paramater doesn't contain any option does nothing. 
+
diff --git a/docs/c-api/coap.h/mg_coap_parse.md b/docs/c-api/coap.h/mg_coap_parse.md
new file mode 100644
index 000000000..2f3bc0c65
--- /dev/null
+++ b/docs/c-api/coap.h/mg_coap_parse.md
@@ -0,0 +1,22 @@
+---
+title: "mg_coap_parse()"
+decl_name: "mg_coap_parse"
+symbol_kind: "func"
+signature: |
+  uint32_t mg_coap_parse(struct mbuf *io, struct mg_coap_message *cm);
+---
+
+Parse COAP message and fills mg_coap_message and returns cm->flags.
+This is a helper function.
+
+NOTE: usually CoAP work over UDP, so lack of data means format error,
+but in theory it is possible to use CoAP over TCP (according to RFC)
+
+The caller have to check results and treat COAP_NOT_ENOUGH_DATA according to
+underlying protocol:
+
+- in case of UDP COAP_NOT_ENOUGH_DATA means COAP_FORMAT_ERROR,
+- in case of TCP client can try to receive more data
+
+Return value: see `mg_coap_send_message()` 
+
diff --git a/docs/c-api/coap.h/mg_coap_send_ack.md b/docs/c-api/coap.h/mg_coap_send_ack.md
new file mode 100644
index 000000000..5cdd0c1d1
--- /dev/null
+++ b/docs/c-api/coap.h/mg_coap_send_ack.md
@@ -0,0 +1,12 @@
+---
+title: "mg_coap_send_ack()"
+decl_name: "mg_coap_send_ack"
+symbol_kind: "func"
+signature: |
+  uint32_t mg_coap_send_ack(struct mg_connection *nc, uint16_t msg_id);
+---
+
+Compose CoAP acknowledgement from `mg_coap_message`
+and send it into `nc` connection.
+Return value: see `mg_coap_send_message()` 
+
diff --git a/docs/c-api/coap.h/mg_coap_send_message.md b/docs/c-api/coap.h/mg_coap_send_message.md
new file mode 100644
index 000000000..34bf3c87c
--- /dev/null
+++ b/docs/c-api/coap.h/mg_coap_send_message.md
@@ -0,0 +1,19 @@
+---
+title: "mg_coap_send_message()"
+decl_name: "mg_coap_send_message"
+symbol_kind: "func"
+signature: |
+  uint32_t mg_coap_send_message(struct mg_connection *nc,
+                                struct mg_coap_message *cm);
+---
+
+Compose CoAP message from `mg_coap_message`
+and send it into `nc` connection.
+Return 0 on success. On error, it is a bitmask:
+
+- `#define MG_COAP_ERROR 0x10000`
+- `#define MG_COAP_FORMAT_ERROR (MG_COAP_ERROR | 0x20000)`
+- `#define MG_COAP_IGNORE (MG_COAP_ERROR | 0x40000)`
+- `#define MG_COAP_NOT_ENOUGH_DATA (MG_COAP_ERROR | 0x80000)`
+- `#define MG_COAP_NETWORK_ERROR (MG_COAP_ERROR | 0x100000)` 
+
diff --git a/docs/c-api/coap.h/mg_set_protocol_coap.md b/docs/c-api/coap.h/mg_set_protocol_coap.md
new file mode 100644
index 000000000..60981fb6b
--- /dev/null
+++ b/docs/c-api/coap.h/mg_set_protocol_coap.md
@@ -0,0 +1,10 @@
+---
+title: "mg_set_protocol_coap()"
+decl_name: "mg_set_protocol_coap"
+symbol_kind: "func"
+signature: |
+  int mg_set_protocol_coap(struct mg_connection *nc);
+---
+
+Set CoAP protocol handler - trigger CoAP specific events 
+
diff --git a/docs/c-api/coap.h/struct_mg_coap_message.md b/docs/c-api/coap.h/struct_mg_coap_message.md
new file mode 100644
index 000000000..0ea618a90
--- /dev/null
+++ b/docs/c-api/coap.h/struct_mg_coap_message.md
@@ -0,0 +1,20 @@
+---
+title: "struct mg_coap_message"
+decl_name: "struct mg_coap_message"
+symbol_kind: "struct"
+signature: |
+  struct mg_coap_message {
+    uint32_t flags;
+    uint8_t msg_type;
+    uint8_t code_class;
+    uint8_t code_detail;
+    uint16_t msg_id;
+    struct mg_str token;
+    struct mg_coap_option *options;
+    struct mg_str payload;
+    struct mg_coap_option *optiomg_tail;
+  };
+---
+
+CoAP message. See RFC 7252 for details. 
+
diff --git a/docs/c-api/coap.h/struct_mg_coap_option.md b/docs/c-api/coap.h/struct_mg_coap_option.md
new file mode 100644
index 000000000..b5eeb15fa
--- /dev/null
+++ b/docs/c-api/coap.h/struct_mg_coap_option.md
@@ -0,0 +1,16 @@
+---
+title: "struct mg_coap_option"
+decl_name: "struct mg_coap_option"
+symbol_kind: "struct"
+signature: |
+  struct mg_coap_option {
+    struct mg_coap_option *next;
+    uint32_t number;
+    struct mg_str value;
+  };
+---
+
+CoAP options.
+Use mg_coap_add_option and mg_coap_free_options
+for creation and destruction. 
+
diff --git a/docs/c-api/dns-server.h/intro.md b/docs/c-api/dns-server.h/intro.md
new file mode 100644
index 000000000..8ac224dd1
--- /dev/null
+++ b/docs/c-api/dns-server.h/intro.md
@@ -0,0 +1,8 @@
+---
+title: "DNS server"
+symbol_kind: "intro"
+decl_name: "dns-server.h"
+---
+
+Disabled by default; enable with `-DMG_ENABLE_DNS_SERVER`.
+
diff --git a/docs/c-api/dns-server.h/items.json b/docs/c-api/dns-server.h/items.json
new file mode 100644
index 000000000..feea0c960
--- /dev/null
+++ b/docs/c-api/dns-server.h/items.json
@@ -0,0 +1,20 @@
+{
+    "items": [
+        {
+            "type": "markdown",
+            "name": "intro.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_dns_create_reply.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_dns_reply_record.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_dns_send_reply.md"
+        }
+    ]
+}
diff --git a/docs/c-api/dns-server.h/mg_dns_create_reply.md b/docs/c-api/dns-server.h/mg_dns_create_reply.md
new file mode 100644
index 000000000..b616c925d
--- /dev/null
+++ b/docs/c-api/dns-server.h/mg_dns_create_reply.md
@@ -0,0 +1,36 @@
+---
+title: "mg_dns_create_reply()"
+decl_name: "mg_dns_create_reply"
+symbol_kind: "func"
+signature: |
+  struct mg_dns_reply mg_dns_create_reply(struct mbuf *io,
+                                          struct mg_dns_message *msg);
+---
+
+Create a DNS reply.
+
+The reply will be based on an existing query message `msg`.
+The query body will be appended to the output buffer.
+"reply + recursion allowed" will be added to the message flags and
+message's num_answers will be set to 0.
+
+Answer records can be appended with `mg_dns_send_reply` or by lower
+level function defined in the DNS API.
+
+In order to send the reply use `mg_dns_send_reply`.
+It's possible to use a connection's send buffer as reply buffers,
+and it will work for both UDP and TCP connections.
+
+Example:
+
+```c
+reply = mg_dns_create_reply(&nc->send_mbuf, msg);
+for (i = 0; i < msg->num_questions; i++) {
+  rr = &msg->questions[i];
+  if (rr->rtype == MG_DNS_A_RECORD) {
+    mg_dns_reply_record(&reply, rr, 3600, &dummy_ip_addr, 4);
+  }
+}
+mg_dns_send_reply(nc, &reply);
+``` 
+
diff --git a/docs/c-api/dns-server.h/mg_dns_reply_record.md b/docs/c-api/dns-server.h/mg_dns_reply_record.md
new file mode 100644
index 000000000..a247c8eca
--- /dev/null
+++ b/docs/c-api/dns-server.h/mg_dns_reply_record.md
@@ -0,0 +1,18 @@
+---
+title: "mg_dns_reply_record()"
+decl_name: "mg_dns_reply_record"
+symbol_kind: "func"
+signature: |
+  int mg_dns_reply_record(struct mg_dns_reply *reply,
+                          struct mg_dns_resource_record *question,
+                          const char *name, int rtype, int ttl, const void *rdata,
+                          size_t rdata_len);
+---
+
+Append a DNS reply record to the IO buffer and to the DNS message.
+
+The message num_answers field will be incremented. It's caller's duty
+to ensure num_answers is propertly initialized.
+
+Returns -1 on error. 
+
diff --git a/docs/c-api/dns-server.h/mg_dns_send_reply.md b/docs/c-api/dns-server.h/mg_dns_send_reply.md
new file mode 100644
index 000000000..d5b15de49
--- /dev/null
+++ b/docs/c-api/dns-server.h/mg_dns_send_reply.md
@@ -0,0 +1,19 @@
+---
+title: "mg_dns_send_reply()"
+decl_name: "mg_dns_send_reply"
+symbol_kind: "func"
+signature: |
+  void mg_dns_send_reply(struct mg_connection *nc, struct mg_dns_reply *r);
+---
+
+Send a DNS reply through a connection.
+
+The DNS data is stored in an IO buffer pointed by reply structure in `r`.
+This function mutates the content of that buffer in order to ensure that
+the DNS header reflects size and flags of the mssage, that might have been
+updated either with `mg_dns_reply_record` or by direct manipulation of
+`r->message`.
+
+Once sent, the IO buffer will be trimmed unless the reply IO buffer
+is the connection's send buffer and the connection is not in UDP mode. 
+
diff --git a/docs/c-api/dns.h/intro.md b/docs/c-api/dns.h/intro.md
new file mode 100644
index 000000000..d9522b18e
--- /dev/null
+++ b/docs/c-api/dns.h/intro.md
@@ -0,0 +1,8 @@
+---
+title: "DNS"
+symbol_kind: "intro"
+decl_name: "dns.h"
+---
+
+
+
diff --git a/docs/c-api/dns.h/items.json b/docs/c-api/dns.h/items.json
new file mode 100644
index 000000000..aa3452e7b
--- /dev/null
+++ b/docs/c-api/dns.h/items.json
@@ -0,0 +1,48 @@
+{
+    "items": [
+        {
+            "type": "markdown",
+            "name": "intro.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_dns_parse_record_data.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_send_dns_query.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_dns_insert_header.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_dns_copy_body.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_dns_encode_record.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_parse_dns.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_dns_uncompress_name.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_set_protocol_dns.md"
+        },
+        {
+            "type": "markdown",
+            "name": "struct_mg_dns_resource_record.md"
+        },
+        {
+            "type": "markdown",
+            "name": "struct_mg_dns_message.md"
+        }
+    ]
+}
diff --git a/docs/c-api/dns.h/mg_dns_copy_body.md b/docs/c-api/dns.h/mg_dns_copy_body.md
new file mode 100644
index 000000000..b2ff61e6e
--- /dev/null
+++ b/docs/c-api/dns.h/mg_dns_copy_body.md
@@ -0,0 +1,15 @@
+---
+title: "mg_dns_copy_body()"
+decl_name: "mg_dns_copy_body"
+symbol_kind: "func"
+signature: |
+  int mg_dns_copy_body(struct mbuf *io, struct mg_dns_message *msg);
+---
+
+Append already encoded body from an existing message.
+
+This is useful when generating a DNS reply message which includes
+all question records.
+
+Return number of appened bytes. 
+
diff --git a/docs/c-api/dns.h/mg_dns_encode_record.md b/docs/c-api/dns.h/mg_dns_encode_record.md
new file mode 100644
index 000000000..4b8a98504
--- /dev/null
+++ b/docs/c-api/dns.h/mg_dns_encode_record.md
@@ -0,0 +1,25 @@
+---
+title: "mg_dns_encode_record()"
+decl_name: "mg_dns_encode_record"
+symbol_kind: "func"
+signature: |
+  int mg_dns_encode_record(struct mbuf *io, struct mg_dns_resource_record *rr,
+                           const char *name, size_t nlen, const void *rdata,
+                           size_t rlen);
+---
+
+Encode and append a DNS resource record to an IO buffer.
+
+The record metadata is taken from the `rr` parameter, while the name and data
+are taken from the parameters, encoded in the appropriate format depending on
+record type, and stored in the IO buffer. The encoded values might contain
+offsets within the IO buffer. It's thus important that the IO buffer doesn't
+get trimmed while a sequence of records are encoded while preparing a DNS
+*reply.
+
+This function doesn't update the `name` and `rdata` pointers in the `rr`
+*struct
+because they might be invalidated as soon as the IO buffer grows again.
+
+Return the number of bytes appened or -1 in case of error. 
+
diff --git a/docs/c-api/dns.h/mg_dns_insert_header.md b/docs/c-api/dns.h/mg_dns_insert_header.md
new file mode 100644
index 000000000..0a9d7dae4
--- /dev/null
+++ b/docs/c-api/dns.h/mg_dns_insert_header.md
@@ -0,0 +1,13 @@
+---
+title: "mg_dns_insert_header()"
+decl_name: "mg_dns_insert_header"
+symbol_kind: "func"
+signature: |
+  int mg_dns_insert_header(struct mbuf *io, size_t pos,
+                           struct mg_dns_message *msg);
+---
+
+Insert a DNS header to an IO buffer.
+
+Return number of bytes inserted. 
+
diff --git a/docs/c-api/dns.h/mg_dns_parse_record_data.md b/docs/c-api/dns.h/mg_dns_parse_record_data.md
new file mode 100644
index 000000000..d8239befe
--- /dev/null
+++ b/docs/c-api/dns.h/mg_dns_parse_record_data.md
@@ -0,0 +1,20 @@
+---
+title: "mg_dns_parse_record_data()"
+decl_name: "mg_dns_parse_record_data"
+symbol_kind: "func"
+signature: |
+  int mg_dns_parse_record_data(struct mg_dns_message *msg,
+                               struct mg_dns_resource_record *rr, void *data,
+                               size_t data_len);
+---
+
+Parse the record data from a DNS resource record.
+
+ - A:     struct in_addr *ina
+ - AAAA:  struct in6_addr *ina
+ - CNAME: char buffer
+
+Returns -1 on error.
+
+TODO(mkm): MX 
+
diff --git a/docs/c-api/dns.h/mg_dns_uncompress_name.md b/docs/c-api/dns.h/mg_dns_uncompress_name.md
new file mode 100644
index 000000000..3db03df89
--- /dev/null
+++ b/docs/c-api/dns.h/mg_dns_uncompress_name.md
@@ -0,0 +1,21 @@
+---
+title: "mg_dns_uncompress_name()"
+decl_name: "mg_dns_uncompress_name"
+symbol_kind: "func"
+signature: |
+  size_t mg_dns_uncompress_name(struct mg_dns_message *msg, struct mg_str *name,
+                                char *dst, int dst_len);
+---
+
+Uncompress a DNS compressed name.
+
+The containing dns message is required because the compressed encoding
+and reference suffixes present elsewhere in the packet.
+
+If name is less than `dst_len` characters long, the remainder
+of `dst` is terminated with `\0' characters. Otherwise, `dst` is not
+*terminated.
+
+If `dst_len` is 0 `dst` can be NULL.
+Return the uncompressed name length. 
+
diff --git a/docs/c-api/dns.h/mg_parse_dns.md b/docs/c-api/dns.h/mg_parse_dns.md
new file mode 100644
index 000000000..3e28efeed
--- /dev/null
+++ b/docs/c-api/dns.h/mg_parse_dns.md
@@ -0,0 +1,10 @@
+---
+title: "mg_parse_dns()"
+decl_name: "mg_parse_dns"
+symbol_kind: "func"
+signature: |
+  int mg_parse_dns(const char *buf, int len, struct mg_dns_message *msg);
+---
+
+Low-level: parses a DNS response. 
+
diff --git a/docs/c-api/dns.h/mg_send_dns_query.md b/docs/c-api/dns.h/mg_send_dns_query.md
new file mode 100644
index 000000000..5dd22c368
--- /dev/null
+++ b/docs/c-api/dns.h/mg_send_dns_query.md
@@ -0,0 +1,11 @@
+---
+title: "mg_send_dns_query()"
+decl_name: "mg_send_dns_query"
+symbol_kind: "func"
+signature: |
+  void mg_send_dns_query(struct mg_connection *nc, const char *name,
+                         int query_type);
+---
+
+Send a DNS query to the remote end. 
+
diff --git a/docs/c-api/dns.h/mg_set_protocol_dns.md b/docs/c-api/dns.h/mg_set_protocol_dns.md
new file mode 100644
index 000000000..7d7d0dc4f
--- /dev/null
+++ b/docs/c-api/dns.h/mg_set_protocol_dns.md
@@ -0,0 +1,19 @@
+---
+title: "mg_set_protocol_dns()"
+decl_name: "mg_set_protocol_dns"
+symbol_kind: "func"
+signature: |
+  void mg_set_protocol_dns(struct mg_connection *nc);
+---
+
+Attach built-in DNS event handler to the given listening connection.
+
+DNS event handler parses incoming UDP packets, treating them as DNS
+requests. If incoming packet gets successfully parsed by the DNS event
+handler, a user event handler will receive `MG_DNS_REQUEST` event, with
+`ev_data` pointing to the parsed `struct mg_dns_message`.
+
+See
+[captive_dns_server](https://github.com/cesanta/mongoose/tree/master/examples/captive_dns_server)
+example on how to handle DNS request and send DNS reply. 
+
diff --git a/docs/c-api/dns.h/struct_mg_dns_message.md b/docs/c-api/dns.h/struct_mg_dns_message.md
new file mode 100644
index 000000000..9838bec9c
--- /dev/null
+++ b/docs/c-api/dns.h/struct_mg_dns_message.md
@@ -0,0 +1,18 @@
+---
+title: "struct mg_dns_message"
+decl_name: "struct mg_dns_message"
+symbol_kind: "struct"
+signature: |
+  struct mg_dns_message {
+    struct mg_str pkt; /* packet body */
+    uint16_t flags;
+    uint16_t transaction_id;
+    int num_questions;
+    int num_answers;
+    struct mg_dns_resource_record questions[MG_MAX_DNS_QUESTIONS];
+    struct mg_dns_resource_record answers[MG_MAX_DNS_ANSWERS];
+  };
+---
+
+DNS message (request and response). 
+
diff --git a/docs/c-api/dns.h/struct_mg_dns_resource_record.md b/docs/c-api/dns.h/struct_mg_dns_resource_record.md
new file mode 100644
index 000000000..8ff7af403
--- /dev/null
+++ b/docs/c-api/dns.h/struct_mg_dns_resource_record.md
@@ -0,0 +1,17 @@
+---
+title: "struct mg_dns_resource_record"
+decl_name: "struct mg_dns_resource_record"
+symbol_kind: "struct"
+signature: |
+  struct mg_dns_resource_record {
+    struct mg_str name; /* buffer with compressed name */
+    int rtype;
+    int rclass;
+    int ttl;
+    enum mg_dns_resource_record_kind kind;
+    struct mg_str rdata; /* protocol data (can be a compressed name) */
+  };
+---
+
+DNS resource record. 
+
diff --git a/docs/c-api/http.h/intro.md b/docs/c-api/http.h/intro.md
new file mode 100644
index 000000000..730204713
--- /dev/null
+++ b/docs/c-api/http.h/intro.md
@@ -0,0 +1,8 @@
+---
+title: "HTTP + Websocket"
+symbol_kind: "intro"
+decl_name: "http.h"
+---
+
+
+
diff --git a/docs/c-api/http.h/items.json b/docs/c-api/http.h/items.json
new file mode 100644
index 000000000..037e457b3
--- /dev/null
+++ b/docs/c-api/http.h/items.json
@@ -0,0 +1,108 @@
+{
+    "items": [
+        {
+            "type": "markdown",
+            "name": "intro.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_set_protocol_http_websocket.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_send_websocket_handshake.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_send_websocket_handshake2.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_connect_ws.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_send_websocket_frame.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_send_websocket_framev.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_printf_websocket_frame.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_send_http_chunk.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_printf_http_chunk.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_send_response_line.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_send_head.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_printf_html_escape.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_parse_http.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_get_http_header.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_http_parse_header.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_parse_multipart.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_get_http_var.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_url_decode.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_http_create_digest_auth_header.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_connect_http.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_serve_http.md"
+        },
+        {
+            "type": "markdown",
+            "name": "struct_http_message.md"
+        },
+        {
+            "type": "markdown",
+            "name": "struct_websocket_message.md"
+        },
+        {
+            "type": "markdown",
+            "name": "struct_mg_http_multipart_part.md"
+        },
+        {
+            "type": "markdown",
+            "name": "struct_mg_serve_http_opts.md"
+        }
+    ]
+}
diff --git a/docs/c-api/http.h/mg_connect_http.md b/docs/c-api/http.h/mg_connect_http.md
new file mode 100644
index 000000000..b897be0ce
--- /dev/null
+++ b/docs/c-api/http.h/mg_connect_http.md
@@ -0,0 +1,35 @@
+---
+title: "mg_connect_http()"
+decl_name: "mg_connect_http"
+symbol_kind: "func"
+signature: |
+  struct mg_connection *mg_connect_http(struct mg_mgr *mgr,
+                                        mg_event_handler_t event_handler,
+                                        const char *url,
+                                        const char *extra_headers,
+                                        const char *post_data);
+---
+
+Helper function that creates outbound HTTP connection.
+
+`url` is a URL to fetch. It must be properly URL-encoded, e.g. have
+no spaces, etc. By default, `mg_connect_http()` sends Connection and
+Host headers. `extra_headers` is an extra HTTP headers to send, e.g.
+`"User-Agent: my-app\r\n"`.
+If `post_data` is NULL, then GET request is created. Otherwise, POST request
+is created with the specified POST data. Note that if the data being posted
+is a form submission, the `Content-Type` header should be set accordingly
+(see example below).
+
+Examples:
+
+```c
+  nc1 = mg_connect_http(mgr, ev_handler_1, "http://www.google.com", NULL,
+                        NULL);
+  nc2 = mg_connect_http(mgr, ev_handler_1, "https://github.com", NULL, NULL);
+  nc3 = mg_connect_http(
+      mgr, ev_handler_1, "my_server:8000/form_submit/",
+      "Content-Type: application/x-www-form-urlencoded\r\n",
+      "var_1=value_1&var_2=value_2");
+``` 
+
diff --git a/docs/c-api/http.h/mg_connect_ws.md b/docs/c-api/http.h/mg_connect_ws.md
new file mode 100644
index 000000000..417279c86
--- /dev/null
+++ b/docs/c-api/http.h/mg_connect_ws.md
@@ -0,0 +1,30 @@
+---
+title: "mg_connect_ws()"
+decl_name: "mg_connect_ws"
+symbol_kind: "func"
+signature: |
+  struct mg_connection *mg_connect_ws(struct mg_mgr *mgr,
+                                      mg_event_handler_t event_handler,
+                                      const char *url, const char *protocol,
+                                      const char *extra_headers);
+---
+
+Helper function that creates an outbound WebSocket connection.
+
+`url` is a URL to connect to. It must be properly URL-encoded, e.g. have
+no spaces, etc. By default, `mg_connect_ws()` sends Connection and
+Host headers. `extra_headers` is an extra HTTP headers to send, e.g.
+`"User-Agent: my-app\r\n"`.
+If `protocol` is not NULL, then a `Sec-WebSocket-Protocol` header is sent.
+
+Examples:
+
+```c
+  nc1 = mg_connect_ws(mgr, ev_handler_1, "ws://echo.websocket.org", NULL,
+                      NULL);
+  nc2 = mg_connect_ws(mgr, ev_handler_1, "wss://echo.websocket.org", NULL,
+                      NULL);
+  nc3 = mg_connect_ws(mgr, ev_handler_1, "ws://api.cesanta.com",
+                      "clubby.cesanta.com", NULL);
+``` 
+
diff --git a/docs/c-api/http.h/mg_get_http_header.md b/docs/c-api/http.h/mg_get_http_header.md
new file mode 100644
index 000000000..5c6d85ba1
--- /dev/null
+++ b/docs/c-api/http.h/mg_get_http_header.md
@@ -0,0 +1,13 @@
+---
+title: "mg_get_http_header()"
+decl_name: "mg_get_http_header"
+symbol_kind: "func"
+signature: |
+  struct mg_str *mg_get_http_header(struct http_message *hm, const char *name);
+---
+
+Search and return header `name` in parsed HTTP message `hm`.
+If header is not found, NULL is returned. Example:
+
+    struct mg_str *host_hdr = mg_get_http_header(hm, "Host"); 
+
diff --git a/docs/c-api/http.h/mg_get_http_var.md b/docs/c-api/http.h/mg_get_http_var.md
new file mode 100644
index 000000000..cc54c2ebe
--- /dev/null
+++ b/docs/c-api/http.h/mg_get_http_var.md
@@ -0,0 +1,16 @@
+---
+title: "mg_get_http_var()"
+decl_name: "mg_get_http_var"
+symbol_kind: "func"
+signature: |
+  int mg_get_http_var(const struct mg_str *buf, const char *name, char *dst,
+                      size_t dst_len);
+---
+
+Fetch an HTTP form variable.
+
+Fetch a variable `name` from a `buf` into a buffer specified by
+`dst`, `dst_len`. Destination is always zero-terminated. Return length
+of a fetched variable. If not found, 0 is returned. `buf` must be
+valid url-encoded buffer. If destination is too small, `-1` is returned. 
+
diff --git a/docs/c-api/http.h/mg_http_create_digest_auth_header.md b/docs/c-api/http.h/mg_http_create_digest_auth_header.md
new file mode 100644
index 000000000..dd98fdc1d
--- /dev/null
+++ b/docs/c-api/http.h/mg_http_create_digest_auth_header.md
@@ -0,0 +1,13 @@
+---
+title: "mg_http_create_digest_auth_header()"
+decl_name: "mg_http_create_digest_auth_header"
+symbol_kind: "func"
+signature: |
+  int mg_http_create_digest_auth_header(char *buf, size_t buf_len,
+                                        const char *method, const char *uri,
+                                        const char *auth_domain, const char *user,
+                                        const char *passwd);
+---
+
+Create Digest authentication header for client request. 
+
diff --git a/docs/c-api/http.h/mg_http_parse_header.md b/docs/c-api/http.h/mg_http_parse_header.md
new file mode 100644
index 000000000..cd7beb6e0
--- /dev/null
+++ b/docs/c-api/http.h/mg_http_parse_header.md
@@ -0,0 +1,23 @@
+---
+title: "mg_http_parse_header()"
+decl_name: "mg_http_parse_header"
+symbol_kind: "func"
+signature: |
+  int mg_http_parse_header(struct mg_str *hdr, const char *var_name, char *buf,
+                           size_t buf_size);
+---
+
+Parse HTTP header `hdr`. Find variable `var_name` and store it's value
+in the buffer `buf`, `buf_size`. Return 0 if variable not found, non-zero
+otherwise.
+
+This function is supposed to parse
+cookies, authentication headers, etcetera. Example (error handling omitted):
+
+    char user[20];
+    struct mg_str *hdr = mg_get_http_header(hm, "Authorization");
+    mg_http_parse_header(hdr, "username", user, sizeof(user));
+
+Return length of the variable's value. If buffer is not large enough,
+or variable not found, 0 is returned. 
+
diff --git a/docs/c-api/http.h/mg_parse_http.md b/docs/c-api/http.h/mg_parse_http.md
new file mode 100644
index 000000000..068ddc16d
--- /dev/null
+++ b/docs/c-api/http.h/mg_parse_http.md
@@ -0,0 +1,15 @@
+---
+title: "mg_parse_http()"
+decl_name: "mg_parse_http"
+symbol_kind: "func"
+signature: |
+  int mg_parse_http(const char *s, int n, struct http_message *hm, int is_req);
+---
+
+Parse a HTTP message.
+
+`is_req` should be set to 1 if parsing request, 0 if reply.
+
+Return number of bytes parsed. If HTTP message is
+incomplete, `0` is returned. On parse error, negative number is returned. 
+
diff --git a/docs/c-api/http.h/mg_parse_multipart.md b/docs/c-api/http.h/mg_parse_multipart.md
new file mode 100644
index 000000000..3eb82cdb7
--- /dev/null
+++ b/docs/c-api/http.h/mg_parse_multipart.md
@@ -0,0 +1,46 @@
+---
+title: "mg_parse_multipart()"
+decl_name: "mg_parse_multipart"
+symbol_kind: "func"
+signature: |
+  size_t mg_parse_multipart(const char *buf, size_t buf_len, char *var_name,
+                            size_t var_name_len, char *file_name,
+                            size_t file_name_len, const char **chunk,
+                            size_t *chunk_len);
+---
+
+Parse buffer `buf`, `buf_len` that contains multipart form data chunks.
+Store chunk name in a `var_name`, `var_name_len` buffer.
+If a chunk is an uploaded file, then `file_name`, `file_name_len` is
+filled with an uploaded file name. `chunk`, `chunk_len`
+points to the chunk data.
+
+Return: number of bytes to skip to the next chunk, or 0 if there are
+        no more chunks.
+
+Usage example:
+
+```c
+   static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
+     switch(ev) {
+       case MG_EV_HTTP_REQUEST: {
+         struct http_message *hm = (struct http_message *) ev_data;
+         char var_name[100], file_name[100];
+         const char *chunk;
+         size_t chunk_len, n1, n2;
+
+         n1 = n2 = 0;
+         while ((n2 = mg_parse_multipart(hm->body.p + n1,
+                                         hm->body.len - n1,
+                                         var_name, sizeof(var_name),
+                                         file_name, sizeof(file_name),
+                                         &chunk, &chunk_len)) > 0) {
+           printf("var: %s, file_name: %s, size: %d, chunk: [%.*s]\n",
+                  var_name, file_name, (int) chunk_len,
+                  (int) chunk_len, chunk);
+           n1 += n2;
+         }
+       }
+       break;
+``` 
+
diff --git a/docs/c-api/http.h/mg_printf_html_escape.md b/docs/c-api/http.h/mg_printf_html_escape.md
new file mode 100644
index 000000000..fd1ff3e0a
--- /dev/null
+++ b/docs/c-api/http.h/mg_printf_html_escape.md
@@ -0,0 +1,10 @@
+---
+title: "mg_printf_html_escape()"
+decl_name: "mg_printf_html_escape"
+symbol_kind: "func"
+signature: |
+  void mg_printf_html_escape(struct mg_connection *nc, const char *fmt, ...);
+---
+
+Send printf-formatted HTTP chunk, escaping HTML tags. 
+
diff --git a/docs/c-api/http.h/mg_printf_http_chunk.md b/docs/c-api/http.h/mg_printf_http_chunk.md
new file mode 100644
index 000000000..a8e6d1427
--- /dev/null
+++ b/docs/c-api/http.h/mg_printf_http_chunk.md
@@ -0,0 +1,11 @@
+---
+title: "mg_printf_http_chunk()"
+decl_name: "mg_printf_http_chunk"
+symbol_kind: "func"
+signature: |
+  void mg_printf_http_chunk(struct mg_connection *nc, const char *fmt, ...);
+---
+
+Send printf-formatted HTTP chunk.
+Functionality is similar to `mg_send_http_chunk()`. 
+
diff --git a/docs/c-api/http.h/mg_printf_websocket_frame.md b/docs/c-api/http.h/mg_printf_websocket_frame.md
new file mode 100644
index 000000000..a65612999
--- /dev/null
+++ b/docs/c-api/http.h/mg_printf_websocket_frame.md
@@ -0,0 +1,14 @@
+---
+title: "mg_printf_websocket_frame()"
+decl_name: "mg_printf_websocket_frame"
+symbol_kind: "func"
+signature: |
+  void mg_printf_websocket_frame(struct mg_connection *nc, int op_and_flags,
+                                 const char *fmt, ...);
+---
+
+Send websocket frame to the remote end.
+
+Like `mg_send_websocket_frame()`, but allows to create formatted message
+with `printf()`-like semantics. 
+
diff --git a/docs/c-api/http.h/mg_send_head.md b/docs/c-api/http.h/mg_send_head.md
new file mode 100644
index 000000000..cd18d36c9
--- /dev/null
+++ b/docs/c-api/http.h/mg_send_head.md
@@ -0,0 +1,21 @@
+---
+title: "mg_send_head()"
+decl_name: "mg_send_head"
+symbol_kind: "func"
+signature: |
+  void mg_send_head(struct mg_connection *n, int status_code,
+                    int64_t content_length, const char *extra_headers);
+---
+
+Send response line and headers.
+This function sends response line with the `status_code`, and automatically
+sends one header: either "Content-Length", or "Transfer-Encoding".
+If `content_length` is negative, then "Transfer-Encoding: chunked" header
+is sent, otherwise, "Content-Length" header is sent.
+
+NOTE: If `Transfer-Encoding` is `chunked`, then message body must be sent
+using `mg_send_http_chunk()` or `mg_printf_http_chunk()` functions.
+Otherwise, `mg_send()` or `mg_printf()` must be used.
+Extra headers could be set through `extra_headers` - and note `extra_headers`
+must NOT be terminated by a new line. 
+
diff --git a/docs/c-api/http.h/mg_send_http_chunk.md b/docs/c-api/http.h/mg_send_http_chunk.md
new file mode 100644
index 000000000..6d017fbbe
--- /dev/null
+++ b/docs/c-api/http.h/mg_send_http_chunk.md
@@ -0,0 +1,25 @@
+---
+title: "mg_send_http_chunk()"
+decl_name: "mg_send_http_chunk"
+symbol_kind: "func"
+signature: |
+  void mg_send_http_chunk(struct mg_connection *nc, const char *buf, size_t len);
+---
+
+Send buffer `buf` of size `len` to the client using chunked HTTP encoding.
+This function first sends buffer size as hex number + newline, then
+buffer itself, then newline. For example,
+  `mg_send_http_chunk(nc, "foo", 3)` whill append `3\r\nfoo\r\n` string to
+the `nc->send_mbuf` output IO buffer.
+
+NOTE: HTTP header "Transfer-Encoding: chunked" should be sent prior to
+using this function.
+
+NOTE: do not forget to send empty chunk at the end of the response,
+to tell the client that everything was sent. Example:
+
+```
+  mg_printf_http_chunk(nc, "%s", "my response!");
+  mg_send_http_chunk(nc, "", 0); // Tell the client we're finished
+``` 
+
diff --git a/docs/c-api/http.h/mg_send_response_line.md b/docs/c-api/http.h/mg_send_response_line.md
new file mode 100644
index 000000000..8f62d717f
--- /dev/null
+++ b/docs/c-api/http.h/mg_send_response_line.md
@@ -0,0 +1,21 @@
+---
+title: "mg_send_response_line()"
+decl_name: "mg_send_response_line"
+symbol_kind: "func"
+signature: |
+  void mg_send_response_line(struct mg_connection *c, int status_code,
+                             const char *extra_headers);
+---
+
+Send response status line.
+If `extra_headers` is not NULL, then `extra_headers` are also sent
+after the reponse line. `extra_headers` must NOT end end with new line.
+Example:
+
+     mg_send_response_line(nc, 200, "Access-Control-Allow-Origin: *");
+
+Will result in:
+
+     HTTP/1.1 200 OK\r\n
+     Access-Control-Allow-Origin: *\r\n 
+
diff --git a/docs/c-api/http.h/mg_send_websocket_frame.md b/docs/c-api/http.h/mg_send_websocket_frame.md
new file mode 100644
index 000000000..bcc5d0c57
--- /dev/null
+++ b/docs/c-api/http.h/mg_send_websocket_frame.md
@@ -0,0 +1,26 @@
+---
+title: "mg_send_websocket_frame()"
+decl_name: "mg_send_websocket_frame"
+symbol_kind: "func"
+signature: |
+  void mg_send_websocket_frame(struct mg_connection *nc, int op_and_flags,
+                               const void *data, size_t data_len);
+---
+
+Send websocket frame to the remote end.
+
+`op_and_flags` specifies frame's type, one of:
+
+- WEBSOCKET_OP_CONTINUE
+- WEBSOCKET_OP_TEXT
+- WEBSOCKET_OP_BINARY
+- WEBSOCKET_OP_CLOSE
+- WEBSOCKET_OP_PING
+- WEBSOCKET_OP_PONG
+
+Orred with one of the flags:
+
+- WEBSOCKET_DONT_FIN: Don't set the FIN flag on the frame to be sent.
+
+`data` and `data_len` contain frame data. 
+
diff --git a/docs/c-api/http.h/mg_send_websocket_framev.md b/docs/c-api/http.h/mg_send_websocket_framev.md
new file mode 100644
index 000000000..4eb3709f9
--- /dev/null
+++ b/docs/c-api/http.h/mg_send_websocket_framev.md
@@ -0,0 +1,13 @@
+---
+title: "mg_send_websocket_framev()"
+decl_name: "mg_send_websocket_framev"
+symbol_kind: "func"
+signature: |
+  void mg_send_websocket_framev(struct mg_connection *nc, int op_and_flags,
+                                const struct mg_str *strings, int num_strings);
+---
+
+Send multiple websocket frames.
+
+Like `mg_send_websocket_frame()`, but composes a frame from multiple buffers. 
+
diff --git a/docs/c-api/http.h/mg_send_websocket_handshake.md b/docs/c-api/http.h/mg_send_websocket_handshake.md
new file mode 100644
index 000000000..20ee7017b
--- /dev/null
+++ b/docs/c-api/http.h/mg_send_websocket_handshake.md
@@ -0,0 +1,22 @@
+---
+title: "mg_send_websocket_handshake()"
+decl_name: "mg_send_websocket_handshake"
+symbol_kind: "func"
+signature: |
+  void mg_send_websocket_handshake(struct mg_connection *nc, const char *uri,
+                                   const char *extra_headers);
+---
+
+Send websocket handshake to the server.
+
+`nc` must be a valid connection, connected to a server. `uri` is an URI
+to fetch, extra_headers` is extra HTTP headers to send or `NULL`.
+
+This function is intended to be used by websocket client.
+
+Note that the Host header is mandatory in HTTP/1.1 and must be
+included in `extra_headers`. `mg_send_websocket_handshake2` offers
+a better API for that.
+
+Deprecated in favour of `mg_send_websocket_handshake2` 
+
diff --git a/docs/c-api/http.h/mg_send_websocket_handshake2.md b/docs/c-api/http.h/mg_send_websocket_handshake2.md
new file mode 100644
index 000000000..27c5c3b82
--- /dev/null
+++ b/docs/c-api/http.h/mg_send_websocket_handshake2.md
@@ -0,0 +1,19 @@
+---
+title: "mg_send_websocket_handshake2()"
+decl_name: "mg_send_websocket_handshake2"
+symbol_kind: "func"
+signature: |
+  void mg_send_websocket_handshake2(struct mg_connection *nc, const char *path,
+                                    const char *host, const char *protocol,
+                                    const char *extra_headers);
+---
+
+Send websocket handshake to the server.
+
+`nc` must be a valid connection, connected to a server. `uri` is an URI
+to fetch, `host` goes into the `Host` header, `protocol` goes into the
+`Sec-WebSocket-Proto` header (NULL to omit), extra_headers` is extra HTTP
+headers to send or `NULL`.
+
+This function is intended to be used by websocket client. 
+
diff --git a/docs/c-api/http.h/mg_serve_http.md b/docs/c-api/http.h/mg_serve_http.md
new file mode 100644
index 000000000..22b326887
--- /dev/null
+++ b/docs/c-api/http.h/mg_serve_http.md
@@ -0,0 +1,28 @@
+---
+title: "mg_serve_http()"
+decl_name: "mg_serve_http"
+symbol_kind: "func"
+signature: |
+  void mg_serve_http(struct mg_connection *nc, struct http_message *hm,
+                     struct mg_serve_http_opts opts);
+---
+
+Serve given HTTP request according to the `options`.
+
+Example code snippet:
+
+```c
+static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
+  struct http_message *hm = (struct http_message *) ev_data;
+  struct mg_serve_http_opts opts = { .document_root = "/var/www" };  // C99
+
+  switch (ev) {
+    case MG_EV_HTTP_REQUEST:
+      mg_serve_http(nc, hm, opts);
+      break;
+    default:
+      break;
+  }
+}
+``` 
+
diff --git a/docs/c-api/http.h/mg_set_protocol_http_websocket.md b/docs/c-api/http.h/mg_set_protocol_http_websocket.md
new file mode 100644
index 000000000..9dcefcba3
--- /dev/null
+++ b/docs/c-api/http.h/mg_set_protocol_http_websocket.md
@@ -0,0 +1,50 @@
+---
+title: "mg_set_protocol_http_websocket()"
+decl_name: "mg_set_protocol_http_websocket"
+symbol_kind: "func"
+signature: |
+  void mg_set_protocol_http_websocket(struct mg_connection *nc);
+---
+
+Attach built-in HTTP event handler to the given connection.
+User-defined event handler will receive following extra events:
+
+- MG_EV_HTTP_REQUEST: HTTP request has arrived. Parsed HTTP request
+ is passed as
+  `struct http_message` through the handler's `void *ev_data` pointer.
+- MG_EV_HTTP_MULTIPART_REQUEST: A multipart POST request has received.
+  This event is sent before body is parsed. After this user
+  should expect a sequence of MG_EV_HTTP_PART_BEGIN/DATA/END requests.
+  This is also the last time when headers and other request fields are
+  accessible.
+- MG_EV_HTTP_REPLY: HTTP reply has arrived. Parsed HTTP reply is passed as
+  `struct http_message` through the handler's `void *ev_data` pointer.
+- MG_EV_HTTP_CHUNK: HTTP chunked-encoding chunk has arrived.
+  Parsed HTTP reply is passed as `struct http_message` through the
+  handler's `void *ev_data` pointer. `http_message::body` would contain
+  incomplete, reassembled HTTP body.
+  It will grow with every new chunk arrived, and
+  potentially can consume a lot of memory. An event handler may process
+  the body as chunks are coming, and signal Mongoose to delete processed
+  body by setting `MG_F_DELETE_CHUNK` in `mg_connection::flags`. When
+  the last zero chunk is received,
+  Mongoose sends `MG_EV_HTTP_REPLY` event with
+  full reassembled body (if handler did not signal to delete chunks) or
+  with empty body (if handler did signal to delete chunks).
+- MG_EV_WEBSOCKET_HANDSHAKE_REQUEST: server has received websocket handshake
+  request. `ev_data` contains parsed HTTP request.
+- MG_EV_WEBSOCKET_HANDSHAKE_DONE: server has completed Websocket handshake.
+  `ev_data` is `NULL`.
+- MG_EV_WEBSOCKET_FRAME: new websocket frame has arrived. `ev_data` is
+  `struct websocket_message *`
+- MG_EV_HTTP_PART_BEGIN: new part of multipart message is started,
+  extra parameters are passed in mg_http_multipart_part
+- MG_EV_HTTP_PART_DATA: new portion of data from multiparted message
+  no additional headers are available, only data and data size
+- MG_EV_HTTP_PART_END: final boundary received, analogue to maybe used to
+  find the end of packet
+  Note: Mongoose should be compiled with MG_ENABLE_HTTP_STREAMING_MULTIPART
+  to enable MG_EV_HTTP_MULTIPART_REQUEST, MG_EV_HTTP_REQUEST_END,
+  MG_EV_HTTP_REQUEST_CANCEL, MG_EV_HTTP_PART_BEGIN, MG_EV_HTTP_PART_DATA,
+  MG_EV_HTTP_PART_END constants 
+
diff --git a/docs/c-api/http.h/mg_url_decode.md b/docs/c-api/http.h/mg_url_decode.md
new file mode 100644
index 000000000..9e2f7e783
--- /dev/null
+++ b/docs/c-api/http.h/mg_url_decode.md
@@ -0,0 +1,18 @@
+---
+title: "mg_url_decode()"
+decl_name: "mg_url_decode"
+symbol_kind: "func"
+signature: |
+  int mg_url_decode(const char *src, int src_len, char *dst, int dst_len,
+                    int is_form_url_encoded);
+---
+
+Decode URL-encoded string.
+
+Source string is specified by (`src`, `src_len`), and destination is
+(`dst`, `dst_len`). If `is_form_url_encoded` is non-zero, then
+`+` character is decoded as a blank space character. This function
+guarantees to `\0`-terminate the destination. If destination is too small,
+then source string is partially decoded and `-1` is returned. Otherwise,
+a length of decoded string is returned, not counting final `\0`. 
+
diff --git a/docs/c-api/http.h/struct_http_message.md b/docs/c-api/http.h/struct_http_message.md
new file mode 100644
index 000000000..60eae685f
--- /dev/null
+++ b/docs/c-api/http.h/struct_http_message.md
@@ -0,0 +1,38 @@
+---
+title: "struct http_message"
+decl_name: "struct http_message"
+symbol_kind: "struct"
+signature: |
+  struct http_message {
+    struct mg_str message; /* Whole message: request line + headers + body */
+  
+    /* HTTP Request line (or HTTP response line) */
+    struct mg_str method; /* "GET" */
+    struct mg_str uri;    /* "/my_file.html" */
+    struct mg_str proto;  /* "HTTP/1.1" -- for both request and response */
+  
+    /* For responses, code and response status message are set */
+    int resp_code;
+    struct mg_str resp_status_msg;
+  
+    /*
+     * Query-string part of the URI. For example, for HTTP request
+     *    GET /foo/bar?param1=val1&param2=val2
+     *    |    uri    |     query_string     |
+     *
+     * Note that question mark character doesn't belong neither to the uri,
+     * nor to the query_string
+     */
+    struct mg_str query_string;
+  
+    /* Headers */
+    struct mg_str header_names[MG_MAX_HTTP_HEADERS];
+    struct mg_str header_values[MG_MAX_HTTP_HEADERS];
+  
+    /* Message body */
+    struct mg_str body; /* Zero-length for requests with no body */
+  };
+---
+
+HTTP message 
+
diff --git a/docs/c-api/http.h/struct_mg_http_multipart_part.md b/docs/c-api/http.h/struct_mg_http_multipart_part.md
new file mode 100644
index 000000000..c4140182c
--- /dev/null
+++ b/docs/c-api/http.h/struct_mg_http_multipart_part.md
@@ -0,0 +1,15 @@
+---
+title: "struct mg_http_multipart_part"
+decl_name: "struct mg_http_multipart_part"
+symbol_kind: "struct"
+signature: |
+  struct mg_http_multipart_part {
+    const char *file_name;
+    const char *var_name;
+    struct mg_str data;
+    int status; /* <0 on error */
+  };
+---
+
+HTTP multipart part 
+
diff --git a/docs/c-api/http.h/struct_mg_serve_http_opts.md b/docs/c-api/http.h/struct_mg_serve_http_opts.md
new file mode 100644
index 000000000..c0fafeed7
--- /dev/null
+++ b/docs/c-api/http.h/struct_mg_serve_http_opts.md
@@ -0,0 +1,104 @@
+---
+title: "struct mg_serve_http_opts"
+decl_name: "struct mg_serve_http_opts"
+symbol_kind: "struct"
+signature: |
+  struct mg_serve_http_opts {
+    /* Path to web root directory */
+    const char *document_root;
+  
+    /* List of index files. Default is "" */
+    const char *index_files;
+  
+    /*
+     * Leave as NULL to disable authentication.
+     * To enable directory protection with authentication, set this to ".htpasswd"
+     * Then, creating ".htpasswd" file in any directory automatically protects
+     * it with digest authentication.
+     * Use `mongoose` web server binary, or `htdigest` Apache utility to
+     * create/manipulate passwords file.
+     * Make sure `auth_domain` is set to a valid domain name.
+     */
+    const char *per_directory_auth_file;
+  
+    /* Authorization domain (domain name of this web server) */
+    const char *auth_domain;
+  
+    /*
+     * Leave as NULL to disable authentication.
+     * Normally, only selected directories in the document root are protected.
+     * If absolutely every access to the web server needs to be authenticated,
+     * regardless of the URI, set this option to the path to the passwords file.
+     * Format of that file is the same as ".htpasswd" file. Make sure that file
+     * is located outside document root to prevent people fetching it.
+     */
+    const char *global_auth_file;
+  
+    /* Set to "no" to disable directory listing. Enabled by default. */
+    const char *enable_directory_listing;
+  
+    /* SSI files pattern. If not set, "**.shtml$|**.shtm$" is used. */
+    const char *ssi_pattern;
+  
+    /* IP ACL. By default, NULL, meaning all IPs are allowed to connect */
+    const char *ip_acl;
+  
+    /* URL rewrites.
+     *
+     * Comma-separated list of `uri_pattern=file_or_directory_path` rewrites.
+     * When HTTP request is received, Mongoose constructs a file name from the
+     * requested URI by combining `document_root` and the URI. However, if the
+     * rewrite option is used and `uri_pattern` matches requested URI, then
+     * `document_root` is ignored. Instead, `file_or_directory_path` is used,
+     * which should be a full path name or a path relative to the web server's
+     * current working directory. Note that `uri_pattern`, as all Mongoose
+     * patterns, is a prefix pattern.
+     *
+     * If uri_pattern starts with `@` symbol, then Mongoose compares it with the
+     * HOST header of the request. If they are equal, Mongoose sets document root
+     * to `file_or_directory_path`, implementing virtual hosts support.
+     * Example: `@foo.com=/document/root/for/foo.com`
+     *
+     * If `uri_pattern` starts with `%` symbol, then Mongoose compares it with
+     * the listening port. If they match, then Mongoose issues a 301 redirect.
+     * For example, to redirect all HTTP requests to the
+     * HTTPS port, do `%80=https://my.site.com`. Note that the request URI is
+     * automatically appended to the redirect location.
+     */
+    const char *url_rewrites;
+  
+    /* DAV document root. If NULL, DAV requests are going to fail. */
+    const char *dav_document_root;
+  
+    /*
+     * DAV passwords file. If NULL, DAV requests are going to fail.
+     * If passwords file is set to "-", then DAV auth is disabled.
+     */
+    const char *dav_auth_file;
+  
+    /* Glob pattern for the files to hide. */
+    const char *hidden_file_pattern;
+  
+    /* Set to non-NULL to enable CGI, e.g. **.cgi$|**.php$" */
+    const char *cgi_file_pattern;
+  
+    /* If not NULL, ignore CGI script hashbang and use this interpreter */
+    const char *cgi_interpreter;
+  
+    /*
+     * Comma-separated list of Content-Type overrides for path suffixes, e.g.
+     * ".txt=text/plain; charset=utf-8,.c=text/plain"
+     */
+    const char *custom_mime_types;
+  
+    /*
+     * Extra HTTP headers to add to each server response.
+     * Example: to enable CORS, set this to "Access-Control-Allow-Origin: *".
+     */
+    const char *extra_headers;
+  };
+---
+
+This structure defines how `mg_serve_http()` works.
+Best practice is to set only required settings, and leave the rest as NULL. 
+
diff --git a/docs/c-api/http.h/struct_websocket_message.md b/docs/c-api/http.h/struct_websocket_message.md
new file mode 100644
index 000000000..37b7912a5
--- /dev/null
+++ b/docs/c-api/http.h/struct_websocket_message.md
@@ -0,0 +1,14 @@
+---
+title: "struct websocket_message"
+decl_name: "struct websocket_message"
+symbol_kind: "struct"
+signature: |
+  struct websocket_message {
+    unsigned char *data;
+    size_t size;
+    unsigned char flags;
+  };
+---
+
+WebSocket message 
+
diff --git a/docs/c-api/items.json b/docs/c-api/items.json
new file mode 100644
index 000000000..1133954a5
--- /dev/null
+++ b/docs/c-api/items.json
@@ -0,0 +1,44 @@
+{
+    "items": [
+        {
+            "type": "section",
+            "name": "mbuf.h"
+        },
+        {
+            "type": "section",
+            "name": "net.h"
+        },
+        {
+            "type": "section",
+            "name": "http.h"
+        },
+        {
+            "type": "section",
+            "name": "json-rpc.h"
+        },
+        {
+            "type": "section",
+            "name": "dns.h"
+        },
+        {
+            "type": "section",
+            "name": "dns-server.h"
+        },
+        {
+            "type": "section",
+            "name": "mqtt.h"
+        },
+        {
+            "type": "section",
+            "name": "mqtt-broker.h"
+        },
+        {
+            "type": "section",
+            "name": "coap.h"
+        },
+        {
+            "type": "section",
+            "name": "util.h"
+        }
+    ]
+}
diff --git a/docs/c-api/json-rpc.h/intro.md b/docs/c-api/json-rpc.h/intro.md
new file mode 100644
index 000000000..8d04b6232
--- /dev/null
+++ b/docs/c-api/json-rpc.h/intro.md
@@ -0,0 +1,8 @@
+---
+title: "JSON-RPC"
+symbol_kind: "intro"
+decl_name: "json-rpc.h"
+---
+
+
+
diff --git a/docs/c-api/json-rpc.h/items.json b/docs/c-api/json-rpc.h/items.json
new file mode 100644
index 000000000..6fc301768
--- /dev/null
+++ b/docs/c-api/json-rpc.h/items.json
@@ -0,0 +1,44 @@
+{
+    "items": [
+        {
+            "type": "markdown",
+            "name": "intro.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_rpc_parse_reply.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_rpc_create_request.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_rpc_create_reply.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_rpc_create_error.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_rpc_create_std_error.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_rpc_dispatch.md"
+        },
+        {
+            "type": "markdown",
+            "name": "struct_mg_rpc_request.md"
+        },
+        {
+            "type": "markdown",
+            "name": "struct_mg_rpc_reply.md"
+        },
+        {
+            "type": "markdown",
+            "name": "struct_mg_rpc_error.md"
+        }
+    ]
+}
diff --git a/docs/c-api/json-rpc.h/mg_rpc_create_error.md b/docs/c-api/json-rpc.h/mg_rpc_create_error.md
new file mode 100644
index 000000000..b6910e02b
--- /dev/null
+++ b/docs/c-api/json-rpc.h/mg_rpc_create_error.md
@@ -0,0 +1,16 @@
+---
+title: "mg_rpc_create_error()"
+decl_name: "mg_rpc_create_error"
+symbol_kind: "func"
+signature: |
+  int mg_rpc_create_error(char *buf, int len, struct mg_rpc_request *req,
+                          int code, const char *message, const char *fmt, ...);
+---
+
+Create JSON-RPC error reply in a given buffer.
+
+Return length of the error, which
+can be larger then `len` that indicates an overflow.
+`fmt` format string should conform to `json_emit()` API,
+see https://github.com/cesanta/frozen 
+
diff --git a/docs/c-api/json-rpc.h/mg_rpc_create_reply.md b/docs/c-api/json-rpc.h/mg_rpc_create_reply.md
new file mode 100644
index 000000000..58a373653
--- /dev/null
+++ b/docs/c-api/json-rpc.h/mg_rpc_create_reply.md
@@ -0,0 +1,16 @@
+---
+title: "mg_rpc_create_reply()"
+decl_name: "mg_rpc_create_reply"
+symbol_kind: "func"
+signature: |
+  int mg_rpc_create_reply(char *buf, int len, const struct mg_rpc_request *req,
+                          const char *result_fmt, ...);
+---
+
+Create JSON-RPC reply in a given buffer.
+
+Return length of the reply, which
+can be larger then `len` that indicates an overflow.
+`result_fmt` format string should conform to `json_emit()` API,
+see https://github.com/cesanta/frozen 
+
diff --git a/docs/c-api/json-rpc.h/mg_rpc_create_request.md b/docs/c-api/json-rpc.h/mg_rpc_create_request.md
new file mode 100644
index 000000000..28c83e404
--- /dev/null
+++ b/docs/c-api/json-rpc.h/mg_rpc_create_request.md
@@ -0,0 +1,16 @@
+---
+title: "mg_rpc_create_request()"
+decl_name: "mg_rpc_create_request"
+symbol_kind: "func"
+signature: |
+  int mg_rpc_create_request(char *buf, int len, const char *method,
+                            const char *id, const char *params_fmt, ...);
+---
+
+Create JSON-RPC request in a given buffer.
+
+Return length of the request, which
+can be larger then `len` that indicates an overflow.
+`params_fmt` format string should conform to `json_emit()` API,
+see https://github.com/cesanta/frozen 
+
diff --git a/docs/c-api/json-rpc.h/mg_rpc_create_std_error.md b/docs/c-api/json-rpc.h/mg_rpc_create_std_error.md
new file mode 100644
index 000000000..b682431c3
--- /dev/null
+++ b/docs/c-api/json-rpc.h/mg_rpc_create_std_error.md
@@ -0,0 +1,22 @@
+---
+title: "mg_rpc_create_std_error()"
+decl_name: "mg_rpc_create_std_error"
+symbol_kind: "func"
+signature: |
+  int mg_rpc_create_std_error(char *buf, int len, struct mg_rpc_request *req,
+                              int code);
+---
+
+Create JSON-RPC error in a given buffer.
+
+Return length of the error, which
+can be larger then `len` that indicates an overflow. See
+JSON_RPC_*_ERROR definitions for standard error values:
+
+- `#define JSON_RPC_PARSE_ERROR (-32700)`
+- `#define JSON_RPC_INVALID_REQUEST_ERROR (-32600)`
+- `#define JSON_RPC_METHOD_NOT_FOUND_ERROR (-32601)`
+- `#define JSON_RPC_INVALID_PARAMS_ERROR (-32602)`
+- `#define JSON_RPC_INTERNAL_ERROR (-32603)`
+- `#define JSON_RPC_SERVER_ERROR (-32000)` 
+
diff --git a/docs/c-api/json-rpc.h/mg_rpc_dispatch.md b/docs/c-api/json-rpc.h/mg_rpc_dispatch.md
new file mode 100644
index 000000000..d58f5026a
--- /dev/null
+++ b/docs/c-api/json-rpc.h/mg_rpc_dispatch.md
@@ -0,0 +1,20 @@
+---
+title: "mg_rpc_dispatch()"
+decl_name: "mg_rpc_dispatch"
+symbol_kind: "func"
+signature: |
+  int mg_rpc_dispatch(const char *buf, int, char *dst, int dst_len,
+                      const char **methods, mg_rpc_handler_t *handlers);
+---
+
+Dispatches a JSON-RPC request.
+
+Parses JSON-RPC request contained in `buf`, `len`.
+Then, dispatches the request to the correct handler method.
+Valid method names should be specified in NULL
+terminated array `methods`, and corresponding handlers in `handlers`.
+Result is put in `dst`, `dst_len`. Return: length of the result, which
+can be larger then `dst_len` that indicates an overflow.
+Overflown bytes are not written to the buffer.
+If method is not found, an error is automatically generated. 
+
diff --git a/docs/c-api/json-rpc.h/mg_rpc_parse_reply.md b/docs/c-api/json-rpc.h/mg_rpc_parse_reply.md
new file mode 100644
index 000000000..36fad9202
--- /dev/null
+++ b/docs/c-api/json-rpc.h/mg_rpc_parse_reply.md
@@ -0,0 +1,24 @@
+---
+title: "mg_rpc_parse_reply()"
+decl_name: "mg_rpc_parse_reply"
+symbol_kind: "func"
+signature: |
+  int mg_rpc_parse_reply(const char *buf, int len, struct json_token *toks,
+                         int max_toks, struct mg_rpc_reply *,
+                         struct mg_rpc_error *);
+---
+
+Parse JSON-RPC reply contained in `buf`, `len` into JSON tokens array
+`toks`, `max_toks`. If buffer contains valid reply, `reply` structure is
+populated. The result of RPC call is located in `reply.result`. On error,
+`error` structure is populated. Returns: the result of calling
+`parse_json(buf, len, toks, max_toks)`:
+
+On success, an offset inside `json_string` is returned
+where parsing has finished. On failure, a negative number is
+returned, one of:
+
+- `#define JSON_STRING_INVALID           -1`
+- `#define JSON_STRING_INCOMPLETE        -2`
+- `#define JSON_TOKEN_ARRAY_TOO_SMALL    -3` 
+
diff --git a/docs/c-api/json-rpc.h/struct_mg_rpc_error.md b/docs/c-api/json-rpc.h/struct_mg_rpc_error.md
new file mode 100644
index 000000000..b2bff13b4
--- /dev/null
+++ b/docs/c-api/json-rpc.h/struct_mg_rpc_error.md
@@ -0,0 +1,16 @@
+---
+title: "struct mg_rpc_error"
+decl_name: "struct mg_rpc_error"
+symbol_kind: "struct"
+signature: |
+  struct mg_rpc_error {
+    struct json_token *message;       /* Whole RPC message */
+    struct json_token *id;            /* Message ID */
+    struct json_token *error_code;    /* error.code */
+    struct json_token *error_message; /* error.message */
+    struct json_token *error_data;    /* error.data, can be NULL */
+  };
+---
+
+JSON-RPC error 
+
diff --git a/docs/c-api/json-rpc.h/struct_mg_rpc_reply.md b/docs/c-api/json-rpc.h/struct_mg_rpc_reply.md
new file mode 100644
index 000000000..fd6060267
--- /dev/null
+++ b/docs/c-api/json-rpc.h/struct_mg_rpc_reply.md
@@ -0,0 +1,14 @@
+---
+title: "struct mg_rpc_reply"
+decl_name: "struct mg_rpc_reply"
+symbol_kind: "struct"
+signature: |
+  struct mg_rpc_reply {
+    struct json_token *message; /* Whole RPC message */
+    struct json_token *id;      /* Message ID */
+    struct json_token *result;  /* Remote call result */
+  };
+---
+
+JSON-RPC response 
+
diff --git a/docs/c-api/json-rpc.h/struct_mg_rpc_request.md b/docs/c-api/json-rpc.h/struct_mg_rpc_request.md
new file mode 100644
index 000000000..fc0bb8ae8
--- /dev/null
+++ b/docs/c-api/json-rpc.h/struct_mg_rpc_request.md
@@ -0,0 +1,15 @@
+---
+title: "struct mg_rpc_request"
+decl_name: "struct mg_rpc_request"
+symbol_kind: "struct"
+signature: |
+  struct mg_rpc_request {
+    struct json_token *message; /* Whole RPC message */
+    struct json_token *id;      /* Message ID */
+    struct json_token *method;  /* Method name */
+    struct json_token *params;  /* Method params */
+  };
+---
+
+JSON-RPC request 
+
diff --git a/docs/c-api/mbuf.h/intro.md b/docs/c-api/mbuf.h/intro.md
new file mode 100644
index 000000000..49c6b7fc8
--- /dev/null
+++ b/docs/c-api/mbuf.h/intro.md
@@ -0,0 +1,11 @@
+---
+title: "Memory Buffers"
+symbol_kind: "intro"
+decl_name: "mbuf.h"
+---
+
+Mbufs are mutable/growing memory buffers, like C++ strings.
+Mbuf can append data to the end of a buffer, or insert data into arbitrary
+position in the middle of a buffer. The buffer grows automatically when
+needed.
+
diff --git a/docs/c-api/mbuf.h/items.json b/docs/c-api/mbuf.h/items.json
new file mode 100644
index 000000000..9f5f2123a
--- /dev/null
+++ b/docs/c-api/mbuf.h/items.json
@@ -0,0 +1,40 @@
+{
+    "items": [
+        {
+            "type": "markdown",
+            "name": "intro.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mbuf_init.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mbuf_free.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mbuf_append.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mbuf_insert.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mbuf_remove.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mbuf_resize.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mbuf_trim.md"
+        },
+        {
+            "type": "markdown",
+            "name": "struct_mbuf.md"
+        }
+    ]
+}
diff --git a/docs/c-api/mbuf.h/mbuf_append.md b/docs/c-api/mbuf.h/mbuf_append.md
new file mode 100644
index 000000000..ea803926e
--- /dev/null
+++ b/docs/c-api/mbuf.h/mbuf_append.md
@@ -0,0 +1,12 @@
+---
+title: "mbuf_append()"
+decl_name: "mbuf_append"
+symbol_kind: "func"
+signature: |
+  size_t mbuf_append(struct mbuf *, const void *data, size_t data_size);
+---
+
+Appends data to the Mbuf.
+
+Return the number of bytes appended, or 0 if out of memory. 
+
diff --git a/docs/c-api/mbuf.h/mbuf_free.md b/docs/c-api/mbuf.h/mbuf_free.md
new file mode 100644
index 000000000..273d24b9f
--- /dev/null
+++ b/docs/c-api/mbuf.h/mbuf_free.md
@@ -0,0 +1,10 @@
+---
+title: "mbuf_free()"
+decl_name: "mbuf_free"
+symbol_kind: "func"
+signature: |
+  void mbuf_free(struct mbuf *);
+---
+
+Free the space allocated for the mbuffer and resets the mbuf structure. 
+
diff --git a/docs/c-api/mbuf.h/mbuf_init.md b/docs/c-api/mbuf.h/mbuf_init.md
new file mode 100644
index 000000000..960f92b81
--- /dev/null
+++ b/docs/c-api/mbuf.h/mbuf_init.md
@@ -0,0 +1,11 @@
+---
+title: "mbuf_init()"
+decl_name: "mbuf_init"
+symbol_kind: "func"
+signature: |
+  void mbuf_init(struct mbuf *, size_t initial_capacity);
+---
+
+Initialize an Mbuf.
+`initial_capacity` specifies the initial capacity of the mbuf. 
+
diff --git a/docs/c-api/mbuf.h/mbuf_insert.md b/docs/c-api/mbuf.h/mbuf_insert.md
new file mode 100644
index 000000000..b9e84a711
--- /dev/null
+++ b/docs/c-api/mbuf.h/mbuf_insert.md
@@ -0,0 +1,14 @@
+---
+title: "mbuf_insert()"
+decl_name: "mbuf_insert"
+symbol_kind: "func"
+signature: |
+  size_t mbuf_insert(struct mbuf *, size_t, const void *, size_t);
+---
+
+Insert data at a specified offset in the Mbuf.
+
+Existing data will be shifted forwards and the buffer will
+be grown if necessary.
+Return the number of bytes inserted. 
+
diff --git a/docs/c-api/mbuf.h/mbuf_remove.md b/docs/c-api/mbuf.h/mbuf_remove.md
new file mode 100644
index 000000000..b4ce18c9d
--- /dev/null
+++ b/docs/c-api/mbuf.h/mbuf_remove.md
@@ -0,0 +1,10 @@
+---
+title: "mbuf_remove()"
+decl_name: "mbuf_remove"
+symbol_kind: "func"
+signature: |
+  void mbuf_remove(struct mbuf *, size_t data_size);
+---
+
+Remove `data_size` bytes from the beginning of the buffer. 
+
diff --git a/docs/c-api/mbuf.h/mbuf_resize.md b/docs/c-api/mbuf.h/mbuf_resize.md
new file mode 100644
index 000000000..92f8b302e
--- /dev/null
+++ b/docs/c-api/mbuf.h/mbuf_resize.md
@@ -0,0 +1,13 @@
+---
+title: "mbuf_resize()"
+decl_name: "mbuf_resize"
+symbol_kind: "func"
+signature: |
+  void mbuf_resize(struct mbuf *, size_t new_size);
+---
+
+Resize an Mbuf.
+
+If `new_size` is smaller than buffer's `len`, the
+resize is not performed. 
+
diff --git a/docs/c-api/mbuf.h/mbuf_trim.md b/docs/c-api/mbuf.h/mbuf_trim.md
new file mode 100644
index 000000000..d1878b03f
--- /dev/null
+++ b/docs/c-api/mbuf.h/mbuf_trim.md
@@ -0,0 +1,10 @@
+---
+title: "mbuf_trim()"
+decl_name: "mbuf_trim"
+symbol_kind: "func"
+signature: |
+  void mbuf_trim(struct mbuf *);
+---
+
+Shrink an Mbuf by resizing its `size` to `len`. 
+
diff --git a/docs/c-api/mbuf.h/struct_mbuf.md b/docs/c-api/mbuf.h/struct_mbuf.md
new file mode 100644
index 000000000..98dcdc33b
--- /dev/null
+++ b/docs/c-api/mbuf.h/struct_mbuf.md
@@ -0,0 +1,14 @@
+---
+title: "struct mbuf"
+decl_name: "struct mbuf"
+symbol_kind: "struct"
+signature: |
+  struct mbuf {
+    char *buf;   /* Buffer pointer */
+    size_t len;  /* Data length. Data is located between offset 0 and len. */
+    size_t size; /* Buffer size allocated by realloc(1). Must be >= len */
+  };
+---
+
+Memory buffer descriptor 
+
diff --git a/docs/c-api/mqtt-broker.h/intro.md b/docs/c-api/mqtt-broker.h/intro.md
new file mode 100644
index 000000000..592ccbc4b
--- /dev/null
+++ b/docs/c-api/mqtt-broker.h/intro.md
@@ -0,0 +1,8 @@
+---
+title: "MQTT Broker"
+symbol_kind: "intro"
+decl_name: "mqtt-broker.h"
+---
+
+
+
diff --git a/docs/c-api/mqtt-broker.h/items.json b/docs/c-api/mqtt-broker.h/items.json
new file mode 100644
index 000000000..2908ffbb4
--- /dev/null
+++ b/docs/c-api/mqtt-broker.h/items.json
@@ -0,0 +1,28 @@
+{
+    "items": [
+        {
+            "type": "markdown",
+            "name": "intro.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_mqtt_broker_init.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_mqtt_broker.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_mqtt_next.md"
+        },
+        {
+            "type": "markdown",
+            "name": "struct_mg_mqtt_session.md"
+        },
+        {
+            "type": "markdown",
+            "name": "struct_mg_mqtt_broker.md"
+        }
+    ]
+}
diff --git a/docs/c-api/mqtt-broker.h/mg_mqtt_broker.md b/docs/c-api/mqtt-broker.h/mg_mqtt_broker.md
new file mode 100644
index 000000000..2532bc6fd
--- /dev/null
+++ b/docs/c-api/mqtt-broker.h/mg_mqtt_broker.md
@@ -0,0 +1,32 @@
+---
+title: "mg_mqtt_broker()"
+decl_name: "mg_mqtt_broker"
+symbol_kind: "func"
+signature: |
+  void mg_mqtt_broker(struct mg_connection *brk, int ev, void *data);
+---
+
+Process a MQTT broker message.
+
+Listening connection expects a pointer to an initialized `mg_mqtt_broker`
+structure in the `user_data` field.
+
+Basic usage:
+
+```c
+mg_mqtt_broker_init(&brk, NULL);
+
+if ((nc = mg_bind(&mgr, address, mg_mqtt_broker)) == NULL) {
+  // fail;
+}
+nc->user_data = &brk;
+```
+
+New incoming connections will receive a `mg_mqtt_session` structure
+in the connection `user_data`. The original `user_data` will be stored
+in the `user_data` field of the session structure. This allows the user
+handler to store user data before `mg_mqtt_broker` creates the session.
+
+Since only the MG_EV_ACCEPT message is processed by the listening socket,
+for most events the `user_data` will thus point to a `mg_mqtt_session`. 
+
diff --git a/docs/c-api/mqtt-broker.h/mg_mqtt_broker_init.md b/docs/c-api/mqtt-broker.h/mg_mqtt_broker_init.md
new file mode 100644
index 000000000..74b7e5db7
--- /dev/null
+++ b/docs/c-api/mqtt-broker.h/mg_mqtt_broker_init.md
@@ -0,0 +1,10 @@
+---
+title: "mg_mqtt_broker_init()"
+decl_name: "mg_mqtt_broker_init"
+symbol_kind: "func"
+signature: |
+  void mg_mqtt_broker_init(struct mg_mqtt_broker *brk, void *user_data);
+---
+
+Initialize a MQTT broker. 
+
diff --git a/docs/c-api/mqtt-broker.h/mg_mqtt_next.md b/docs/c-api/mqtt-broker.h/mg_mqtt_next.md
new file mode 100644
index 000000000..5c4eab9d4
--- /dev/null
+++ b/docs/c-api/mqtt-broker.h/mg_mqtt_next.md
@@ -0,0 +1,18 @@
+---
+title: "mg_mqtt_next()"
+decl_name: "mg_mqtt_next"
+symbol_kind: "func"
+signature: |
+  struct mg_mqtt_session *mg_mqtt_next(struct mg_mqtt_broker *brk,
+                                       struct mg_mqtt_session *s);
+---
+
+Iterate over all mqtt sessions connections. Example:
+
+```c
+struct mg_mqtt_session *s;
+for (s = mg_mqtt_next(brk, NULL); s != NULL; s = mg_mqtt_next(brk, s)) {
+  // Do something
+}
+``` 
+
diff --git a/docs/c-api/mqtt-broker.h/struct_mg_mqtt_broker.md b/docs/c-api/mqtt-broker.h/struct_mg_mqtt_broker.md
new file mode 100644
index 000000000..d78e620e4
--- /dev/null
+++ b/docs/c-api/mqtt-broker.h/struct_mg_mqtt_broker.md
@@ -0,0 +1,13 @@
+---
+title: "struct mg_mqtt_broker"
+decl_name: "struct mg_mqtt_broker"
+symbol_kind: "struct"
+signature: |
+  struct mg_mqtt_broker {
+    struct mg_mqtt_session *sessions; /* Session list */
+    void *user_data;                  /* User data */
+  };
+---
+
+MQTT broker. 
+
diff --git a/docs/c-api/mqtt-broker.h/struct_mg_mqtt_session.md b/docs/c-api/mqtt-broker.h/struct_mg_mqtt_session.md
new file mode 100644
index 000000000..4ce850145
--- /dev/null
+++ b/docs/c-api/mqtt-broker.h/struct_mg_mqtt_session.md
@@ -0,0 +1,17 @@
+---
+title: "struct mg_mqtt_session"
+decl_name: "struct mg_mqtt_session"
+symbol_kind: "struct"
+signature: |
+  struct mg_mqtt_session {
+    struct mg_mqtt_broker *brk;          /* Broker */
+    struct mg_mqtt_session *next, *prev; /* mg_mqtt_broker::sessions linkage */
+    struct mg_connection *nc;            /* Connection with the client */
+    size_t num_subscriptions;            /* Size of `subscriptions` array */
+    struct mg_mqtt_topic_expression *subscriptions;
+    void *user_data; /* User data */
+  };
+---
+
+MQTT session (Broker side). 
+
diff --git a/docs/c-api/mqtt.h/intro.md b/docs/c-api/mqtt.h/intro.md
new file mode 100644
index 000000000..55117eee2
--- /dev/null
+++ b/docs/c-api/mqtt.h/intro.md
@@ -0,0 +1,8 @@
+---
+title: "MQTT"
+symbol_kind: "intro"
+decl_name: "mqtt.h"
+---
+
+
+
diff --git a/docs/c-api/mqtt.h/items.json b/docs/c-api/mqtt.h/items.json
new file mode 100644
index 000000000..b77926f70
--- /dev/null
+++ b/docs/c-api/mqtt.h/items.json
@@ -0,0 +1,80 @@
+{
+    "items": [
+        {
+            "type": "markdown",
+            "name": "intro.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_set_protocol_mqtt.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_send_mqtt_handshake.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_send_mqtt_handshake_opt.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_mqtt_publish.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_mqtt_subscribe.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_mqtt_unsubscribe.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_mqtt_disconnect.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_mqtt_connack.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_mqtt_puback.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_mqtt_pubrec.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_mqtt_pubrel.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_mqtt_pubcomp.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_mqtt_suback.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_mqtt_unsuback.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_mqtt_ping.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_mqtt_pong.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_mqtt_next_subscribe_topic.md"
+        },
+        {
+            "type": "markdown",
+            "name": "struct_mg_mqtt_topic_expression.md"
+        }
+    ]
+}
diff --git a/docs/c-api/mqtt.h/mg_mqtt_connack.md b/docs/c-api/mqtt.h/mg_mqtt_connack.md
new file mode 100644
index 000000000..3b22d0a0f
--- /dev/null
+++ b/docs/c-api/mqtt.h/mg_mqtt_connack.md
@@ -0,0 +1,10 @@
+---
+title: "mg_mqtt_connack()"
+decl_name: "mg_mqtt_connack"
+symbol_kind: "func"
+signature: |
+  void mg_mqtt_connack(struct mg_connection *nc, uint8_t return_code);
+---
+
+Send a CONNACK command with a given `return_code`. 
+
diff --git a/docs/c-api/mqtt.h/mg_mqtt_disconnect.md b/docs/c-api/mqtt.h/mg_mqtt_disconnect.md
new file mode 100644
index 000000000..2437c21d4
--- /dev/null
+++ b/docs/c-api/mqtt.h/mg_mqtt_disconnect.md
@@ -0,0 +1,10 @@
+---
+title: "mg_mqtt_disconnect()"
+decl_name: "mg_mqtt_disconnect"
+symbol_kind: "func"
+signature: |
+  void mg_mqtt_disconnect(struct mg_connection *nc);
+---
+
+Send a DISCONNECT command. 
+
diff --git a/docs/c-api/mqtt.h/mg_mqtt_next_subscribe_topic.md b/docs/c-api/mqtt.h/mg_mqtt_next_subscribe_topic.md
new file mode 100644
index 000000000..3e7eeab52
--- /dev/null
+++ b/docs/c-api/mqtt.h/mg_mqtt_next_subscribe_topic.md
@@ -0,0 +1,15 @@
+---
+title: "mg_mqtt_next_subscribe_topic()"
+decl_name: "mg_mqtt_next_subscribe_topic"
+symbol_kind: "func"
+signature: |
+  int mg_mqtt_next_subscribe_topic(struct mg_mqtt_message *msg,
+                                   struct mg_str *topic, uint8_t *qos, int pos);
+---
+
+Extract the next topic expression from a SUBSCRIBE command payload.
+
+Topic expression name will point to a string in the payload buffer.
+Return the pos of the next topic expression or -1 when the list
+of topics is exhausted. 
+
diff --git a/docs/c-api/mqtt.h/mg_mqtt_ping.md b/docs/c-api/mqtt.h/mg_mqtt_ping.md
new file mode 100644
index 000000000..acaa11ac5
--- /dev/null
+++ b/docs/c-api/mqtt.h/mg_mqtt_ping.md
@@ -0,0 +1,10 @@
+---
+title: "mg_mqtt_ping()"
+decl_name: "mg_mqtt_ping"
+symbol_kind: "func"
+signature: |
+  void mg_mqtt_ping(struct mg_connection *nc);
+---
+
+Send a PINGREQ command. 
+
diff --git a/docs/c-api/mqtt.h/mg_mqtt_pong.md b/docs/c-api/mqtt.h/mg_mqtt_pong.md
new file mode 100644
index 000000000..da353b572
--- /dev/null
+++ b/docs/c-api/mqtt.h/mg_mqtt_pong.md
@@ -0,0 +1,10 @@
+---
+title: "mg_mqtt_pong()"
+decl_name: "mg_mqtt_pong"
+symbol_kind: "func"
+signature: |
+  void mg_mqtt_pong(struct mg_connection *nc);
+---
+
+Send a PINGRESP command. 
+
diff --git a/docs/c-api/mqtt.h/mg_mqtt_puback.md b/docs/c-api/mqtt.h/mg_mqtt_puback.md
new file mode 100644
index 000000000..aad96f669
--- /dev/null
+++ b/docs/c-api/mqtt.h/mg_mqtt_puback.md
@@ -0,0 +1,10 @@
+---
+title: "mg_mqtt_puback()"
+decl_name: "mg_mqtt_puback"
+symbol_kind: "func"
+signature: |
+  void mg_mqtt_puback(struct mg_connection *nc, uint16_t message_id);
+---
+
+Send a PUBACK command with a given `message_id`. 
+
diff --git a/docs/c-api/mqtt.h/mg_mqtt_pubcomp.md b/docs/c-api/mqtt.h/mg_mqtt_pubcomp.md
new file mode 100644
index 000000000..aab320f61
--- /dev/null
+++ b/docs/c-api/mqtt.h/mg_mqtt_pubcomp.md
@@ -0,0 +1,10 @@
+---
+title: "mg_mqtt_pubcomp()"
+decl_name: "mg_mqtt_pubcomp"
+symbol_kind: "func"
+signature: |
+  void mg_mqtt_pubcomp(struct mg_connection *nc, uint16_t message_id);
+---
+
+Send a PUBCOMP command with a given `message_id`. 
+
diff --git a/docs/c-api/mqtt.h/mg_mqtt_publish.md b/docs/c-api/mqtt.h/mg_mqtt_publish.md
new file mode 100644
index 000000000..8b28c57ba
--- /dev/null
+++ b/docs/c-api/mqtt.h/mg_mqtt_publish.md
@@ -0,0 +1,12 @@
+---
+title: "mg_mqtt_publish()"
+decl_name: "mg_mqtt_publish"
+symbol_kind: "func"
+signature: |
+  void mg_mqtt_publish(struct mg_connection *nc, const char *topic,
+                       uint16_t message_id, int flags, const void *data,
+                       size_t len);
+---
+
+Publish a message to a given topic. 
+
diff --git a/docs/c-api/mqtt.h/mg_mqtt_pubrec.md b/docs/c-api/mqtt.h/mg_mqtt_pubrec.md
new file mode 100644
index 000000000..e5173f771
--- /dev/null
+++ b/docs/c-api/mqtt.h/mg_mqtt_pubrec.md
@@ -0,0 +1,10 @@
+---
+title: "mg_mqtt_pubrec()"
+decl_name: "mg_mqtt_pubrec"
+symbol_kind: "func"
+signature: |
+  void mg_mqtt_pubrec(struct mg_connection *nc, uint16_t message_id);
+---
+
+Send a PUBREC command with a given `message_id`. 
+
diff --git a/docs/c-api/mqtt.h/mg_mqtt_pubrel.md b/docs/c-api/mqtt.h/mg_mqtt_pubrel.md
new file mode 100644
index 000000000..899e8b9db
--- /dev/null
+++ b/docs/c-api/mqtt.h/mg_mqtt_pubrel.md
@@ -0,0 +1,10 @@
+---
+title: "mg_mqtt_pubrel()"
+decl_name: "mg_mqtt_pubrel"
+symbol_kind: "func"
+signature: |
+  void mg_mqtt_pubrel(struct mg_connection *nc, uint16_t message_id);
+---
+
+Send a PUBREL command with a given `message_id`. 
+
diff --git a/docs/c-api/mqtt.h/mg_mqtt_suback.md b/docs/c-api/mqtt.h/mg_mqtt_suback.md
new file mode 100644
index 000000000..943fd65e3
--- /dev/null
+++ b/docs/c-api/mqtt.h/mg_mqtt_suback.md
@@ -0,0 +1,12 @@
+---
+title: "mg_mqtt_suback()"
+decl_name: "mg_mqtt_suback"
+symbol_kind: "func"
+signature: |
+  void mg_mqtt_suback(struct mg_connection *nc, uint8_t *qoss, size_t qoss_len,
+                      uint16_t message_id);
+---
+
+Send a SUBACK command with a given `message_id`
+and a sequence of granted QoSs. 
+
diff --git a/docs/c-api/mqtt.h/mg_mqtt_subscribe.md b/docs/c-api/mqtt.h/mg_mqtt_subscribe.md
new file mode 100644
index 000000000..0978b071a
--- /dev/null
+++ b/docs/c-api/mqtt.h/mg_mqtt_subscribe.md
@@ -0,0 +1,12 @@
+---
+title: "mg_mqtt_subscribe()"
+decl_name: "mg_mqtt_subscribe"
+symbol_kind: "func"
+signature: |
+  void mg_mqtt_subscribe(struct mg_connection *nc,
+                         const struct mg_mqtt_topic_expression *topics,
+                         size_t topics_len, uint16_t message_id);
+---
+
+Subscribe to a bunch of topics. 
+
diff --git a/docs/c-api/mqtt.h/mg_mqtt_unsuback.md b/docs/c-api/mqtt.h/mg_mqtt_unsuback.md
new file mode 100644
index 000000000..e3f6e6ea4
--- /dev/null
+++ b/docs/c-api/mqtt.h/mg_mqtt_unsuback.md
@@ -0,0 +1,10 @@
+---
+title: "mg_mqtt_unsuback()"
+decl_name: "mg_mqtt_unsuback"
+symbol_kind: "func"
+signature: |
+  void mg_mqtt_unsuback(struct mg_connection *nc, uint16_t message_id);
+---
+
+Send a UNSUBACK command with a given `message_id`. 
+
diff --git a/docs/c-api/mqtt.h/mg_mqtt_unsubscribe.md b/docs/c-api/mqtt.h/mg_mqtt_unsubscribe.md
new file mode 100644
index 000000000..73a283e3e
--- /dev/null
+++ b/docs/c-api/mqtt.h/mg_mqtt_unsubscribe.md
@@ -0,0 +1,11 @@
+---
+title: "mg_mqtt_unsubscribe()"
+decl_name: "mg_mqtt_unsubscribe"
+symbol_kind: "func"
+signature: |
+  void mg_mqtt_unsubscribe(struct mg_connection *nc, char **topics,
+                           size_t topics_len, uint16_t message_id);
+---
+
+Unsubscribe from a bunch of topics. 
+
diff --git a/docs/c-api/mqtt.h/mg_send_mqtt_handshake.md b/docs/c-api/mqtt.h/mg_send_mqtt_handshake.md
new file mode 100644
index 000000000..1e903f90c
--- /dev/null
+++ b/docs/c-api/mqtt.h/mg_send_mqtt_handshake.md
@@ -0,0 +1,10 @@
+---
+title: "mg_send_mqtt_handshake()"
+decl_name: "mg_send_mqtt_handshake"
+symbol_kind: "func"
+signature: |
+  void mg_send_mqtt_handshake(struct mg_connection *nc, const char *client_id);
+---
+
+Send MQTT handshake. 
+
diff --git a/docs/c-api/mqtt.h/mg_send_mqtt_handshake_opt.md b/docs/c-api/mqtt.h/mg_send_mqtt_handshake_opt.md
new file mode 100644
index 000000000..c1d3fd4c2
--- /dev/null
+++ b/docs/c-api/mqtt.h/mg_send_mqtt_handshake_opt.md
@@ -0,0 +1,11 @@
+---
+title: "mg_send_mqtt_handshake_opt()"
+decl_name: "mg_send_mqtt_handshake_opt"
+symbol_kind: "func"
+signature: |
+  void mg_send_mqtt_handshake_opt(struct mg_connection *nc, const char *client_id,
+                                  struct mg_send_mqtt_handshake_opts);
+---
+
+Send MQTT handshake with optional parameters. 
+
diff --git a/docs/c-api/mqtt.h/mg_set_protocol_mqtt.md b/docs/c-api/mqtt.h/mg_set_protocol_mqtt.md
new file mode 100644
index 000000000..a559eae82
--- /dev/null
+++ b/docs/c-api/mqtt.h/mg_set_protocol_mqtt.md
@@ -0,0 +1,20 @@
+---
+title: "mg_set_protocol_mqtt()"
+decl_name: "mg_set_protocol_mqtt"
+symbol_kind: "func"
+signature: |
+  void mg_set_protocol_mqtt(struct mg_connection *nc);
+---
+
+Attach built-in MQTT event handler to the given connection.
+
+The user-defined event handler will receive following extra events:
+
+- MG_EV_MQTT_CONNACK
+- MG_EV_MQTT_PUBLISH
+- MG_EV_MQTT_PUBACK
+- MG_EV_MQTT_PUBREC
+- MG_EV_MQTT_PUBREL
+- MG_EV_MQTT_PUBCOMP
+- MG_EV_MQTT_SUBACK 
+
diff --git a/docs/c-api/mqtt.h/struct_mg_mqtt_topic_expression.md b/docs/c-api/mqtt.h/struct_mg_mqtt_topic_expression.md
new file mode 100644
index 000000000..8ae14b2d1
--- /dev/null
+++ b/docs/c-api/mqtt.h/struct_mg_mqtt_topic_expression.md
@@ -0,0 +1,13 @@
+---
+title: "struct mg_mqtt_topic_expression"
+decl_name: "struct mg_mqtt_topic_expression"
+symbol_kind: "struct"
+signature: |
+  struct mg_mqtt_topic_expression {
+    const char *topic;
+    uint8_t qos;
+  };
+---
+
+puback 
+
diff --git a/docs/c-api/net.h/intro.md b/docs/c-api/net.h/intro.md
new file mode 100644
index 000000000..bb03baccc
--- /dev/null
+++ b/docs/c-api/net.h/intro.md
@@ -0,0 +1,12 @@
+---
+title: "Core: TCP/UDP/SSL"
+symbol_kind: "intro"
+decl_name: "net.h"
+---
+
+NOTE: Mongoose manager is single threaded. It does not protect
+its data structures by mutexes, therefore all functions that are dealing
+with particular event manager should be called from the same thread,
+with exception of `mg_broadcast()` function. It is fine to have different
+event managers handled by different threads.
+
diff --git a/docs/c-api/net.h/items.json b/docs/c-api/net.h/items.json
new file mode 100644
index 000000000..7c8bd4d56
--- /dev/null
+++ b/docs/c-api/net.h/items.json
@@ -0,0 +1,116 @@
+{
+    "items": [
+        {
+            "type": "markdown",
+            "name": "intro.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_mgr_init.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_mgr_free.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_mgr_poll.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_broadcast.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_next.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_add_sock.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_add_sock_opt.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_bind.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_bind_opt.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_connect.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_connect_opt.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_set_ssl.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_send.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_printf.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_vprintf.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_socketpair.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_check_ip_acl.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_enable_multithreading.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_enable_javascript.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_set_timer.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_time.md"
+        },
+        {
+            "type": "markdown",
+            "name": "struct_mg_str.md"
+        },
+        {
+            "type": "markdown",
+            "name": "struct_mg_mgr.md"
+        },
+        {
+            "type": "markdown",
+            "name": "struct_mg_connection.md"
+        },
+        {
+            "type": "markdown",
+            "name": "struct_mg_add_sock_opts.md"
+        },
+        {
+            "type": "markdown",
+            "name": "struct_mg_bind_opts.md"
+        },
+        {
+            "type": "markdown",
+            "name": "struct_mg_connect_opts.md"
+        }
+    ]
+}
diff --git a/docs/c-api/net.h/mg_add_sock.md b/docs/c-api/net.h/mg_add_sock.md
new file mode 100644
index 000000000..268dc3344
--- /dev/null
+++ b/docs/c-api/net.h/mg_add_sock.md
@@ -0,0 +1,13 @@
+---
+title: "mg_add_sock()"
+decl_name: "mg_add_sock"
+symbol_kind: "func"
+signature: |
+  struct mg_connection *mg_add_sock(struct mg_mgr *, sock_t, mg_event_handler_t);
+---
+
+Create a connection, associate it with the given socket and event handler,
+and add it to the manager.
+
+For more options see the `mg_add_sock_opt` variant. 
+
diff --git a/docs/c-api/net.h/mg_add_sock_opt.md b/docs/c-api/net.h/mg_add_sock_opt.md
new file mode 100644
index 000000000..9a94aee7f
--- /dev/null
+++ b/docs/c-api/net.h/mg_add_sock_opt.md
@@ -0,0 +1,15 @@
+---
+title: "mg_add_sock_opt()"
+decl_name: "mg_add_sock_opt"
+symbol_kind: "func"
+signature: |
+  struct mg_connection *mg_add_sock_opt(struct mg_mgr *, sock_t,
+                                        mg_event_handler_t,
+                                        struct mg_add_sock_opts);
+---
+
+Create a connection, associate it with the given socket and event handler,
+and add to the manager.
+
+See the `mg_add_sock_opts` structure for a description of the options. 
+
diff --git a/docs/c-api/net.h/mg_bind.md b/docs/c-api/net.h/mg_bind.md
new file mode 100644
index 000000000..b6106219b
--- /dev/null
+++ b/docs/c-api/net.h/mg_bind.md
@@ -0,0 +1,13 @@
+---
+title: "mg_bind()"
+decl_name: "mg_bind"
+symbol_kind: "func"
+signature: |
+  struct mg_connection *mg_bind(struct mg_mgr *, const char *,
+                                mg_event_handler_t);
+---
+
+Create listening connection.
+
+See `mg_bind_opt` for full documentation. 
+
diff --git a/docs/c-api/net.h/mg_bind_opt.md b/docs/c-api/net.h/mg_bind_opt.md
new file mode 100644
index 000000000..4fb514bf7
--- /dev/null
+++ b/docs/c-api/net.h/mg_bind_opt.md
@@ -0,0 +1,26 @@
+---
+title: "mg_bind_opt()"
+decl_name: "mg_bind_opt"
+symbol_kind: "func"
+signature: |
+  struct mg_connection *mg_bind_opt(struct mg_mgr *mgr, const char *address,
+                                    mg_event_handler_t handler,
+                                    struct mg_bind_opts opts);
+---
+
+Create listening connection.
+
+`address` parameter tells which address to bind to. It's format is the same
+as for the `mg_connect()` call, where `HOST` part is optional. `address`
+can be just a port number, e.g. `:8000`. To bind to a specific interface,
+an IP address can be specified, e.g. `1.2.3.4:8000`. By default, a TCP
+connection is created. To create UDP connection, prepend `udp://` prefix,
+e.g. `udp://:8000`. To summarize, `address` paramer has following format:
+`[PROTO://][IP_ADDRESS]:PORT`, where `PROTO` could be `tcp` or `udp`.
+
+See the `mg_bind_opts` structure for a description of the optional
+parameters.
+
+Return a new listening connection, or `NULL` on error.
+NOTE: Connection remains owned by the manager, do not free(). 
+
diff --git a/docs/c-api/net.h/mg_broadcast.md b/docs/c-api/net.h/mg_broadcast.md
new file mode 100644
index 000000000..94fceb8f0
--- /dev/null
+++ b/docs/c-api/net.h/mg_broadcast.md
@@ -0,0 +1,19 @@
+---
+title: "mg_broadcast()"
+decl_name: "mg_broadcast"
+symbol_kind: "func"
+signature: |
+  void mg_broadcast(struct mg_mgr *, mg_event_handler_t func, void *, size_t);
+---
+
+Pass a message of a given length to all connections.
+
+Must be called from a thread that does NOT call `mg_mgr_poll()`.
+Note that `mg_broadcast()` is the only function
+that can be, and must be, called from a different (non-IO) thread.
+
+`func` callback function will be called by the IO thread for each
+connection. When called, event would be `MG_EV_POLL`, and message will
+be passed as `ev_data` pointer. Maximum message size is capped
+by `MG_CTL_MSG_MESSAGE_SIZE` which is set to 8192 bytes. 
+
diff --git a/docs/c-api/net.h/mg_check_ip_acl.md b/docs/c-api/net.h/mg_check_ip_acl.md
new file mode 100644
index 000000000..957a684fb
--- /dev/null
+++ b/docs/c-api/net.h/mg_check_ip_acl.md
@@ -0,0 +1,27 @@
+---
+title: "mg_check_ip_acl()"
+decl_name: "mg_check_ip_acl"
+symbol_kind: "func"
+signature: |
+  int mg_check_ip_acl(const char *acl, uint32_t remote_ip);
+---
+
+Verify given IP address against the ACL.
+
+`remote_ip` - an IPv4 address to check, in host byte order
+`acl` - a comma separated list of IP subnets: `x.x.x.x/x` or `x.x.x.x`.
+Each subnet is
+prepended by either a - or a + sign. A plus sign means allow, where a
+minus sign means deny. If a subnet mask is omitted, such as `-1.2.3.4`,
+this means to deny only that single IP address.
+Subnet masks may vary from 0 to 32, inclusive. The default setting
+is to allow all accesses. On each request the full list is traversed,
+and the last match wins. Example:
+
+`-0.0.0.0/0,+192.168/16` - deny all acccesses, only allow 192.168/16 subnet
+
+To learn more about subnet masks, see the
+link:https://en.wikipedia.org/wiki/Subnetwork[Wikipedia page on Subnetwork]
+
+Return -1 if ACL is malformed, 0 if address is disallowed, 1 if allowed. 
+
diff --git a/docs/c-api/net.h/mg_connect.md b/docs/c-api/net.h/mg_connect.md
new file mode 100644
index 000000000..388196e31
--- /dev/null
+++ b/docs/c-api/net.h/mg_connect.md
@@ -0,0 +1,13 @@
+---
+title: "mg_connect()"
+decl_name: "mg_connect"
+symbol_kind: "func"
+signature: |
+  struct mg_connection *mg_connect(struct mg_mgr *mgr, const char *address,
+                                   mg_event_handler_t handler);
+---
+
+Connect to a remote host.
+
+See `mg_connect_opt()` for full documentation. 
+
diff --git a/docs/c-api/net.h/mg_connect_opt.md b/docs/c-api/net.h/mg_connect_opt.md
new file mode 100644
index 000000000..d169ded10
--- /dev/null
+++ b/docs/c-api/net.h/mg_connect_opt.md
@@ -0,0 +1,57 @@
+---
+title: "mg_connect_opt()"
+decl_name: "mg_connect_opt"
+symbol_kind: "func"
+signature: |
+  struct mg_connection *mg_connect_opt(struct mg_mgr *mgr, const char *address,
+                                       mg_event_handler_t handler,
+                                       struct mg_connect_opts opts);
+---
+
+Connect to a remote host.
+
+`address` format is `[PROTO://]HOST:PORT`. `PROTO` could be `tcp` or `udp`.
+`HOST` could be an IP address,
+IPv6 address (if Mongoose is compiled with `-DMG_ENABLE_IPV6`), or a host
+name. If `HOST` is a name, Mongoose will resolve it asynchronously. Examples
+of valid addresses: `google.com:80`, `udp://1.2.3.4:53`, `10.0.0.1:443`,
+`[::1]:80`
+
+See the `mg_connect_opts` structure for a description of the optional
+parameters.
+
+Returns a new outbound connection, or `NULL` on error.
+
+NOTE: Connection remains owned by the manager, do not free().
+
+NOTE: To enable IPv6 addresses, `-DMG_ENABLE_IPV6` should be specified
+in the compilation flags.
+
+NOTE: New connection will receive `MG_EV_CONNECT` as it's first event
+which will report connect success status.
+If asynchronous resolution fail, or `connect()` syscall fail for whatever
+reason (e.g. with `ECONNREFUSED` or `ENETUNREACH`), then `MG_EV_CONNECT`
+event report failure. Code example below:
+
+```c
+static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
+  int connect_status;
+
+  switch (ev) {
+    case MG_EV_CONNECT:
+      connect_status = * (int *) ev_data;
+      if (connect_status == 0) {
+        // Success
+      } else  {
+        // Error
+        printf("connect() error: %s\n", strerror(connect_status));
+      }
+      break;
+    ...
+  }
+}
+
+  ...
+  mg_connect(mgr, "my_site.com:80", ev_handler);
+``` 
+
diff --git a/docs/c-api/net.h/mg_enable_javascript.md b/docs/c-api/net.h/mg_enable_javascript.md
new file mode 100644
index 000000000..cb2753866
--- /dev/null
+++ b/docs/c-api/net.h/mg_enable_javascript.md
@@ -0,0 +1,14 @@
+---
+title: "mg_enable_javascript()"
+decl_name: "mg_enable_javascript"
+symbol_kind: "func"
+signature: |
+  enum v7_err mg_enable_javascript(struct mg_mgr *m, struct v7 *v7,
+                                   const char *init_js_file_name);
+---
+
+Enable server-side JavaScript scripting.
+Requires `-DMG_ENABLE_JAVASCRIPT` compilation flag, and V7 engine sources.
+v7 instance must not be destroyed during manager's lifetime.
+Return V7 error. 
+
diff --git a/docs/c-api/net.h/mg_enable_multithreading.md b/docs/c-api/net.h/mg_enable_multithreading.md
new file mode 100644
index 000000000..3498e4de3
--- /dev/null
+++ b/docs/c-api/net.h/mg_enable_multithreading.md
@@ -0,0 +1,14 @@
+---
+title: "mg_enable_multithreading()"
+decl_name: "mg_enable_multithreading"
+symbol_kind: "func"
+signature: |
+  void mg_enable_multithreading(struct mg_connection *nc);
+---
+
+Enable multi-threaded handling for the given listening connection `nc`.
+For each accepted connection, Mongoose will create a separate thread
+and run event handler in that thread. Thus, if an event hanler is doing
+a blocking call or some long computation, that will not slow down
+other connections. 
+
diff --git a/docs/c-api/net.h/mg_mgr_free.md b/docs/c-api/net.h/mg_mgr_free.md
new file mode 100644
index 000000000..07ca25d3c
--- /dev/null
+++ b/docs/c-api/net.h/mg_mgr_free.md
@@ -0,0 +1,12 @@
+---
+title: "mg_mgr_free()"
+decl_name: "mg_mgr_free"
+symbol_kind: "func"
+signature: |
+  void mg_mgr_free(struct mg_mgr *);
+---
+
+De-initializes Mongoose manager.
+
+Close and deallocate all active connections. 
+
diff --git a/docs/c-api/net.h/mg_mgr_init.md b/docs/c-api/net.h/mg_mgr_init.md
new file mode 100644
index 000000000..b59506bdf
--- /dev/null
+++ b/docs/c-api/net.h/mg_mgr_init.md
@@ -0,0 +1,15 @@
+---
+title: "mg_mgr_init()"
+decl_name: "mg_mgr_init"
+symbol_kind: "func"
+signature: |
+  void mg_mgr_init(struct mg_mgr *mgr, void *user_data);
+---
+
+Initialize Mongoose manager. Side effect: ignores SIGPIPE signal.
+`mgr->user_data` field will be initialized with `user_data` parameter.
+That is an arbitrary pointer, where user code can associate some data
+with the particular Mongoose manager. For example, a C++ wrapper class
+could be written, in which case `user_data` can hold a pointer to the
+class instance. 
+
diff --git a/docs/c-api/net.h/mg_mgr_poll.md b/docs/c-api/net.h/mg_mgr_poll.md
new file mode 100644
index 000000000..f25c75956
--- /dev/null
+++ b/docs/c-api/net.h/mg_mgr_poll.md
@@ -0,0 +1,15 @@
+---
+title: "mg_mgr_poll()"
+decl_name: "mg_mgr_poll"
+symbol_kind: "func"
+signature: |
+  time_t mg_mgr_poll(struct mg_mgr *, int milli);
+---
+
+This function performs the actual IO, and must be called in a loop
+(an event loop). Returns the current timestamp.
+`milli` is the maximum number of milliseconds to sleep.
+`mg_mgr_poll()` checks all connection for IO readiness. If at least one
+of the connections is IO-ready, `mg_mgr_poll()` triggers respective
+event handlers and returns. 
+
diff --git a/docs/c-api/net.h/mg_next.md b/docs/c-api/net.h/mg_next.md
new file mode 100644
index 000000000..fc817262d
--- /dev/null
+++ b/docs/c-api/net.h/mg_next.md
@@ -0,0 +1,20 @@
+---
+title: "mg_next()"
+decl_name: "mg_next"
+symbol_kind: "func"
+signature: |
+  struct mg_connection *mg_next(struct mg_mgr *, struct mg_connection *);
+---
+
+Iterate over all active connections.
+
+Returns next connection from the list
+of active connections, or `NULL` if there is no more connections. Below
+is the iteration idiom:
+
+```c
+for (c = mg_next(srv, NULL); c != NULL; c = mg_next(srv, c)) {
+  // Do something with connection `c`
+}
+``` 
+
diff --git a/docs/c-api/net.h/mg_printf.md b/docs/c-api/net.h/mg_printf.md
new file mode 100644
index 000000000..281fb4fd5
--- /dev/null
+++ b/docs/c-api/net.h/mg_printf.md
@@ -0,0 +1,12 @@
+---
+title: "mg_printf()"
+decl_name: "mg_printf"
+symbol_kind: "func"
+signature: |
+  int mg_printf(struct mg_connection *, const char *fmt, ...);
+---
+
+Send `printf`-style formatted data to the connection.
+
+See `mg_send` for more details on send semantics. 
+
diff --git a/docs/c-api/net.h/mg_send.md b/docs/c-api/net.h/mg_send.md
new file mode 100644
index 000000000..e1aed3e03
--- /dev/null
+++ b/docs/c-api/net.h/mg_send.md
@@ -0,0 +1,14 @@
+---
+title: "mg_send()"
+decl_name: "mg_send"
+symbol_kind: "func"
+signature: |
+  void mg_send(struct mg_connection *, const void *buf, int len);
+---
+
+Send data to the connection.
+
+Note that sending functions do not actually push data to the socket.
+They just append data to the output buffer. MG_EV_SEND will be delivered when
+the data has actually been pushed out. 
+
diff --git a/docs/c-api/net.h/mg_set_ssl.md b/docs/c-api/net.h/mg_set_ssl.md
new file mode 100644
index 000000000..c2212b870
--- /dev/null
+++ b/docs/c-api/net.h/mg_set_ssl.md
@@ -0,0 +1,19 @@
+---
+title: "mg_set_ssl()"
+decl_name: "mg_set_ssl"
+symbol_kind: "func"
+signature: |
+  const char *mg_set_ssl(struct mg_connection *nc, const char *cert,
+                         const char *ca_cert);
+---
+
+Enable SSL for a given connection.
+`cert` is a server certificate file name for a listening connection,
+or a client certificate file name for an outgoing connection.
+Certificate files must be in PEM format. Server certificate file
+must contain a certificate, concatenated with a private key, optionally
+concatenated with parameters.
+`ca_cert` is a CA certificate, or NULL if peer verification is not
+required.
+Return: NULL on success, or error message on error. 
+
diff --git a/docs/c-api/net.h/mg_set_timer.md b/docs/c-api/net.h/mg_set_timer.md
new file mode 100644
index 000000000..e559c26b2
--- /dev/null
+++ b/docs/c-api/net.h/mg_set_timer.md
@@ -0,0 +1,31 @@
+---
+title: "mg_set_timer()"
+decl_name: "mg_set_timer"
+symbol_kind: "func"
+signature: |
+  double mg_set_timer(struct mg_connection *c, double timestamp);
+---
+
+Schedule MG_EV_TIMER event to be delivered at `timestamp` time.
+`timestamp` is a UNIX time (a number of seconds since Epoch). It is
+`double` instead of `time_t` to allow for sub-second precision.
+Return the old timer value.
+
+Example: set connect timeout to 1.5 seconds:
+
+```
+ c = mg_connect(&mgr, "cesanta.com", ev_handler);
+ mg_set_timer(c, mg_time() + 1.5);
+ ...
+
+ void ev_handler(struct mg_connection *c, int ev, void *ev_data) {
+ switch (ev) {
+   case MG_EV_CONNECT:
+     mg_set_timer(c, 0);  // Clear connect timer
+     break;
+   case MG_EV_TIMER:
+     log("Connect timeout");
+     c->flags |= MG_F_CLOSE_IMMEDIATELY;
+     break;
+``` 
+
diff --git a/docs/c-api/net.h/mg_socketpair.md b/docs/c-api/net.h/mg_socketpair.md
new file mode 100644
index 000000000..1509c0f3a
--- /dev/null
+++ b/docs/c-api/net.h/mg_socketpair.md
@@ -0,0 +1,12 @@
+---
+title: "mg_socketpair()"
+decl_name: "mg_socketpair"
+symbol_kind: "func"
+signature: |
+  int mg_socketpair(sock_t[2], int sock_type);
+---
+
+Create a socket pair.
+`sock_type` can be either `SOCK_STREAM` or `SOCK_DGRAM`.
+Return 0 on failure, 1 on success. 
+
diff --git a/docs/c-api/net.h/mg_time.md b/docs/c-api/net.h/mg_time.md
new file mode 100644
index 000000000..73b5e3870
--- /dev/null
+++ b/docs/c-api/net.h/mg_time.md
@@ -0,0 +1,10 @@
+---
+title: "mg_time()"
+decl_name: "mg_time"
+symbol_kind: "func"
+signature: |
+  double mg_time();
+---
+
+A sub-second precision version of time(). 
+
diff --git a/docs/c-api/net.h/mg_vprintf.md b/docs/c-api/net.h/mg_vprintf.md
new file mode 100644
index 000000000..ff66e264f
--- /dev/null
+++ b/docs/c-api/net.h/mg_vprintf.md
@@ -0,0 +1,10 @@
+---
+title: "mg_vprintf()"
+decl_name: "mg_vprintf"
+symbol_kind: "func"
+signature: |
+  int mg_vprintf(struct mg_connection *, const char *fmt, va_list ap);
+---
+
+Same as `mg_printf()`, but takes `va_list ap` as an argument. 
+
diff --git a/docs/c-api/net.h/struct_mg_add_sock_opts.md b/docs/c-api/net.h/struct_mg_add_sock_opts.md
new file mode 100644
index 000000000..1f399874c
--- /dev/null
+++ b/docs/c-api/net.h/struct_mg_add_sock_opts.md
@@ -0,0 +1,17 @@
+---
+title: "struct mg_add_sock_opts"
+decl_name: "struct mg_add_sock_opts"
+symbol_kind: "struct"
+signature: |
+  struct mg_add_sock_opts {
+    void *user_data;           /* Initial value for connection's user_data */
+    unsigned int flags;        /* Initial connection flags */
+    const char **error_string; /* Placeholder for the error string */
+  };
+---
+
+Optional parameters to `mg_add_sock_opt()`.
+
+`flags` is an initial `struct mg_connection::flags` bitmask to set,
+see `MG_F_*` flags definitions. 
+
diff --git a/docs/c-api/net.h/struct_mg_bind_opts.md b/docs/c-api/net.h/struct_mg_bind_opts.md
new file mode 100644
index 000000000..a72e7a16a
--- /dev/null
+++ b/docs/c-api/net.h/struct_mg_bind_opts.md
@@ -0,0 +1,22 @@
+---
+title: "struct mg_bind_opts"
+decl_name: "struct mg_bind_opts"
+symbol_kind: "struct"
+signature: |
+  struct mg_bind_opts {
+    void *user_data;           /* Initial value for connection's user_data */
+    unsigned int flags;        /* Extra connection flags */
+    const char **error_string; /* Placeholder for the error string */
+  #ifdef MG_ENABLE_SSL
+    /* SSL settings. */
+    const char *ssl_cert;    /* Server certificate to present to clients */
+    const char *ssl_ca_cert; /* Verify client certificates with this CA bundle */
+  #endif
+  };
+---
+
+Optional parameters to `mg_bind_opt()`.
+
+`flags` is an initial `struct mg_connection::flags` bitmask to set,
+see `MG_F_*` flags definitions. 
+
diff --git a/docs/c-api/net.h/struct_mg_connect_opts.md b/docs/c-api/net.h/struct_mg_connect_opts.md
new file mode 100644
index 000000000..167035c2d
--- /dev/null
+++ b/docs/c-api/net.h/struct_mg_connect_opts.md
@@ -0,0 +1,28 @@
+---
+title: "struct mg_connect_opts"
+decl_name: "struct mg_connect_opts"
+symbol_kind: "struct"
+signature: |
+  struct mg_connect_opts {
+    void *user_data;           /* Initial value for connection's user_data */
+    unsigned int flags;        /* Extra connection flags */
+    const char **error_string; /* Placeholder for the error string */
+  #ifdef MG_ENABLE_SSL
+    /* SSL settings. */
+    const char *ssl_cert;    /* Client certificate to present to the server */
+    const char *ssl_ca_cert; /* Verify server certificate using this CA bundle */
+  
+    /*
+     * Server name verification. If ssl_ca_cert is set and the certificate has
+     * passed verification, its subject will be verified against this string.
+     * By default (if ssl_server_name is NULL) hostname part of the address will
+     * be used. Wildcard matching is supported. A special value of "*" disables
+     * name verification.
+     */
+    const char *ssl_server_name;
+  #endif
+  };
+---
+
+Optional parameters to `mg_connect_opt()` 
+
diff --git a/docs/c-api/net.h/struct_mg_connection.md b/docs/c-api/net.h/struct_mg_connection.md
new file mode 100644
index 000000000..fb72db9ba
--- /dev/null
+++ b/docs/c-api/net.h/struct_mg_connection.md
@@ -0,0 +1,63 @@
+---
+title: "struct mg_connection"
+decl_name: "struct mg_connection"
+symbol_kind: "struct"
+signature: |
+  struct mg_connection {
+    struct mg_connection *next, *prev; /* mg_mgr::active_connections linkage */
+    struct mg_connection *listener;    /* Set only for accept()-ed connections */
+    struct mg_mgr *mgr;                /* Pointer to containing manager */
+  
+    sock_t sock; /* Socket to the remote peer */
+    int err;
+    union socket_address sa; /* Remote peer address */
+    size_t recv_mbuf_limit;  /* Max size of recv buffer */
+    struct mbuf recv_mbuf;   /* Received data */
+    struct mbuf send_mbuf;   /* Data scheduled for sending */
+    SSL *ssl;
+    SSL_CTX *ssl_ctx;
+    time_t last_io_time;              /* Timestamp of the last socket IO */
+    double ev_timer_time;             /* Timestamp of the future MG_EV_TIMER */
+    mg_event_handler_t proto_handler; /* Protocol-specific event handler */
+    void *proto_data;                 /* Protocol-specific data */
+    void (*proto_data_destructor)(void *proto_data);
+    mg_event_handler_t handler; /* Event handler function */
+    void *user_data;            /* User-specific data */
+    union {
+      void *v;
+      /*
+       * the C standard is fussy about fitting function pointers into
+       * void pointers, since some archs might have fat pointers for functions.
+       */
+      mg_event_handler_t f;
+    } priv_1;       /* Used by mg_enable_multithreading() */
+    void *priv_2;   /* Used by mg_enable_multithreading() */
+    void *mgr_data; /* Implementation-specific event manager's data. */
+    unsigned long flags;
+  /* Flags set by Mongoose */
+  #define MG_F_LISTENING (1 << 0)          /* This connection is listening */
+  #define MG_F_UDP (1 << 1)                /* This connection is UDP */
+  #define MG_F_RESOLVING (1 << 2)          /* Waiting for async resolver */
+  #define MG_F_CONNECTING (1 << 3)         /* connect() call in progress */
+  #define MG_F_SSL_HANDSHAKE_DONE (1 << 4) /* SSL specific */
+  #define MG_F_WANT_READ (1 << 5)          /* SSL specific */
+  #define MG_F_WANT_WRITE (1 << 6)         /* SSL specific */
+  #define MG_F_IS_WEBSOCKET (1 << 7)       /* Websocket specific */
+  
+  /* Flags that are settable by user */
+  #define MG_F_SEND_AND_CLOSE (1 << 10)      /* Push remaining data and close  */
+  #define MG_F_CLOSE_IMMEDIATELY (1 << 11)   /* Disconnect */
+  #define MG_F_WEBSOCKET_NO_DEFRAG (1 << 12) /* Websocket specific */
+  #define MG_F_DELETE_CHUNK (1 << 13)        /* HTTP specific */
+  
+  #define MG_F_USER_1 (1 << 20) /* Flags left for application */
+  #define MG_F_USER_2 (1 << 21)
+  #define MG_F_USER_3 (1 << 22)
+  #define MG_F_USER_4 (1 << 23)
+  #define MG_F_USER_5 (1 << 24)
+  #define MG_F_USER_6 (1 << 25)
+  };
+---
+
+Mongoose connection. 
+
diff --git a/docs/c-api/net.h/struct_mg_mgr.md b/docs/c-api/net.h/struct_mg_mgr.md
new file mode 100644
index 000000000..f510e1b08
--- /dev/null
+++ b/docs/c-api/net.h/struct_mg_mgr.md
@@ -0,0 +1,21 @@
+---
+title: "struct mg_mgr"
+decl_name: "struct mg_mgr"
+symbol_kind: "struct"
+signature: |
+  struct mg_mgr {
+    struct mg_connection *active_connections;
+    const char *hexdump_file; /* Debug hexdump file path */
+  #ifndef MG_DISABLE_SOCKETPAIR
+    sock_t ctl[2]; /* Socketpair for mg_wakeup() */
+  #endif
+    void *user_data; /* User data */
+    void *mgr_data;  /* Implementation-specific event manager's data. */
+  #ifdef MG_ENABLE_JAVASCRIPT
+    struct v7 *v7;
+  #endif
+  };
+---
+
+Mongoose event manager. 
+
diff --git a/docs/c-api/net.h/struct_mg_str.md b/docs/c-api/net.h/struct_mg_str.md
new file mode 100644
index 000000000..6c0ad613b
--- /dev/null
+++ b/docs/c-api/net.h/struct_mg_str.md
@@ -0,0 +1,13 @@
+---
+title: "struct mg_str"
+decl_name: "struct mg_str"
+symbol_kind: "struct"
+signature: |
+  struct mg_str {
+    const char *p; /* Memory chunk pointer */
+    size_t len;    /* Memory chunk length */
+  };
+---
+
+Describes chunk of memory 
+
diff --git a/docs/c-api/util.h/intro.md b/docs/c-api/util.h/intro.md
new file mode 100644
index 000000000..3b516c8a7
--- /dev/null
+++ b/docs/c-api/util.h/intro.md
@@ -0,0 +1,8 @@
+---
+title: "Utilities"
+symbol_kind: "intro"
+decl_name: "util.h"
+---
+
+
+
diff --git a/docs/c-api/util.h/items.json b/docs/c-api/util.h/items.json
new file mode 100644
index 000000000..4b5b52e01
--- /dev/null
+++ b/docs/c-api/util.h/items.json
@@ -0,0 +1,96 @@
+{
+    "items": [
+        {
+            "type": "markdown",
+            "name": "intro.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_skip.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_ncasecmp.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_casecmp.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_vcmp.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_vcasecmp.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_base64_decode.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_base64_encode.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_stat.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_fopen.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_open.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_start_thread.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_conn_addr_to_str.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_sock_to_str.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_sock_addr_to_str.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_hexdump.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_hexdump_connection.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_avprintf.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_is_big_endian.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_next_comma_list_entry.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_match_prefix.md"
+        },
+        {
+            "type": "markdown",
+            "name": "mg_mk_str.md"
+        },
+        {
+            "type": "markdown",
+            "name": "MG_MK_STR.md"
+        }
+    ]
+}
diff --git a/docs/c-api/util.h/mg_avprintf.md b/docs/c-api/util.h/mg_avprintf.md
new file mode 100644
index 000000000..efc424d00
--- /dev/null
+++ b/docs/c-api/util.h/mg_avprintf.md
@@ -0,0 +1,22 @@
+---
+title: "mg_avprintf()"
+decl_name: "mg_avprintf"
+symbol_kind: "func"
+signature: |
+  int mg_avprintf(char **buf, size_t size, const char *fmt, va_list ap);
+---
+
+Print message to buffer. If buffer is large enough to hold the message,
+return buffer. If buffer is to small, allocate large enough buffer on heap,
+and return allocated buffer.
+This is a supposed use case:
+
+   char buf[5], *p = buf;
+   p = mg_avprintf(&p, sizeof(buf), "%s", "hi there");
+   use_p_somehow(p);
+   if (p != buf) {
+     free(p);
+   }
+
+The purpose of this is to avoid malloc-ing if generated strings are small. 
+
diff --git a/docs/c-api/util.h/mg_base64_decode.md b/docs/c-api/util.h/mg_base64_decode.md
new file mode 100644
index 000000000..3fa77428f
--- /dev/null
+++ b/docs/c-api/util.h/mg_base64_decode.md
@@ -0,0 +1,16 @@
+---
+title: "mg_base64_decode()"
+decl_name: "mg_base64_decode"
+symbol_kind: "func"
+signature: |
+  int mg_base64_decode(const unsigned char *s, int len, char *dst);
+---
+
+Decode base64-encoded string `s`, `len` into the destination `dst`.
+Destination has to have enough space to hold decoded buffer.
+Decoding stops either when all string has been decoded, or invalid
+character appeared.
+Destination is '\0'-terminated.
+Return number of decoded characters. On success, that should be equal to
+`len`. On error (invalid character) the return value is smaller then `len`. 
+
diff --git a/docs/c-api/util.h/mg_base64_encode.md b/docs/c-api/util.h/mg_base64_encode.md
new file mode 100644
index 000000000..c3b5c05e2
--- /dev/null
+++ b/docs/c-api/util.h/mg_base64_encode.md
@@ -0,0 +1,12 @@
+---
+title: "mg_base64_encode()"
+decl_name: "mg_base64_encode"
+symbol_kind: "func"
+signature: |
+  void mg_base64_encode(const unsigned char *src, int src_len, char *dst);
+---
+
+Base64-encode chunk of memory `src`, `src_len` into the destination `dst`.
+Destination has to have enough space to hold encoded buffer.
+Destination is '\0'-terminated. 
+
diff --git a/docs/c-api/util.h/mg_casecmp.md b/docs/c-api/util.h/mg_casecmp.md
new file mode 100644
index 000000000..8d23dbf69
--- /dev/null
+++ b/docs/c-api/util.h/mg_casecmp.md
@@ -0,0 +1,10 @@
+---
+title: "mg_casecmp()"
+decl_name: "mg_casecmp"
+symbol_kind: "func"
+signature: |
+  int mg_casecmp(const char *s1, const char *s2);
+---
+
+Cross-platform version of `strcasecmp()`. 
+
diff --git a/docs/c-api/util.h/mg_conn_addr_to_str.md b/docs/c-api/util.h/mg_conn_addr_to_str.md
new file mode 100644
index 000000000..f17bfb70f
--- /dev/null
+++ b/docs/c-api/util.h/mg_conn_addr_to_str.md
@@ -0,0 +1,21 @@
+---
+title: "mg_conn_addr_to_str()"
+decl_name: "mg_conn_addr_to_str"
+symbol_kind: "func"
+signature: |
+  void mg_conn_addr_to_str(struct mg_connection *nc, char *buf, size_t len,
+                           int flags);
+---
+
+Convert connection's local or remote address into string.
+
+The `flags` parameter is a bit mask that controls the behavior,
+see `MG_SOCK_STRINGIFY_*` definitions.
+
+- MG_SOCK_STRINGIFY_IP - print IP address
+- MG_SOCK_STRINGIFY_PORT - print port number
+- MG_SOCK_STRINGIFY_REMOTE - print remote peer's IP/port, not local address
+
+If both port number and IP address are printed, they are separated by `:`.
+If compiled with `-DMG_ENABLE_IPV6`, IPv6 addresses are supported. 
+
diff --git a/docs/c-api/util.h/mg_fopen.md b/docs/c-api/util.h/mg_fopen.md
new file mode 100644
index 000000000..3446670c2
--- /dev/null
+++ b/docs/c-api/util.h/mg_fopen.md
@@ -0,0 +1,14 @@
+---
+title: "mg_fopen()"
+decl_name: "mg_fopen"
+symbol_kind: "func"
+signature: |
+  FILE *mg_fopen(const char *path, const char *mode);
+---
+
+Open the given file and return a file stream.
+
+`path` and `mode` should be UTF8 encoded.
+
+Return value is the same as for the `fopen()` call. 
+
diff --git a/docs/c-api/util.h/mg_hexdump.md b/docs/c-api/util.h/mg_hexdump.md
new file mode 100644
index 000000000..ed02068aa
--- /dev/null
+++ b/docs/c-api/util.h/mg_hexdump.md
@@ -0,0 +1,15 @@
+---
+title: "mg_hexdump()"
+decl_name: "mg_hexdump"
+symbol_kind: "func"
+signature: |
+  int mg_hexdump(const void *buf, int len, char *dst, int dst_len);
+---
+
+Generates human-readable hexdump of memory chunk.
+
+Takes a memory buffer `buf` of length `len` and creates a hex dump of that
+buffer in `dst`. Generated output is a-la hexdump(1).
+Return length of generated string, excluding terminating `\0`. If returned
+length is bigger than `dst_len`, overflow bytes are discarded. 
+
diff --git a/docs/c-api/util.h/mg_hexdump_connection.md b/docs/c-api/util.h/mg_hexdump_connection.md
new file mode 100644
index 000000000..2e6d520d7
--- /dev/null
+++ b/docs/c-api/util.h/mg_hexdump_connection.md
@@ -0,0 +1,15 @@
+---
+title: "mg_hexdump_connection()"
+decl_name: "mg_hexdump_connection"
+symbol_kind: "func"
+signature: |
+  void mg_hexdump_connection(struct mg_connection *nc, const char *path,
+                             const void *buf, int num_bytes, int ev);
+---
+
+Generates human-readable hexdump of the data sent or received by connection.
+`path` is a file name where hexdump should be written. `num_bytes` is
+a number of bytes sent/received. `ev` is one of the `MG_*` events sent to
+an event handler. This function is supposed to be called from the
+event handler. 
+
diff --git a/docs/c-api/util.h/mg_is_big_endian.md b/docs/c-api/util.h/mg_is_big_endian.md
new file mode 100644
index 000000000..ba33f4d7d
--- /dev/null
+++ b/docs/c-api/util.h/mg_is_big_endian.md
@@ -0,0 +1,10 @@
+---
+title: "mg_is_big_endian()"
+decl_name: "mg_is_big_endian"
+symbol_kind: "func"
+signature: |
+  int mg_is_big_endian(void);
+---
+
+Return true if target platform is big endian. 
+
diff --git a/docs/c-api/util.h/mg_match_prefix.md b/docs/c-api/util.h/mg_match_prefix.md
new file mode 100644
index 000000000..17da2ea7a
--- /dev/null
+++ b/docs/c-api/util.h/mg_match_prefix.md
@@ -0,0 +1,12 @@
+---
+title: "mg_match_prefix()"
+decl_name: "mg_match_prefix"
+symbol_kind: "func"
+signature: |
+  int mg_match_prefix(const char *pattern, int pattern_len, const char *str);
+---
+
+Match 0-terminated string (mg_match_prefix) or string with given length
+mg_match_prefix_n against a glob pattern.
+Match is case-insensitive. Return number of bytes matched, or -1 if no match. 
+
diff --git a/docs/c-api/util.h/mg_mk_str.md b/docs/c-api/util.h/mg_mk_str.md
new file mode 100644
index 000000000..4862e8625
--- /dev/null
+++ b/docs/c-api/util.h/mg_mk_str.md
@@ -0,0 +1,10 @@
+---
+title: "MG_MK_STR()"
+decl_name: "MG_MK_STR"
+symbol_kind: "func"
+signature: |
+  #define MG_MK_STR(str_literal);
+---
+
+Macro for initializing mg_str. 
+
diff --git a/docs/c-api/util.h/mg_ncasecmp.md b/docs/c-api/util.h/mg_ncasecmp.md
new file mode 100644
index 000000000..3e113810d
--- /dev/null
+++ b/docs/c-api/util.h/mg_ncasecmp.md
@@ -0,0 +1,10 @@
+---
+title: "mg_ncasecmp()"
+decl_name: "mg_ncasecmp"
+symbol_kind: "func"
+signature: |
+  int mg_ncasecmp(const char *s1, const char *s2, size_t len);
+---
+
+Cross-platform version of `strncasecmp()`. 
+
diff --git a/docs/c-api/util.h/mg_next_comma_list_entry.md b/docs/c-api/util.h/mg_next_comma_list_entry.md
new file mode 100644
index 000000000..e82d06095
--- /dev/null
+++ b/docs/c-api/util.h/mg_next_comma_list_entry.md
@@ -0,0 +1,21 @@
+---
+title: "mg_next_comma_list_entry()"
+decl_name: "mg_next_comma_list_entry"
+symbol_kind: "func"
+signature: |
+  const char *mg_next_comma_list_entry(const char *list, struct mg_str *val,
+                                       struct mg_str *eq_val);
+---
+
+A helper function for traversing a comma separated list of values.
+It returns a list pointer shifted to the next value, or NULL if the end
+of the list found.
+Value is stored in val vector. If value has form "x=y", then eq_val
+vector is initialized to point to the "y" part, and val vector length
+is adjusted to point only to "x".
+If list is just a comma separated list of entries, like "aa,bb,cc" then
+`eq_val` will contain zero-length string.
+
+The purpose of this function is to parse comma separated string without
+any copying/memory allocation. 
+
diff --git a/docs/c-api/util.h/mg_open.md b/docs/c-api/util.h/mg_open.md
new file mode 100644
index 000000000..385446709
--- /dev/null
+++ b/docs/c-api/util.h/mg_open.md
@@ -0,0 +1,14 @@
+---
+title: "mg_open()"
+decl_name: "mg_open"
+symbol_kind: "func"
+signature: |
+  int mg_open(const char *path, int flag, int mode);
+---
+
+Open the given file and return a file stream.
+
+`path` should be UTF8 encoded.
+
+Return value is the same as for the `open()` syscall. 
+
diff --git a/docs/c-api/util.h/mg_skip.md b/docs/c-api/util.h/mg_skip.md
new file mode 100644
index 000000000..858dc1d77
--- /dev/null
+++ b/docs/c-api/util.h/mg_skip.md
@@ -0,0 +1,17 @@
+---
+title: "mg_skip()"
+decl_name: "mg_skip"
+symbol_kind: "func"
+signature: |
+  const char *mg_skip(const char *s, const char *end_string,
+                      const char *delimiters, struct mg_str *v);
+---
+
+Fetch substring from input string `s`, `end` into `v`.
+Skips initial delimiter characters. Records first non-delimiter character
+as the beginning of substring `v`. Then scans the rest of the string
+until a delimiter character or end-of-string is found.
+`delimiters` is a 0-terminated string containing delimiter characters.
+Either one of `delimiters` or `end_string` terminates the search.
+Return an `s` pointer, advanced forward where parsing stopped. 
+
diff --git a/docs/c-api/util.h/mg_sock_addr_to_str.md b/docs/c-api/util.h/mg_sock_addr_to_str.md
new file mode 100644
index 000000000..0563630b1
--- /dev/null
+++ b/docs/c-api/util.h/mg_sock_addr_to_str.md
@@ -0,0 +1,13 @@
+---
+title: "mg_sock_addr_to_str()"
+decl_name: "mg_sock_addr_to_str"
+symbol_kind: "func"
+signature: |
+  void mg_sock_addr_to_str(const union socket_address *sa, char *buf, size_t len,
+                           int flags);
+---
+
+Convert socket's address into string.
+
+`flags` is MG_SOCK_STRINGIFY_IP and/or MG_SOCK_STRINGIFY_PORT. 
+
diff --git a/docs/c-api/util.h/mg_sock_to_str.md b/docs/c-api/util.h/mg_sock_to_str.md
new file mode 100644
index 000000000..fb233b560
--- /dev/null
+++ b/docs/c-api/util.h/mg_sock_to_str.md
@@ -0,0 +1,10 @@
+---
+title: "mg_sock_to_str()"
+decl_name: "mg_sock_to_str"
+symbol_kind: "func"
+signature: |
+  void mg_sock_to_str(sock_t sock, char *buf, size_t len, int flags);
+---
+
+Legacy interface. 
+
diff --git a/docs/c-api/util.h/mg_start_thread.md b/docs/c-api/util.h/mg_start_thread.md
new file mode 100644
index 000000000..11b66d30a
--- /dev/null
+++ b/docs/c-api/util.h/mg_start_thread.md
@@ -0,0 +1,13 @@
+---
+title: "mg_start_thread()"
+decl_name: "mg_start_thread"
+symbol_kind: "func"
+signature: |
+  void *mg_start_thread(void *(*thread_func);
+---
+
+Start a new detached thread.
+Arguments and semantic is the same as pthead's `pthread_create()`.
+`thread_func` is a thread function, `thread_func_param` is a parameter
+that is passed to the thread function. 
+
diff --git a/docs/c-api/util.h/mg_stat.md b/docs/c-api/util.h/mg_stat.md
new file mode 100644
index 000000000..66c3d75f5
--- /dev/null
+++ b/docs/c-api/util.h/mg_stat.md
@@ -0,0 +1,14 @@
+---
+title: "mg_stat()"
+decl_name: "mg_stat"
+symbol_kind: "func"
+signature: |
+  int mg_stat(const char *path, cs_stat_t *st);
+---
+
+Perform a 64-bit `stat()` call against given file.
+
+`path` should be UTF8 encoded.
+
+Return value is the same as for `stat()` syscall. 
+
diff --git a/docs/c-api/util.h/mg_vcasecmp.md b/docs/c-api/util.h/mg_vcasecmp.md
new file mode 100644
index 000000000..54cb1ab02
--- /dev/null
+++ b/docs/c-api/util.h/mg_vcasecmp.md
@@ -0,0 +1,11 @@
+---
+title: "mg_vcasecmp()"
+decl_name: "mg_vcasecmp"
+symbol_kind: "func"
+signature: |
+  int mg_vcasecmp(const struct mg_str *str2, const char *str1);
+---
+
+Cross-platform version of `strncasecmp()` where first string is
+specified by `struct mg_str`. 
+
diff --git a/docs/c-api/util.h/mg_vcmp.md b/docs/c-api/util.h/mg_vcmp.md
new file mode 100644
index 000000000..74c29d12a
--- /dev/null
+++ b/docs/c-api/util.h/mg_vcmp.md
@@ -0,0 +1,11 @@
+---
+title: "mg_vcmp()"
+decl_name: "mg_vcmp"
+symbol_kind: "func"
+signature: |
+  int mg_vcmp(const struct mg_str *str2, const char *str1);
+---
+
+Cross-platform version of `strcmp()` where where first string is
+specified by `struct mg_str`. 
+
diff --git a/docs/design-concept/conn-flags.md b/docs/design-concept/conn-flags.md
new file mode 100644
index 000000000..e7533deba
--- /dev/null
+++ b/docs/design-concept/conn-flags.md
@@ -0,0 +1,32 @@
+---
+title: Connection flags
+---
+
+Each connection has a `flags` bit field. Some flags are set by Mongoose, for
+example if a user creates an outbound UDP connection using `udp://1.2.3.4:5678`
+address, Mongoose is going to set `MG_F_UDP` flag for that connection. Other
+flags are meant to be set only by user event handler to tell Mongoose how to
+behave.  Below is a list of connection flags that are meant to be set by event
+handlers:
+
+* `MG_F_FINISHED_SENDING_DATA` tells Mongoose that all data has been appended
+  to the `send_mbuf`. As soon as Mongoose sends it to the socket, the
+  connection will be closed.
+* `MG_F_BUFFER_BUT_DONT_SEND` tells Mongoose to append data to the `send_mbuf`
+  but hold on sending it, because the data will be modified later and then will
+  be sent by clearing `MG_F_BUFFER_BUT_DONT_SEND` flag.
+* `MG_F_CLOSE_IMMEDIATELY` tells Mongoose to close the connection immediately,
+  usually after some error
+* `MG_F_USER_1`, `MG_F_USER_2`, `MG_F_USER_3`, `MG_F_USER_4` could be used by a
+  developer to store application-specific state
+
+Flags below are set by Mongoose:
+
+* `MG_F_SSL_HANDSHAKE_DONE` SSL only, set when SSL handshake is done.
+* `MG_F_CONNECTING` set when connection is in connecting state after
+  `mg_connect()` call but connect did not finish yet.
+* `MG_F_LISTENING` set for all listening connections
+* `MG_F_UDP` set if connection is UDP
+* `MG_F_IS_WEBSOCKET` set if connection is a Websocket connection
+* `MG_F_WEBSOCKET_NO_DEFRAG` should be set by a user if user wants to switch
+  off automatic Websocket frame defragmentation
diff --git a/docs/design-concept/event-handler.md b/docs/design-concept/event-handler.md
new file mode 100644
index 000000000..264647cd1
--- /dev/null
+++ b/docs/design-concept/event-handler.md
@@ -0,0 +1,31 @@
+---
+title: Event handler function
+---
+
+Each connection has an event handler function associated with it. That function
+must be implemented by user. Event handler is the key element of the Mongoose
+application, since it defines application's behavior. This is how an event
+handler function looks like:
+
+```c
+static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
+  switch (ev) {
+    /* Event handler code that defines behavior of the connection */
+    ...
+  }
+}
+```
+
+- `struct mg_connection *nc`: Connection that has received an event.
+- `int ev`: Event number, defined in `mongoose.h`. For example, when data
+  arrives on inbound connection `ev` would be `MG_EV_RECV`.
+- `void *ev_data`: This pointer points to the event-specific data, and it has
+  different meaning for different events. For example, for `MG_EV_RECV` event,
+  `ev_data` is an `int *` pointer, pointing to the number of bytes received
+  from the remote peer and saved into the receive IO buffer. Exact meaning of
+  `ev_data` is described for each event. Protocol-specific events usually have
+  `ev_data` pointing to structures that hold protocol-specific information.
+
+NOTE: `struct mg_connection` has `void *user_data` which is a placeholder for
+an application-specific data. Mongoose does not use that pointer. Event handler
+can store any kind of information there.
diff --git a/docs/design-concept/events.md b/docs/design-concept/events.md
index da02fac8e..d8d632c1a 100644
--- a/docs/design-concept/events.md
+++ b/docs/design-concept/events.md
@@ -2,3 +2,51 @@
 title: Events
 ---
 
+Mongoose accepts incoming connections, reads and writes data, and calls
+specified event handler for each connection when appropriate. Typical event
+sequence is this:
+
+- For outbound connection: `MG_EV_CONNECT` -> (`MG_EV_RECV`, `MG_EV_SEND`,
+  `MG_EV_POLL` ...) -> `MG_EV_CLOSE`
+- For inbound connection: `MG_EV_ACCEPT` ->  (`MG_EV_RECV`, `MG_EV_SEND`,
+  `MG_EV_POLL` ...) -> `MG_EV_CLOSE`
+
+
+Below is a list of core events triggered by Mongoose (note that each protocol
+triggers protocol-specific events in addition to the core ones):
+
+- `MG_EV_ACCEPT`: sent when new server connection is accepted by a listening
+  connection. `void *ev_data` is `union socket_address` of the remote peer.
+
+- `MG_EV_CONNECT`: sent when a new outbound connection created by `mg_connect()`
+  either failed or succeeded. `void *ev_data` is `int *success`.  If `success`
+  is 0, then connection has been established, otherwise it contains error code.
+  See `mg_connect_opt()` function for code example.
+
+- `MG_EV_RECV`: New data is received and appended to the end of `recv_mbuf`.
+  `void *ev_data` is `int *num_received_bytes`. Typically, event handler should
+  check received data in `nc->recv_mbuf`, discard processed data by calling
+  `mbuf_remove()`, set connection flags `nc->flags` if necessary (see `struct
+  mg_connection`), and write data the remote peer by output functions like
+  `mg_send()`.
+
+  **WARNING**: Mongoose uses `realloc()` to expand receive buffer.  It is
+  user's responsibility to discard processed data from the beginning of receive
+  buffer, note the `mbuf_remove()` call in the example above.
+
+- `MG_EV_SEND`: Mongoose has written data to the remote peer and discarded
+  written data from the `mg_connection::send_mbuf`. `void *ev_data` is `int
+  *num_sent_bytes`.
+
+  **NOTE**: Mongoose output functions only append data to the
+  `mg_connection::send_mbuf`, they do not do any socket writes.  An actual IO
+  is done by `mg_mgr_poll()`. `MG_EV_SEND` event is just a notification about
+  an IO has been done.
+
+- `MG_EV_POLL`: Sent to all connections on each invocation of `mg_mgr_poll()`.
+  This event could be used to do any housekeeping, for example check whether
+  certain timeout has expired and close the connection, or send heartbeet
+  message, et cetera.
+
+- `MG_EV_TIMER`: Sent to the connection if `mg_set_timer()` was called.
+
diff --git a/docs/design-concept/intro.md b/docs/design-concept/intro.md
index 3c5a41b71..2142b62fd 100644
--- a/docs/design-concept/intro.md
+++ b/docs/design-concept/intro.md
@@ -3,22 +3,22 @@ title: Design Concept
 ---
 
 Mongoose is a multi-protocol networking library that implements non-blocking,
-asyncronous IO and provides event-based API. It has three basic data structures:
+asyncronous IO and provides event-based API. It has three basic data
+structures:
 
-- [`struct mg_mgr`](#TODO) is an event manager that holds all active
-  connections
-- [`struct mg_connection`](#TODO) describes a connection
-- [`struct mbuf`](#TODO) describes data buffer (received or sent data)
+- `struct mg_mgr` is an event manager that holds all active connections
+- `struct mg_connection` describes a connection
+- `struct mbuf` describes data buffer (received or sent data)
 
 Connections could be either *listening*, *outbound* or *inbound*.  Outbound
-connections are created by [`mg_connect()`](#TODO) call.  Listening connections
-are created by [`mg_bind()`](#TODO) call.  Inbound connections are those
-accepted by a listening connection.  Each connection is described by [`struct
-mg_connection`](#TODO) structure, which has a number of fields like socket,
-event handler function, send/receive buffer, flags, et cetera.
+connections are created by `mg_connect()` call.  Listening connections are
+created by `mg_bind()` call.  Inbound connections are those accepted by a
+listening connection.  Each connection is described by `struct mg_connection`
+structure, which has a number of fields like socket, event handler function,
+send/receive buffer, flags, et cetera.
 
 Mongoose usage pattern is to declare and initialize event manager, create
-connections and create an event loop by calling [`mg_mgr_poll()`](#TODO) in a
-loop.  [`mg_mgr_poll()`](#TODO) iterates over all sockets, accepts new
-connections, sends and receives data, closes connections, and calls event
-handler functions for the respective events.
+connections and create an event loop by calling `mg_mgr_poll()` in a loop.
+`mg_mgr_poll()` iterates over all sockets, accepts new connections, sends and
+receives data, closes connections, and calls event handler functions for the
+respective events.
diff --git a/docs/design-concept/items.json b/docs/design-concept/items.json
index 50ffece2e..c939cbe9b 100644
--- a/docs/design-concept/items.json
+++ b/docs/design-concept/items.json
@@ -1,6 +1,9 @@
 {
   "items": [
     { "type": "markdown", "name": "intro.md" },
-    { "type": "markdown", "name": "memory-buffers.md" }
+    { "type": "markdown", "name": "memory-buffers.md" },
+    { "type": "markdown", "name": "event-handler.md" },
+    { "type": "markdown", "name": "events.md" },
+    { "type": "markdown", "name": "conn-flags.md" }
   ]
 }
diff --git a/docs/design-concept/memory-buffers.md b/docs/design-concept/memory-buffers.md
index 6cb41548e..fa0f23c53 100644
--- a/docs/design-concept/memory-buffers.md
+++ b/docs/design-concept/memory-buffers.md
@@ -2,19 +2,14 @@
 title: Memory buffers
 ---
 
-Each connection has send and receive buffer,
-[`struct mg_connection::send_mbuf`](#TODO)
-and
-[`struct mg_connection::recv_mbuf`](#ODO) respectively.
-When data arrives,
-Mongoose appends received data to the `recv_mbuf` and
-triggers `MG_EV_RECV` event. User may send data back by calling one of the
-output functions, like [`mg_send()`](#TODO) or
-[`mg_printf()`](#TODO). Output functions append data to the
-`send_mbuf`. When Mongoose
-successfully writes data to the socket, it discards data from
-[`mg_connection::send_mbuf`](#TODO) and
-sends `MG_EV_SEND` event. When connection is closed, `MG_EV_CLOSE` event is sent.
+Each connection has send and receive buffer, `struct mg_connection::send_mbuf`
+and `struct mg_connection::recv_mbuf` respectively.  When data arrives,
+Mongoose appends received data to the `recv_mbuf` and triggers `MG_EV_RECV`
+event. User may send data back by calling one of the output functions, like
+`mg_send()` or `mg_printf()`. Output functions append data to the `send_mbuf`.
+When Mongoose successfully writes data to the socket, it discards data from
+`struct mg_connection::send_mbuf` and sends `MG_EV_SEND` event. When connection
+is closed, `MG_EV_CLOSE` event is sent.
 
 ![](../../static/img/mongoose/mbuf.png)
 
diff --git a/docs/items.json b/docs/items.json
index d3394c8bb..7360d0150 100644
--- a/docs/items.json
+++ b/docs/items.json
@@ -1,6 +1,8 @@
 {
   "items": [
     { "type": "section", "name": "usage-example" },
-    { "type": "section", "name": "design-concept" }
+    { "type": "section", "name": "design-concept" },
+    { "type": "section", "name": "build-options" },
+    { "type": "flat_sections_set", "name": "c-api" }
   ]
 }
-- 
GitLab