API Reference
Welcome to the CogniCity API. CogniCity is the engine that powers Urban Risk Map. You can use this API to access CogniCity data including flood reports and sensor measurements that are stored in the CogniCity database. You can view example requests in the dark area to the right, and you can switch the programming language of the examples with the tabs in the top right.
CogniCity deployments are organised into instances for different countries. Each instance may support mapping for one of more cities. Currently available instances:
The CogniCity API is accessible via the data subdomain of each instance, for example:
The CogniCity Sensors API is accessible via the sensors subdomain of each instance, for example:
Authentication
curl "endpoint" -H "Authorization: token or key"
import axios from 'axios'; // package to make http requests
/* Request with API key authentication */
axios.get('/endpoint', {headers: {'x-api-key': 'key'}})
.then(response => console.log(response))
.catch(err => console.log(err))
/* Request with token authentication */
axios.get('/endpoint', {headers: {'Authorization': 'token'}})
.then(response => console.log(response))
.catch(err => console.log(err))
Some CogniCity endpoints require authentication in the form of either an API key or a JSON Web Token. Authentication keys and tokens are passed via the x-api-key or Authorization header respectively. Endpoints requiring authentication are detailed below.
x-api-key: key
Authorization: token
Errors
The CogniCity APIs uses the following error codes:
| Error Code | Meaning |
|---|---|
| 400 | Bad Request - Your request is invalid. |
| 403 | Forbidden - Your API key or authentication token is wrong. |
| 404 | Not Found - The specified report could not be found. |
| 409 | Conflict - Report already recieved. |
| 415 | Unsupported Media Type - The file being uploaded is not supported by the system. |
| 429 | Too Many Requests - You have exceeded API request quota. |
| 500 | Internal Server Error - We had a problem with our server. Try again later. |
| 503 | Service Unavailable - The service is down and we cannot respond to requests. |
Data Formats
Response structure:
{
"statusCode": { Number },
"result": { Object | Array }
}
CogniCity provides responses in JSON format. The statusCode object gives the HTTP response status for the request (also available in the response header). The response property may be either an Object or an Array depending on the data returned.
Where responses contain geographical information both the GeoJSON and TopoJSON formats are supported.
The /floods endpoint also supports responses using the Common Alerting Protocol, an XML format.
CogniCity uses the PostgreSQL BIGINT data type. As these numbers are potentially greater than JavaScript's Numbers.MAX_SAFE_INTEGER they are returned as strings.
Version
GET /
Gets the CogniCity server and database versions.
The following attributes are returned:
versionrefers to CogniCity Server release versionschemarefers to the CogniCity Database release version
curl '/'
const request = require('request');
request(
{
method: 'GET',
uri: '/'
},
function (error, response, body) {
console.log(error);
console.log(response.statusCode);
console.log(body)
}
)
Example JSON output:
{
"version":"3.0.6",
"schema":"3.0.6"
}
HTTP Request
GET /
Chatbot API
The chatbot API exposes endpoints to receive incoming messages from social media platforms (e.g. via webhooks) and functions to send replies to users (e.g. on succesful report submission). Note that chatbot APIs may run on a custom domain.
The APIs are organised by social media network.
Send and receive Facebook messenger events.
POST /facebook/send
curl -X POST '/facebook/send' -H 'Content-Type: application/json' -H 'x-api-key: key' -d '{
"reportId": 1,
"instanceRegionCode": "brw",
"language": "en",
"username": "userid",
"network": "facebook"
}'
import axios from 'axios'; // package to make http requests
axios.post('/', {
reportId: 1,
instanceRegionCode: "brw",
language: "en",
username: "userid",
network: "facebook"
}, {headers: {'x-api-key': 'key'}})
.then(response => console.log(response))
.catch(err => console.log(err))```
The above command returns JSON structured like this:
{}
Send a reply to user after they submit a report via Facebook messenger.
HTTP Request
POST /facebook/send
Properties
| Attribute | Required | Description | Example |
|---|---|---|---|
| reportId | true | The unique ID of the report submitted | none |
| instanceRegionCode | true | The instance region containing the report (from the /cities endpoint). May be null. | "brw" |
| language | true | The user's 2 letter language if known. May be null | "en" |
| username | true | The username or user id number from the social network | "123" |
| network | true | The name of the social network of the user | "facebook" |
GET /facebook/webhook
curl "/facebook/webhook?hub.verify_token=<token>"
// Webhook configured at developers.facebook.com
The above command returns JSON structured like this:
{
// hub challenge value
}
This endpoint responds to a Facebook Webhook authentication challenge. See the Facebook developer documentation.
HTTP Request
GET /facebook/webhook
POST /facebook/webhook
curl -X POST '/facebook/webhook' -H 'Content-Type: application/json' -H 'x-api-key: key' -d '{
<message event>
}'
// Webhook configured at developers.facebook.com
The above command returns JSON structured like this:
{}
This endpoint responds to a Facebook Webhook message event. See Facebook documentation for more details.
HTTP Request
POST /facebook/webhook
Send and receive Twitter direct message events.
POST /twitter/send
curl -X POST '/twitter/send' -H 'Content-Type: application/json' -H 'x-api-key: key' -d '{
"reportId": 1,
"instanceRegionCode": "brw",
"language": "en",
"username": "userid",
"network": "twitter"
}'
import axios from 'axios'; // package to make http requests
axios.post('/', {
reportId: 1,
instanceRegionCode: "brw",
language: "en",
username: "userid",
network: "twitter"
}, {headers: {'x-api-key': 'key'}})
.then(response => console.log(response))
.catch(err => console.log(err))```
The above command returns JSON structured like this:
{}
Send a reply to user after they submit a report as a Twitter direct message.
HTTP Request
POST /twitter/send
Properties
| Attribute | Required | Description | Example |
|---|---|---|---|
| reportId | true | The unique ID of the report submitted | none |
| instanceRegionCode | true | The instance region containing the report (from the /cities endpoint). May be null. | "brw" |
| language | true | The user's 2 letter language if known. May be null | "en" |
| username | true | The username or user id number from the social network | "123" |
| network | true | The name of the social network of the user | "twitter" |
GET /twitter/webhook
curl "/twitter/webhook?crc_token=<token>"
// Webhook configured at developer.twitter.com
The above command returns JSON structured like this:
{
"response_token": "<token>"
}
This endpoint responds to a twitter Webhook challenge response check. See the Twitter developer documentation.
HTTP Request
GET /twitter/webhook
POST /twitter/webhook
curl -X POST '/twitter/webhook' -H 'Content-Type: application/json' -H 'x-api-key: key' -d '{
<message event>
}'
// Webhook configured at developer.twitter.com
The above command returns JSON structured like this:
{}
This endpoint responds to a Twitter webhook message event. See twitter documentation for more details.
HTTP Request
POST /twitter/webhook
Data API
The Data API provides the core reporting and mapping functionality of CogniCity. The Cards endpoint enables residents to submit hazard reports and the Reports endpoint provides submitted reports for client applications. Additional endpoints support the core funciotnality with additional data.
Cards
Report cards for diaster events issued via social media chatbots. Report cards are the mechanism by which users can submit hazard reports. Cards are issued using a one-time-link based on a globally unique identifier (GUID) and can only be used to submit one hazard report. Subsequent hazard reports may be submitted by the user requesting a new card.
The card flow is as follows:
- Request a new card (POST /cards)
- Submit hazard report (PUT /cards/:id)
- Upload image (GET /cards/:id/images)
GET /cards/:id
This endpoint lists the status of a card. It is useful for checking whether a card has already been used to submit a hazard report.
curl /cards/:id
import axios from 'axios'; // package to make http requests
axios.get('/cards')
.then(response => console.log(response))
.catch(err => console.log(err))
The above command returns JSON structured as shown below. Note that in this example the card has not yet been submitted by the user. When querying a report that has been submitted additional report details including reportId are provided by this endpoint.
{
"statusCode": 200,
"result": {
"card_id": "guid",
"network": "twitter",
"language": "en",
"received": false,
"report": null
}
}
HTTP Request
GET /cards/:id
POST /cards
This endpoint creates a new card with a GUI, in preparation for submission of hazard information by user.
curl -X POST /cards
-H 'Content-Type: application/json' \
-H 'x-api-key: api-key' \
-d '{
"username": "123",
"network":"twitter",
"language":"en"
}'
import axios from 'axios'; // package to make http requests
axios.post('/cards', {
username: "123",
network: "twitter",
language: "en"
}, {headers: {'x-api-key': 'key'}})
.then(response => console.log(response))
.catch(err => console.log(err))
The above command returns JSON structured like this:
{
"cardId": "guid",
"created": true
}
HTTP Request
POST /cards
New Card Attributes
| Attribute | Type | Description | Required |
|---|---|---|---|
| username | string | User social network username or id | Yes |
| network | string | Name of social network (e.g. 'twitter') | Yes |
| language | string | Two-letter language code for user (e.g. 'en') | Yes |
PUT /cards/:id
This endpoint receives card information to create a hazard report. Once data is received a report will be generated and become available in the reports endpoint.
curl -X PUT /cards/:id
-H 'Content-Type: application/json'
-H 'x-api-key: api_key'
-d '{
"card_data":{
"report_type":"flood",
"flood_depth": 20
},
"disaster_type": "flood",
"text": "Very big flood",
"created_at":"2016-12-13T19:25:29Z",
"location": {
"lat":-6.4,
"lng":106.6
}
}'
import axios from 'axios'; // package to make http requests
axios.put('/', {
card_data:{
report_type:"flood",
flood_depth: 20
},
disaster_type: "flood",
text: "Very big flood",
created_at:"2016-12-13T19:25:29Z",
location: {
lat:-6.4,
lng:106.6
}
}, {headers: {'x-api-key': 'key'}})
.then(response => console.log(response))
.catch(err => console.log(err))
The above command returns JSON structured like this:
{
"statusCode": 200,
"cardId": "guid",
"created": true
}
HTTP Request
PUT /cards/:id
Card Report Attributes
| Attribute | Type | Description | Required |
|---|---|---|---|
| card_data | object | Object containing hazard specific data | Yes |
| disaster_type | string | Hazard type | Yes |
| text | string | Hazard description | Yes |
| created_at | string | Timestamp in ISO8601 format YYYY-MM-DDTHH:MM:SSZ | Yes |
| disaster_type | string | Hazard type | Yes |
| location | object | Point location, latitude and longitude | Yes |
GET /cards/:id/images
Get a signed AWS S3 URL to upload an image associated with a card. This must be done after card report has been created. Only one image can exist for a given card. See more in the AWS documentation.
curl GET /cards/:id/images
import axios from 'axios'; // package to make http requests
axios.get('/cards/:id/images')
.then(response => console.log(response))
.catch(err => console.log(err))
The above command returns JSON structured like this:
{
"signedRequest": "https://s3.us-west-2.amazonaws.com/domain/originals/guid.jpeg?aws-signature",
"url": "https://s3.us-west-2.amazonaws.com/domain/originals/guid.jpeg"
}
HTTP Request
GET /cards/:id/images
Cities
CogniCity deployments are organised by city. Cities are delineated by a unique three letter code and a bounding box geometry. Note that the term "city" is used somewhat arbitrairily for organisational purposes. Cities may refer to an urban conurbation or wider metropolitan area. For example in the United States "Broward" is used to refer to Broward County which includes multiple cities and non-urban areas.
GET /cities
curl "/cities?geoformat=geojson"
import axios from 'axios'; // package to make http requests
axios.get('/cities', {
params: {
geoformat: 'geojson'
}
})
.then(response => console.log(response))
.catch(err => console.log(err))
The above command returns JSON structured like this:
{
"statusCode": 200,
"result": {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
-80.56454636,
26.4393434677
],
[
-80.011194015,
26.4376911515
],
[
-80.0147106747,
25.8743814793
],
[
-80.5690752042,
25.8759818852
],
[
-80.56454636,
26.4393434677
]
]
]
},
"properties": {
"code": "brw",
"name": "broward"
}
}
]
}
}
This endpoint returns all cities covered by the CogniCity instance, including their three letter code and bounding box geometry.
HTTP Request
GET /cities
Query Parameters
| Parameter | Required | Description | Default |
|---|---|---|---|
| geoformat | false | Specifies either 'geojson' or 'topojson' | topojson |
Response
The returned data uses the GeoJSON FeatureCollection or TopoJSON GeometryCollection types. The properties of each sensor feature as described in the following table.
| Attribute | Type | Description |
|---|---|---|
| code | string | Unique 3 letter code for each city |
| name | string | City name |
Feeds
The feeds endpoint supports input of hazard reports from third-party data-streams such as local civic applications. Reports collected from external data feeds are available from the /reports endpoint.
POST /qlue
This endpoint accepts hazard reports from the Qlue Smart City Application.
curl -X post /feeds/qlue
-H 'Content-Type: application/json' \
-H 'x-api-key: api-key' \
-d '{
"post_id": "123",
"created_at": "twitter",
"title": "en",
"text": "flooding!",
"image_url": "url",
"qlue_city": "jabodetabek",
"disaster_type": "flood",
"location": {
"lat":-6.2,
"lon":106.8
}
}'
import axios from 'axios'; // package to make http requests
axios.post('/feeds/qlue', {
post_id: 123,
created_at: "2018-06-18T00:00+0700",
title: "en",
text: "flooding!",
image_url: "url",
qlue_city: "jabodetabek",
disaster_type: "flood",
location: {
lat:-6.2,
lon:106.8
}
}, {headers: {'x-api-key': 'key'}})
.then(response => console.log(response))
.catch(err => console.log(err))
The above command returns JSON structured like this:
{
"post_id": 1,
"created": true
}
HTTP Request
POST /feeds/qlue
Qlue Report Attributes
| Attribute | Type | Description | Required |
|---|---|---|---|
| post_id | number | Qlue identifier | Yes |
| created_at | string | Timestamp in ISO8601 format YYYY-MM-DDTHH:MM:SS | Yes |
| title | string | Title of report | No |
| text | string | Hazard description | Yes |
| image_url | string | URL of image | No |
| qlue_city | string | City of report origin | No |
| disaster_type | string | Hazard type | Yes |
| location | object | Point location, latitude and longitude | Yes |
Floods
The floods endpoint provides flood hazard seveirty by local area. This information is created through the CogniCity Risk Evaluation Matrix, and is nowt operational in all cities. Local areas are delineated by available local boundary data (e.g. Fire grids in the US, or RW districts in Indonesia).
In addition to topojson and geojson support the floods endpoint supports the Common Alerting Protocol (CAP).
Flood State Codes
Flood state by area is represneted by numberic code, as follows:
| Code | Severity | Description |
|---|---|---|
| 1 | Unknown | AN UNKNOWN LEVEL OF FLOODING - USE CAUTION |
| 2 | Minor | FLOODING OF BETWEEN 10 AND 70 CENTIMETERS |
| 3 | Moderate | FLOODING OF BETWEEN 71 and 150 CENTIMETERS |
| 4 | Severe | FLOODING OF OVER 150 CENTIMETERS |
GET /floods
This endpoint gets flood hazard information by local area.
curl /floods
import axios from 'axios'; // package to make http requests
axios.get('/floods')
.then(response => console.log(response))
.catch(err => console.log(err))
The above commands returns JSON structured as follows (example taken from petabencana.id for Jakarta).
{
"statusCode": 200,
"result": {
"type": "Topology",
"objects": {
"output": {
"type": "GeometryCollection",
"geometries": [
{
"type": "Polygon",
"properties": {
"area_id": "5",
"geom_id": "3174040004009000",
"area_name": "RW 09",
"parent_name": "GROGOL",
"city_name": "Jakarta",
"state": 1,
"last_updated": "2016-12-19T13:53:52.274Z"
},
"arcs": [
[
0
]
]
}
]
}
},
"arcs": [
[
[
9999,
7847
],
[
-507,
-6
],
[
-695,
-70
],
[
-317,
-221
],
[
-761,
-18
],
[
-516,
98
],
[
-641,
-61
],
[
-649,
-119
],
[
-169,
-762
],
[
-181,
-519
],
[
48,
-602
],
[
-130,
-162
],
[
64,
-1235
],
[
81,
-2351
],
[
136,
-1098
],
[
15,
-675
],
[
-1250,
-40
],
[
-879,
-6
],
[
-924,
217
],
[
-924,
425
],
[
-1800,
138
],
[
830,
1540
],
[
565,
1455
],
[
764,
1975
],
[
1018,
2079
],
[
384,
788
],
[
389,
1061
],
[
1398,
-76
],
[
296,
-25
],
[
360,
6
],
[
392,
-9
],
[
360,
-9
],
[
377,
12
],
[
323,
25
],
[
354,
76
],
[
296,
89
],
[
211,
42
],
[
290,
52
],
[
217,
28
],
[
341,
110
],
[
43,
-67
],
[
57,
-174
],
[
109,
-159
],
[
154,
-257
],
[
115,
-370
],
[
99,
-346
],
[
124,
-357
],
[
133,
-422
]
]
],
"transform": {
"scale": [
0.0000003311331833192323,
0.00000032713269326930546
],
"translate": [
106.7917869997,
-6.158925
]
},
"bbox": [
106.7917869997,
-6.158925,
106.7950980004,
-6.1556540002
]
}
}
Data example when requested in CAP XML format.
<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<id>https://data.petabencana.id/floods</id>
<title>petabencana.id Flood Affected Areas</title>
<updated>2016-12-19T23:08:52+07:00</updated>
<author>
<name>petabencana.id</name>
<uri>https://petabencana.id/</uri>
</author>
<entry>
<id>https://data.petabencana.id/floods?parent_name=GROGOL&area_name=RW%2009&time=2016-12-19T22:41:35+07:00</id>
<title>GROGOL.RW_09.2016-12-19T22:41:35+07:00 Flood Affected Area</title>
<updated>2016-12-19T22:41:35+07:00</updated>
<content type="text/xml">
<alert xmlns="urn:oasis:names:tc:emergency:cap:1.2">
<identifier>GROGOL.RW_09.2016-12-19T22:41:35+07:00</identifier>
<sender>BPBD.JAKARTA.GOV.ID</sender>
<sent>2016-12-19T22:41:35+07:00</sent>
<status>Actual</status>
<msgType>Alert</msgType>
<scope>Public</scope>
<info>
<category>Met</category>
<event>FLOODING</event>
<urgency>Immediate</urgency>
<severity>Minor</severity>
<certainty>Observed</certainty>
<senderName>JAKARTA EMERGENCY MANAGEMENT AGENCY</senderName>
<headline>FLOOD WARNING</headline>
<description>AT 22:41 WIB THE JAKARTA EMERGENCY MANAGEMENT AGENCY OBSERVED FLOODING OF BETWEEN 10 and 70 CENTIMETERS IN GROGOL, RW 09.</description>
<web>https://petabencana.id/</web>
<area>
<areaDesc>RW 09, GROGOL</areaDesc>
<polygon>-6.1563580003,106.7950980004 -6.1563600004,106.7949299998 -6.1563829997,106.7947 -6.1564550003,106.7945949997 -6.1564609997,106.7943429997 -6.156429,106.7941719999 -6.156449,106.7939600001 -6.156488,106.793745 -6.1567369998,106.7936890001 -6.1569070004,106.7936290001 -6.1571040005,106.7936449999 -6.1571570003,106.7936019997 -6.157561,106.7936229998 -6.1583300004,106.7936500001 -6.1586889999,106.7936950004 -6.1589100002,106.7936999998 -6.1589229999,106.7932860005 -6.158925,106.7929949996 -6.1588540003,106.7926889999 -6.1587150002,106.7923830002 -6.1586699999,106.7917869997 -6.158166,106.7920619998 -6.1576899997,106.7922490003 -6.1570440005,106.7925020003 -6.1563639997,106.7928389996 -6.1561060004,106.7929660001 -6.1557589997,106.7930949997 -6.1557839999,106.7935580004 -6.1557920003,106.7936560004 -6.1557900002,106.7937749996 -6.1557930003,106.7939050002 -6.1557960005,106.7940240003 -6.1557920003,106.7941489998 -6.1557839999,106.7942560002 -6.1557589997,106.7943730002 -6.1557300001,106.7944710002 -6.1557160004,106.7945409999 -6.1556990005,106.7946369998 -6.1556900001,106.7947090004 -6.1556540002,106.7948220002 -6.1556760003,106.794836 -6.1557330003,106.794855 -6.155785,106.7948909998 -6.1558690002,106.7949420004 -6.1559900004,106.7949800003 -6.1561030002,106.7950130001 -6.1562200002,106.7950540001 -6.1563580003,106.7950980004 </polygon>
</area>
</info>
</alert>
</content>
</entry>
</feed>
HTTP Request
GET /floods
Request Parameters
| Attribute | Type | Description | Required | Default |
|---|---|---|---|---|
| city | string | Which city do we want data for (e.g. 'jbd')? | No | None |
| format | string | Format to return data in (one of 'json', 'xml') | No | json |
| geoformat | string | What format should geographic result use (one of 'topojson', 'geojson', 'cap') | No | topojson |
| minimum_state | number | The minimum flood state that should be returned (min: 1, max: 4) | No | None |
GET /floods/states
Get flooded areas without geospatial boundary data. Areas are referenced by area_id property. This is useful for updating state without the overhead of requesting the complete geographic data-set.
Example lists flooded areas in Jakarta with a state of 1 of higher.
curl /floods/states?minimum_state=1&city=jbd
import axios from 'axios'; // package to make http requests
axios.get('/floods/states?minimum_state=1&city=jbd')
.then(response => console.log(response))
.catch(err => console.log(err))
The above command returns JSON structured like this:
{
"statusCode": 200,
"result": [
{
"area_id": "5",
"state": 1,
"last_updated": "2016-12-19T13:53:52.274Z"
}
]
}
Request Parameters
| Attribute | Type | Description | Required | Default |
|---|---|---|---|---|
| city | string | Which city do we want data for (e.g. 'jbd')? | No | None |
| minimum_state | number | The minimum flood state that should be returned (min: 1, max: 4) | No | None |
HTTP Request
GET /floods/states?minimum_state=1&city=jbd
PUT /floods/:id
This endpoint receives new flood state information for a given local area.
curl -X PUT /floods/:id
-H 'Content-Type: application/json'
-H 'Authorization': 'token',
-d '{
"state": 2
}'
import axios from 'axios'; // package to make http requests
axios.put('/floods/:id', {
state: 2
}, {headers: {'Authorization': 'token'}})
.then(response => console.log(response))
.catch(err => console.log(err))
The above command returns JSON structured like this:
{
"localAreaId": "<id>",
"state": 2,
"updated": true
}
HTTP Request
PUT /floods/:id
Flood State Attributes
| Attribute | Type | Description | Required |
|---|---|---|---|
| state | number | Flood severity | Yes |
DELETE /floods/:id
This endpoint clears the flood state for a given local area.
curl -X DELETE /floods/:id
import axios from 'axios'; // package to make http requests
axios.delete('/floods/:id/')
.then(response => console.log(response))
.catch(err => console.log(err))
The above command returns JSON structured like this:
{
"localAreaId": "<id>",
"state": null,
"updated": true
}
HTTP Request
DELETE /floods/:id
GET /floods/archive
This endpoint provides an archive of flooded areas, presented as the maximum flood state recorded for all flood affected areas within the specified time period. Maximum flood state is recorded alonside local area. Use the /floods endpoint to get the geographic boundaries of local areas.
curl GET /floods/archive?start=2017-11-02T00:00:00+0700&end=2017-11-05T00:00:00+0700
import axios from 'axios'; // package to make http requests
axios.get('/floods/archive?start=2017-11-02T00:00:00+0700&end=2017-11-05T00:00:00+0700')
.then(response => console.log(response))
.catch(err => console.log(err))
The above command returns JSON structure like this:
{
"statusCode": 200,
"result": [
{
"area_id": "509",
"last_updated": "2017-11-03T22:57:01.387Z",
"max_state": 1
},
{
"area_id": "510",
"last_updated": "2017-11-03T22:57:10.463Z",
"max_state": 4
}
]
}
HTTP Request
GET /floods/archive
Request Parameters
| Attribute | Type | Description | Required | Default |
|---|---|---|---|---|
| city | string | Which city do we want data for (e.g. 'jbd')? | No | None |
| start | string | Start time for timeseries as ISO 8601 format (YYYY-MM-DDTHH:mm:ss+ZZZZ) | Yes | None |
| end | string | End time for timeseries as ISO 8601 format (YYYY-MM-DDTHH:mm:ss+ZZZZ) | Yes | None |
GET /floods/timeseries
This endpoint provides a time series of flooded areas data represented as a count of flood affected areas every hour within the specificed time period. The count is recoreded alongside an hourly timestamp in ISO8601 format at UTC.
curl GET /floods/timeseries?start=2017-11-20T00:00:00+0700&end=2017-11-21T00:00:00+0700
import axios from 'axios'; // package to make http requests
axios.get('/floods/timeseries?start=2017-11-20T00:00:00+0700&end=2017-11-21T00:00:00+0700')
.then(response => console.log(response))
.catch(err => console.log(err))
The above command returns JSON structured like this:
{
"statusCode": 200,
"result": [
{
"ts": "2017-11-20T16:00:00.000Z",
"count": "0"
},
{
"ts": "2017-11-20T17:00:00.000Z",
"count": "2"
},
{
"ts": "2017-11-20T18:00:00.000Z",
"count": "10"
},
{
"ts": "2017-11-20T19:00:00.000Z",
"count": "0"
},
{
"ts": "2017-11-20T20:00:00.000Z",
"count": "0"
}
]
}
HTTP Request
GET /floods/timeseries
Request Parameters
| Attribute | Type | Description | Required | Default |
|---|---|---|---|---|
| city | string | Which city do we want data for (e.g. 'jbd')? | No | None |
| start | string | Start time for timeseries as ISO 8601 format (YYYY-MM-DDTHH:mm:ss+ZZZZ) | Yes | None |
| end | string | End time for timeseries as ISO 8601 format (YYYY-MM-DDTHH:mm:ss+ZZZZ) | Yes | None |
Infrastructure
CogniCity stores the locations of local infrastructure including flood gates, pumps, waterways and drainage basins to assist mapping. Note that not all infrastructure are necessarily available in each instance.
Available Infrastructure Types
The following types of infrastructure are available:
- floodgates
- pumps
- waterways
- sites (measurement stations)
- basins (drainage)
GET /infrastructure
This endpoint returns the location and attributes of the specific infrastructure.
curl /infrastructure/pumps
import axios from 'axios'; // package to make http requests
axios.get('/infrastructure/pumps',
.then(response => console.log(response))
.catch(err => console.log(err))
The above command returns JSON structured like this:
{
"statusCode": 200,
"result": {
"type": "Topology",
"objects": {
"output": {
"type": "GeometryCollection",
"geometries": [
{
"type": "Point",
"properties": {
"name": "PA Marina"
},
"coordinates": [
7164,
7352,
0
]
},
{
"type": "Point",
"properties": {
"name": "Pompa Waduk Setia Budi Barat"
},
"coordinates": [
5312,
5077,
0
]
},
// etc. etc. //
{
"type": "Point",
"properties": {
"name": "Pompa UP Senen"
},
"coordinates": [
6143,
6544,
0
]
}
]
}
},
"arcs": [],
"transform": {
"scale": [
0.000020651319451945148,
0.000020217245084508508
],
"translate": [
106.7188310623,
-6.3060956581
]
},
"bbox": [
106.7188310623,
-6.3060956581,
106.9253236055,
-6.1039434245
]
}
}
HTTP Request
GET /infrastructure/:type
Request Parameters
| Attribute | Type | Description | Required | Default |
|---|---|---|---|---|
| city | string | Which city do we want data for (e.g. 'jbd')? | No | None |
| format | string | Format of the returned data (must be 'json') | No | json |
| geoformat | string | Format for geographical objects (one of 'geojson' or 'topojson') | No | topojson |
Reports
The reports endpoint contains CogniCity reports submitted by the public. Reports are represented by point-geometries and their accompanying properties (e.g. description, time etc.). Note that all times are UTC, and geometries use the WGS 1984 coordinate system.
GET /reports
curl "/reports?city=brw&geoformat=geojson"
import axios from 'axios'; // package to make http requests
axios.get('/reports', {
params: {
city: 'brw',
geoformat: 'geojson'
}
})
.then(response => console.log(response))
.catch(err => console.log(err))
The above command returns JSON structured like this:
{
"statusCode": 200,
"result": {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
-80.0946879387,
26.1381793399
]
},
"properties": {
"pkey": "94",
"created_at": "2018-06-19T17:53:43.229Z",
"source": "grasp",
"status": "confirmed",
"url": "ad63ccb2-024f-4617-81a1-4e8782499afa",
"image_url": "https://images.riskmap.us/ad63ccb2-024f-4617-81a1-4e8782499afa.jpg",
"disaster_type": "flood",
"report_data": {
"report_type": "flood",
"flood_depth": 8
},
"tags": {
"district_id": null,
"local_area_id": null,
"instance_region_code": "brw"
},
"title": null,
"text": "Test flood report (MIT)"
}
}
]
}
}
This endpoint retrieves all reports. Note that all times are UTC, and geometries use the WGS 1984 coordinate system.
HTTP Request
GET /reports
Query Parameters
| Parameter | Required | Description | Default | Example |
|---|---|---|---|---|
| city | false | Filter reports by 3-letter city code (see cities endpoint for details). If no city specified then reports for all cities in CogniCity instance are returned | none | brw |
| geoformat | false | Specifies either 'geojson' or 'topojson' | topojson | geojson |
| timeperiod | false | Time period in seconds to filter reports by, must be strictly between 1 and 604800 (1 week) | 3600 (1 hour) | 3600 |
PATCH /reports/:id
Edit report tags, including 'points' for up/down vote functionality.
curl -X PATCH /reports/:id
-H 'Content-Type: application/json'
-d '{"points": 1}'
import axios from 'axios'; // package to make http requests
axios.patch('/reports/:id', {
points: 1
})
.then(response => console.log(response))
.catch(err => console.log(err))
The above command returns JSON structured like this:
{
"statusCode": 200,
"id": "id",
"points": 5
}
HTTP Request
PATCH /reports/:id
Report Attributes
| Parameter | Required | Description | Default | Example |
|---|---|---|---|---|
| points | true | Value of either -1 or 1 to be added to report points value | none | -1 |
PATCH /reports/:id/flag
Set a report's flag value.
curl -X PATCH /reports/:id/flag
-H 'Content-Type: application/json'
-d '{"flag": true}'
import axios from 'axios'; // package to make http requests
axios.patch('/reports/:id/flag', {
flag: true
})
.then(response => console.log(response))
.catch(err => console.log(err))
The above command returns JSON structured like this:
{
"statusCode": 200,
"id": "id",
"flag": true
}
HTTP Request
PATCH /reports/:id/flag
Report Attributes
| Parameter | Required | Description | Default | Example |
|---|---|---|---|---|
| flag | true | Value of either true or false to be added to report flag value | none | true |
GET /reports/archive
curl "/reports/archive?city=brw&geoformat=geojson&start=2018-06-15T00:00:00-0400&end=2018-06-19T15:00:00-0400"
import axios from 'axios'; // package to make http requests
axios.get('/reports/archive', {
params: {
city: 'brw',
geoformat: 'geojson',
start: '2018-06-15T00:00:00-0400',
end: '2017-06-19T15:00:00-0400'
}
})
.then(response => console.log(response))
.catch(err => console.log(err))
The above command returns JSON structured like this:
{
"statusCode": 200,
"result": {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
-80.0977993011,
26.140336808
]
},
"properties": {
"pkey": "92",
"created_at": "2018-06-15T18:48:57.084Z",
"source": "grasp",
"status": "confirmed",
"url": "d56c91dc-15c9-4d3b-83f1-cc86b94ae330",
"image_url": null,
"disaster_type": "flood",
"report_data": {
"report_type": "flood",
"flood_depth": 10
},
"tags": {
"district_id": null,
"local_area_id": "1375",
"instance_region_code": "brw"
},
"title": null,
"text": "test flood"
}
}
]
}
}
This endpoint retrieves reports within the specified time period. The maximum duration between start and end times is one week. Note that all times are UTC, and geometries use the WGS 1984 coordinate system.
HTTP Request
GET /reports/archive
Query Parameters
| Parameter | Required | Description | Default | Example |
|---|---|---|---|---|
| city | false | Filter reports by 3-letter city code (see cities endpoint for details). If no city specified then reports for all cities in CogniCity instance are returned | none | brw |
| geoformat | false | Specifies either 'geojson' or 'topojson' | topojson | geojson |
| start | true | Start time for archive period in ISO 8601 string format | none | 2018-06-15T00:00:00-0400 |
| end | true | End time for archive period in ISO 8601 string format. Must bet within 604800 seconds (1 week) from start time | none | 2017-06-19T15:00:00-0400 |
GET /reports/timeseries
curl "/reports/timeseries?city=brw&start=2018-06-19T13:00:00%2D0400&end=2018-06-19T15:00:00%2D0400"
import axios from 'axios'; // package to make http requests
axios.get('/reports/timeseries', {
params: {
start: '2018-06-19T13:00:00-0400',
end: '2018-06-19T15:00:00-0400'
}
})
.then(response => console.log(response))
.catch(err => console.log(err))
The above command returns JSON structured like this:
{
"statusCode": 200,
"result": [
{
"ts": "2018-06-19T17:00:00.000Z",
"count": "1"
},
{
"ts": "2018-06-19T18:00:00.000Z",
"count": "0"
},
{
"ts": "2018-06-19T19:00:00.000Z",
"count": "0"
}
]
}
This endpoint generates a time series of reports presented as a count of reports every hour within the specified time period. The maximum duration between start and end times is one week. Report count is recorded alongside an hourly UTC timestamp in ISO 8061 format.
HTTP Request
GET /reports/timeseries
Query Parameters
| Parameter | Required | Description | Default | Example |
|---|---|---|---|---|
| city | false | Filter reports by 3-letter city code (see cities endpoint for details). If no city specified then reports for all cities in CogniCity instance are returned | none | jbd |
| start | true | Start time for archive period in ISO 8601 string format | none | 2017-02-21T07:00:00+0700 |
| end | true | End time for archive period in ISO 8601 string format. Must bet within 604800 seconds (1 week) from start time | none | 2017-02-21T19:00:00+0700 |
Sensors API
The CogniCity Sensors endpoints supports centralizing data from automated sensor networks. Sensor data can be inserted into the database for storage, and subsequently served as GeoJSON or TopoJSON to support map visualisations.
Sensor locations are point geometries defined using latitude and longitude coordinates in the WGS 1984 coordinate system.
Sensors
GET /
This endpoint returns a collection of sensors and their properties within the specified bounding box. If no bounding box is provided all sensors in the database will be returned.
curl "/?bbox=-81,27,-79,25&geoformat=geojson"
import axios from 'axios'; // package to make http requests
axios.get('/', {
params: {
bbox: '-81,27,-79,25',
geoformat: 'geojson'
}
})
.then(response => console.log(response))
.catch(err => console.log(err))
The response body contains the following JSON object:
{
"statusCode": 200,
"result": {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
-80.3853056,
26.0341111
]
},
"properties": {
"id": "2",
"created": "2017-10-24T22:35:58.875Z",
"properties": {
"uid": "260653080184901",
"type": "GW",
"class": "62610",
"units": "ft"
}
}
},
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
-80.1153333,
26.31780556
]
},
"properties": {
"id": "3",
"created": "2017-10-24T22:35:58.883Z",
"properties": {
"uid": "261903080065601",
"type": "GW",
"class": "62610",
"units": "ft"
}
}
}
]
}
}
HTTP Request
GET /
Query Parameters
| Parameter | Required | Description | Default | Example |
|---|---|---|---|---|
| bbox | false | A list of longitude and latitude pairs representing the top left and bottom right corners of a bounding box for sensor locations. | none | longitude, latitude, longitude, latitude |
| geoformat | false | Specifies either 'geojson' or 'topojson' | geojson | geojson |
| agency | false | Optional filter properties.agency of the sensor (e.g. 'USGS') |
Response
The returned data uses the GeoJSON FeatureCollection or TopoJSON GeometryCollection types. The properties of each sensor feature as described in the following table.
| Attribute | Type | Description |
|---|---|---|
| id | integer | Unique sensor identifier |
| created | string | timestamp sensor created in database (ISO 8601 format) |
| properties | json | metadata attributes for each sensor |
POST /
This endpoint creates a new sensor. On success a GeoJSON feature representing the new sensor is returned.
curl -X POST / -H 'Content-Type: application/json' -H 'x-api-key: key' -d '{
"properties":{
"name": "test sensor",
"agency": "usgs"
},
"location":{
"lat": 25.0,
"lng": -80.0
}
}'
import axios from 'axios'; // package to make http requests
axios.post('/', {
properties: {
name: "test sensor",
agency: "usgs"
},
location: {
lat: 25.0,
lng: -80.0
}
}, {headers: {'x-api-key': 'key'}})
.then(response => console.log(response))
.catch(err => console.log(err))
The above command returns JSON structured like this:
{
"statusCode": 200,
"result": {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
-80.0,
25.0
]
},
"properties": {
"id": "4",
"created": "2018-03-16T18:25:07.613Z",
"properties": {
"name": "test sensor",
"agency": "usgs"
}
}
}
]
}
}
HTTP Request
POST /
New Sensor Attributes
| Attribute | Type | Description | Required |
|---|---|---|---|
| properties | object | Sensor metadata properties | Yes |
| properties.agency | string | Optional agency tag for sensor (e.g. 'usgs') | |
| location | object | An object with lat and lng numerical values representing the sensor's latitude and longitude |
Yes |
DELETE /:id
curl -X DELETE /4 -H 'Content-Type: application/json' -H 'x-api-key: key'
import axios from 'axios'; // http requests
// delete record 2345 from sensor 4
axios.delete('/sensors/4', {headers: {'x-api-key': 'key'}, {'content-type': 'application/json'}})
.then(response => console.log(response))
.catch(err => console.log(err))
{
"statusCode": 200,
"body": {}
}
This endpoint deletes a sensor and any data from that sensor. On success the statusCode and an empty body object are returned.
HTTP Request
DELETE /:id
Data
GET /:id
curl "/3"
import axios from 'axios'; // package to make http requests
axios.get('/3')
.then(response => console.log(response))
.catch(err => console.log(err))
The above command returns JSON structured like this:
{
"statusCode": 200,
"result": [
{
"dataId": "24439",
"sensorId": "3",
"created": "2018-03-16T17:37:47.116Z",
"properties": {
"type": "observation",
"observations": [
{
"value": "3.84",
"dateTime": "2018-03-15T13:45:00.000-04:00"
},
{
"value": "3.84",
"dateTime": "2018-03-15T14:00:00.000-04:00"
}
]
}
}
]
}
This endpoint retrieves a list of data for a specific sensor. Data are organised into records, indexed by the id attribute. The created attribute details when the record was last updated. The properties attribute contains the data for the record. The properties object may be in varying formats. The example shows a properties object for a single data record which contains an observations array of measurements. Data records are returned in reverse chronological order by created date.
HTTP Request
GET /:id
URL Parameters
| Parameter | Description |
|---|---|
| ID | The ID of the sensor to retrieve |
| type | Optional filter for the type field |
| limit | Optional limit on number of returned records |
Response
| Attribute | Type | Description |
|---|---|---|
| dataId | integer | Unique data record identifier |
| sensorId | integer | The ID of the sensor |
| created | string | Data record update time (ISO 8601 format) |
| properties | object | Record data |
POST /:id
curl -X POST /4 -H 'Content-Type: application/json' -H 'x-api-key: key' -d '{
"properties":{
"METAR": "CYYQ 182200Z 07002KT 15SM OVC017 06/03 A2966 RMK SC10 3 POLAR BEARS ALNG RNWY==",
"type": "observation"
}
}'
import axios from 'axios'; // package to make http requests
axios.post('/4', {
properties: {
METAR: "CYYQ 182200Z 07002KT 15SM OVC017 06/03 A2966 RMK SC10 3 POLAR BEARS ALNG RNWY==",
type: "observation"
},
}, {headers: {'x-api-key': 'key'}})
.then(response => console.log(response))
.catch(err => console.log(err))
The above command returns JSON structured like this:
{
"statusCode": 200,
"result": {
"dataId": "240288",
"sensorId": "4",
"created": "2018-03-16T19:30:33.042Z"
}
}
This endpoint adds a new data record to the specified sensor. On success the sensor ID and an updated timestamp are returned.
HTTP Request
POST /:id
URL Parameters
| Parameter | Description |
|---|---|
| ID | The ID of the sensor |
New Sensor Attributes
| Attribute | Type | Description | Required |
|---|---|---|---|
| properties | object | New data record to be added | Yes |
| properties.type | string | Optional type tag for different measurement types (e.g. observation vs manual, or mean vs daily max) |
DELETE /:id/:dataId
curl -X DELETE /4/2345 -H 'Content-Type: application/json' -H 'x-api-key: key'
import axios from 'axios'; // http requests
// delete record 2345 from sensor 4
axios.delete('/sensors/4/2345', {headers: {'x-api-key': 'key'}, {'content-type': 'application/json'}})
.then(response => console.log(response))
.catch(err => console.log(err))
{
"statusCode": 200,
"body": {}
}
This endpoint deletes a data record for the specified sensor. On success the statusCode and an empty body object are returned.
HTTP Request
DELETE /:id/:dataId
URL Parameters
| Parameter | Description |
|---|---|
| ID | The ID of the sensor |
| DATAID | The ID of the data record to delete |