diff --git a/api_documentation/api_documentation.go b/api_documentation/api_documentation.go
index ba8a9b5ca789976eec0662f5c93ddda692bb6e76..57517c79d6faf6d9a36fe0db3763a5d68fbd9a46 100644
--- a/api_documentation/api_documentation.go
+++ b/api_documentation/api_documentation.go
@@ -2,55 +2,74 @@ package api_documentation
 
 import (
 	"fmt"
-	"reflect"
 	"strings"
 
 	"gitlab.com/uafrica/go-utils/handler_utils"
-
-	"gitlab.com/uafrica/go-utils/errors"
 )
 
 type NoParams struct{}
+type DocPath map[string]DocMethodInfo
+
 
 type Docs struct {
 	Paths map[string]DocPath `json:"paths"`
 }
 
-type DocPath struct {
-	Methods map[string]DocMethod `json:"methods"`
-}
 
-type DocMethod struct {
-	Description string              `json:"description"`
-	Parameters  map[string]DocParam `json:"parameters,omitempty"`
-	Request     interface{}         `json:"request,omitempty"`
-	Response    interface{}         `json:"response,omitempty"`
+type DocMethodInfo struct {
+	Summary    string              `json:"summary"`
+	Tags []string `json:"tags"`
+	Parameters []DocParam `json:"parameters,omitempty"`
+	Responses    map[string]DocResponseValue         `json:"responses,omitempty"`
 }
 
 type DocParam struct {
 	Name        string
+	In string
 	Type        string
 	Description string
+	Schema DocSchema
 }
 
+type DocSchema struct {
+	Ref string `json:"$ref"`
+}
+
+type DocResponseValue struct {
+	Description string  `json:"description"`
+	Schema      *DocSchemaResponse `json:"schema,omitempty"`
+}
+
+type DocSchemaResponse struct {
+	Type  *string `json:"type,omitempty"`
+	Items DocSchema  `json:"items"`
+}
+
+
 func GetDocs(endpointHandlers map[string]map[string]interface{}) (Docs, error) {
 	docs := Docs{
 		Paths: map[string]DocPath{},
 	}
+
+	var validationError error
+	if endpointHandlers, validationError = handler_utils.ValidateAPIEndpoints(endpointHandlers); validationError != nil {
+		return Docs{}, validationError
+	}
+
+
 	for path, methods := range endpointHandlers {
-		docPath := DocPath{
-			Methods: map[string]DocMethod{},
-		}
+		docPath := DocPath{}
 		for method, methodHandler := range methods {
-			docMethod := DocMethod{}
+			docMethod := DocMethodInfo{}
 			if handler, ok := methodHandler.(handler_utils.Handler); !ok {
-				docMethod.Description = "Not available"
+				docMethod.Summary = "Not available"
 			} else {
 				//purpose
-				docMethod.Description = "Not available - see request and response structs"
+				docMethod.Summary = "Not available - see request and response structs"
+				docMethod.Tags = []string{path}
 
 				//describe parameters
-				docMethod.Parameters = map[string]DocParam{}
+				docMethod.Parameters = []DocParam{}
 				for i := 0; i < handler.RequestParamsType.NumField(); i++ {
 					f := handler.RequestParamsType.Field(i)
 
@@ -59,108 +78,136 @@ func GetDocs(endpointHandlers map[string]map[string]interface{}) (Docs, error) {
 						name = f.Name
 					}
 
-					docMethod.Parameters[f.Name] = DocParam{
+					parameter := DocParam{
 						Name:        name,
 						Type:        fmt.Sprintf("%v", f.Type),
 						Description: f.Tag.Get("doc"),
 					}
-				}
 
-				//describe request schema
-				var err error
-				docMethod.Request, err = DocSchema(fmt.Sprintf("%s %s %s", method, path, "request"), handler.RequestBodyType)
-				if err != nil {
-					return Docs{}, errors.Wrapf(err, "failed to document request")
+					docMethod.Parameters = append(docMethod.Parameters, parameter)
 				}
-				docMethod.Response, err = DocSchema(fmt.Sprintf("%s %s %s", method, path, "response"), handler.ResponseType)
-				if err != nil {
-					return Docs{}, errors.Wrapf(err, "failed to document response")
-				}
-			}
 
-			docPath.Methods[method] = docMethod
-		}
-		docs.Paths[path] = docPath
-	}
-	return docs, nil
-}
+				 if handler.RequestBodyType != nil {
+					 parameter := DocParam{
+						 Name:        "body",
+						 In: 		"body",
+						 Schema: DocSchema{Ref: "#/definitions/Pet"},
+					 }
 
-func DocSchema(description string, t reflect.Type) (interface{}, error) {
-	if t == nil {
-		return nil, nil
-	}
-	schema := map[string]interface{}{
-		"description": description,
-	}
+					 docMethod.Parameters = append(docMethod.Parameters, parameter)
+				 }
 
-	if t.Kind() == reflect.Ptr {
-		schema["optional"] = true
-		t = t.Elem()
-	}
+				 if handler.ResponseType != nil {
+					 responses := map[string]DocResponseValue{}
 
-	switch t.Kind() {
-	case reflect.Int64, reflect.Int32, reflect.Int16, reflect.Int8, reflect.Int,
-		reflect.Uint64, reflect.Uint32, reflect.Uint16, reflect.Uint8, reflect.Uint,
-		reflect.Float64, reflect.Float32,
-		reflect.Bool,
-		reflect.String:
-		schema["type"] = fmt.Sprintf("%v", t)
-
-	case reflect.Interface:
-		schema["type"] = "interface{}" //any value...?
-
-	case reflect.Struct:
-		schema["type"] = "object"
-		properties := map[string]interface{}{}
-		for i := 0; i < t.NumField(); i++ {
-			f := t.Field(i)
-			if !f.Anonymous {
-				fieldName := f.Tag.Get("json")
-				if fieldName == "" {
-					fieldName = f.Name
-				}
-				if fieldName == "-" {
-					continue //json does not marshal these
-				}
-				fieldName = strings.Replace(fieldName, ",omitempty", "", -1)
+					 responses["200"] = DocResponseValue{
+						 Description: "successful operation",
+						 Schema: &DocSchemaResponse{
+							 Items: DocSchema{Ref:  "#/definitions/Pet"},
+						 },
+					 }
 
-				var err error
-				fieldDesc := f.Tag.Get("doc")
-				if fieldDesc == "" {
-					fieldDesc = description + "." + fieldName
-				}
-				properties[fieldName], err = DocSchema(fieldDesc, f.Type)
-				if err != nil {
-					return nil, errors.Wrapf(err, "failed to document %v.%s", t, fieldName)
-				}
-			}
-		}
-		schema["properties"] = properties
+					 docMethod.Responses = responses
 
-	case reflect.Map:
-		schema["type"] = "map"
-		keySchema, err := DocSchema("key", t.Key())
-		if err != nil {
-			return nil, errors.Wrapf(err, "cannot make schema for %v map key", t)
-		}
-		schema["key"] = keySchema
-		elemSchema, err := DocSchema("items", t.Elem())
-		if err != nil {
-			return nil, errors.Wrapf(err, "cannot make schema for %v map elem", t)
-		}
-		schema["items"] = elemSchema
+				 }
 
-	case reflect.Slice:
-		schema["type"] = "array"
-		elemSchema, err := DocSchema("items", t.Elem())
-		if err != nil {
-			return nil, errors.Wrapf(err, "cannot make schema for %v slice elem", t)
-		}
-		schema["items"] = elemSchema
 
-	default:
-		return nil, errors.Errorf("cannot generate schema for %v kind=%v", t, t.Kind())
-	}
 
-	return schema, nil
+				//describe request schema
+				// var err error
+				// docMethod.Request, err = DocSchema(fmt.Sprintf("%s %s %s", method, path, "request"), handler.RequestBodyType)
+				// if err != nil {
+				// 	return Docs{}, errors.Wrapf(err, "failed to document request")
+				// }
+				// docMethod.Response, err = DocSchema(fmt.Sprintf("%s %s %s", method, path, "response"), handler.ResponseType)
+				// if err != nil {
+				// 	return Docs{}, errors.Wrapf(err, "failed to document response")
+				// }
+			}
+
+			docPath[strings.ToLower(method)] = docMethod
+		}
+		docs.Paths[path] = docPath
+	}
+	return docs, nil
 }
+//
+// func DocSchema(description string, t reflect.Type) (interface{}, error) {
+// 	if t == nil {
+// 		return nil, nil
+// 	}
+// 	schema := map[string]interface{}{
+// 		"description": description,
+// 	}
+//
+// 	if t.Kind() == reflect.Ptr {
+// 		schema["optional"] = true
+// 		t = t.Elem()
+// 	}
+//
+// 	switch t.Kind() {
+// 	case reflect.Int64, reflect.Int32, reflect.Int16, reflect.Int8, reflect.Int,
+// 		reflect.Uint64, reflect.Uint32, reflect.Uint16, reflect.Uint8, reflect.Uint,
+// 		reflect.Float64, reflect.Float32,
+// 		reflect.Bool,
+// 		reflect.String:
+// 		schema["type"] = fmt.Sprintf("%v", t)
+//
+// 	case reflect.Interface:
+// 		schema["type"] = "interface{}" //any value...?
+//
+// 	case reflect.Struct:
+// 		schema["type"] = "object"
+// 		properties := map[string]interface{}{}
+// 		for i := 0; i < t.NumField(); i++ {
+// 			f := t.Field(i)
+// 			if !f.Anonymous {
+// 				fieldName := f.Tag.Get("json")
+// 				if fieldName == "" {
+// 					fieldName = f.Name
+// 				}
+// 				if fieldName == "-" {
+// 					continue //json does not marshal these
+// 				}
+// 				fieldName = strings.Replace(fieldName, ",omitempty", "", -1)
+//
+// 				var err error
+// 				fieldDesc := f.Tag.Get("doc")
+// 				if fieldDesc == "" {
+// 					fieldDesc = description + "." + fieldName
+// 				}
+// 				properties[fieldName], err = DocSchema(fieldDesc, f.Type)
+// 				if err != nil {
+// 					return nil, errors.Wrapf(err, "failed to document %v.%s", t, fieldName)
+// 				}
+// 			}
+// 		}
+// 		schema["properties"] = properties
+//
+// 	case reflect.Map:
+// 		schema["type"] = "map"
+// 		// keySchema, err := DocSchema("key", t.Key())
+// 		// if err != nil {
+// 		// 	return nil, errors.Wrapf(err, "cannot make schema for %v map key", t)
+// 		// }
+// 		// schema["key"] = keySchema
+// 		// // elemSchema, err := DocSchema("items", t.Elem())
+// 		// if err != nil {
+// 		// 	return nil, errors.Wrapf(err, "cannot make schema for %v map elem", t)
+// 		// }
+// 		// schema["items"] = elemSchema
+//
+// 	case reflect.Slice:
+// 		schema["type"] = "array"
+// 		// elemSchema, err := DocSchema("items", t.Elem())
+// 		// if err != nil {
+// 		// 	return nil, errors.Wrapf(err, "cannot make schema for %v slice elem", t)
+// 		// }
+// 		// schema["items"] = elemSchema
+//
+// 	default:
+// 		return nil, errors.Errorf("cannot generate schema for %v kind=%v", t, t.Kind())
+// 	}
+//
+// 	return schema, nil
+// }
diff --git a/handler_utils/handler.go b/handler_utils/handler.go
index 89c8c8ae51416140910c5f7a493c60cb1b8554a0..b1e6cad0926cd5941ec66f73b9462fdbfed6eed0 100644
--- a/handler_utils/handler.go
+++ b/handler_utils/handler.go
@@ -62,6 +62,11 @@ func NewHandler(handlerFunction interface{}) (Handler, error) {
 		return h, errors.Errorf("last result %v is not error type", handlerFunctionType.Out(handlerFunctionType.NumOut()-1))
 	}
 
+	// First result is the response object
+	if handlerFunctionType.NumOut() > 0 {
+		h.ResponseType =  handlerFunctionType.Out(0)
+	}
+
 	h.FuncValue = reflect.ValueOf(handlerFunction)
 	return h, nil
 }