{"issue":{"state":"open","created_at":"2011-09-22T18:20:15Z","updated_at":"2011-12-06T10:50:55Z","user":{"gravatar_id":"c1a7cdd1e157bc90735781d12427e084","id":467098,"url":"https://api.github.com/users/emiliopavia","login":"emiliopavia","avatar_url":"https://secure.gravatar.com/avatar/c1a7cdd1e157bc90735781d12427e084?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-140.png"},"comments":28,"body":"## Reporting noises\r\n\r\nThe server should accept a JSON via POST with all the noise data. Here is an example:\r\n\r\n    {\r\n       \"uid\":\"775ab8a39e95529b8517c28e367562ba\",\r\n       \"types\":[\"artificial\",\"indoor\"],\r\n       \"rms\":\"19.06\",\r\n       \"lon\":\"14.715231\",\r\n       \"lat\":\"36.926070\",\r\n       \"duration\":\"5.000\",\r\n       \"hash\":\"5Hqy2J2afbBHcMEArttcc7x8V1Hky4j6ul0mQHsZpiE=\",\r\n       \"timestamp\":\"1316709857\"\r\n    }\r\n\r\nThe server will send back to the client a JSON response with a status code and the ID of the recorded noise. Here is an example:\r\n\r\n    {\r\n       \"status\":\"0\",\r\n       \"id\":\"123456\"\r\n    }\r\n\r\nPossible status codes are:\r\n\r\n*   0: The request was succesfully handled.\r\n* 100: The server could not read the JSON object you provided.\r\n* 101: The request has an incorrect signature. (more about the signature later)\r\n* 102: The request was already sent to the server (duplicate).\r\n\r\n## Assigning tags\r\n\r\nThe server should accept a JSON via POST with the tags and the id of the noise. Here is an example:\r\n\r\n    {\r\n       \"id\":\"123456\",\r\n       \"timestamp\":\"1316710341\",\r\n       \"uid\":\"775ab8a39e95529b8517c28e367562ba\",\r\n       \"tags\":[\"tag1\",\"tag2\"],\r\n       \"hash\":\"sD56c6HNjf8tQMCbzSZyc0dKKEMctD0/ucvhMLSWN0A=\"\r\n    }\r\n\r\nThe server will send back to the client a JSON response with a status code. Here is an example:\r\n\r\n    {\r\n       \"status\":\"0\"\r\n    }\r\n\r\nPossible status codes are:\r\n\r\n*  0: The request was succesfully handled.\r\n* 100: The server could not read the JSON object you provided.\r\n* 101: The request has an incorrect signature. (more about the signature later)\r\n* 102: The request was already sent to the server (duplicate).\r\n\r\n\r\n### Requesting map data\r\n\r\nThe server should accept a JSON via POST with all the noise data. Here is an example:\r\n\r\n    {\r\n       \"lat_delta\":\"0.012591\",\r\n       \"lat\":\"36.926275\",\r\n       \"lon\":\"14.715028\",\r\n       \"hash\":\"Rk6Fb1BWyuKC0YNgSgAMZAsm4WyKAwcg5h46PRYIhL8=\",\r\n       \"lon_delta\":\"0.013733\"\r\n    }\r\n\r\n\"lat\" and \"lon\" are respectively the latitude and the longitude of the center of the map while \"lat_delta\" and \"lon_delta\" determine the visible map area (i.e. the zoom level). It's up to the server to decide if a region is too wide (or contains too many objects to be represented), in this case it would return a subset of all the objects on none of them. The server will response with a JSON containing a status code and a \"data\" field containing an array of noise objects. Each object will contain the following data:\r\n\r\nid: An identifier for the report (must be unique).\r\nlat: The latitude in decimal degrees of the report.\r\nlon: The longitude in decimal degrees of the report.\r\ndb: The average level of noise.\r\ntimestamp: The unix timestamp (in seconds) of the report.\r\nduration: The duration of the sampling (in seconds).\r\n\r\n## Security\r\n\r\nThe hash value sent by the client to the server is a signature of the request calculated using a SHA256 HMAC with a shared secret. The HMAC is calculated on the JSON data with the \"hash\" key left blank. For example:\r\n\r\n    {\r\n       \"uid\":\"775ab8a39e95529b8517c28e367562ba\",\r\n       \"types\":[\"artificial\",\"indoor\"],\r\n       \"rms\":\"19.06\",\r\n       \"lon\":\"14.715231\",\r\n       \"lat\":\"36.926070\",\r\n       \"duration\":\"5.000\",\r\n       \"hash\":\"\",\r\n       \"timestamp\":\"1316709857\"\r\n    }\r\n\r\nWhen receiving the request the server should strip the hash value from the payload, calculate the HMAC using the shared secret and checking if the calculated value matches with the provided one. If there is a match the request can be considered valid. The timestamp value can be used by the server to prevent  \"replay attacks\": if it receives more than one request from the same uid (that is unique and identifies a particular device) with the same timestamp they can be discarded.","assignee":null,"id":1716529,"pull_request":{"patch_url":null,"html_url":null,"diff_url":null},"labels":[],"number":1,"title":"APIs proposal","html_url":"https://github.com/WideTag/WideNoise-iOS/issues/1","closed_at":null,"url":"https://api.github.com/repos/WideTag/WideNoise-iOS/issues/1","milestone":null},"action":"created","comment":{"created_at":"2011-12-06T10:50:55Z","updated_at":"2011-12-06T10:50:55Z","user":{"gravatar_id":"033e75287fa50d88a19b0a13c32cd85d","id":4389,"url":"https://api.github.com/users/folletto","login":"folletto","avatar_url":"https://secure.gravatar.com/avatar/033e75287fa50d88a19b0a13c32cd85d?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-140.png"},"body":"The user agent is passed in the JSON string, there's an example in the middle of this discussion, trying to consolidate the data in a single point.\r\n\r\nAbout the documentation, I started a write-up in the Wiki above. It's still probably not a 1:1 match with the implementation, feel free to update it of you find any error.","id":3030776,"url":"https://api.github.com/repos/WideTag/WideNoise-iOS/issues/comments/3030776"}}