Entities¶
Entities allow you to share information between forms, enabling the collection of longitudinal data, management of cases over time, and support for other complex workflows.
The following endpoints provides access to Entities related data.
Where:
Entity- Each item that gets managed by an ODK workflow. Entities are automatically created from submissions received from a form that contains entity definitions.EntityList- a dataset that contains Entities of the same type.entity_list_id- An EntityList’s unique identifierentity_id- An Entity’s unique identifier
Create EntityList¶
POST /api/v2/entity-lists
This endpoint is used to create a single EntityList dataset within a project. Entities for the dataset can then be created from a form or via the API.
EntityList name must not include . or start with __
EntityList name is unique per project.
The EntityList by default has no properties. See Create EntityList Property to add properties.
Example
curl -X POST "https://api.ona.io/api/v2/entity-lists" \
-H "Authorization: Token ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "trees",
"project": "2",
}'
Response
Status: 201 Created
Body:
{
"id":1,
"name":"trees",
"project":2,
"date_created":"2024-06-27T07:35:53.451077Z",
"date_modified":"2024-06-27T07:35:53.451091Z"
}
Get a list of EntityLists¶
GET /api/v2/entity-lists
This endpoint is used to get all EntityList datasets.
The user must have view permission for each dataset.
The maximum number of items returned is 1000. To get more results than this, pagination is required. Refer to getting paginated results section.
Example
curl -X GET https://api.ona.io/api/v2/entity-lists
Response
Status: 200 OK
Body:
[
{
"url":"http://testserver/api/v2/entity-lists/9",
"id":9,
"name":"trees",
"project":"http://testserver/api/v1/projects/9",
"public":false,
"datecreated":"2024-04-17T11:26:24.630117Z",
"datemodified":"2024-04-17T11:26:25.050823Z",
"numregistrationforms":1,
"numfollowupforms":1,
"numentities":1
}
]
Get a list of Entities for a specific project¶
GET /api/v2/entity-lists?project=<project_id>
Example
curl -X GET https://api.ona.io/api/v2/entity-lists?project=9
Response
Status: 200 OK
Body:
[
{
"url":"http://testserver/api/v2/entity-lists/9",
"id":9,
"name":"trees",
"project":"http://testserver/api/v1/projects/9",
"public":false,
"datecreated":"2024-04-17T11:26:24.630117Z",
"datemodified":"2024-04-17T11:26:25.050823Z",
"numregistrationforms":1,
"numfollowupforms":1,
"numentities":1
}
]
Get a paginated list of EntityLists¶
GET /api/v2/entity-lists?page=<page>&page_size=<page_size>
Returns a list of projects using page number and the number of items per page. Use the page parameter to specify page number and page_size parameter is used to set the custom page size.
page- Integer representing the page.page_size- Integer representing the number of records that should be returned in a single page. The maximum number of items that can be requested in a page via thepage_sizequery param is10,000.
Example
curl -X GET https://api.ona.io/api/v2/entity-lists?page=1&page_size=100
Response
Status: 200 OK
Body:
[
{
"url":"http://testserver/api/v2/entity-lists/9",
"id":9,
"name":"trees",
"project":"http://testserver/api/v1/projects/9",
"public":false,
"datecreated":"2024-04-17T11:26:24.630117Z",
"datemodified":"2024-04-17T11:26:25.050823Z",
"numregistrationforms":1,
"numfollowupforms":1,
"numentities":1
}
]
Get EntityList Details¶
GET /api/v2/entity-lists/<entity_list_id>
This endpoint is used to get a single EntityList.
Example
curl -X GET https://api.ona.io/api/v2/entity-lists/1
Response
Status: 200 OK
Body:
{
"id":16,
"name":"trees",
"project":"http://testserver/api/v1/projects/13",
"public":false,
"date_created":"2024-04-17T11:43:08.530848Z",
"date_modified":"2024-04-17T11:43:09.030105Z",
"num_registration_forms":1,
"num_follow_up_forms":1,
"num_entities":1,
"registration_forms":[
{
"title":"Trees registration",
"xform":"http://testserver/api/v1/forms/15",
"id_string":"trees_registration",
"save_to":[
"geometry",
"species",
"circumference_cm"
]
}
],
"follow_up_forms":[
{
"title":"Trees follow-up",
"xform":"http://testserver/api/v1/forms/16",
"id_string":"trees_follow_up"
}
]
}
Download EntityList¶
GET api/v2/entity-lists/<entity_list_id>/download
or
GET api/v2/entity-lists/<entity_list_id>.csv
This endpoints are used to download the dataset in CSV format.
Example
curl -X GET https://api.ona.io/api/v2/entity-lists/1/download \
-H "Authorization: Token ACCESS_TOKEN"
Response
Status: 200 OK
Delete EntityList¶
DELETE api/v2/entity-lists/<entity_list_id>
This endpoint is used to delete a single EntityList dataset.
Example
curl -X DELETE https://api.ona.io/api/v2/entity-lists/1 \
-H "Authorization: Token ACCESS_TOKEN"
Response
Status: 204 No Content
Create EntityList Property¶
POST /api/v2/entity-lists/<entity_list_id>/properties
This endpoint is used to create a property for an EntityList dataset. Properties define the fields that can be used when creating or updating Entities in the dataset.
The following validation rules apply to property names:
Property name must not start with
__(reserved prefix)Property name cannot be
nameorlabel(reserved names)Property name must be unique per EntityList (case-sensitive)
Example
curl -X POST "https://api.ona.io/api/v2/entity-lists/1/properties" \
-H "Authorization: Token ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "height_cm"
}'
Response
Status: 201 Created
Body:
{
"name": "height_cm",
"entity_list": 1
}
Get a list of Entities¶
GET api/v2/entity-lists/<entity_list_id>/entities
This endpoint is used to get Entities belonging to a single EntityList dataset.
The maximum number of items returned is 1000. To get more results than this, pagination is required. Refer to getting paginated results section.
Example
curl -X GET https://api.ona.io/api/v2/entity-lists/1/entities
Response
Status: 200 OK
Body:
[
{
"url":"http://testserver/api/v2/entity-lists/1/entities/3",
"id":3,
"uuid": "dbee4c32-a922-451c-9df7-42f40bf78f48",
"date_created": "2024-06-20T07:37:20.416054Z",
"data": {
"species":"purpleheart",
"geometry":"-1.286905 36.772845 0 0",
"circumference_cm":300,
"label":"300cm purpleheart",
}
},
{
"url":"http://testserver/api/v2/entity-lists/1/entities/4",
"id":4,
"uuid": "517185b4-bc06-450c-a6ce-44605dec5480",
"date_created": "2024-06-20T07:38:20.416054Z",
"data": {
"species":"wallaba",
"geometry":"-1.305796 36.791849 0 0",
"intake_notes":"Looks malnourished",
"circumference_cm":100,
"label":"100cm wallaba",
}
}
]
Get a paginated list of Entities¶
GET /api/v2/entity-lists/1/entities?page=<page>&page_size=<page_size>
Returns a list of projects using page number and the number of items per page. Use the page parameter to specify page number and page_size parameter is used to set the custom page size.
page- Integer representing the page.page_size- Integer representing the number of records that should be returned in a single page. The maximum number of items that can be requested in a page via thepage_sizequery param is10,000.
Example
curl -X GET https://api.ona.io/api/v2/entity-lists/1/entities?page=1&page_size=100
Response
Status: 200 OK
Body:
[
{
"url":"http://testserver/api/v2/entity-lists/1/entities/3",
"id":3,
"uuid": "dbee4c32-a922-451c-9df7-42f40bf78f48",
"date_created": "2024-06-20T07:37:20.416054Z",
"data": {
"species":"purpleheart",
"geometry":"-1.286905 36.772845 0 0",
"circumference_cm":300,
"label":"300cm purpleheart",
}
}
]
Search a list of Entities¶
GET /api/v2/entity-lists/1/entities?search=<search_term>
Limit list of Entities to those whose data partially matches the provided search term.
Matches are case insensitive.
Example
curl -X GET https://api.ona.io/api/v2/entity-lists/1/entities?search=wallaba
Response
Status: 200 OK
Body:
[
{
"url":"http://testserver/api/v2/entity-lists/1/entities/4",
"id":4,
"uuid": "517185b4-bc06-450c-a6ce-44605dec5480",
"date_created": "2024-06-20T07:38:20.416054Z",
"data": {
"species":"wallaba",
"geometry":"-1.305796 36.791849 0 0",
"intake_notes":"Looks malnourished",
"circumference_cm":100,
"label":"100cm wallaba",
}
}
]
Create Entity¶
POST /api/v2/entity-lists/1/entities
This endpoint is used for creating a single Entity in the Entity List.
Note
The EntityList must have properties defined before you can create Entities. If the EntityList has no properties, the request will fail with:
Status:
400 Bad RequestBody:
{"error": "EntityList has no properties defined"}
The data is passed as JSON in the request body. The following keys are available:
label- A user-friendly label for forms that use Entities.data- An object with values for user-defined Dataset properties. (Not all properties need to have values.). A property must exist in the EntityList dataset.uuid(optional) - A unique ID. If not provided, one will be generated for the Entity upon creation. The uuid is unique per Entity List.
All property values are of type string.
Example
curl -X POST https://api.ona.io/api/v2/entity-lists/1/entities \
-H "Authorization: Token ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"label": "30cm mora",
"uuid": "dbee4c32-a922-451c-9df7-42f40bf78f48",
"data": {
"geometry": "-1.286805 36.772845 0 0",
"species": "mora",
"circumference_cm": "30"
}
}'
Response
Status: 201 Created
Body:
{
"id": 1,
"uuid": "dbee4c32-a922-451c-9df7-42f40bf78f48",
"date_created": "2024-06-20T07:37:20.416054Z",
"date_modified": "2024-06-20T08:37:20.416054Z",
"data": {
"geometry": "-1.286805 36.772845 0 0",
"species": "mora",
"circumference_cm": "30",
"label": "30cm mora",
}
}
Get Entity Details¶
GET api/v2/entity-lists/<entity_list_id>/entities/<entity_id>
This endpoint is used to get a single Entity.
Example
curl -X GET https://api.ona.io/api/v2/entity-lists/1/entities/3
Response
Status: 200 OK
Body:
{
"id":3,
"uuid": "dbee4c32-a922-451c-9df7-42f40bf78f48",
"date_created": "2024-06-20T07:37:20.416054Z",
"date_modified": "2024-06-20T07:37:20.416054Z",
"data": {
"species":"purpleheart",
"geometry":"-1.286905 36.772845 0 0",
"circumference_cm":300,
"label":"300cm purpleheart",
}
}
Update Entity¶
PATCH api/v2/entity-lists/<entity_list_id>/entities/<entity_id>
This endpoint is used to update the label or the properties (passed as JSON in the request body) of an Entity.
You only need to include the properties you wish to update. To unset the value of any property, you can set it to empty string (“”).
A property must exist in the EntityList dataset.
The label must be a non-empty string.
The uuid is unique per Entity List.
Example
curl -X PATCH https://api.ona.io/api/v2/entity-lists/1/entities/1 \
-H "Authorization: Token ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"label": "30cm mora",
"data": {
"geometry": "-1.286805 36.772845 0 0",
"species": "mora",
"circumference_cm": "30"
}
}'
Response
Status: 200 OK
Body:
{
"id": 1,
"uuid": "dbee4c32-a922-451c-9df7-42f40bf78f48",
"date_created": "2024-06-20T07:37:20.416054Z",
"date_modified": "2024-06-20T08:37:20.416054Z",
"data": {
"geometry": "-1.286805 36.772845 0 0",
"species": "mora",
"circumference_cm": "30",
"label": "30cm mora",
}
}
Delete Entity¶
DELETE api/v2/entity-lists/<entity_list_id>/entities
The endpoint is used to delete a single Entity or multiple Entities. The IDs of Entities to be deleted are specified with a JSON payload like this:
{
"entity_ids": [1, 2, 3]
}
entity_ids must be provided and cannot be an empty list. The items in the list must be valid IDs of Entities that are in the EntityList.
Example
curl -X DELETE https://api.ona.io/api/v2/entity-lists/1/entities \
-H "Authorization: Token ACCESS_TOKEN"
-d '{
"entity_ids": [1, 2, 3]
}'
Response
Status: 204 No Content
Import Entities from CSV¶
POST /api/v2/entity-lists/<entity_list_id>/import-entities
This endpoint is used to import multiple entities from a CSV file into an EntityList dataset. The import process is asynchronous and returns a task ID that can be used to check the import status.
The CSV file must contain columns that match the properties defined in the EntityList dataset. The following parameters are supported:
csv_file- The CSV file to import (required)label_column- The name of the column containing entity labels (optional, defaults to “label”)uuid_column- The name of the column containing entity UUIDs (optional, defaults to “uuid”)
CSV File Requirements:
Must be a valid CSV file with .csv extension
First row should contain column headers
UUID column values must be unique within the EntityList
Label column values must be non-empty strings
Note
The EntityList must have properties defined before you can import Entities. If the EntityList has no properties, the import request will fail with:
Status:
400 Bad RequestBody:
{"error": "EntityList has no properties defined"}
Example
curl -X POST https://api.ona.io/api/v2/entity-lists/1/import-entities \
-H "Authorization: Token ACCESS_TOKEN" \
-F "csv_file=@trees.csv" \
-F "label_column=label" \
-F "uuid_column=uuid"
CSV File Content Example (trees.csv):
label,species,circumference_cm,uuid
300cm purpleheart,purpleheart,300,dbee4c32-a922-451c-9df7-42f40bf78f48
200cm mora,mora,200,517185b4-bc06-450c-a6ce-44605dec5480
100cm wallaba,wallaba,100,8f2e1a3b-9c4d-4e5f-8a7b-1c2d3e4f5a6b
Response
Status: 202 Accepted
Body:
{
"task_id": "2335468b-646d-4831-b874-028431c1d339"
}
Check Import Status¶
GET /api/v2/entity-lists/<entity_list_id>/import-entities?task_id=<task_id>
This endpoint is used to check the status of an ongoing CSV import operation. Use the task_id returned from the import request to monitor progress.
Parameters:
task_id- The task ID returned from the import request (required)
Example
curl -X GET https://api.ona.io/api/v2/entity-lists/1/import-entities?task_id=2335468b-646d-4831-b874-028431c1d339 \
-H "Authorization: Token ACCESS_TOKEN"
Response
Status: 200 OK
Body:
{
"task_id": "d7b1e80b",
"state": "SUCCESS",
"result": {
"processed": 325,
"created": 300,
"updated": 25,
"errors": []
}
}
Task States
The import status endpoint returns different states depending on the progress of the import operation:
PENDING- Task is queued but not yet startedSTARTED- Task has begun processingPROGRESS- Task is actively processing rowsSUCCESS- Task completed successfullyFAILURE- Task failed with an errorRETRY- Task is being retried due to a temporary error
Error Handling
When the import task fails, the response will include error details:
CSV Validation Errors (400 Bad Request)
When CSV validation fails, the response includes specific error messages:
{
"task_id": "d7b1e80b",
"state": "FAILURE",
"result": {
"error": "CSV must include a 'label' column."
}
}
Common CSV validation errors include:
Missing required columns (label column)
Invalid CSV format
Empty label values
Duplicate UUIDs within the CSV
Invalid property values
General Import Errors (500 Internal Server Error)
For other types of failures (database errors, connection issues, etc.):
{
"task_id": "d7b1e80b",
"state": "FAILURE",
"result": {
"error": "The job failed. Please try again."
}
}
Row-Level Errors
Even when the overall import succeeds, individual rows may have errors. These are included in the success response:
{
"task_id": "d7b1e80b",
"state": "SUCCESS",
"result": {
"processed": 325,
"created": 322,
"updated": 0,
"errors": [
[4, "Invalid UUID format"],
[7, "Label cannot be empty"],
[12, "Property 'species' is required"]
]
}
}
The errors array contains tuples of [row_number, error_message] for rows that failed to import. Row numbers start from 2 (accounting for the header row). Only the first 50 errors are included in the response.