-
Notifications
You must be signed in to change notification settings - Fork 3
Akvo Flow REST API
The Akvo Flow REST API is a read-only API that enables an organization/user to use a third party application to request data gathered with Akvo Flow. Being a read-only API means that we currently only support GET
requests.
All requests to the API are sent over HTTPS and are accessed via the base URL
https://api.akvo.org/flow/orgs/<organization-subdomain>
The organisation sub domain is identified by looking at the dashboard URL for one's organisation. e.g. if your dashboard URL is https://myakvo.akvoflow.org
, then the API request base URL would be
https://api.akvo.org/flow/orgs/myakvo
Following the base URL, we define a number of endpoints that can be queried depending on the required data. Note that all data is returned from the API in JSON format.
All GET
requests to the API require the following request headers to be included in order to be considered valid.
-
User-Agent:
e.g. curl/7.54.0 Accept: application/vnd.akvo.flow.v2+json
Authorization: Bearer <token>
For information on how to get a valid <token>
see the Authentication page.
At the first entry point into the dashboard, we start by browsing the folder structure.
The URL for accessing the folder structure starts with the root folder
https://api.akvo.org/flow/orgs/<organization-subdomain>/folders?parentId=<parentId>
or
https://api.akvo.org/flow/orgs/<organization-subdomain>/folders?parent_id=<parent_id>
e.g. https://api.akvo.org/flow/orgs/myakvo/folders?parentId=12345
or https://api.akvo.org/flow/orgs/myakvo/folders?parent_id=12345
The root folder, i.e. highest level folder is accessed by https://api.akvo.org/flow/orgs/myakvo/folders?parentId=0
An example response from this endpoint is shown below:
{
folders: [
{
id: "123",
parentId: "0"
name: "A Folder",
createdAt: "2017-02-23T03:30:58",
modifiedAt: "2017-02-23T03:30:58",
foldersUrl: "https://.../folders?parent_id=123",
surveysUrl: "https://.../surveys?folder_id=123",
}, {
id: "321",
parentId: "123"
name: "Another Folder",
createdAt: "2017-02-23T03:30:58",
modifiedAt: "2017-02-23T03:30:58",
foldersUrl: "https://.../folders?parent_id=321",
surveysUrl: "https://.../surveys?folder_id=321",
}
]
}
The top level element is folders
that is an array of folder objects. Each folder object has the following properties.
Element | Description | Type |
---|---|---|
id | The internal folder ID
|
Number |
parentId | the ID of the parent of this object. If the parentId is 0 then this folder is located in the root directory of the instance. |
Number |
name | The name of the folder | String |
createdAt | The date of creation of the folder | String |
modifiedAt | The date of last modification of the folder properties | String |
foldersUrl | The URL to browse other folders contained within this folder | String |
surveysUrl | The URL to browse surveys contained within this folder | String |
Retrieving survey definitions follows from the list of folders. When we have the list of folders as indicated in the previous section, each folder object has a surveysUrl
element that can be used to retrieve the list of surveys within that folder. The endpoint for retrieving surveys is defined as:
https://api.akvo.org/flow/orgs/<organization-subdomain>/surveys?folderId=<folder-id>
or
https://api.akvo.org/flow/orgs/<organization-subdomain>/surveys?folder_id=<folder_id>
e.g. https://api.akvo.org/flow/orgs/myakvo/surveys?folderId=321
or https://api.akvo.org/flow/orgs/myakvo/surveys?folder_id=321
The return object from querying such a URL is as follows:
{
surveys: [
{
id: "223"
folderId: "123",
name: "A Survey",
createdAt: "2017-02-23T03:30:58",
modifiedAt: "2017-02-23T03:30:58",
surveyUrl: "https://.../surveys/223",
}, {
id: "221",
folderId: "123"
name: "Another Survey",
createdAt: "2017-02-23T03:30:58",
modifiedAt: "2017-02-23T03:30:58",
surveyUrl: "https://.../surveys/221",
}
]
}
The top level is a surveys
element, that is an array of survey objects, each containing the following items.
Element | Description | Type |
---|---|---|
id | The id of the survey | Number |
folderId | the id of the folder in which the survey is included | Number |
name | the survey name | String |
createdAt | The date of creation of the survey | String |
modifiedAt | The data of last modification of the survey properties | String |
surveyUrl | The URL for accessing the complete survey definition of this survey object | String |
The surveyUrl
element contained in each object in the surveys list (see browsing surveys in a folder), enables the retrieval of a full survey definition for that particular survey object. We define the following endpoint
https://api.akvo.org/flow/orgs/<organization-subdomain>/surveys/<survey-id>
e.g. https://api.akvo.org/flow/orgs/myakvo/surveys/223
An example of a survey definition response is shown below:
{
id: "223",
name: "A Survey",
registrationFormId: "12345"
createdAt: "2017-02-23T03:30:58",
modifiedAt: "2017-02-23T03:30:58",
forms: [{},{},{}],
dataPointsUrl: "https://.../data_points?survey_id=<survey_id>"
}
Element | Description | Type |
---|---|---|
id | The id of this survey | Number |
name | The name of the survey | String |
registrationFormId | The id of the registration form | String |
createdAt | The date of creation of the survey | String |
modifiedAt | The modification date of the survey | String |
forms | An array of elements containing form definitions for this survey | Array |
dataPointsUrl | The URL used to retrieve a list of datapoints associated with this survey | String |
A survey may contain one or more form objects. In case of multiple form objects this is a monitoring survey.
{
id: "1234",
surveyId: "2345",
name: "A Form",
createdAt: "2017-02-23T03:30:58",
modifiedAt: "2017-02-23T03:30:58",
questionGroups: [],
formInstancesUrl: "https://.../form_instances?survey_id=<survey_id>&form_id=<form_id>",
}
Element | Description | Type |
---|---|---|
id | The id of this form object | Number |
surveyId | The id of the survey under which this form is found | Number |
name | The name of the form | String |
createdAt | The date of creation of the form | String |
modifiedAt | The modification date of the form | String |
questionGroups | An array in which each object corresponds to a group of questions as grouped by the survey designer | Array |
formInstancesUrl: | The URL used to retrieve form responses associated with this form | |
String |
{
id: "3456",
name: "A Question Group",
isRepeatable: false,
createdAt: "2017-02-23T03:30:58",
modifiedAt: "2017-02-23T03:30:58",
questions: []
}
Element | Description | Type |
---|---|---|
id | the id of this question group | Number |
name | the name of the question group | String |
isRepeatable | this indicates whether a question group has been defined as repeatable | Boolean |
createdAt | The date of creation of the question group | String |
modifiedAt | The modification date of the question group | String |
questions | An array of objects representing questions contained in this question group | Array |
{
id: "3444",
name: "Yet Another Question?",
type: "OPTION",
order: 1,
variableName: "first_name",
createdAt: "2017-02-23T03:30:58",
modifiedAt: "2017-02-23T03:30:58",
}
Element | Description | Type |
---|---|---|
id | the question Id | Number |
name | the name of the question | String |
type | The question type. We currently define a number of question types `` | String |
order | The order of the question in a group | Number |
variableName | The user defined identifier for a question | String |
createdAt | The date of creation of the question | String |
modifiedAt | The modification date of the question | String |
The full survey definition looks like this:
{
id: "223",
name: "A Survey",
createdAt: "2017-02-23T03:30:58",
modifiedAt: "2017-02-23T03:30:58",
forms: [
{
id: "1234",
surveyId: "2345",
name: "A Form",
createdAt: "2017-02-23T03:30:58",
modifiedAt: "2017-02-23T03:30:58",
questionGroups: [
{
id: "3456",
name: "A Question Group",
isRepeatable: false,
createdAt: "2017-02-23T03:30:58",
modifiedAt: "2017-02-23T03:30:58",
questions: [
{
id: "4567",
name: "A Question?",
type: "FREE_TEXT",
createdAt: "2017-02-23T03:30:58",
modifiedAt: "2017-02-23T03:30:58",
},
{
id: "3765",
name: "Another Question?",
type: "VIDEO",
createdAt: "2017-02-23T03:30:58",
modifiedAt: "2017-02-23T03:30:58",
}
]
},
{
id: "2543",
name: "Another Question Group",
isRepeatable: true,
createdAt: "2017-02-23T03:30:58",
modifiedAt: "2017-02-23T03:30:58",
questions: [
{
id: "3444",
name: "Yet Another Question?",
type: "OPTION",
createdAt: "2017-02-23T03:30:58",
modifiedAt: "2017-02-23T03:30:58",
}
]
}
]
}
]
}
We define the following endpoint for accessing data points gathered for a survey
https://api.akvo.org/flow/orgs/<organization-subdomain>/data_points?survey_id=<survey-id>
e.g. https://api.akvo.org/flow/orgs/myakvo/data_points?survey_id=123456
When queried this way, the list of data points returned is limited in number and we provide a pagination mechanism to enable requesting more datapoints if the user requires.
An example response from a query to this endpoint is shown below:
{
nextPageUrl: "https://.../data_points?survey_id=<survey_id>?page_size=N&cursor=32jfiosdjdf"
dataPoints: [
{
id: "23124",
displayName: "foo",
identifier: "fkdos-dso-dofks"
latitude: 56.2,
longitude: 23.6,
createdAt: "2017-02-23T03:30:58",
modifiedAt: "2017-02-23T03:30:58",
},
{
// ...
}
]
}
Element | Description | Type |
---|---|---|
nextPageUrl | Since the endpoint returns a limited number of results, we provide a paging URL which can be used to request the next N set of data points that we are interested in | String |
dataPoints | An array of data point objects | Array |
Element | Description | Type |
---|---|---|
id | The id of the datapoint | Number |
displayName | the display name of the data point? | String |
identifier | The data point identifier string | String |
latitude | The latitude of the datapoint | Number |
longitude | The longitude of the datapoint | Number |
createdAt | The date of creation of the data point | String |
modifiedAt | The last modification date of the data point | String |
We define the endpoint for retrieving form responses as follows:
https://api.akvo.org/flow/orgs/<organization-subdomain>/form_instances?survey_id=<survey_id>&form_id=<form_id>
e.g. https://api.akvo.org/flow/orgs/<organization-subdomain>/form_instances?survey_id=<survey-id>&form_id=<form_id>
The endpoint can optionally take the following request parameters:
Parameter | Description |
---|---|
page_size | This defines the number of results that we would like to return in a single query. It is an optional parameter. If not set we return 30 form instances in a response. The maximum value is 300. |
cursor | This defines the first element in the results set. Without it, we always return forms responses starting with the first element returned by the query. This value is typically not set by a user of the API, rather the user picks this value from a response to a previous API request. |
submission_date | Optional parameter. Defines a expression to filter the form instances by a given date/time. The filter expression must be URLEncoded. There is support for inequality operators: >= > <= < . |
An example responses from the form responses endpoint is:
{
nextPageUrl: "https://.../form_instances?survey_id=<survey_id>&form_id=<form_id>&page_size=N&cursor=32jifso543jggifa",
formInstances: []
}
An example of filter expressions for submission_date
parameter:
submission_date=%3E%3D1573480968
submission_date=%3E%3D2019-11-11T14%3A02%3A48Z
They both represent the same filter (submission_date>=1573480968
). One using Epoch timestamp, the other a full ISO-8601 formatted date/time with timezone.
Element | Description | Type |
---|---|---|
nextPageUrl | When retrieving results in batches, this URL would be used to retrieve the next batch of results | String |
formInstances | This returns a list of objects that correspond to the form responses | Array |
Each form instance object has the following structure
{
id: "3456",
dataPointId: "4567",
identifier: "hxeq-lb2e-g1n2",
displayName: "",
deviceIdentifier: "foo",
submissionDate: "2017-02-23T03:30:58",
submitter: "John",
duration: 123,
responses: {}
}
Element | Description | Type |
---|---|---|
id | the form instance id | Number |
dataPointId | the id of the data point to which this form instance is associated | Number |
identifier | the string identifier of the datapoint to which this form instance is associated | String |
displayName | the display name of the datapoint with which this form instance is associated | String |
deviceIdentifier | the device on which this response was collected | String |
submissionDate | The submission date of this form response | String |
submitter | The user specified on the device where this data was collected | String |
duration | The time in seconds it took to gather the data for this form | Integer |
responses | An object corresponding to the responses for this form | Object |
We define the endpoint for retrieving question statistics. Only NUMBER
and OPTION
question are supported.
https://api.akvo.org/flow/orgs/<organization-subdomain>/stats?survey_id=<survey_id>&form_id=<form_id>&question_id=<question_id>
e.g. https://api.akvo.org/flow/orgs/<organization-subdomain>/form_instances?survey_id=<survey-id>&form_id=<form_id>
The endpoint can optionally take the following request parameters:
Parameter | Description | Type |
---|---|---|
survey_id | The id of this survey | Number |
form_id | The id of this form | Number |
question_id | The id of this question | Number |
Example response:
For option question
{
"Northern": 129,
"Ti Ahmadia": 1,
"Kigbatito": 7,
"Kpembe/Lipo": 1,
"Kafaba": 1,
"Jankonto": 4,
"Kijewu": 2,
"Jemtito": 1,
"Kulpi Gonja": 3,
"New Makango": 1,
"Garinshanu": 1,
"Sisipe": 6,
"Masaka": 2,
"Kumbrupe": 4,
"Sass": 3
}
For number question
{
"sd": 165.42890102277977,
"max": 365,
"min": 0,
"mean": 134.67441860465115,
"count": 129
}