{"_id":"open311","_rev":"28-5825e80ef10417aa0fac36f43de245c2","name":"open311","description":"A Node.js module for interacting with an Open311 API.","dist-tags":{"latest":"0.0.12"},"versions":{"0.0.3":{"name":"open311","description":"A Node.js module for interacting with the Open311 API.","version":"0.0.3","homepage":"http://voiceingov.org","author":{"name":"Mark Headd","email":"mheadd@voiceingov.org","url":"http://voiceingov.org"},"main":"./lib/open311","repositories":[{"type":"git","url":"https://github.com/mheadd/node-open311"}],"engines":{"node":">= 0.2.4"},"_id":"open311@0.0.3","_nodeSupported":true,"_npmVersion":"0.2.12","_nodeVersion":"v0.2.4","dist":{"shasum":"c81f744207bf6e96d9337f279a9f47d5f7fac6a9","tarball":"https://registry.npmjs.org/open311/-/open311-0.0.3.tgz","integrity":"sha512-aI9T64O9F7gBAGQW92q6WedFN+jyKXSurkddFL5UHtJdvc9xYxZkewXnaK9WwkFmlglpIKm4slVphR1pVqbTng==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCHxauWqWRg75sL5ZwLAf66SnBEgEW/z/E3oHY2UAeDZUCIQCNVvUskZHAZEAfBbywGn94ypbBxWSXm4Wfn2ebPagI/g=="}]},"directories":{}},"0.0.4":{"name":"open311","description":"A Node.js module for interacting with an Open311 API.","version":"0.0.4","homepage":"http://voiceingov.org","author":{"name":"Mark Headd","email":"mheadd@voiceingov.org","url":"http://voiceingov.org"},"main":"./lib/open311","repositories":[{"type":"git","url":"https://github.com/mheadd/node-open311"}],"engines":{"node":"0.4.2"},"_id":"open311@0.0.4","_nodeSupported":true,"_npmVersion":"0.2.12","_nodeVersion":"v0.4.2","dist":{"shasum":"ecc61c7ccb902af6cbb96268b64e5b36c4ce06aa","tarball":"https://registry.npmjs.org/open311/-/open311-0.0.4.tgz","integrity":"sha512-oHm7Sj72uGunm49IItLaRaaxAMdZLlo74nf2azSZmetBWwSiBe7xrRmF1R9hrd4V4JAvBmuSzXwcFTZmt/Zfzg==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIH9jaBsbNkj+zSq3igwgdvpBa6Dwh/UaaRpAMAEtMAOKAiAMTHv8aWd7uL7Feq36vppAbjKDsDqPHwQVHpKHoO3TMQ=="}]},"directories":{}},"0.0.5":{"name":"open311","description":"A Node.js module for interacting with an Open311 API.","version":"0.0.5","homepage":"http://voiceingov.org","author":{"name":"Mark Headd","email":"mheadd@voiceingov.org","url":"http://voiceingov.org"},"main":"./lib/open311","repositories":[{"type":"git","url":"https://github.com/mheadd/node-open311"}],"engines":{"node":"0.4.2"},"_id":"open311@0.0.5","_nodeSupported":false,"_npmVersion":"0.2.12","_nodeVersion":"v0.4.3","dist":{"shasum":"226bbdba7c342bff8f5f4ed971d15863ac49c379","tarball":"https://registry.npmjs.org/open311/-/open311-0.0.5.tgz","integrity":"sha512-53pi31HBhMZW7sECFcvqCnmKV/ZTku8Q3qSnU2lufFSRWEdJPU4LAN999vOh8o6gB48O2RBZIDFQ6Nt/NAPDBA==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCGeeca/rb78+BE7Ro9aPJYm31EYzoEUSfn819gYcHrUgIgJODKkuqfnHwU4WhLAFx2Btd+z5rjpt8uaEdOigtNiWc="}]},"directories":{}},"0.0.6":{"name":"open311","description":"A Node.js module for interacting with an Open311 API.","version":"0.0.6","homepage":"http://voiceingov.org","author":{"name":"Mark Headd","email":"mheadd@voiceingov.org","url":"http://voiceingov.org"},"main":"./lib/open311","repositories":[{"type":"git","url":"https://github.com/mheadd/node-open311"}],"engines":{"node":"> 0.4.2"},"_id":"open311@0.0.6","_nodeSupported":true,"_npmVersion":"0.2.12","_nodeVersion":"v0.4.3","dist":{"shasum":"6c4a6dcacd97a739f56057f0e9e6f8e7c8e4c9f7","tarball":"https://registry.npmjs.org/open311/-/open311-0.0.6.tgz","integrity":"sha512-bFO9ARB/xlOvu5Rz4usIg55n4QwdJQAkrOBGgQF/HYVC3xk9pJkUL1M2Et+y1bVJlIdn8hcRwMvUXXtx5lZ2wA==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCYvJdDGgPXHWbzspQRbof40Pxcq7i5GrZ2j8FXUuerAgIgBZ5E2jDy2C9X5b0Nsl4L9+H9uPbe2lxGXCVe5bEgDz4="}]},"directories":{}},"0.0.7":{"name":"open311","description":"A Node.js module for interacting with an Open311 API.","version":"0.0.7","homepage":"http://voiceingov.org","author":{"name":"Mark Headd","email":"mheadd@voiceingov.org","url":"http://voiceingov.org"},"main":"./lib/open311","repositories":[{"type":"git","url":"https://github.com/mheadd/node-open311"}],"engines":{"node":"> 0.4.1"},"_id":"open311@0.0.7","_nodeSupported":true,"_npmVersion":"0.2.12","_nodeVersion":"v0.4.2","dist":{"shasum":"3d63773f9352d5be097119087c2fcb3e2fde3eef","tarball":"https://registry.npmjs.org/open311/-/open311-0.0.7.tgz","integrity":"sha512-+qq77cwBLOarANuRnb2XSjo/JFaO3bJGINARCr8BI4P2tEgT+62ZnEyp5at4n8eUq4B1qwVuEbv08ot/tH2Gkg==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIAYJZVdSFF7hVmxJ4RRlk7lXYqloskfGYKG8wStEgabOAiEA853FRW+G5x2N3pbxTAXvnNiHv1tpe25SKR4xyU0eklY="}]},"maintainers":[{"name":"mheadd","email":"mheadd@voxeo.com"}],"directories":{}},"0.0.8":{"name":"open311","description":"A Node.js module for interacting with an Open311 API.","version":"0.0.8","homepage":"http://voiceingov.org","author":{"name":"Mark Headd","email":"mheadd@voiceingov.org","url":"http://voiceingov.org"},"main":"./lib/open311","repositories":[{"type":"git","url":"https://github.com/mheadd/node-open311"}],"engines":{"node":"> 0.4.1"},"_id":"open311@0.0.8","_nodeSupported":true,"_npmVersion":"0.2.12","_nodeVersion":"v0.4.2","dist":{"shasum":"3961da589ba056a0bfd4808414874f285210df01","tarball":"https://registry.npmjs.org/open311/-/open311-0.0.8.tgz","integrity":"sha512-Q/yhVXNnRkL40BnzUwSP5jquuyLCKWuoIIFBUQ4yaGCRySNc53b8nV6ZyTwpKHfLG7+jjTKz+KWzcBBTo6nelg==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCrs6cpJdyaiOqvsbhXKeslboofvtUvseLoBwXGD2ayuwIgMq4PB0bEJ88kouhCFuqah2zwUqSvr/E959EvEBwBwvU="}]},"maintainers":[{"name":"mheadd","email":"mheadd@voxeo.com"}],"directories":{}},"0.0.9":{"name":"open311","description":"A Node.js module for interacting with an Open311 API.","version":"0.0.9","homepage":"https://github.com/codeforamerica/node-open311","author":{"name":"Mark Headd","email":"mheadd@gmail.com","url":"http://civic.io"},"contributors":[{"name":"Ben Sheldon","email":"ben@codeforamerica.org"}],"main":"./open311","repository":{"type":"git","url":"git://github.com/codeforamerica/node-open311.git"},"license":"BSD","engines":{"node":"0.8.x"},"scripts":{"test":"./node_modules/mocha/bin/mocha"},"dependencies":{"request":"~2.11.0","lodash":"~0.6.1","sparkxml":"git://github.com/codeforamerica/node-sparkxml.git","xml2json":"~0.2.4"},"devDependencies":{"mocha":"~1.4.1","chai":"~1.2.0","sinon":"~1.4.2"},"_npmUser":{"name":"bensheldon","email":"ben@codeforamerica.org"},"_id":"open311@0.0.9","optionalDependencies":{},"_engineSupported":false,"_npmVersion":"1.1.12","_nodeVersion":"v0.6.14","_defaultsLoaded":true,"dist":{"shasum":"5fc2e8426c5bbfc1166260fc3aceb26b7ca82a87","tarball":"https://registry.npmjs.org/open311/-/open311-0.0.9.tgz","integrity":"sha512-RfsBmMv2XNPCTqf1oGe5Jm1wsV4ZtnJvGrVkUV//xKwbkaBEBYbv2hCX63fwT5LVBbm2Hdk+70BvTp5mCMLtlQ==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCS18PxpIM25r04sauMHHfbcP5NyP4BLfaKztl3wDtWSQIgR3Ytalx6EEKLiUPF591IcoGfv+sVUzOyDiAw2PbWFVQ="}]},"readme":"# node-open311\n\n[![Build Status](https://secure.travis-ci.org/codeforamerica/node-open311.png)](http://travis-ci.org/codeforamerica/node-open311)\n\nA Node.js module for interacting with the Open311 API ([GeoReport v2](http://wiki.open311.org/GeoReport_v2)). This module is more than a simple wrapper; it attempts to normalize the response from different Open311 endpoints' _interpretation_ of the Open311 specification to return consistent results, regardless of implementation or format:\n\n- All responses are returned as native javascript objects/arrays\n- XML-only endpoints are parsed into native javascript objects/arrays that are consistent with JSON results\n- Invalid responses (e.g. malformed JSON that some endpoints may return), are cleaned up and returned as native javascript objects/arrays\n\n## Installation\n\n`npm install open311`\n\n## Brief Example\n\n```javascript\nvar Open311 = require('open311');\n\t\n// Example Open311 Server: City of Baltimore \n// More options here: http://wiki.open311.org/GeoReport_v2/Servers\nvar options = {\n  endpoint     : \"http://311.baltimorecity.gov/open311/v2/\",\n  jurisdiction : \"baltimorecity.gov\"\n};\n\t\n// Create a new Open311 object.\nvar baltimore = new Open311(options);\n\t\n// Call serviceRequest with service_request_id\n// to get the status of a specific service request.\nbaltimore.serviceRequest('12-00677322', function(err, data){ \n  console.log(data); // do something with the data!\n});\n```\n\n## Usage\n\n### new Open311(options)\n\nTo use this library, you must instantiate a new Open311 object: `var open311 = new Open311(options)`. \n\nYou can construct by passing a string that corresponds to the id of a city that is defined in the [`cities.json`](https://github.com/codeforamerica/node-open311/blob/master/cities.json) file. \n\ne.g. `var baltimore = new Open311('baltimore');`\n\nOr, you can pass individual `options`, including:\n\n- `endpoint`: the URL of the Open311 server; required for all methods except `Open311.serviceDiscovery()`\n- `jurisdiction`: (optional) the `jurisdiction_id` for a given city, if required\n- `discovery`: the URL Service Discovery; required if using `Open311.serviceDiscovery()` method\n- `format`: the format data should be requested in; only required for XML-only Open311 servers (default: `json`)\n- `apiKey`: your API key; required if using `Open311.submitServiceRequest()` method\n\nAll methods use the standard `callback(err, data)` format.\n\n### serviceDiscovery([options], callback)\n\nFetches a city's Service Discovery listing that has URLs of Open311 servers. (Standard: [Service Discovery](http://wiki.open311.org/Service_Discovery))\n\nOptional options:\n\n- `cache`: if `true` the fetched endpoints will set/overwrite the endpoint URL of the Open311 object (default: `false`)\n- `type`: when caching, sets the `test` or `production` endpoint server (default: `production`)\n- `specification`: when caching, sets the matching API specification of the endpoint server (default `http://wiki.open311.org/GeoReport_v2`);\n- `index`: (optional) when caching, if the Service Discovery list multiple servers with identical production/specification settings, this is the index of the resulting matched servers (default: `0`)\n\n```javascript\nvar baltimore = new Open311({\n  discovery: \"http://311.baltimorecity.gov/open311/discovery.json\"\n});\n\n// Make the API call\nbaltimore.serviceDiscovery({\n  cache: true,\n  type: \"production\"\n}, function(err, data) {\n  // `data` contains the content of the Service Discovery\n  // `baltimore.endpoint` should now be set because \n  //  we set `cache: true`\n});\n```\n\n\n### serviceList(callback)\n\nFetches a list of acceptable 311 service request types and their associated service codes. (Standard: [GET Service List](http://wiki.open311.org/GeoReport_v2#GET_Service_List))\n\n```javascript\n// an example with Washington, DC, which is an XML-only endpoint\nvar dc = new Open311({\n  \"endpoint\": \"http://app.311.dc.gov/CWI/Open311/v2/\",\n  \"format\": \"xml\",\n  \"jurisdiction\": \"dc.gov\"\n});\n\n// Make the API call\ndc.serviceDiscovery(function(err, data) {\n  // `data` contains a javascript array of javascript objects\n});\n```\n\n### serviceDefinition(service_code, callback)\n\nFetches attributes associated with a service code. Those attributes may be required when submitting a new Service Request (Standard: [GET Service Definition\n](http://wiki.open311.org/GeoReport_v2#GET_Service_Definition))\n\n`service_code` is the string/number returned from an entry in `Open311.serviceList()`\n\n### submitRequest(data, callback)\n\nSubmit a service request. (Standard: [POST Service Request](http://wiki.open311.org/GeoReport_v2#POST_Service_Request))\n\nAccording to the Open311 specification, `data` must include:\n\n- `service_code`\n- `lat` & `long` _OR_ `address_string` _OR_ `address_id`: the specification is wiggly here, but `lat`/`long` is near universally required (despite the \"OR\")\n- attributes (see `Open311.serviceDefinition`) set with the key `attribute[<code>]` _OR_ assign `data.attributes` to be an object with key/values: e.g. Submitting this:\n    \n  ```javascript\n  data = {\n    \"service_code\": \"ABANDONED_VEHICLE\",\n    \"lat\": 12.345,\n    \"long\": 67.890,\n    \"attributes\": {\n      \"license_plate\": \"A234567\",\n      \"color\": \"blue\"\n    }\n  }\n  ```\n  \n  ...will result in the appropriate and standard-compliant attributes being constructed:\n  \n  ```javascript\n  data = {\n    \"service_code\": \"ABANDONED_VEHICLE\",\n    \"lat\": 12.345,\n    \"long\": 67.890,\n    \"attribute[license_plate]\": \"A234567\",\n    \"attribute[color]\": \"blue\"\n  }\n  ```\n\n\n### token(token, callback)\n\nFetches the service_request_id from a temporary token that was received when submitting a Service Request. This is unnecessary if the response from creating a service request does not contain a token. \n(Standard: [GET service_request_id from a token](http://wiki.open311.org/GeoReport_v2#GET_service_request_id_from_a_token))\n\n`token` should either be a string or number.\n\n### serviceRequests([[service_request_ids]], [params], callback) \nFetch a list of existing service requests based on query parameters (Standard: [GET Service Requests](http://wiki.open311.org/GeoReport_v2#GET_Service_Requests))\n\nOptional params might include those on the existing standard, such as:\n- `service_request_id`: a comma delimited list of `service_request_id`s to fetch... or you can submit a javascript array of them as the first argument and they will be formatted correctly in the parameters\n- `service_code`: filter the by the service request's service_code\n- `start_date` / `end_date`: filter by the earliest/latest requested_datetime (when the request was submitted).\n- `status`: filter by the status (`open`/`closed`)\n\nOr params might include those not on the standard but widely supported, such as:\n\n- `page` and `page_size`: for paging through results\n\n\n### serviceRequest(service_request_id, callback)\n\nFetches an individual request by its `service_request_id`. (Standard: [GET Service Request](http://wiki.open311.org/GeoReport_v2#GET_Service_Request)).\n\nNote that this is just an alias to `Open311.serviceRequests`, so instead of submitting a single string/numerical `service_request_id`, you can submit an array of them of multiple `service_request_id`s too.\n\ne.g. you can do any of these:\n\n\n```javascript\n// as a string\nbaltimore.serviceRequest('12-00677322', function(err, data){ \n  console.log(data); // do something with the data!\n});\n```\n\nOR\n\n```javascript\n// as an array\nbaltimore.serviceRequest(['12-00677322'], function(err, data){ \n  console.log(data); // do something with the data!\n});\n```\n\nOR\n\n```javascript\n// as an even BIGGER array\nbaltimore.serviceRequest(['12-00677322', '12-00677323'], function(err, data){ \n  console.log(data); // do something with the data!\n});\n```\n\nOR\n\n```javascript\n// as a comma separated query parameter\n// ...but why would you ever want to do that?\nbaltimore.serviceRequest({\n  service_request_id: \"12-00677322,12-00677323\"\n}, function(err, data){ \n  console.log(data); // do something with the data!\n});\n```\n\n\n","maintainers":[{"name":"mheadd","email":"mheadd@voxeo.com"},{"name":"bensheldon","email":"ben@codeforamerica.org"}]},"0.0.10":{"name":"open311","description":"A Node.js module for interacting with an Open311 API.","version":"0.0.10","homepage":"https://github.com/codeforamerica/node-open311","author":{"name":"Mark Headd","email":"mheadd@gmail.com","url":"http://civic.io"},"contributors":[{"name":"Ben Sheldon","email":"ben@codeforamerica.org"}],"main":"./open311","repository":{"type":"git","url":"git://github.com/codeforamerica/node-open311.git"},"license":"BSD","engines":{"node":"0.8.x"},"scripts":{"test":"./node_modules/mocha/bin/mocha"},"dependencies":{"request":"~2.11.0","lodash":"~0.6.1","sparkxml":"git://github.com/codeforamerica/node-sparkxml.git","xml2json":"~0.2.4"},"devDependencies":{"mocha":"~1.4.1","chai":"~1.2.0","sinon":"~1.4.2"},"_npmUser":{"name":"bensheldon","email":"ben@codeforamerica.org"},"_id":"open311@0.0.10","optionalDependencies":{},"_engineSupported":false,"_npmVersion":"1.1.12","_nodeVersion":"v0.6.14","_defaultsLoaded":true,"dist":{"shasum":"cd72fbcfc5324a4a32660111411e49b7b031a184","tarball":"https://registry.npmjs.org/open311/-/open311-0.0.10.tgz","integrity":"sha512-ylUt8SVivH+e57Ra+7gVecoA0+RQgbkqP1GtQn9aSInkSUlir50d4my1z5Zq2KGkeSGdy5aro2O94coSAYTW1g==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBc5QXhbCxXfp8J9BUFieO3pNAiAplHoko4gJoni8K0QAiEAqN4GmXYqYZ5ivZqfueCb5CJp0HtsmUng9yORqKpLJz8="}]},"readme":"# node-open311\n\n[![Build Status](https://secure.travis-ci.org/codeforamerica/node-open311.png)](http://travis-ci.org/codeforamerica/node-open311)\n\nA Node.js module for interacting with the Open311 API ([GeoReport v2](http://wiki.open311.org/GeoReport_v2)). This module is more than a simple wrapper; it attempts to normalize the response from different Open311 endpoints' _interpretation_ of the Open311 specification to return consistent results, regardless of implementation or format:\n\n- All responses are returned as native javascript objects/arrays\n- XML-only endpoints are parsed into native javascript objects/arrays that are consistent with JSON results\n- Invalid responses (e.g. malformed JSON that some endpoints may return), are cleaned up and returned as native javascript objects/arrays\n\n## Installation\n\n`npm install open311`\n\n## Brief Example\n\n```javascript\nvar Open311 = require('open311');\n\t\n// Example Open311 Server: City of Baltimore \n// More options here: http://wiki.open311.org/GeoReport_v2/Servers\nvar options = {\n  endpoint     : \"http://311.baltimorecity.gov/open311/v2/\",\n  jurisdiction : \"baltimorecity.gov\"\n};\n\t\n// Create a new Open311 object.\nvar baltimore = new Open311(options);\n\t\n// Call serviceRequest with service_request_id\n// to get the status of a specific service request.\nbaltimore.serviceRequest('12-00677322', function(err, data){ \n  console.log(data); // do something with the data!\n});\n```\n\n## Usage\n\n### new Open311(options)\n\nTo use this library, you must instantiate a new Open311 object: `var open311 = new Open311(options)`. \n\nYou can construct by passing a string that corresponds to the id of a city that is defined in the [`cities.json`](https://github.com/codeforamerica/node-open311/blob/master/cities.json) file. \n\ne.g. `var baltimore = new Open311('baltimore');`\n\nOr, you can pass individual `options`, including:\n\n- `endpoint`: the URL of the Open311 server; required for all methods except `Open311.serviceDiscovery()`\n- `jurisdiction`: (optional) the `jurisdiction_id` for a given city, if required\n- `discovery`: the URL Service Discovery; required if using `Open311.serviceDiscovery()` method\n- `format`: the format data should be requested in; only required for XML-only Open311 servers (default: `json`)\n- `apiKey`: your API key; required if using `Open311.submitServiceRequest()` method\n\nAll methods use the standard `callback(err, data)` format.\n\n### serviceDiscovery([options], callback)\n\nFetches a city's Service Discovery listing that has URLs of Open311 servers. (Standard: [Service Discovery](http://wiki.open311.org/Service_Discovery))\n\nOptional options:\n\n- `cache`: if `true` the fetched endpoints will set/overwrite the endpoint URL of the Open311 object (default: `false`)\n- `type`: when caching, sets the `test` or `production` endpoint server (default: `production`)\n- `specification`: when caching, sets the matching API specification of the endpoint server (default `http://wiki.open311.org/GeoReport_v2`);\n- `index`: (optional) when caching, if the Service Discovery list multiple servers with identical production/specification settings, this is the index of the resulting matched servers (default: `0`)\n\n```javascript\nvar baltimore = new Open311({\n  discovery: \"http://311.baltimorecity.gov/open311/discovery.json\"\n});\n\n// Make the API call\nbaltimore.serviceDiscovery({\n  cache: true,\n  type: \"production\"\n}, function(err, data) {\n  // `data` contains the content of the Service Discovery\n  // `baltimore.endpoint` should now be set because \n  //  we set `cache: true`\n});\n```\n\n\n### serviceList(callback)\n\nFetches a list of acceptable 311 service request types and their associated service codes. (Standard: [GET Service List](http://wiki.open311.org/GeoReport_v2#GET_Service_List))\n\n```javascript\n// an example with Washington, DC, which is an XML-only endpoint\nvar dc = new Open311({\n  \"endpoint\": \"http://app.311.dc.gov/CWI/Open311/v2/\",\n  \"format\": \"xml\",\n  \"jurisdiction\": \"dc.gov\"\n});\n\n// Make the API call\ndc.serviceDiscovery(function(err, data) {\n  // `data` contains a javascript array of javascript objects\n});\n```\n\n### serviceDefinition(service_code, callback)\n\nFetches attributes associated with a service code. Those attributes may be required when submitting a new Service Request (Standard: [GET Service Definition\n](http://wiki.open311.org/GeoReport_v2#GET_Service_Definition))\n\n`service_code` is the string/number returned from an entry in `Open311.serviceList()`\n\n### submitRequest(data, callback)\n\nSubmit a service request. (Standard: [POST Service Request](http://wiki.open311.org/GeoReport_v2#POST_Service_Request))\n\nAccording to the Open311 specification, `data` must include:\n\n- `service_code`\n- `lat` & `long` _OR_ `address_string` _OR_ `address_id`: the specification is wiggly here, but `lat`/`long` is near universally required (despite the \"OR\")\n- attributes (see `Open311.serviceDefinition`) set with the key `attribute[<code>]` _OR_ assign `data.attributes` to be an object with key/values: e.g. Submitting this:\n    \n  ```javascript\n  data = {\n    \"service_code\": \"ABANDONED_VEHICLE\",\n    \"lat\": 12.345,\n    \"long\": 67.890,\n    \"attributes\": {\n      \"license_plate\": \"A234567\",\n      \"color\": \"blue\"\n    }\n  }\n  ```\n  \n  ...will result in the appropriate and standard-compliant attributes being constructed:\n  \n  ```javascript\n  data = {\n    \"service_code\": \"ABANDONED_VEHICLE\",\n    \"lat\": 12.345,\n    \"long\": 67.890,\n    \"attribute[license_plate]\": \"A234567\",\n    \"attribute[color]\": \"blue\"\n  }\n  ```\n\n\n### token(token, callback)\n\nFetches the service_request_id from a temporary token that was received when submitting a Service Request. This is unnecessary if the response from creating a service request does not contain a token. \n(Standard: [GET service_request_id from a token](http://wiki.open311.org/GeoReport_v2#GET_service_request_id_from_a_token))\n\n`token` should either be a string or number.\n\n### serviceRequests([[service_request_ids]], [params], callback) \nFetch a list of existing service requests based on query parameters (Standard: [GET Service Requests](http://wiki.open311.org/GeoReport_v2#GET_Service_Requests))\n\nOptional params might include those on the existing standard, such as:\n- `service_request_id`: a comma delimited list of `service_request_id`s to fetch... or you can submit a javascript array of them as the first argument and they will be formatted correctly in the parameters\n- `service_code`: filter the by the service request's service_code\n- `start_date` / `end_date`: filter by the earliest/latest requested_datetime (when the request was submitted).\n- `status`: filter by the status (`open`/`closed`)\n\nOr params might include those not on the standard but widely supported, such as:\n\n- `page` and `page_size`: for paging through results\n\n\n### serviceRequest(service_request_id, callback)\n\nFetches an individual request by its `service_request_id`. (Standard: [GET Service Request](http://wiki.open311.org/GeoReport_v2#GET_Service_Request)).\n\nNote that this is just an alias to `Open311.serviceRequests`, so instead of submitting a single string/numerical `service_request_id`, you can submit an array of them of multiple `service_request_id`s too.\n\ne.g. you can do any of these:\n\n\n```javascript\n// as a string\nbaltimore.serviceRequest('12-00677322', function(err, data){ \n  console.log(data); // do something with the data!\n});\n```\n\nOR\n\n```javascript\n// as an array\nbaltimore.serviceRequest(['12-00677322'], function(err, data){ \n  console.log(data); // do something with the data!\n});\n```\n\nOR\n\n```javascript\n// as an even BIGGER array\nbaltimore.serviceRequest(['12-00677322', '12-00677323'], function(err, data){ \n  console.log(data); // do something with the data!\n});\n```\n\nOR\n\n```javascript\n// as a comma separated query parameter\n// ...but why would you ever want to do that?\nbaltimore.serviceRequest({\n  service_request_id: \"12-00677322,12-00677323\"\n}, function(err, data){ \n  console.log(data); // do something with the data!\n});\n```\n\n\n","maintainers":[{"name":"mheadd","email":"mheadd@voxeo.com"},{"name":"bensheldon","email":"ben@codeforamerica.org"}]},"0.0.11":{"name":"open311","description":"A Node.js module for interacting with an Open311 API.","version":"0.0.11","homepage":"https://github.com/codeforamerica/node-open311","author":{"name":"Mark Headd","email":"mheadd@gmail.com","url":"http://civic.io"},"contributors":[{"name":"Ben Sheldon","email":"ben@codeforamerica.org"}],"main":"./open311","repository":{"type":"git","url":"git://github.com/codeforamerica/node-open311.git"},"license":"BSD","engines":{"node":"0.6.x"},"scripts":{"test":"./node_modules/mocha/bin/mocha"},"dependencies":{"request":"~2.11.0","lodash":"~0.6.1","sparkxml":"git://github.com/codeforamerica/node-sparkxml.git","xml2json":"~0.2.4"},"devDependencies":{"mocha":"~1.4.1","chai":"~1.2.0","sinon":"~1.4.2"},"_npmUser":{"name":"bensheldon","email":"ben@codeforamerica.org"},"_id":"open311@0.0.11","optionalDependencies":{},"_engineSupported":true,"_npmVersion":"1.1.12","_nodeVersion":"v0.6.14","_defaultsLoaded":true,"dist":{"shasum":"f85a0d391d0bf9fd04ca7067b3895f7f3e5cce05","tarball":"https://registry.npmjs.org/open311/-/open311-0.0.11.tgz","integrity":"sha512-OGL7T1gaSYugF6sj3VdgR61OfeFI4HAHUxSCHfA4n5uwiJFmV7Zd/8SmnyXww1bxPw0VoBkKzucjB5rmcJfSjA==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDAQkgZ9izxf0R8tj0zj4SPCDJTFkA7sOJN3178tvq7YQIga3DDqUo2PwIYbsayl0OQO8bv1sb+LnSoEeENSkk/l64="}]},"readme":"# node-open311\n\n[![Build Status](https://secure.travis-ci.org/codeforamerica/node-open311.png)](http://travis-ci.org/codeforamerica/node-open311)\n\nA Node.js module for interacting with the Open311 API ([GeoReport v2](http://wiki.open311.org/GeoReport_v2)). This module is more than a simple wrapper; it attempts to normalize the response from different Open311 endpoints' _interpretation_ of the Open311 specification to return consistent results, regardless of implementation or format:\n\n- All responses are returned as native javascript objects/arrays\n- XML-only endpoints are parsed into native javascript objects/arrays that are consistent with JSON results\n- Invalid responses (e.g. malformed JSON that some endpoints may return), are cleaned up and returned as native javascript objects/arrays\n\n## Installation\n\n`npm install open311`\n\n## Brief Example\n\n```javascript\nvar Open311 = require('open311');\n\t\n// Example Open311 Server: City of Baltimore \n// More options here: http://wiki.open311.org/GeoReport_v2/Servers\nvar options = {\n  endpoint     : \"http://311.baltimorecity.gov/open311/v2/\",\n  jurisdiction : \"baltimorecity.gov\"\n};\n\t\n// Create a new Open311 object.\nvar baltimore = new Open311(options);\n\t\n// Call serviceRequest with service_request_id\n// to get the status of a specific service request.\nbaltimore.serviceRequest('12-00677322', function(err, data){ \n  console.log(data); // do something with the data!\n});\n```\n\n## Usage\n\n### new Open311(options)\n\nTo use this library, you must instantiate a new Open311 object: `var open311 = new Open311(options)`. \n\nYou can construct by passing a string that corresponds to the id of a city that is defined in the [`cities.json`](https://github.com/codeforamerica/node-open311/blob/master/cities.json) file. \n\ne.g. `var baltimore = new Open311('baltimore');`\n\nOr, you can pass individual `options`, including:\n\n- `endpoint`: the URL of the Open311 server; required for all methods except `Open311.serviceDiscovery()`\n- `jurisdiction`: (optional) the `jurisdiction_id` for a given city, if required\n- `discovery`: the URL Service Discovery; required if using `Open311.serviceDiscovery()` method\n- `format`: the format data should be requested in; only required for XML-only Open311 servers (default: `json`)\n- `apiKey`: your API key; required if using `Open311.submitServiceRequest()` method\n\nAll methods use the standard `callback(err, data)` format.\n\n### serviceDiscovery([options], callback)\n\nFetches a city's Service Discovery listing that has URLs of Open311 servers. (Standard: [Service Discovery](http://wiki.open311.org/Service_Discovery))\n\nOptional options:\n\n- `cache`: if `true` the fetched endpoints will set/overwrite the endpoint URL of the Open311 object (default: `false`)\n- `type`: when caching, sets the `test` or `production` endpoint server (default: `production`)\n- `specification`: when caching, sets the matching API specification of the endpoint server (default `http://wiki.open311.org/GeoReport_v2`);\n- `index`: (optional) when caching, if the Service Discovery list multiple servers with identical production/specification settings, this is the index of the resulting matched servers (default: `0`)\n\n```javascript\nvar baltimore = new Open311({\n  discovery: \"http://311.baltimorecity.gov/open311/discovery.json\"\n});\n\n// Make the API call\nbaltimore.serviceDiscovery({\n  cache: true,\n  type: \"production\"\n}, function(err, data) {\n  // `data` contains the content of the Service Discovery\n  // `baltimore.endpoint` should now be set because \n  //  we set `cache: true`\n});\n```\n\n\n### serviceList(callback)\n\nFetches a list of acceptable 311 service request types and their associated service codes. (Standard: [GET Service List](http://wiki.open311.org/GeoReport_v2#GET_Service_List))\n\n```javascript\n// an example with Washington, DC, which is an XML-only endpoint\nvar dc = new Open311({\n  \"endpoint\": \"http://app.311.dc.gov/CWI/Open311/v2/\",\n  \"format\": \"xml\",\n  \"jurisdiction\": \"dc.gov\"\n});\n\n// Make the API call\ndc.serviceDiscovery(function(err, data) {\n  // `data` contains a javascript array of javascript objects\n});\n```\n\n### serviceDefinition(service_code, callback)\n\nFetches attributes associated with a service code. Those attributes may be required when submitting a new Service Request (Standard: [GET Service Definition\n](http://wiki.open311.org/GeoReport_v2#GET_Service_Definition))\n\n`service_code` is the string/number returned from an entry in `Open311.serviceList()`\n\n### submitRequest(data, callback)\n\nSubmit a service request. (Standard: [POST Service Request](http://wiki.open311.org/GeoReport_v2#POST_Service_Request))\n\nAccording to the Open311 specification, `data` must include:\n\n- `service_code`\n- `lat` & `long` _OR_ `address_string` _OR_ `address_id`: the specification is wiggly here, but `lat`/`long` is near universally required (despite the \"OR\")\n- attributes (see `Open311.serviceDefinition`) set with the key `attribute[<code>]` _OR_ assign `data.attributes` to be an object with key/values: e.g. Submitting this:\n    \n  ```javascript\n  data = {\n    \"service_code\": \"ABANDONED_VEHICLE\",\n    \"lat\": 12.345,\n    \"long\": 67.890,\n    \"attributes\": {\n      \"license_plate\": \"A234567\",\n      \"color\": \"blue\"\n    }\n  }\n  ```\n  \n  ...will result in the appropriate and standard-compliant attributes being constructed:\n  \n  ```javascript\n  data = {\n    \"service_code\": \"ABANDONED_VEHICLE\",\n    \"lat\": 12.345,\n    \"long\": 67.890,\n    \"attribute[license_plate]\": \"A234567\",\n    \"attribute[color]\": \"blue\"\n  }\n  ```\n\n\n### token(token, callback)\n\nFetches the service_request_id from a temporary token that was received when submitting a Service Request. This is unnecessary if the response from creating a service request does not contain a token. \n(Standard: [GET service_request_id from a token](http://wiki.open311.org/GeoReport_v2#GET_service_request_id_from_a_token))\n\n`token` should either be a string or number.\n\n### serviceRequests([[service_request_ids]], [params], callback) \nFetch a list of existing service requests based on query parameters (Standard: [GET Service Requests](http://wiki.open311.org/GeoReport_v2#GET_Service_Requests))\n\nOptional params might include those on the existing standard, such as:\n- `service_request_id`: a comma delimited list of `service_request_id`s to fetch... or you can submit a javascript array of them as the first argument and they will be formatted correctly in the parameters\n- `service_code`: filter the by the service request's service_code\n- `start_date` / `end_date`: filter by the earliest/latest requested_datetime (when the request was submitted).\n- `status`: filter by the status (`open`/`closed`)\n\nOr params might include those not on the standard but widely supported, such as:\n\n- `page` and `page_size`: for paging through results\n\n\n### serviceRequest(service_request_id, callback)\n\nFetches an individual request by its `service_request_id`. (Standard: [GET Service Request](http://wiki.open311.org/GeoReport_v2#GET_Service_Request)).\n\nNote that this is just an alias to `Open311.serviceRequests`, so instead of submitting a single string/numerical `service_request_id`, you can submit an array of them of multiple `service_request_id`s too.\n\ne.g. you can do any of these:\n\n\n```javascript\n// as a string\nbaltimore.serviceRequest('12-00677322', function(err, data){ \n  console.log(data); // do something with the data!\n});\n```\n\nOR\n\n```javascript\n// as an array\nbaltimore.serviceRequest(['12-00677322'], function(err, data){ \n  console.log(data); // do something with the data!\n});\n```\n\nOR\n\n```javascript\n// as an even BIGGER array\nbaltimore.serviceRequest(['12-00677322', '12-00677323'], function(err, data){ \n  console.log(data); // do something with the data!\n});\n```\n\nOR\n\n```javascript\n// as a comma separated query parameter\n// ...but why would you ever want to do that?\nbaltimore.serviceRequest({\n  service_request_id: \"12-00677322,12-00677323\"\n}, function(err, data){ \n  console.log(data); // do something with the data!\n});\n```\n\n\n","maintainers":[{"name":"mheadd","email":"mheadd@voxeo.com"},{"name":"bensheldon","email":"ben@codeforamerica.org"}]},"0.0.12":{"name":"open311","description":"A Node.js module for interacting with an Open311 API.","version":"0.0.12","homepage":"https://github.com/codeforamerica/node-open311","author":{"name":"Mark Headd","email":"mheadd@gmail.com","url":"http://civic.io"},"contributors":[{"name":"Ben Sheldon","email":"ben@codeforamerica.org"}],"main":"./open311","repository":{"type":"git","url":"git://github.com/codeforamerica/node-open311.git"},"license":"BSD","engines":{"node":">0.6.0"},"scripts":{"test":"./node_modules/mocha/bin/mocha"},"dependencies":{"request":"~2.11.0","lodash":"~0.6.1","sparkxml":"git://github.com/codeforamerica/node-sparkxml.git","xml2json":"~0.2.4"},"devDependencies":{"mocha":"~1.4.1","chai":"~1.2.0","sinon":"~1.4.2"},"_npmUser":{"name":"bensheldon","email":"ben@codeforamerica.org"},"_id":"open311@0.0.12","optionalDependencies":{},"_engineSupported":true,"_npmVersion":"1.1.12","_nodeVersion":"v0.6.14","_defaultsLoaded":true,"dist":{"shasum":"e4ad83716585921b72fb8d679f7d2b39d961e8af","tarball":"https://registry.npmjs.org/open311/-/open311-0.0.12.tgz","integrity":"sha512-jwK7RRrGKWaK7sC+g7G6d5AyKEQNfWp6tKCsLt6shjO712lgtW8Wkipc6vK84hYg8eyv0vcAPKH3Orj06K/YKQ==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCOYmc+ymLJuWTXwgSpjlJbSjDr/iFV+WxTEIr9wxUmVQIgF5xW1BjV4KlpCV56WGS7Wg0x19paMQCJbr8OLJygN3U="}]},"readme":"# node-open311\n\n[![Build Status](https://secure.travis-ci.org/codeforamerica/node-open311.png)](http://travis-ci.org/codeforamerica/node-open311)\n\nA Node.js module for interacting with the Open311 API ([GeoReport v2](http://wiki.open311.org/GeoReport_v2)). This module is more than a simple wrapper; it attempts to normalize the response from different Open311 endpoints' _interpretation_ of the Open311 specification to return consistent results, regardless of implementation or format:\n\n- All responses are returned as native javascript objects/arrays\n- XML-only endpoints are parsed into native javascript objects/arrays that are consistent with JSON results\n- Invalid responses (e.g. malformed JSON that some endpoints may return), are cleaned up and returned as native javascript objects/arrays\n\n## Installation\n\n`npm install open311`\n\n## Brief Example\n\n```javascript\nvar Open311 = require('open311');\n\t\n// Example Open311 Server: City of Baltimore \n// More options here: http://wiki.open311.org/GeoReport_v2/Servers\nvar options = {\n  endpoint     : \"http://311.baltimorecity.gov/open311/v2/\",\n  jurisdiction : \"baltimorecity.gov\"\n};\n\t\n// Create a new Open311 object.\nvar baltimore = new Open311(options);\n\t\n// Call serviceRequest with service_request_id\n// to get the status of a specific service request.\nbaltimore.serviceRequest('12-00677322', function(err, data){ \n  console.log(data); // do something with the data!\n});\n```\n\n## Usage\n\n### new Open311(options)\n\nTo use this library, you must instantiate a new Open311 object: `var open311 = new Open311(options)`. \n\nYou can construct by passing a string that corresponds to the id of a city that is defined in the [`cities.json`](https://github.com/codeforamerica/node-open311/blob/master/cities.json) file. \n\ne.g. `var baltimore = new Open311('baltimore');`\n\nOr, you can pass individual `options`, including:\n\n- `endpoint`: the URL of the Open311 server; required for all methods except `Open311.serviceDiscovery()`\n- `jurisdiction`: (optional) the `jurisdiction_id` for a given city, if required\n- `discovery`: the URL Service Discovery; required if using `Open311.serviceDiscovery()` method\n- `format`: the format data should be requested in; only required for XML-only Open311 servers (default: `json`)\n- `apiKey`: your API key; required if using `Open311.submitServiceRequest()` method\n\nAll methods use the standard `callback(err, data)` format.\n\n### serviceDiscovery([options], callback)\n\nFetches a city's Service Discovery listing that has URLs of Open311 servers. (Standard: [Service Discovery](http://wiki.open311.org/Service_Discovery))\n\nOptional options:\n\n- `cache`: if `true` the fetched endpoints will set/overwrite the endpoint URL of the Open311 object (default: `false`)\n- `type`: when caching, sets the `test` or `production` endpoint server (default: `production`)\n- `specification`: when caching, sets the matching API specification of the endpoint server (default `http://wiki.open311.org/GeoReport_v2`);\n- `index`: (optional) when caching, if the Service Discovery list multiple servers with identical production/specification settings, this is the index of the resulting matched servers (default: `0`)\n\n```javascript\nvar baltimore = new Open311({\n  discovery: \"http://311.baltimorecity.gov/open311/discovery.json\"\n});\n\n// Make the API call\nbaltimore.serviceDiscovery({\n  cache: true,\n  type: \"production\"\n}, function(err, data) {\n  // `data` contains the content of the Service Discovery\n  // `baltimore.endpoint` should now be set because \n  //  we set `cache: true`\n});\n```\n\n\n### serviceList(callback)\n\nFetches a list of acceptable 311 service request types and their associated service codes. (Standard: [GET Service List](http://wiki.open311.org/GeoReport_v2#GET_Service_List))\n\n```javascript\n// an example with Washington, DC, which is an XML-only endpoint\nvar dc = new Open311({\n  \"endpoint\": \"http://app.311.dc.gov/CWI/Open311/v2/\",\n  \"format\": \"xml\",\n  \"jurisdiction\": \"dc.gov\"\n});\n\n// Make the API call\ndc.serviceDiscovery(function(err, data) {\n  // `data` contains a javascript array of javascript objects\n});\n```\n\n### serviceDefinition(service_code, callback)\n\nFetches attributes associated with a service code. Those attributes may be required when submitting a new Service Request (Standard: [GET Service Definition\n](http://wiki.open311.org/GeoReport_v2#GET_Service_Definition))\n\n`service_code` is the string/number returned from an entry in `Open311.serviceList()`\n\n### submitRequest(data, callback)\n\nSubmit a service request. (Standard: [POST Service Request](http://wiki.open311.org/GeoReport_v2#POST_Service_Request))\n\nAccording to the Open311 specification, `data` must include:\n\n- `service_code`\n- `lat` & `long` _OR_ `address_string` _OR_ `address_id`: the specification is wiggly here, but `lat`/`long` is near universally required (despite the \"OR\")\n- attributes (see `Open311.serviceDefinition`) set with the key `attribute[<code>]` _OR_ assign `data.attributes` to be an object with key/values: e.g. Submitting this:\n    \n  ```javascript\n  data = {\n    \"service_code\": \"ABANDONED_VEHICLE\",\n    \"lat\": 12.345,\n    \"long\": 67.890,\n    \"attributes\": {\n      \"license_plate\": \"A234567\",\n      \"color\": \"blue\"\n    }\n  }\n  ```\n  \n  ...will result in the appropriate and standard-compliant attributes being constructed:\n  \n  ```javascript\n  data = {\n    \"service_code\": \"ABANDONED_VEHICLE\",\n    \"lat\": 12.345,\n    \"long\": 67.890,\n    \"attribute[license_plate]\": \"A234567\",\n    \"attribute[color]\": \"blue\"\n  }\n  ```\n\n\n### token(token, callback)\n\nFetches the service_request_id from a temporary token that was received when submitting a Service Request. This is unnecessary if the response from creating a service request does not contain a token. \n(Standard: [GET service_request_id from a token](http://wiki.open311.org/GeoReport_v2#GET_service_request_id_from_a_token))\n\n`token` should either be a string or number.\n\n### serviceRequests([[service_request_ids]], [params], callback) \nFetch a list of existing service requests based on query parameters (Standard: [GET Service Requests](http://wiki.open311.org/GeoReport_v2#GET_Service_Requests))\n\nOptional params might include those on the existing standard, such as:\n- `service_request_id`: a comma delimited list of `service_request_id`s to fetch... or you can submit a javascript array of them as the first argument and they will be formatted correctly in the parameters\n- `service_code`: filter the by the service request's service_code\n- `start_date` / `end_date`: filter by the earliest/latest requested_datetime (when the request was submitted).\n- `status`: filter by the status (`open`/`closed`)\n\nOr params might include those not on the standard but widely supported, such as:\n\n- `page` and `page_size`: for paging through results\n\n\n### serviceRequest(service_request_id, callback)\n\nFetches an individual request by its `service_request_id`. (Standard: [GET Service Request](http://wiki.open311.org/GeoReport_v2#GET_Service_Request)).\n\nNote that this is just an alias to `Open311.serviceRequests`, so instead of submitting a single string/numerical `service_request_id`, you can submit an array of them of multiple `service_request_id`s too.\n\ne.g. you can do any of these:\n\n\n```javascript\n// as a string\nbaltimore.serviceRequest('12-00677322', function(err, data){ \n  console.log(data); // do something with the data!\n});\n```\n\nOR\n\n```javascript\n// as an array\nbaltimore.serviceRequest(['12-00677322'], function(err, data){ \n  console.log(data); // do something with the data!\n});\n```\n\nOR\n\n```javascript\n// as an even BIGGER array\nbaltimore.serviceRequest(['12-00677322', '12-00677323'], function(err, data){ \n  console.log(data); // do something with the data!\n});\n```\n\nOR\n\n```javascript\n// as a comma separated query parameter\n// ...but why would you ever want to do that?\nbaltimore.serviceRequest({\n  service_request_id: \"12-00677322,12-00677323\"\n}, function(err, data){ \n  console.log(data); // do something with the data!\n});\n```\n\n\n","maintainers":[{"name":"mheadd","email":"mheadd@voxeo.com"},{"name":"bensheldon","email":"ben@codeforamerica.org"}]}},"maintainers":[{"name":"mheadd","email":"mheadd@voxeo.com"},{"name":"bensheldon","email":"ben@codeforamerica.org"}],"time":{"modified":"2022-06-22T23:26:25.038Z","created":"2011-01-24T13:41:06.774Z","0.0.3":"2011-01-24T13:41:06.929Z","0.0.4":"2011-03-04T02:35:37.473Z","0.0.5":"2011-03-31T02:03:45.106Z","0.0.6":"2011-03-31T02:07:31.915Z","0.0.7":"2011-09-12T17:44:39.546Z","0.0.8":"2011-09-12T17:53:59.072Z","0.0.9":"2012-09-06T21:54:21.373Z","0.0.10":"2012-09-14T15:28:32.273Z","0.0.11":"2012-09-18T18:07:13.861Z","0.0.12":"2012-09-19T02:47:16.733Z"},"author":{"name":"Mark Headd","email":"mheadd@gmail.com","url":"http://civic.io"},"repository":{"type":"git","url":"git://github.com/codeforamerica/node-open311.git"}}