-
Notifications
You must be signed in to change notification settings - Fork 7
REST_API
The APIs can authenticate with HTTP basic, for which you must provide a user email and password, or through the unified system for InSTEDD Platform which is handled through the GUISSO gem.
For long-term system integration, you may want to create a user that is only used for API purposes so it is less affected by resetting passwords, permission changes, etc than a person.
API in within internal staging releases is subject to changes without versioning. Changes to public releases will be versioned and documented. The documentation below may be out of sync with any specific deployed version in staging.
If you have questions or find issues please feel free to contact discuss here: InSTEDD Technology Users Community (Google Group)
Unless you want to use discovery APIs, you can get started by
- Going to your collection property tabs
- Under the 'Overview' tab look at the API Access section
- You will have links to the query API, and you can see your collection ID in that URL.
You can get your collections by querying
- /api/collections.json
[{"created_at":"2012-03-27T07:40:06Z","description":"","id":350,"lat":"-2.002419","lng":"29.933107","name":"Hospitals","public":null,"updated_at":"2012-03-28T07:58:02Z"}]
The format can be specified by the extension of the request. For example,
- /api/collections/350.json
- /api/collections/350.rss
- /api/collections/350.csv
The GeoJSON format has a different URL:
- /api/collections/350/geo.json
The RSS return format fulfils the GeoRSS specification using the //http://www.w3.org/2003/01/geo/wgs84\_pos// namespace, and latitude and longitude fields are presented in geo:lat and geo:long elements corresponding to that namespace. This makes it easy to consume the data from GeoRSS compatible tools. Keep in mind the consuming application will need to provide the login credentials unless the collection has a public layer.
Note: For these examples we will assume you have an Collection ID of 350
Getting all sites in a collection: /api/collections/350.json
ResourceMap allows filtering sites by every kind of property defined in the collection. It also allows counting, sorting and paging.
A count of items in the collection can be obtained by calling:
- /api/collections/350/count.json
You can retrieve only one item by ID the following way:
- /api/sites/:id.json
- /api/sites/:id.rss
Note: The ID field is the internal system ID of the item, not some field you created and treat as an ID field.
ResourceMap stores a site version every time a change is made. These versions are called "histories". Each history has an autoincremental version number and valid_from/valid_to fields that indicate the from/to dates in which this version was the current one. Each history contains the complete site information, and not only the changed values. It also includes the email of the user that performed the last update in the site.
To get all histories of a site:
- GET /api/collections/:collection_id/sites/:site_id/histories.json
To get a particular site's version:
- GET /api/collections/:collection_id/sites/:id/histories.json?version=:version_number
Note: You need to be the admin of the collection to be allowed to query site histories
Sample return data:
GET to /api/collections/428/sites/119815/histories.json?version=3
Sample return data:
GET to /api/collections/428/sites/119815/histories.json?version=3
[{
collection_id: 428,
name: "angola",
lat: "-12.892942",
lng: "16.776647",
created_at: "2013-10-29T20:07:07Z",
updated_at: "2013-10-31T21:14:42Z",
properties: {
1561: 2.34,
1562: 2,
1563: true,
1564: 2,
1565: [
3,
1,
2
],
1573: "100001-8",
1574: "2"
},
valid_since: "2013-10-29T20:07:07Z",
valid_to: "2013-10-31T21:14:42Z",
site_id: 119815,
uuid: "cc33e476-4879-4096-a5e5-1baf8fd2af0b",
version: 3,
user: "[email protected]"
}]
Note: You need to be the admin of the collection to be allowed to query the metadata information
You can get a definition of your layer metadata here:
- /api/collections/350/layers.json
This will return all metadata about fields (codes, lookup values and codes, etc) in the collection with ID = 350, grouped in layers.
For more specific actions follow this link
You can get which users have access to which layers here:
- /api/collections/350/memberships.json
This will return all the users that have access to the system collection with ID= 350, and their permissions to read and write to different layers and sites. Of course, accessing this information is only possible if the login used in the request has permissions as an owner of the collection.
This is a sample return data for membership's query:
[
{"user_id":2,"user_display_name":"[email protected]","admin":true,"layers":[],"sites": {"read":null,"write":null}},
{"user_id":1,"user_display_name":"[email protected]","admin":false,
"layers":[
{"layer_id":53,"read":true,"write":false},
{"layer_id":56,"read":true,"write":true},
{"layer_id":58,"read":true,"write":false}],
"sites":{
"write":{
"all_sites":false,
"some_sites":[
{"id":"8376","name":"Site 3"}]},
"read":{"all_sites":true,"some_sites":[]}}},
{"user_id":7,"user_display_name":"[email protected]","admin":false,
"layers":[],
"sites":{
"read":{
"all_sites":false,
"some_sites":[
{"id":"8376","name":"Site 3"},
{"id":"11487","name":"Site 4"}]},
"write":{
"all_sites":false,
"some_sites":[
{"id":"11487","name":"Site 4"}]}}}
]
As a user of ResourceMap, permission information can be requested for any collection. Should this user not have access to the collection, the response is an empty object. Otherwise, the membership information will be provided as with the previous endpoint.
- /api/collections/350/memberships/personal.json
Here are some examples so you can see the JSON and RSS formats:
- /api/collections/350.json
{
"name": "Hospitals",
"totalPages": 1,
"sites": [
{
"id": 17442,
"name": "Sunshine Hospital",
"createdAt": "2012-03-28T07:55:56+00:00",
"updatedAt": "2012-03-28T07:55:56+00:00",
"lat": -1.901301,
"long": 30.418267,
"properties": {
"Color": "1",
"Services": [
"XR",
"OBG"
],
"NUMBEDS": "20",
"MGR": "Mr. Richard"
},
"groups": [ ]
},
{
"id": 17443,
"name": "Butare Family Hospital",
"createdAt": "2012-03-28T07:57:05+00:00",
"updatedAt": "2012-03-28T07:57:05+00:00",
"lat": -2.602733,
"long": 29.737324,
"properties": {
"Color": "1",
"Services": [
"XR"
],
"NUMBEDS": "30",
"MGR": "Mr. Daniel"
},
"groups": [ ]
},
{
"id": 17444,
"name": "Musanze Hospital",
"createdAt": "2012-03-28T07:58:01+00:00",
"updatedAt": "2012-03-28T07:58:01+00:00",
"lat": -1.503223,
"long": 29.643731,
"properties": {
"Color": "3",
"Services": [
"XR",
"OBG",
"TR"
],
"NUMBEDS": "55",
"MGR": "Mrs. Liz"
},
"groups": [ ]
}
]
}
- /api/collections/350.rss
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:rm="http://resourcemap.instedd.org/api/1.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>Hospitals</title>
<item>
<title>Sunshine Hospital</title>
<pubDate>2012-03-28T07:55:56+00:00</pubDate>
<link>http://resmap-stg.instedd.org/api/sites/17442.rss</link>
<guid>http://resmap-stg.instedd.org/api/sites/17442.rss</guid>
<geo:lat>-1.901301</geo:lat>
<geo:long>30.418267</geo:long>
<rm:properties>
<rm:Color>1</rm:Color>
<rm:Services>["XR", "OBG"]</rm:Services>
<rm:NUMBEDS>20</rm:NUMBEDS>
<rm:MGR>Mr. Richard</rm:MGR>
</rm:properties>
</item>
<item>
<title>Butare Family Hospital</title>
<pubDate>2012-03-28T07:57:05+00:00</pubDate>
<link>http://resmap-stg.instedd.org/api/sites/17443.rss</link>
<guid>http://resmap-stg.instedd.org/api/sites/17443.rss</guid>
<geo:lat>-2.602733</geo:lat>
<geo:long>29.737324</geo:long>
<rm:properties>
<rm:Color>1</rm:Color>
<rm:Services>["XR"]</rm:Services>
<rm:NUMBEDS>30</rm:NUMBEDS>
<rm:MGR>Mr. Daniel</rm:MGR>
</rm:properties>
</item>
<item>
<title>Musanze Hospital</title>
<pubDate>2012-03-28T07:58:01+00:00</pubDate>
<link>http://resmap-stg.instedd.org/api/sites/17444.rss</link>
<guid>http://resmap-stg.instedd.org/api/sites/17444.rss</guid>
<geo:lat>-1.503223</geo:lat>
<geo:long>29.643731</geo:long>
<rm:properties>
<rm:Color>3</rm:Color>
<rm:Services>["XR", "OBG", "TR"]</rm:Services>
<rm:NUMBEDS>55</rm:NUMBEDS>
<rm:MGR>Mrs. Liz</rm:MGR>
</rm:properties>
</item>
</channel>
</rss>
GeoJson Example with one site only:
{
"type":"Feature",
"geometry":null,
"properties":{
"features":{
"type":"FeatureCollection",
"features":[
{
"type":"Feature",
"geometry":{
"type":"Point",
"coordinates":[
30.418267,
-1.901301
]
},
"id":17442,
"properties":{
"name":"Sunshine Hospital",
"createdAt":"2012-03-28T07:55:56+00:00",
"updatedAt":"2012-05-08T14:42:25+00:00",
"properties":{
"Color":"1",
"Services":[
"XR",
"OBG"
],
"NUMBEDS":"20",
"MGR":"Mr. Richard"
}
}
}
]
},
"name":"Hospitals",
"count":3,
"totalPages":1
}
}
You can query the activity rss feed for your collections via API.
The URL is /api/activity.rss
This feed will show all user's activity in all collections in which you are a member.
Optionally you can specify in what kind of activities and in which collections are you interested.
- /api/activity.rss?collection_ids[]=32&collection_ids[]=31 : filters all kind of activity in collection with internal id 32 or 31
The options for filtering kind of activity are:
- collection,created
- collection,csv_imported
- collection,imported
- layer,created
- layer,changed
- layer,deleted
- site,created
- site,changed
- site,deleted
For example:
- /api/activity.rss?kinds[]=site,deleted&kinds[]=layer,deleted : filters sites and layer delete action of all users in all collections.
You can also combine collection_ids and kinds in the same query.
You can update a single property in a Site you should do a POST to:
- /api/sites/:site_id/update_property.json
Note: site_id is the internal system ID of the site
And you should pass the parameters you want to update:
- ?es_code=350&value=Mr. Richard
350 is the property internal ID and Mr. Richard is the new value for the property
To find the ID of the field you need to update, query for layers or fields of your collection. The es_code required is the numerical ID of the field, not the code or the name. More information on querying metadata here: API for Metadata queries
-
Text Fields: ?es_code=350&value=Changed Text
-
Numeric Fields: ?es_code=350&value=1234
-
Select One Fields: ?es_code=350&value=2 // 2 is the internal ID for the option
-
Select Many Fields: ?es_code=350&value[]=2&value[]=1 // 1 and 2 are the internal ID for the options
-
Hierarchy Fields: ?es_code=350&value[]=2 // 2 is the internal ID for the hierarchy
-
Date Fields: ?es_code=350&value[]=12/26/2012 // The date is in MM/DD/YYYY format
-
Site Fields: ?es_code=350&value=12456 // 12456 is the referred Site internal ID
-
User Fields: ?es_code=350&value=[email protected] // [email protected] is the user's email
-
Email Fields: ?es_code=350&value=[email protected]
-
Phone Fields: ?es_code=350&value=15555555555
For deleting the field's value, simply do not pass the parameter "value".
- ?es_code=350 : will delete the value for property with internal ID = 350.
This works for all field's types.
For changing name or location, you should do a PUT to:
- /collections/:collection_id/sites/:site_id.json
With parameters:
"site": {"name": "New Site Name"}
or:
"site": {"lat": -12.834253993970767, "lng": 30.15640980316266}
For changing more than one property, you should do a PUT to
- /collections/:collection_id/sites/:site_id.json
With parameters:
{"site": {"id": :site_id, "name": "New Site Name", "lat": -12.83425399397077, "lng": 30.15640980316266, "properties": {"206": "new text value", "207": "12345", "208": 2}}}
Each property value format depends on the field's type. The format is specified in "Param format" section.
The action you need to use is
- /api/sites/:site_id/partial_update.json via POST
Through this action those parameters included in the request are updated, but not the ones that are not present.
The format of the parameters are the same of in "Full Update" section above.
All sites matching the search parameters will be updates according to an updates hash.
POST to
- /api/collections/:collection_id/update_sites
with the collection's id, those filters you want to select sites to update from and an updates hash for those properties to be changed as parameters.
Example:
{"id" => :collection_id, "name" => 'Regional Hospital', "updates" => {"properties" => { "active" => true }}}
You can create a new site by issuing a POST to:
- /api/collections/:collection_id/sites.json
Example URL:
- /api/collections/485/sites.json
Authentication mechanism: Basic (see Accessing the API)
site (required): a JSON object sent as form-data. Sites have some built-in fields (available in every site of every collection in Resource Map) and others which are collection specific.
Built-in fields are:
- name (text): the name of the site to be created. Required.
- lat (decimal): latitude of the site to be created. Optional.
- lng (decimal): longitude of the site to be created. Optional.
Collection specific site fields are inside the properties property. Since there are different types of fields (text, numeric, date, etc.), the validation criteria for each value provided inside the properties field varies.
Collection specific site fields are of the form "FIELD_ID":"VALUE", where FIELD_ID is an integer. To retrieve field ids of your collection specific site fields see API for Metadata queries.
Here's an example raw HTTP request that creates a site on an example collection:
POST /collections/485/sites.json HTTP/1.1
Host: resourcemap.instedd.org
Authorization: Basic (YOUR BASIC AUTH ENCODED CREDENTIALS)
Cache-Control: no-cache
----WebKitFormBoundaryE19zNvXGzXaLvS5C
Content-Disposition: form-data; name="site"
{"name":"New Site","lat":-12.83425399397077,"lng":30.15640980316266,"properties":{"2000":"new text value","2001":"12345","2002":"2"}}
----WebKitFormBoundaryE19zNvXGzXaLvS5C
Remarks:
- Notice the format of the Authorization header, which is where we state that we're using Basic Auth.
- Content-Disposition is where you specify that you're sending a form-data param.
- The param name is specified as name="site".
- The site JSON object is built as discussed above. Pay special attention to the properties field: in this case, the request will only succeed if the target collection has specific fields with ids 2000, 2001 and 2002.
If the request to create a site succeeds, Resource Map will return a JSON object with the complete representation of the site just created.
{
"collection_id": 485,
"created_at": "2013-11-20T20:06:35Z",
"id": 116195,
"id_with_prefix": "NB3",
"lat": "-12.83425399397077",
"lng": "30.15640980316266",
"location_mode": "automatic",
"name": "New Site",
"properties": {
"2000": "new text value",
"2001": 12345,
"2002": 2
},
"updated_at": "2013-11-20T20:06:35Z",
"uuid": "29e6f5bb-d072-4a20-9fb1-54bf04589d57",
"version": 1
}
For deleting a site, do a DELETE to:
- api/sites/:site_id
You should be a collection admin for being able to modify metadata.
To create a new layer, do a POST to:
//Note: You need to set the Content-Type Header to "application/json"
- /api/collections/:collection_id/layers.json
Parameters:
{
"layer":{
"name":"New Layer",
"ord":"1",
"fields_attributes":{
"0":{
"name":"Text Field",
"code":"text_field_code",
"kind":"text",
"ord":"1"
},
"1":{
"name":"Numeric Field",
"code":"numeric_field_code",
"kind":"numeric",
"ord":"2"
},
"2":{
"name":"Select One",
"code":"select_field_one_code",
"kind":"select_one",
"ord":"3",
"config":{
"options":{
"0":{
"id":"1",
"code":"opt_1_code",
"label":"Option 1 Label"
},
"1":{
"id":"2",
"code":"opt_2_code",
"label":"Option 2 Label"
}
}
}
},
"3":{
"name":"Select Many",
"code":"select_field_many_code",
"kind":"select_many",
"ord":"4",
"config":{
"options":{
"0":{
"id":"1",
"code":"opt_1_code",
"label":"Option 1 Label"
},
"1":{
"id":"2",
"code":"opt_2_code",
"label":"Option 2 Label"
}
}
}
},
"4":{
"name":"Hierarchy ",
"code":"hierachy_field_code",
"kind":"hierarchy",
"ord":"5",
"config":{
"hierarchy":{
"0":{
"order":"1",
"id":"code_1",
"name":"Dad",
"sub":{
"0":{
"order":"2",
"id":"code_2",
"name":"Son"
},
"1":{
"order":"3",
"id":"code_3",
"name":"Bro"
}
}
}
}
}
},
"5":{
"name":"Date ",
"code":"date_field_code",
"kind":"date",
"ord":"6"
},
"6":{
"name":"Site",
"code":"site_field_code",
"kind":"site",
"ord":"7"
},
"7":{
"name":"User",
"code":"user_field_code",
"kind":"user",
"ord":"8"
},
"8":{
"name":"Email",
"code":"email_field_code",
"kind":"email",
"ord":"9"
},
"9":{
"name":"Phone",
"code":"phone_field_code",
"kind":"phone",
"ord":"10"
},
"10":{
"ord":"11",
"name":"Identifier",
"code":"identifier_field_code",
"kind":"identifier",
"config":{
"context":"field_context",
"agency":"field_agency"
}
}
}
}
}
This will create a new field for each type.
To update an existing layer, you should do a PUT to:
- /api/collections/:collection_id/layers/:layer_id.json
Note: You need to set the Content-Type Header to "application/json"
Note: In this example we are assuming that the layer_id of the layer you want to update is 59 and the field's ids are form 241 to 250. All ids should correspond to existing layers and fields.
Parameters:
{
"layer":{
"id":"59",
"name":"Existing Layer",
"ord":"1",
"fields_attributes":{
"0":{
"id":"241",
"name":"Text Field New Name",
"code":"text_field_code",
"kind":"text",
"ord":"1",
"layer_id":"59"
},
"1":{
"id":"242",
"name":"Numeric Field",
"code":"numeric_field_code",
"kind":"numeric",
"ord":"2",
"layer_id":"59"
},
"2":{
"id":"243",
"name":"Select One",
"code":"select_field_one_code",
"kind":"select_one",
"ord":"3",
"layer_id":"59",
"config":{
"options":{
"0":{
"id":"1",
"code":"opt_1_code",
"label":"Option 1 Label"
},
"1":{
"id":"2",
"code":"opt_2_code",
"label":"Option 2 Label"
}
}
}
},
"3":{
"id":"244",
"name":"Select Many",
"code":"select_field_many_code",
"kind":"select_many",
"ord":"4",
"layer_id":"59",
"config":{
"options":{
"0":{
"id":"1",
"code":"opt_1_code",
"label":"Option 1 Label"
},
"1":{
"id":"2",
"code":"opt_2_code",
"label":"Option 2 Label"
}
}
}
},
"4":{
"id":"245",
"name":"Hierarchy ",
"code":"hierachy_field_code",
"kind":"hierarchy",
"ord":"5",
"layer_id":"59",
"config":{
"hierarchy":{
"0":{
"order":"1",
"id":"code_1",
"name":"Dad",
"sub":{
"0":{
"order":"2",
"id":"code_2",
"name":"Son"
},
"1":{
"order":"3",
"id":"code_3",
"name":"Bro"
}
}
}
}
}
},
"5":{
"id":"246",
"name":"Date ",
"code":"date_field_code",
"kind":"date",
"ord":"6",
"layer_id":"59"
},
"6":{
"id":"247",
"name":"Site",
"code":"site_field_code",
"kind":"site",
"ord":"7",
"layer_id":"59"
},
"7":{
"id":"248",
"name":"User",
"code":"user_field_code",
"kind":"user",
"ord":"8",
"layer_id":"59"
},
"8":{
"id":"249",
"name":"Email",
"code":"email_field_code",
"kind":"email",
"ord":"9",
"layer_id":"59"
},
"9":{
"id":"250",
"name":"Phone",
"code":"phone_field_code",
"kind":"phone",
"ord":"10",
"layer_id":"59"
}
}
}
}
To delete an existing layer you should do a DELETE to:
- /api/collections/:collection_id/layers/:layer_id
You should be a collection admin for being able to modify permissions.
To create a new membership to a collection for a user, do a POST to:
Parameters: {"email"=>"[email protected]", "collection_id"=>":collection_id"}
The email must be that of an existing user in the system.
This will return the operation status and the user_id:
{"status":"added","user_id":6,"user_display_name":"[email protected]"}
After creating the membership for the user, if you want to make them collection admin you should do a POST to:
- /api/collections/:collection_id/memberships/:user_id/set_admin.json
Revoking admin permission is similar: Do a POST to:
- /api/collections/:collection_id/memberships/:user_id/unset_admin.json
Users can have read and/or write permission to a collection's layer.
A POST to:
- /api/collections/:collection_id/memberships/:user_id/set_layer_access.json
With parameters:
{"layer_id"=>"58", "verb"=>"read", "access"=>"true" }
Will create a read permission for the user with internal ID = :user_id to the layer with internal ID = 58 of the collection with internal ID = :collection_id. This means that they will be able to see all site's properties inside the layer 58, but won't be able to change them.
With parameters:
{"layer_id"=>"58", "verb"=>"write", "access"=>"true"}
Will create a write permission for the user with internal ID = :user_id to the layer with internal ID = 58 of the collection with internal ID = :collection_id. This means that theyable to modify all site's properties inside the layer 58.
You need to do a POST to
- /api/collections/:collection_id/memberships/:user_id/set_layer_access.json
With parameters:
{"layer_id"=>"58", "verb"=>"read", "access"=>"false" }
Or
{"layer_id"=>"58", "verb"=>"write", "access"=>"false"}
To delete a user's membership from a collection, do a DELETE to:
- /api/collections/:collection_id/memberships/:user_id.json
For setting access to all layers in an specific site to a user, you should do a POST to:
- /collections/:collection_id/sites_permission
With parameters:
{
"write"=>
{"all_sites"=>"false","some_sites"=>
{"0"=>{"id"=>"8376","name"=>"Site 3"}
}
}
}
This means that the user with internal ID=1 will be able to see all properties of sites 3 and 4 (with internal IDs = 8376 and 11487) but will be only able to modify the Site 3's data.