Skip to main content
Version: 2.0

Holders

Introduction

Holders (i.e. credential holders) represent end users of the access control system. In pdk.io, holders are referred to as people.

The holder object

{
"id": "8b37106e-fb08-4700-b14d-70a3967b5086",
"firstName": "John",
"lastName": "Wiegand",
"email": "john@example.com",
"photoUrl": "http://systems.pdk.io/images/b7c96600-6310-11ee-90fc-598e4a89e620",
"partition": "619cceb0-ac58-4b15-a8ec-32efcb0476ba",
"enabled": true,
"activeDate": "2023-10-04T00:00:00",
"expireDate": "2025-10-04T00:00:00",
"pin": "1234",
"duressPin": "91234",
"customFields": {
"test_custom_field": "1234567"
},
"groups": [
{
"id": "65ebe88c-865b-40c9-9d79-0c8c0d206bba",
"name": "Test Group",
"partition": "619cceb0-ac58-4b15-a8ec-32efcb0476ba"
}
],
"credentials": [
{
"id": "7500d9fb-9fe6-4a28-9cef-80850e857b83",
"holderId": "8b37106e-fb08-4700-b14d-70a3967b5086",
"credentialNumber": 1234567,
"facilityCode": null,
"description": null,
"types": ["card"]
},
{
"id": "1a936e12-f609-4dc4-8b91-d7690e5c690c",
"holderId": "8b37106e-fb08-4700-b14d-70a3967b5086",
"credentialNumber": null,
"facilityCode": null,
"description": null,
"types": ["touch", "token"]
}
]
}
PropertyTypeDescription
idStringThe holder ID.
firstNameStringThe holder's first name.
lastNameStringThe holder's last name.
emailStringThe holder's email address.
photoUrlStringThe URL of the holder's photo.
partitionStringThe ID of the partition that this holder is associated with.
enabledBooleanWhether rules will be processed for this holder.
activeDateStringThe date rules will start processing for this holder. This is formatted as YYYY-MM-DDTHH:mm:ss.
expireDateStringThe date rules will stop processing for this holder. This is formatted as YYYY-MM-DDTHH:mm:ss.
pinStringThe holder's PIN code.
duressPinStringThe holder's duress PIN code.
customFieldsObjectAn object containing custom field values for this holder.
groupsObject[]An array of group objects representing the groups this holder is assigned to.
credentialsObject[]An array of credential objects representing the credentials issued to this holder.

Basic Endpoints

Create a holder

Request

POST https://systems.pdk.io/{{system_id}}/holders HTTP/1.1
Authorization: Bearer {{system_token}}
Content-Type: application/json

{
"firstName": "John",
"lastName": "Wiegand"
}
ParameterLocationTypeRequiredDescription
system_idPathStringYesThe system ID.
system_tokenHeaderStringYesA valid system token.
firstNameBodyStringYesThe holder's first name. The maximum length is 35 characters.
lastNameBodyStringYesThe holder's last name. The maximum length is 35 characters.
emailBodyStringNoThe holder's email address.
partitionBodyStringNoThe ID of the partition that this holder should be associated with.
enabledBodyBooleanNoWhether rules should be processed for this holder. The default value is true.
activeDateBodyStringNoThe date to start processing rules for this holder. This is formatted as YYYY-MM-DDTHH:mm:ss.
expireDateBodyStringNoThe date to stop processing rules for this holder. This is formatted as YYYY-MM-DDTHH:mm:ss.
pinBodyStringNoThe holder's PIN code. Possible values include a string of digits or null.
duressPinBodyStringNoThe holder's duress PIN code. Possible values include a string of digits or null.
customFieldsBodyObjectNoAn object containing custom field values for this holder.

Response

The response contains the ID of the newly created holder object.

HTTP/1.1 201 OK
Content-Type: application/json

{
"id": "8b37106e-fb08-4700-b14d-70a3967b5086"
}

Retrieve a holder

Request

GET https://systems.pdk.io/{{system_id}}/holders/{{holder_id}} HTTP/1.1
Authorization: Bearer {{system_token}}
ParameterLocationTypeRequiredDescription
system_idPathStringYesThe system ID.
holder_idPathStringYesThe holder ID.
system_tokenHeaderStringYesA valid system token.
tip

If you need to retrieve a holder by a field other than the holder ID (e.g. email address), you can preview a holder report using the desired field as a filter.

Response

The response contains a holder object.

HTTP/1.1 200 OK
Content-Type: application/json

{
"id": "8b37106e-fb08-4700-b14d-70a3967b5086",
"firstName": "John",
"lastName": "Wiegand",
"email": "john@example.com",
"photoUrl": "http://systems.pdk.io/images/b7c96600-6310-11ee-90fc-598e4a89e620",
"partition": "619cceb0-ac58-4b15-a8ec-32efcb0476ba",
"enabled": true,
"activeDate": "2023-10-04T00:00:00",
"expireDate": "2025-10-04T00:00:00",
"pin": "1234",
"duressPin": "91234",
"customFields": {
"test_custom_field": "1234567"
},
"groups": [
{
"id": "65ebe88c-865b-40c9-9d79-0c8c0d206bba",
"name": "Test Group",
"partition": "619cceb0-ac58-4b15-a8ec-32efcb0476ba"
}
],
"credentials": [
{
"id": "7500d9fb-9fe6-4a28-9cef-80850e857b83",
"holderId": "8b37106e-fb08-4700-b14d-70a3967b5086",
"credentialNumber": 1234567,
"facilityCode": null,
"description": null,
"types": ["card"]
},
{
"id": "1a936e12-f609-4dc4-8b91-d7690e5c690c",
"holderId": "8b37106e-fb08-4700-b14d-70a3967b5086",
"credentialNumber": null,
"facilityCode": null,
"description": null,
"types": ["touch", "token"]
}
]
}

Update a holder

Request

PUT https://systems.pdk.io/{{system_id}}/holders/{{holder_id}} HTTP/1.1
Authorization: Bearer {{system_token}}
Content-Type: application/json

{
"firstName": "John",
"lastName": "Wiegand",
"partition": "619cceb0-ac58-4b15-a8ec-32efcb0476ba",
"enabled": true,
"activeDate": null,
"expireDate": null,
"pin": null,
"duressPin": null
}
ParameterLocationTypeRequiredDescription
system_idPathStringYesThe system ID.
holder_idPathStringYesThe holder ID.
system_tokenHeaderStringYesA valid system token.
firstNameBodyStringYesThe holder's first name. The maximum length is 35 characters.
lastNameBodyStringYesThe holder's last name. The maximum length is 35 characters.
emailBodyStringNoThe holder's email address.
partitionBodyStringYesThe ID of the partition that this holder should be associated with.
enabledBodyBooleanYesWhether rules should be processed for this holder. The default value is true.
activeDateBodyStringYesThe date to start processing rules for this holder. This is formatted as YYYY-MM-DDTHH:mm:ss.
expireDateBodyStringYesThe date to stop processing rules for this holder. This is formatted as YYYY-MM-DDTHH:mm:ss.
pinBodyStringYesThe holder's PIN code. Possible values include a string of digits or null.
duressPinBodyStringYesThe holder's duress PIN code. Possible values include a string of digits or null.
customFieldsBodyObjectNoAn object containing custom field values for this holder.

Response

HTTP/1.1 204 No Content

Delete a holder

Request

DELETE https://systems.pdk.io/{{system_id}}/holders/{{holder_id}} HTTP/1.1
Authorization: Bearer {{system_token}}
ParameterLocationTypeRequiredDescription
system_idPathStringYesThe system ID.
holder_idPathStringYesThe holder ID.
system_tokenHeaderStringYesA valid system token.

Response

HTTP/1.1 204 No Content

List all holders

Request

GET https://systems.pdk.io/{{system_id}}/holders HTTP/1.1
Authorization: Bearer {{system_token}}
ParameterLocationTypeRequiredDescription
system_idPathStringYesThe system ID.
includeQueryStringNoA comma-delimited list of additional properties to include in the response. Available properties include credentials, groups, partition, and rules.
pageQueryIntegerNoThe zero-based page number used for pagination. The default value is 0.
per_pageQueryIntegerNoThe number of items per page used for pagination. The default value is 10 and the maximum value is 100.
system_tokenHeaderStringYesA valid system token.

Response

The response contains an array of holder objects.

HTTP/1.1 200 OK
Content-Type: application/json

[
{
"id": "8b37106e-fb08-4700-b14d-70a3967b5086",
"firstName": "John",
"lastName": "Wiegand",
"email": "john@example.com",
"photoUrl": "http://systems.pdk.io/images/b7c96600-6310-11ee-90fc-598e4a89e620",
"partition": "619cceb0-ac58-4b15-a8ec-32efcb0476ba",
"enabled": true,
"activeDate": "2023-10-04T00:00:00",
"expireDate": "2025-10-04T00:00:00",
"pin": "1234",
"duressPin": "91234",
"customFields": {
"test_custom_field": "1234567"
},
"groups": [
{
"id": "65ebe88c-865b-40c9-9d79-0c8c0d206bba",
"name": "Test Group",
"partition": "619cceb0-ac58-4b15-a8ec-32efcb0476ba"
}
],
"credentials": [
{
"id": "7500d9fb-9fe6-4a28-9cef-80850e857b83",
"holderId": "8b37106e-fb08-4700-b14d-70a3967b5086",
"credentialNumber": 1234567,
"facilityCode": null,
"description": null,
"types": ["card"]
},
{
"id": "1a936e12-f609-4dc4-8b91-d7690e5c690c",
"holderId": "8b37106e-fb08-4700-b14d-70a3967b5086",
"credentialNumber": null,
"facilityCode": null,
"description": null,
"types": ["touch", "token"]
}
]
}
]

List all holders in a group

Request

GET https://systems.pdk.io/{{system_id}}/groups/{{group_id}}/holders HTTP/1.1
Authorization: Bearer {{system_token}}
ParameterLocationTypeRequiredDescription
system_idPathStringYesThe system ID.
group_idPathStringYesThe group ID.
pageQueryStringNoThe zero-based page number used for pagination. The default value is 0.
per_pageQueryIntegerNoThe number of items per page used for pagination. The default value is 10 and the maximum value is 100.
system_tokenHeaderStringYesA valid system token.

Response

The response contains an array of holder objects.

HTTP/1.1 200 OK
Content-Type: application/json

[
{
"id": "8b37106e-fb08-4700-b14d-70a3967b5086",
"firstName": "John",
"lastName": "Wiegand",
"email": "john@example.com",
"photoUrl": "http://systems.pdk.io/images/b7c96600-6310-11ee-90fc-598e4a89e620",
"partition": "619cceb0-ac58-4b15-a8ec-32efcb0476ba",
"enabled": true,
"activeDate": "2023-10-04T00:00:00",
"expireDate": "2025-10-04T00:00:00",
"pin": "1234",
"duressPin": "91234",
"customFields": {
"test_custom_field": "1234567"
},
"groups": [
{
"id": "65ebe88c-865b-40c9-9d79-0c8c0d206bba",
"name": "Test Group",
"partition": "619cceb0-ac58-4b15-a8ec-32efcb0476ba"
}
],
"credentials": [
{
"id": "7500d9fb-9fe6-4a28-9cef-80850e857b83",
"holderId": "8b37106e-fb08-4700-b14d-70a3967b5086",
"credentialNumber": 1234567,
"facilityCode": null,
"description": null,
"types": ["card"]
},
{
"id": "1a936e12-f609-4dc4-8b91-d7690e5c690c",
"holderId": "8b37106e-fb08-4700-b14d-70a3967b5086",
"credentialNumber": null,
"facilityCode": null,
"description": null,
"types": ["touch", "token"]
}
]
}
]

Update a holder's photo

Request

PUT https://systems.pdk.io/{{system_id}}/holders/{{holder_id}}/photo HTTP/1.1
Authorization: Bearer {{system_token}}
Content-Type: application/json

{
"base64": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHgAAAB4CAAAAAAcD2kOAAABZklEQVR4Ae3XAYnDMBTG8RqogBqIgRqogBiYgRiogBqYgRiIgBh4Bj5Rd13yIAs5uHHrGwffH2DNI+MH3cLWCR+KMGHChAkTJkz4tQgTJkyYMGHChAkTJkyYcIqDZDAXlOQevqtLiYPSr+B1GhQH84iztOnaHQDiNGi9AA7txCUrWF1tsYJ7JvwFvq2PlvqeUlJ4qYMyq5/vFoI7X2dBWktTu/v2wnHSm9jfiYAmKXvu53X29aI0dbvfC8enG5kTbGEHzRiednNY9BQd+XJ4DaUDZ27S3C5Xwv3RvLcjL3YwfDubkx2M0MtWMHJYmul1sB/8xKbgVM4mx6m1Kx2tYcjyIRjeFJZtU8qZwar5fF4d5TzhGrj/I7DXQxT0a+0vg9tinrvJnG1g6UcHbGBgn5v1fMAMhuxOlz7jLXCOj6D9+AiTyxMMnitbMp8WCRMmTJgwYcKECRMmTJgwYcKECRMmTPhfwV9kH2srWmFAYQAAAABJRU5ErkJggg=="
}
ParameterLocationTypeRequiredDescription
system_idPathStringYesThe system ID.
holder_idPathStringYesThe holder ID.
system_tokenHeaderStringYesA valid system token.
base64BodyStringYesThe photo encoded as a data URL.

Response

HTTP/1.1 204 No Content

Preview a holder file import

Request

POST https://systems.pdk.io/{{system_id}}/holders/import/preview HTTP/1.1
Authorization: Bearer {{system_token}}
Content-Type: application/json
Want-Digest: sha-265

{
"csv": "First Name,Last Name\nJohn, Wiegand\nJames, Maxwell\nMichael, Faraday"
}

ParameterLocationTypeRequiredDescription
system_idPathStringYesThe system ID.
system_tokenHeaderStringYesA valid system token.
csvBodyStringYesA CSV string containing a list of holders to be imported. A CSV template can be downloaded here.
partitionBodyStringNoThe partition ID.
upsertBodyBooleanNoWhether the import should update or delete existing records.
info

Including the Want-Digest header in the request will produce a Digest header in the response. The value provided in the Digest header will be required if conflicts need to be resolved when importing holders from a file.

Response

HTTP/1.1 200 OK
Content-Type: application/json

{
"toBeCreated": 3,
"toBeUpdated": 0,
"toBeDeleted": 0,
"conflicts": [
{
"line": 2,
"firstName": "John",
"lastName": "Wiegand",
"matches": [
{
"id": "8b37106e-fb08-4700-b14d-70a3967b5086",
"firstName": "John",
"lastName": "Wiegand"
}
]
}
]
}
PropertyTypeDescription
toBeCreatedIntegerThe number of holders that would be created by this import.
toBeUpdatedIntegerThe number of holders that would be updated by this import.
toBeDeletedIntegerThe number of holders that would be deleted by this import.
conflictsObject[]A list of conflicts that will need to be resolved when executing this import.
conflicts.lineIntegerThe line number of the conflict.
conflicts.idStringThe ID of the holder associated with the conflict.
conflicts.firstNameStringThe first name of the holder associated with the conflict.
conflicts.lastNameStringThe last name of the holder associated with the conflict.
conflicts.matchesObject[]An array of conflicting holder objects. Note that only the id, firstName, and lastName properties are included.

Import holders from a file

tip

This endpoint is intended for one-time import operations (e.g. importing records from an old access control system). Ongoing data synchronization should be implemented using individual requests, which are more efficient and allow for more granular error handling.

Request

POST https://systems.pdk.io/{{system_id}}/holders/import HTTP/1.1
Authorization: Bearer {{system_token}}
Digest: {{digest}}
Content-Type: application/json

{
"csv": "First Name,Last Name\nJohn, Wiegand\nJames, Maxwell\nMichael, Faraday",
"resolutions": [
{
"line": 2,
"decision": "skip"
}
]
}
ParameterLocationTypeRequiredDescription
system_idPathStringYesThe system ID.
system_tokenHeaderStringYesA valid system token.
digestHeaderStringSometimesThe digest value obtained from the Digest header in the response of the preview a holder file import endpoint. This is required if the import has conflicts that need to be resolved.
csvBodyStringYesA CSV string containing a list of holders to be imported. A CSV template can be downloaded here.
resolutionsBodyObject[]SometimesAn array of objects describing how individual conflicts should be handled. This is required if the import has conflicts that need to be resolved.
resolutions.lineBodyIntegerYesThe line number of the conflict.
resolutions.decisionBodyStringYesHow the conflict should be handled. Possible values include create, update, delete, and skip.
partitionBodyStringNoThe partition ID.
upsertBodyBooleanNoWhether the import should update or delete existing records.

Response

The response contains an array of holder objects representing the holders that were created or updated.

HTTP/1.1 200 OK
Content-Type: application/json

[
{
"id": "8b37106e-fb08-4700-b14d-70a3967b5086",
"email": null,
"firstName": "John",
"lastName": "Wiegand",
"groups": [],
"credentials": [],
"enabled": true,
"partition": "619cceb0-ac58-4b15-a8ec-32efcb0476ba",
"cards": []
},
{
"id": "069f32ab-13f3-41e5-9a3f-7ab728d8184f",
"email": null,
"firstName": "James",
"lastName": "Maxwell",
"groups": [],
"credentials": [],
"enabled": true,
"partition": "619cceb0-ac58-4b15-a8ec-32efcb0476ba",
"cards": []
},
{
"id": "8cd9992c-cb9c-4d07-ac3a-5c5e8165266a",
"email": null,
"firstName": "Michael",
"lastName": "Faraday",
"groups": [],
"credentials": [],
"enabled": true,
"partition": "619cceb0-ac58-4b15-a8ec-32efcb0476ba",
"cards": []
}
]

Delete many holders

Request

POST https://systems.pdk.io/{{system_id}}/holders/bulk-delete HTTP/1.1
Authorization: Bearer {{system_token}}
Content-Type: application/json

{
"holders": [
"8b37106e-fb08-4700-b14d-70a3967b5086",
"069f32ab-13f3-41e5-9a3f-7ab728d8184f",
"8cd9992c-cb9c-4d07-ac3a-5c5e8165266a"
]
}
ParameterLocationTypeRequiredDescription
system_idPathStringYesThe system ID.
system_tokenHeaderStringYesA valid system token.
holdersBodyString[]YesA list of holder IDs representing holders who should be deleted.

Response

HTTP/1.1 200 OK
Content-Type: application/json

{
"deleted": [
"8b37106e-fb08-4700-b14d-70a3967b5086",
"069f32ab-13f3-41e5-9a3f-7ab728d8184f",
"8cd9992c-cb9c-4d07-ac3a-5c5e8165266a"
]
}
PropertyTypeDescription
deletedString[]A list of holder IDs representing holders who were deleted.