Entity Management¶
(introduced: version 2023.3)
⚠️ In this API and in the related ODK XForms specification, collections of
Entities
are referred to asDatasets
. The term "Entity List" is used for this concept in the Central frontend UI, user facing documentation, and all other text intended for end users who are not developers.
Entities are data objects that can be shared between Forms to support workflows with multiple steps. They can be created either through form design or through this API. A collection of Entities
is a Dataset.
Entities Metadata¶
GET /projects/{projectId}/datasets/{name}/entities
This endpoint returns a list of the Entities of a Dataset. Please note that this endpoint only returns metadata of the entities not the data. If you want to get the data of all entities then please refer to OData Dataset ServiceYou can provide ?deleted=true
to get only deleted entities.
Request
Parameters
projectId |
The numeric ID of the Project Example: |
name |
Name of the Dataset Example: |
Response
HTTP Status: 200
Content Type: application/json
[
{
"uuid": "uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44",
"createdAt": "2018-01-19T23:58:03.395Z",
"updatedAt": "2018-03-21T12:45:02.312Z",
"deletedAt": "2018-03-21T12:45:02.312Z",
"creatorId": 1,
"currentVersion": {
"label": "John (88)",
"current": true,
"createdAt": "2018-03-21T12:45:02.312Z",
"creatorId": 1,
"userAgent": "Enketo/3.0.4",
"version": 1,
"baseVersion": null,
"branchId": null,
"trunkVersion": null,
"branchBaseVersion": null,
"conflictingProperties": null
}
}
]
array
|
HTTP Status: 200
Content Type: application/json; extended
[
{
"uuid": "uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44",
"createdAt": "2018-01-19T23:58:03.395Z",
"updatedAt": "2018-03-21T12:45:02.312Z",
"deletedAt": "2018-03-21T12:45:02.312Z",
"creatorId": 1,
"conflict": null,
"creator": {
"createdAt": "2018-04-18T23:19:14.802Z",
"displayName": "My Display Name",
"id": 115,
"type": "user",
"updatedAt": "2018-04-18T23:42:11.406Z",
"deletedAt": "2018-04-18T23:42:11.406Z"
},
"currentVersion": {
"label": "John (88)",
"current": true,
"createdAt": "2018-03-21T12:45:02.312Z",
"creatorId": 1,
"userAgent": "Enketo/3.0.4",
"version": 1,
"baseVersion": null,
"branchId": null,
"trunkVersion": null,
"branchBaseVersion": null,
"conflictingProperties": null,
"creator": {
"createdAt": "2018-04-18T23:19:14.802Z",
"displayName": "My Display Name",
"id": 115,
"type": "user",
"updatedAt": "2018-04-18T23:42:11.406Z",
"deletedAt": "2018-04-18T23:42:11.406Z"
}
}
}
]
array
|
HTTP Status: 403
Content Type: application/json
{
"code": 403.1,
"message": "The authenticated actor does not have rights to perform that action."
}
object
|
Creating Entities¶
POST /projects/{projectId}/datasets/{name}/entities
Creates one or more Entities in the Dataset.
For creating a single Entity, the request body takes a JSON representation of the Entity, which has the following properties:
- A
data
object containing values for the user-defined Dataset properties. (Not all properties have to have values.) - A
label
property, which cannot be blank or an empty string. (This is used as a human-readable label in Forms that consume Entities.) - An optional
uuid
property. If theuuid
is not specified, Central will generate a UUID for an Entity with the provided data and label.
{ "label": "John Doe", "data": { "firstName": "John", "age": "22" } }
The value type of all properties is string
.
For creating multiple Entities in bulk, the request body takes an array entities
containing a list of Entity objects as described above. The bulk entity version also takes a source
property with a required name
field and optional size
, for example to capture the filename and size of a bulk upload source.
{ "entities": [...], "source": {"name": "file.csv", "size": 100} }
You can provide header X-Action-Notes
to store the metadata about the request. The metadata can retrieved using Entity Audit Log
Request
Parameters
projectId |
The numeric ID of the Project Example: |
name |
Name of the Dataset Example: |
Request body
{
"entities": [
{
"uuid": "54a405a0-53ce-4748-9788-d23a30cc3afa",
"label": "John Doe (22)",
"data": {
"firstName": "John",
"age": "22"
}
},
{
"uuid": "0c3a7922-b611-42ca-a961-944e09fa9aa2",
"label": "Amy Jane (38)",
"data": {
"firstName": "Amy",
"age": "38"
}
}
],
"source": {
"name": "my_dataset.csv",
"size": 100
}
}
object
|
object
|
Response
HTTP Status: 200
Content Type: application/json
{
"uuid": "uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44",
"createdAt": "2018-01-19T23:58:03.395Z",
"updatedAt": "2018-03-21T12:45:02.312Z",
"deletedAt": "2018-03-21T12:45:02.312Z",
"creatorId": 1,
"conflict": null,
"currentVersion": {
"label": "John (88)",
"current": true,
"createdAt": "2018-03-21T12:45:02.312Z",
"creatorId": 1,
"userAgent": "Enketo/3.0.4",
"conflictingProperties": null,
"version": 1,
"baseVersion": null,
"branchId": null,
"trunkVersion": null,
"branchBaseVersion": null,
"data": {
"firstName": "John",
"age": "88"
},
"dataReceived": {
"label": "John (88)",
"firstName": "John",
"age": "88"
}
}
}
object
|
HTTP Status: 403
Content Type: application/json
{
"code": 403.1,
"message": "The authenticated actor does not have rights to perform that action."
}
object
|
Getting Entity Details¶
GET /projects/{projectId}/datasets/{name}/entities/{uuid}
This returns the metadata and current data of an Entity.
The data and label of an Entity are found in the currentVersion
object under data
and label
respectively. The currentVersion
object also contains version-specific metadata fields such as version
, baseVersion
, details about conflicts that version introduced, etc. See the versions endpoint for more details.
The Entity also contains top-level system metadata such as uuid
, createdAt
and updatedAt
timestamps, and creatorId
(or full creator
if extended metadata is requested).
Conflicts
An Entity's metadata also has a conflict
field, which indicates the current conflict status of the Entity. The value of a conflict can either be:
null
. The Entity does not have conflicting versions.soft
. The Entity has a version that was based on a version other than the version immediately prior to it. (The specifiedbaseVerson
was not the latest version on the server.)hard
. The Entity has a version that was based on a version other than the version immediately prior to it. Further, that version updated the same property as another update.
If an Entity has a conflict, it can be marked as resolved. After that, the conflict field will be null until a new conflicting version is received.
Request
Parameters
projectId |
The numeric ID of the Project Example: |
name |
Name of the Dataset Example: |
uuid |
UUID of the Entity Example: |
Response
HTTP Status: 200
Content Type: application/json
{
"uuid": "uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44",
"createdAt": "2018-01-19T23:58:03.395Z",
"updatedAt": "2018-03-21T12:45:02.312Z",
"deletedAt": "2018-03-21T12:45:02.312Z",
"creatorId": 1,
"conflict": null,
"currentVersion": {
"label": "John (88)",
"current": true,
"createdAt": "2018-03-21T12:45:02.312Z",
"creatorId": 1,
"userAgent": "Enketo/3.0.4",
"conflictingProperties": null,
"version": 1,
"baseVersion": null,
"branchId": null,
"trunkVersion": null,
"branchBaseVersion": null,
"data": {
"firstName": "John",
"age": "88"
},
"dataReceived": {
"firstName": "John",
"age": "88",
"label": "John (88)"
}
}
}
array
|
HTTP Status: 200
Content Type: application/json; extended
{
"uuid": "uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44",
"createdAt": "2018-01-19T23:58:03.395Z",
"updatedAt": "2018-03-21T12:45:02.312Z",
"deletedAt": "2018-03-21T12:45:02.312Z",
"creatorId": 1,
"conflict": null,
"creator": {
"createdAt": "2018-04-18T23:19:14.802Z",
"displayName": "My Display Name",
"id": 115,
"type": "user",
"updatedAt": "2018-04-18T23:42:11.406Z",
"deletedAt": "2018-04-18T23:42:11.406Z"
},
"currentVersion": {
"label": "John (88)",
"current": true,
"createdAt": "2018-03-21T12:45:02.312Z",
"creatorId": 1,
"userAgent": "Enketo/3.0.4",
"conflictingProperties": null,
"version": 1,
"baseVersion": null,
"branchId": null,
"trunkVersion": null,
"branchBaseVersion": null,
"data": {
"firstName": "John",
"age": "88"
},
"dataReceived": {
"firstName": "John",
"age": "88",
"label": "John (88)"
},
"creator": {
"createdAt": "2018-04-18T23:19:14.802Z",
"displayName": "My Display Name",
"id": 115,
"type": "user",
"updatedAt": "2018-04-18T23:42:11.406Z",
"deletedAt": "2018-04-18T23:42:11.406Z"
}
}
}
array
|
HTTP Status: 403
Content Type: application/json
{
"code": 403.1,
"message": "The authenticated actor does not have rights to perform that action."
}
object
|
Deleting an Entity¶
DELETE /projects/{projectId}/datasets/{name}/entities/{uuid}
Use this API to delete an Entity. With this API, Entity is soft-deleted, which means it is still in the database and you can retreive it by passing ?deleted=true
to GET /projects/:id/datasets/:name/entities. In the future, we will provide a way to restore deleted entities and purge deleted entities.
Request
Parameters
projectId |
The numeric ID of the Project Example: |
name |
Name of the Dataset Example: |
uuid |
UUID of the Entity Example: |
Response
HTTP Status: 200
Content Type: application/json
{
"success": true
}
object
|
HTTP Status: 403
Content Type: application/json
{
"code": 403.1,
"message": "The authenticated actor does not have rights to perform that action."
}
object
|
Updating an Entity¶
PATCH /projects/{projectId}/datasets/{name}/entities/{uuid}
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 (""). The label must be a non-empty string. Setting a property to null
will throw an error. Attempting to update a property that doesn't exist in the Dataset will throw an error.
Specifying a base version
You must either provide the query parameter baseVersion
or use the force=true
query parameter. The specified baseVersion
must match the current version of the Entity on the server or the request will be rejected. This acts as a check to ensure you are not trying to update based on stale data. To update an Entity regardless of its current state, use the force
flag with value true
.
Resolving a conflict
You can also use this endpoint to resolve an Entity conflict by passing the resolve=true
query parameter, in which case providing data in the request body is optional. When not providing new data, only the conflict
status from the Entity will be cleared and no new version will be created. When providing data, the conflict
will be cleared and an updated version of the Entity will be added.
Request
Parameters
projectId |
The numeric ID of the Project Example: |
name |
Name of the Dataset Example: |
uuid |
UUID of the Entity Example: |
baseVersion (query) |
The base version of the Entity you are applying the update to (must match the latest version on the server) Example: |
force (query) |
Flag to forcefully update the Entity Example: |
resolve (query) |
Flag to resolve the conflict Example: |
Request body
{
"label": "John Doe (88)",
"data": {
"firstName": "John",
"age": "88"
}
}
object
|
Response
HTTP Status: 200
Content Type: application/json
{
"uuid": "uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44",
"createdAt": "2018-01-19T23:58:03.395Z",
"updatedAt": "2018-03-21T12:45:02.312Z",
"deletedAt": "2018-03-21T12:45:02.312Z",
"creatorId": 1,
"conflict": null,
"currentVersion": {
"label": "John (88)",
"current": true,
"createdAt": "2018-03-21T12:45:02.312Z",
"creatorId": 1,
"userAgent": "Enketo/3.0.4",
"conflictingProperties": null,
"version": 1,
"baseVersion": null,
"branchId": null,
"trunkVersion": null,
"branchBaseVersion": null,
"data": {
"firstName": "John",
"age": "88"
},
"dataReceived": {
"firstName": "John",
"age": "88",
"label": "John (88)"
}
}
}
object
|
HTTP Status: 403
Content Type: application/json
{
"code": 403.1,
"message": "The authenticated actor does not have rights to perform that action."
}
object
|
Listing Versions¶
GET /projects/{projectId}/datasets/{name}/entities/{uuid}/versions
This returns the Entity metadata and data for every version of this Entity, in ascending creation order.
This endpoint supports retrieving extended metadata; provide a header X-Extended-Metadata: true
to return a creator
data object alongside the creatorId
Actor ID reference.
There is an optional query flag relevantToConflict
that returns the subset of past versions of an Entity that are relevant to the Entity's current conflict. This includes the latest version, the base version, the previous server version, and any other versions since the last time the Entity was in a conflict-free state. If the Entity is not in conflict, zero versions are returned.
Request
Parameters
projectId |
The numeric ID of the Project Example: |
name |
Name of the Dataset Example: |
uuid |
UUID of the Entity Example: |
relevantToConflict (query) |
Flag to return only the versions of the entity that are relevant to the current conflict. Example: |
Response
HTTP Status: 200
Content Type: application/json
[
{
"label": "John (88)",
"current": true,
"createdAt": "2018-03-21T12:45:02.312Z",
"creatorId": 1,
"userAgent": "Enketo/3.0.4",
"version": 1,
"baseVersion": null,
"branchId": null,
"trunkVersion": null,
"branchBaseVersion": null,
"conflict": null,
"resolved": false,
"lastGoodVersion": true,
"relevantToConflict": false,
"conflictingProperties": null,
"baseDiff": [],
"serverDiff": [],
"source": "// Similar to Audit.details. This property is experimental and may change in the future.",
"data": {
"firstName": "John",
"age": "88"
},
"dataReceived": {
"firstName": "John",
"age": "88",
"label": "John (88)"
}
}
]
array
|
HTTP Status: 200
Content Type: application/json; extended
[
{
"label": "John (88)",
"current": true,
"createdAt": "2018-03-21T12:45:02.312Z",
"creatorId": 1,
"userAgent": "Enketo/3.0.4",
"version": 1,
"baseVersion": null,
"branchId": null,
"trunkVersion": null,
"branchBaseVersion": null,
"conflict": null,
"resolved": false,
"lastGoodVersion": true,
"relevantToConflict": false,
"conflictingProperties": null,
"baseDiff": [],
"serverDiff": [],
"source": "// Similar to Audit.details. This property is experimental and may change in the future.",
"data": {
"firstName": "John",
"age": "88"
},
"dataReceived": {
"firstName": "John",
"age": "88",
"label": "John (88)"
},
"creator": {
"createdAt": "2018-04-18T23:19:14.802Z",
"displayName": "My Display Name",
"id": 115,
"type": "user",
"updatedAt": "2018-04-18T23:42:11.406Z",
"deletedAt": "2018-04-18T23:42:11.406Z"
}
}
]
array
|
HTTP Status: 403
Content Type: application/json
{
"code": 403.1,
"message": "The authenticated actor does not have rights to perform that action."
}
object
|
Getting changes between Versions¶
GET /projects/{projectId}/datasets/{name}/entities/{uuid}/diffs
This returns the changes, or edits, between different versions of an Entity. These changes are returned as an array of arrays. Between two Entities, there is an array of objects representing how each property changed. This change object contains the old and new values, as well as the property name.
Request
Parameters
projectId |
The numeric ID of the Project Example: |
name |
Name of the Dataset Example: |
uuid |
UUID of the Entity Example: |
Response
HTTP Status: 200
Content Type: application/json
[
[
{
"new": "John",
"old": "Dana",
"propertyName": "firstName"
},
{
"new": "Doe",
"old": "Roe",
"propertyName": "lastName"
},
{
"new": "John Doe",
"old": "Jane Roe",
"propertyName": "label"
}
],
[
{
"new": "Robert",
"old": "Doe",
"propertyName": "firstName"
},
{
"new": "Robert Doe",
"old": "Doe Doe",
"propertyName": "label"
}
]
]
array
|
HTTP Status: 403
Content Type: application/json
{
"code": 403.1,
"message": "The authenticated actor does not have rights to perform that action."
}
object
|
Entity Audit Log¶
GET /projects/{projectId}/datasets/{name}/entities/{uuid}/audits
Returns Server Audit Logs relating to an Entity. They will be returned most recent first.
Request
Parameters
projectId |
The numeric ID of the Project Example: |
name |
Name of the Dataset Example: |
uuid |
UUID of the Entity Example: |
Response
HTTP Status: 200
Content Type: application/json
[
{
"actorId": 42,
"action": "entity.create",
"acteeId": "85cb9aff-005e-4edd-9739-dc9c1a829c44",
"loggedAt": "2018-04-18T23:19:14.802Z"
}
]
array
|
HTTP Status: 403
Content Type: application/json
{
"code": 403.1,
"message": "The authenticated actor does not have rights to perform that action."
}
object
|