diff --git a/api.go b/api.go
index 6f29dce..a1710cd 100644
--- a/api.go
+++ b/api.go
@@ -1,10 +1,9 @@
 package apidAnalytics
 
 import (
-	"database/sql"
-	"encoding/json"
 	"github.com/30x/apid"
 	"net/http"
+	"strings"
 )
 
 var analyticsBasePath string
@@ -15,8 +14,8 @@
 }
 
 type dbError struct {
-	reason string
-	errorCode    string
+	ErrorCode string `json:"errorCode"`
+	Reason    string `json:"reason"`
 }
 
 type tenant struct {
@@ -32,66 +31,35 @@
 
 func saveAnalyticsRecord(w http.ResponseWriter, r *http.Request) {
 
+	w.Header().Set("Content-Type", "application/json; charset=UTF-8")
+
 	db, _ := data.DB()
 	if db == nil {
-		w.WriteHeader(http.StatusServiceUnavailable)
-		w.Write([]byte("Still initializing service"))
+		writeError(w, http.StatusInternalServerError,"INTERNAL_SERVER_ERROR","Service is not initialized completely")
+		return
+	}
+
+	if !strings.EqualFold(r.Header.Get("Content-Type"),"application/json") {
+		writeError(w, http.StatusBadRequest, "UNSUPPORTED_CONTENT_TYPE","Only supported content type is application/json")
 		return
 	}
 
 	vars := apid.API().Vars(r)
 	scopeuuid := vars["bundle_scope_uuid"]
-	tenant, err := getTenantForScope(scopeuuid)
-	if err.errorCode != "" {
-		w.Header().Set("Content-Type", "application/json; charset=UTF-8")
-		switch err.errorCode {
-		case "SEARCH_INTERNAL_ERROR":
-			w.WriteHeader(http.StatusInternalServerError)
-			if err := json.NewEncoder(w).Encode(errResponse{"SEARCH_INTERNAL_ERROR", err.reason}); err != nil {
-				panic(err)
-			}
+	tenant, dbErr := getTenantForScope(scopeuuid)
+	if dbErr.ErrorCode != "" {
+		switch dbErr.ErrorCode {
+		case "INTERNAL_SEARCH_ERROR":
+			writeError(w, http.StatusInternalServerError, "INTERNAL_SEARCH_ERROR", dbErr.Reason)
 		case "UNKNOWN_SCOPE":
-			w.WriteHeader(http.StatusBadRequest)
-			if err := json.NewEncoder(w).Encode(errResponse{"UNKNOWN_SCOPE", err.reason}); err != nil {
-				panic(err)
-			}
+			writeError(w, http.StatusBadRequest, "UNKNOWN_SCOPE", dbErr.Reason)
 		}
 	} else {
-		message := saveToFile(tenant)
-		w.WriteHeader(http.StatusOK)
-		w.Write([]byte(message))
-	}
-}
-
-func getTenantForScope(scopeuuid string) (tenant, dbError) {
-	// TODO: create a cache during init and refresh it on every failure or listen for snapshot update event
-	var org, env string
-	{
-		db, err := apid.Data().DB()
-		switch {
-		case err != nil:
-			reason := err.Error()
-			errorCode := "SEARCH_INTERNAL_ERROR"
-			return tenant{org, env}, dbError{reason, errorCode}
-		}
-
-		error := db.QueryRow("SELECT env, org FROM DATA_SCOPE WHERE id = ?;", scopeuuid).Scan(&env, &org)
-
-		switch {
-		case error == sql.ErrNoRows:
-			reason := "No tenant found for this scopeuuid: " + scopeuuid
-			errorCode := "UNKNOWN_SCOPE"
-			return tenant{org, env}, dbError{reason, errorCode}
-		case error != nil:
-			reason := error.Error()
-			errorCode := "SEARCH_INTERNAL_ERROR"
-			return tenant{org, env}, dbError{reason, errorCode}
+		err := processPayload(tenant, scopeuuid, r);
+		if err.ErrorCode == "" {
+			w.WriteHeader(http.StatusOK)
+		} else {
+			writeError(w, http.StatusBadRequest, err.ErrorCode, err.Reason)
 		}
 	}
-	return tenant{org, env}, dbError{}
-}
-
-func saveToFile(tenant tenant) string {
-	message := "hey " + tenant.org + "~" + tenant.env
-	return message
 }
diff --git a/apidAnalytics_test.go b/apidAnalytics_test.go
index 97050f4..dcbf64c 100644
--- a/apidAnalytics_test.go
+++ b/apidAnalytics_test.go
@@ -9,7 +9,7 @@
 	Context("get tenant for valid scopeuuid", func() {
 		It("should return testorg and testenv", func() {
 			tenant, dbError := getTenantForScope("testid")
-			Expect(dbError.reason).To(Equal(""))
+			Expect(dbError.Reason).To(Equal(""))
 			Expect(tenant.org).To(Equal("testorg"))
 			Expect(tenant.env).To(Equal("testenv"))
 		})
@@ -19,7 +19,7 @@
 		It("should return empty tenant and a db error", func() {
 			tenant, dbError := getTenantForScope("wrongid")
 			Expect(tenant.org).To(Equal(""))
-			Expect(dbError.errorCode).To(Equal("UNKNOWN_SCOPE"))
+			Expect(dbError.ErrorCode).To(Equal("UNKNOWN_SCOPE"))
 		})
 	})
 })
\ No newline at end of file
diff --git a/helper.go b/helper.go
new file mode 100644
index 0000000..b092db1
--- /dev/null
+++ b/helper.go
@@ -0,0 +1,173 @@
+package apidAnalytics
+
+import (
+	"database/sql"
+	"encoding/json"
+	"github.com/30x/apid"
+	"net/http"
+	"io"
+	"io/ioutil"
+	"strings"
+	"compress/gzip"
+)
+
+type developerInfo struct {
+	apiProduct	string
+	developerApp	string
+	developerEmail	string
+	developer	string
+}
+
+func getTenantForScope(scopeuuid string) (tenant, dbError) {
+	// TODO: create a cache during init and refresh it on every failure or listen for snapshot update event
+	var org, env string
+	{
+		db, err := apid.Data().DB()
+		switch {
+		case err != nil:
+			reason := err.Error()
+			errorCode := "INTERNAL_SEARCH_ERROR"
+			return tenant{org, env}, dbError{errorCode, reason}
+		}
+
+		error := db.QueryRow("SELECT env, org FROM DATA_SCOPE WHERE id = ?;", scopeuuid).Scan(&env, &org)
+
+		switch {
+		case error == sql.ErrNoRows:
+			reason := "No tenant found for this scopeuuid: " + scopeuuid
+			errorCode := "UNKNOWN_SCOPE"
+			return tenant{org, env}, dbError{errorCode, reason}
+		case error != nil:
+			reason := error.Error()
+			errorCode := "INTERNAL_SEARCH_ERROR"
+			return tenant{org, env}, dbError{errorCode, reason}
+		}
+	}
+	return tenant{org, env}, dbError{}
+}
+
+
+func processPayload(tenant tenant, scopeuuid string,  r *http.Request) errResponse {
+	var gzipEncoded bool
+	if r.Header.Get("Content-Encoding") != "" {
+		if !strings.EqualFold(r.Header.Get("Content-Encoding"),"gzip") {
+			return errResponse{"UNSUPPORTED_CONTENT_ENCODING", "Only supported content encoding is gzip"}
+		}  else {
+			gzipEncoded = true
+		}
+	}
+
+	var reader io.ReadCloser
+	var err error
+	if gzipEncoded {
+		reader, err = gzip.NewReader(r.Body)			// reader for gzip encoded data
+		if err != nil {
+			return errResponse{"BAD_DATA", "Gzip data cannot be read"}
+		}
+	} else {
+		reader = r.Body
+	}
+
+	body, _ := ioutil.ReadAll(reader)
+	errMessage := validateAndEnrich(tenant, scopeuuid,  body)
+	if errMessage.ErrorCode != "" {
+		return errMessage
+	}
+	return errResponse{}
+}
+
+func validateAndEnrich(tenant tenant, scopeuuid string, body []byte) errResponse {
+	var raw map[string]interface{}
+	json.Unmarshal(body, &raw)
+	if records := raw["records"]; records != nil {
+		for _, eachRecord := range records.([]interface{}) {
+			recordMap := eachRecord.(map[string]interface{})
+			valid, err := validate(recordMap)
+			if valid {
+				enrich(recordMap, scopeuuid, tenant)
+				log.Debugf("Raw records : %v ", eachRecord)
+			} else {
+				return err				// Even if there is one bad record, then reject entire batch
+			}
+		}
+		// TODO: add the batch of records to a channel for consumption
+	} else {
+		return errResponse{"NO_RECORDS", "No analytics records in the payload"}
+	}
+	return errResponse{}
+}
+
+func validate(recordMap map[string]interface{}) (bool, errResponse) {
+	elems := []string{"client_received_start_timestamp"}
+	for _, elem := range elems {
+		if recordMap[elem] == nil {
+			return false, errResponse{"MISSING_FIELD", "Missing field: " + elem}
+		}
+	}
+
+	crst, exists1 := recordMap["client_received_start_timestamp"]
+	cret, exists2 := recordMap["client_received_end_timestamp"]
+	if exists1 && exists2 {
+		if crst.(int64) > cret.(int64) {
+			return false, errResponse{"BAD_DATA", "client_received_start_timestamp > client_received_end_timestamp"}
+
+		}
+	}
+	// api key is required to find other info
+	_, exists3 := recordMap["client_id"]
+	if !exists3 {
+		return false, errResponse{"BAD_DATA", "client_id cannot be null"}
+	}
+	return true, errResponse{}
+}
+
+func enrich(recordMap map[string]interface{}, scopeuuid string, tenant tenant) {
+	recordMap["organization"] = tenant.org
+	recordMap["environment"] = tenant.env
+	apiKey := recordMap["client_id"].(string)
+	devInfo := getDeveloperInfo(scopeuuid, apiKey)
+	recordMap["api_product"] = devInfo.apiProduct
+	recordMap["developer_app"] = devInfo.developerApp
+	recordMap["developer_email"] = devInfo.developerEmail
+	recordMap["developer"] = devInfo.developer
+}
+
+// if info not found then dont set it
+func getDeveloperInfo(scopeuuid string, apiKey string) developerInfo {
+	// TODO: create a cache during init and refresh it on update event
+	var apiProduct, developerApp, developerEmail, developer  string
+	{
+		db, err := apid.Data().DB()
+		switch {
+		case err != nil:
+			return developerInfo{}
+		}
+
+		// TODO: query needs to change (wont work, it is just a placeholder)
+		error := db.QueryRow("SELECT apiProduct, developerApp, developerEmail, developer FROM DATA_SCOPE WHERE id = ?;", scopeuuid).Scan(&apiProduct, &developerApp, &developerEmail, &developer)
+
+		switch {
+		case error == sql.ErrNoRows:
+			return developerInfo{}
+		case error != nil:
+			return developerInfo{}
+		}
+	}
+	return developerInfo{apiProduct, developerApp, developerEmail, developer}
+	// For local testing
+	//return developerInfo{"test_product", "test_app", "test@test.com", "test"}
+}
+
+func writeError(w http.ResponseWriter, status int, code string, reason string) {
+	w.WriteHeader(status)
+	e := errResponse{
+		ErrorCode: code,
+		Reason:    reason,
+	}
+	bytes, err := json.Marshal(e)
+	if err != nil {
+		log.Errorf("unable to marshal errorResponse: %v", err)
+	} else {
+		w.Write(bytes)
+	}
+}
