Skip to content

Akvo Flow REST API

Iván Perdomo edited this page Nov 7, 2022 · 16 revisions

Introduction

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.

Request headers

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.

Available Endpoints

Browsing the folder structure.

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

Browsing surveys in a folder

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

Retrieving a survey definition

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>"
}

Survey elements

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.

Form elements

{
    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

QuestionGroup elements

{
    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

Question elements

{
    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",
			}
		    ]
		}
	    ]
	}
    ]
}

Retrieving collected data

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

DataPoints elements

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

Retrieving form responses

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

FormInstances elements

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

Retrieving question statistics

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
}