The Coly API Documentation provides descriptive information for developers who would like to integrate the functionality of the Coly API into their solution.
The Coly engine is provided in four simple steps.
The API endpoints are documented in the same order as the user flow above.
Go to API section to get started!
Our data models have several types(or layers) that define our approach. Simply speaking, the data lifecycle reveals steps and actions that should be taken to reach them.
Diagram1: Visualisation of model dependencies
Core-level models contain crucial data for system operations.
Created
- Creating an empty tenant record.Updated
- Update client's payload data.Joined2Unit
- Creates new Assignment
records thus linking Tenant
and Unit
.LeftUnit
- Set's Assignment
record as inactiveArchived
- Changes record access rights, thus making it read-only
. No updates or any other actions than recovery are available. At the end of the predefined archive record lifetime, it moves to the state Disabled
Disabled
- Restricts any further public access to data. Life-time defined by coly data retention policy.Anonymised
- Record is being stripped from personal or any sensitive information. Further access is intended solely for the ML training unit.
Created
- Creating empty unit record.Updated
- Update client's payload data.TenantJoined
- Creates new Assignment
record thus linking Tenant
and Unit
.TenantLeft
- Set's Assignment
record as inactive.Archived
- Changes record access rights, thus making it read-only
. No updates or any other actions than recovery are available. At the end of the predefined archive record lifetime, it moves to the state Disabled
.Disabled
- Restricts any further public access to data. Life-time defined by coly data retention policy.Anonymised
- Record is being stripped from personal or any sensitive information. Further access is intended solely for the ML training unit.
Base API URL:
xxxxxxxxxx
https://me-api.coly.io/v1
To connect with our API, you will need to generate an API key. Please follow these steps:
After obtaining the API key, include it in all requests by setting the Authorization header as follows:
xxxxxxxxxx
Authorization: Application {yourApiKey}
Remember to replace {yourApiKey}
with your actual API key.
For example:
xxxxxxxxxx
Authorization: Application TfdZmYRpqVbqaHQoMMWKokbGLQPSvYzgjOhHwtRZJWZTeAObAaDbYzVKpnsjiqmf
API Versioning:
The current version of our API is indicated by the v1
prefix in the base URL. This means all endpoints are accessed under this version. Should there be a transition to a new version (e.g., v2
), we will provide advance notice and ensure backward compatibility, allowing continued access to v1
endpoints.
Our API leverages the Either pattern, a common approach in functional programming, to standardize the structure of all responses. This strategy enables the API to always return a 200 status code, regardless of whether the operation was successful. The outcome of the operation is conveyed in the response's type field, which can be either 'success' or 'failure'.
Note: While the following example uses TypeScript, the 'Either' pattern is language-agnostic and can be adapted to your preferred programming language:
xinterface Success<T> {
type: 'success';
value: T;
}
interface Failure<E> {
type: 'failure';
value: E;
}
type Either<E, T> = Failure<E> | Success<T>;
In every response, you'll find the data property structured as one of the following:
xxxxxxxxxx
// Successful response:
{
"type": "success",
"value": { } // The requested data
}
// Failed response:
{
"type": "failure",
"value": { } // Error data
}
The value of a successfull response will vary across different requests, but all error messages will conform to this structure:
xxxxxxxxxx
interface Error {
code: FailCode;
message: string;
}
In this format, the message field provides a human-readable explanation primarily for debugging. However, it may change over time, so it should not be relied upon for application logic. On the other hand, the FailCode
is a unique, constant identifier for a specific type of failure and can be used to handle errors in your application.
Every API endpoint will provide a list of possible FailCodes for each request.
Here are examples of a successful and a failed request:
xxxxxxxxxx
// Successful request
GET http://localhost:7001/v1/tenants?search=adam
// Successful response
{
"type": "success",
"value": {
"total": 1,
"list": [ { } ] // List of data
}
}
xxxxxxxxxx
// Failed request
GET http://localhost:7001/v1/tenants/abdca582-43d1-4dd8-f652-ad63451a75ad
xxxxxxxxxx
// Failed response
{
"type": "failure",
"value": {
"code": "Tenant::NotFound",
"message": "Specified tenant record wasn't found."
}
}
One common FailCode for all requests is InputValidation::Failed
, which signifies an issue with the request body format. Example:
xxxxxxxxxx
{
"type": "failure",
"value": {
"code": "InputValidation::Failed",
"message": "[Description of the validation fail]"
}
}
For the remainder of this API documentation, we will describe the structure of the 'value' field and the potential FailCodes for each request.
Although almost all requests return a 200 status code, there are a few exceptions:
404
: The requested route doesn't exist.401
: The provided API key is invalid.500
: A system error occurred on our side. This is unintentional and will be addressed promptly. If this happens please get in touch with the team at Coly.
For any of the entities below (tenant
and unit
), the following query params are supported when fetching from the backend:
pageSize
: The number of records to return per page. This is used for pagination purposes. This field is mandatory.pageNumber
: The page number to return. This is used in conjunction with pageSize
for pagination. This field is mandatory.sortDirection
: The sorting direction, either asc
for ascending or desc
for descending. This is optional, and will default to asc
.
Example:
xxxxxxxxxx
GET /tenants?pageSize=20&pageNumber=1&sortDirection=asc
The Tenants
entity mainly refers to the tenants within a shared living space, or tenants taking the Psychometry Assessment
using our product. Each tenant will have their personality
and coreValues
traits calculated after taking the assessment. The score they get will play a key role in matching the individual to a specific unit.
Creates Tenants
record and returns it. It requires email
, firstname
, lastname
to create a Tenants
record.
xxxxxxxxxx
POST /tenants
xxxxxxxxxx
{
"email": "james.bond@mymail.com",
"lastname": "Bond",
"firstname": "James"
}
xxxxxxxxxx
{
"id": "993abaa6-693b-456d-b58b-424057c5f0e3",
"createdAt": "2022-11-20T17:55:41.266Z",
"createdBy": "72d6943c-2b64-43bf-8c38-93c83dc4edab",
"updatedAt": "2022-11-20T17:55:41.266Z",
"updatedBy": "72d6943c-2b64-43bf-8c38-93c83dc4edab",
"archivedAt": null,
"archivedBy": null,
"firstname": "James",
"lastname": "Bond",
"email": "james.bond@mymail.com",
"gender": null,
"language": null,
"country": null,
"birthDate": null,
"psychometry": null
}
Retrieve a single tenant's record with all the detailed pieces of information that you need.
xxxxxxxxxx
GET /tenants/:id
xxxxxxxxxx
{
"id": "11131f6e-5654-4d72-bff0-b4d60b1c9b3a",
"createdAt": "2022-10-19T19:37:03.602Z",
"createdBy": "72d6943c-2b64-43bf-8c38-93c83dc4edab",
"updatedAt": "2022-10-19T19:37:03.602Z",
"updatedBy": "72d6943c-2b64-43bf-8c38-93c83dc4edab",
"archivedAt": null,
"archivedBy": null,
"firstname": "Lucy",
"lastname": "Carlson",
"email": "lucy.carlson@mymail.com",
"gender": null,
"language": null,
"country": null,
"birthDate": null,
"psychometry": {
"traits": {
"personality": {
"emotionalStability": 100,
"conscientiousness": 100,
"agreeableness": 100,
"extroversion": 100,
"openness": 100
},
"coreValues": {
"selfDirection": 68.1000781861,
"universalism": 25.6450351837,
"achievement": 90.2267396403,
"benevolence": 38.7802971071,
"conformity": 67.4745895231,
"tradition": 88.8975762314,
"security": 88.4284597342,
"hedonism": 64.7380766224,
"activity": 63.6434714621,
"power": 93.6669272869
}
},
"submittedAt": "2022-10-19T19:47:03.891Z",
},
"assignment": {
"assignedAt": "2024-01-22T11:26:29.217Z",
"assignedBy": "b2555444-5071-7005-4e38-fe7a4f084987",
"moveInAt": "2024-01-22T00:00:00.000Z",
"unit": {
"id": "ea5d0c05-c43f-408c-a650-288e3674c35c",
"createdAt": "2024-01-22T11:26:21.716Z",
"createdBy": "b2555444-5071-7005-4e38-fe7a4f084987",
"updatedAt": "2024-01-22T11:26:29.224Z",
"updatedBy": "b2555444-5071-7005-4e38-fe7a4f084987",
"archivedAt": null,
"archivedBy": null,
"title": "Spruce St 66",
"capacity": 4,
"members": 1,
"status": "Vacant"
}
}
}
Retrieves the list of tenant's records, with the total number of Tenants
and their detailed pieces of information.
xxxxxxxxxx
GET /tenants
xxxxxxxxxx
{
"total": 1,
"list": [
{
"id": "11131f6e-5654-4d72-bff0-b4d60b1c9b3a",
"createdAt": "2022-10-19T19:37:03.602Z",
"createdBy": "72d6943c-2b64-43bf-8c38-93c83dc4edab",
"updatedAt": "2022-10-19T19:37:03.602Z",
"updatedBy": "72d6943c-2b64-43bf-8c38-93c83dc4edab",
"archivedAt": null,
"archivedBy": null,
"firstname": "John",
"lastname": "Doe",
"email": "john.doe@coly.io",
"gender": null,
"language": null,
"country": null,
"birthDate": null,
"psychometry": {
"traits": {
"personality": {
"emotionalStability": 100,
"conscientiousness": 100,
"agreeableness": 100,
"extroversion": 100,
"openness": 100
},
"coreValues": {
"selfDirection": 68.1000781861,
"universalism": 25.6450351837,
"achievement": 90.2267396403,
"benevolence": 38.7802971071,
"conformity": 67.4745895231,
"tradition": 88.8975762314,
"security": 88.4284597342,
"hedonism": 64.7380766224,
"activity": 63.6434714621,
"power": 93.6669272869
}
},
"submittedAt": "2022-10-19T19:47:03.891Z",
}
}
],
"isDone": false
}
include units in tenants with the following query param
xxxxxxxxxx
GET /tenants?relations[]=unit
Tenants
record fields and returns updated tenant record.Psychometric Assessment
exists.xxxxxxxxxx
PUT /tenants/:id
xxxxxxxxxx
{
"email": "james.dean@mymail.com",
"lastname": "Dean",
"firstname": "James"
}
xxxxxxxxxx
{
"id": "993abaa6-693b-456d-b58b-424057c5f0e3",
"createdAt": "2022-11-20T17:55:41.266Z",
"createdBy": "72d6943c-2b64-43bf-8c38-93c83dc4edab",
"updatedAt": "2022-11-20T17:55:41.266Z",
"updatedBy": "72d6943c-2b64-43bf-8c38-93c83dc4edab",
"archivedAt": null,
"archivedBy": null,
"firstname": "James",
"lastname": "Dean",
"email": "james.dean@mymail.com",
"gender": null,
"language": null,
"country": null,
"birthDate": null,
"psychometry": null
}
Archive Tenants
record status.
xxxxxxxxxx
PATCH /tenants/:id/archive
xxxxxxxxxx
{
"id": "993abaa6-693b-456d-b58b-424057c5f0e3",
"createdAt": "2022-11-20T17:55:41.266Z",
"createdBy": "72d6943c-2b64-43bf-8c38-93c83dc4edab",
"updatedAt": "2022-11-20T17:55:41.266Z",
"updatedBy": "72d6943c-2b64-43bf-8c38-93c83dc4edab",
"archivedAt": "2022-11-20T18:10:01.449Z",
"archivedBy": "72d6943c-2b64-43bf-8c38-93c83dc4edab",
"firstname": "James",
"lastname": "Dean",
"email": "james.dean@mymail.com",
"gender": null,
"language": null,
"country": null,
"birthDate": null,
"psychometry": {
"traits": {
"personality": {
"emotionalStability": 10.7896794371,
"conscientiousness": 2.7365129007,
"agreeableness": 0.5473025801,
"extroversion": 11.6497263487,
"openness": 9.3041438624
},
"coreValues": {
"selfDirection": 11.493354183,
"universalism": 0.7036747459,
"achievement": 41.2822517592,
"benevolence": 1.0946051603,
"conformity": 2.1892103206,
"tradition": 47.3025801407,
"security": 10.6333072713,
"hedonism": 1.8764659891,
"activity": 1.4073494918,
"power": 7.662236122
}
},
"submittedAt": "2023-05-19T11:34:04.535Z",
}
}
Restores a Tenants
record from the archive.
xxxxxxxxxx
PATCH /tenants/:id/restore
xxxxxxxxxx
{
"id": "993abaa6-693b-456d-b58b-424057c5f0e3",
"createdAt": "2022-11-20T17:55:41.266Z",
"createdBy": "72d6943c-2b64-43bf-8c38-93c83dc4edab",
"updatedAt": "2022-11-20T17:55:41.266Z",
"updatedBy": "72d6943c-2b64-43bf-8c38-93c83dc4edab",
"archivedAt": null,
"archivedBy": null,
"firstname": "James",
"lastname": "Dean",
"email": "james.dean@mymail.com",
"gender": null,
"language": null,
"country": null,
"birthDate": null,
"psychometry": null
}
Disabling and deleting Tenants
record from archived.
xxxxxxxxxx
DELETE /tenants/:id
Note that only the archived records can be deleted.
When the desired record is missing:
xxxxxxxxxx
Tenant::NotFound
When creating a Tenant
record, the user's email should be unique and not be reused unless the tenant has been removed from the platform:
xxxxxxxxxx
User::EmailUsed
(Note that this error is prefixed with User
, as it applies system-wide to any type of user.)
For archived records, they are not allowed to be matched, or assigned to units. To achieve this, you would need to restore the record first:
xxxxxxxxxx
Tenant::ArchiveStatusRestriction
For non-archived records, you would have to archive the record first to disable/delete it:
xxxxxxxxxx
Tenant::ArchiveStatusRequired
If there is a case of an unknown Error
, there is a high chance of server-side error. Contact us through our email dev@coly.io with detailed information about the error:
xxxxxxxxxx
Tenant::Unknown
To initiate the assessment process for a tenant, use the endpoint below. This action triggers an automated email sequence to encourage the tenant to complete their psychometric assessment. The sequence includes an initial invitation followed by reminders if the assessment isn't completed within specific intervals.
xxxxxxxxxx
POST /notifications/invite/tenant
Behavior:
Upon invoking this endpoint, an email is dispatched to the specified tenant, marking the commencement of a notification chain. If the tenant does not complete the assessment within 3 days, they receive a follow-up reminder. A final reminder is sent if the assessment remains incomplete 5 days after the initial email. Triggering this endpoint for a tenant will reset any existing reminder sequences for them, starting the process anew.
xxxxxxxxxx
{
"tenantId": "5a7cc372-8d04-4d33-8186-41416ebd41e5",
}
A successful request returns {"type": "success"}
, indicating the email sequence has been initiated. If the tenant cannot be found, the response will be {"type": "failure"}
, accompanied by a failcode of Tenant::NotFound
.
The Units
entity is a collection of Tenants
. Usually refers to a unit of Tenants
who live in a shared living space. A unit is created by title
and capacity
. A unit with tenants contains a calculated average score of the personality
and coreValues
, scale that can be used to match an incoming tenant.
Creates Unit
record and returns it. It requires a Unit name
and a capacity
of tenants for the unit.
xxxxxxxxxx
POST /units
xxxxxxxxxx
{
"title": "Apartment A",
"capacity": 4,
}
xxxxxxxxxx
{
"id": "8291747b-f415-4854-95ff-40c43919201c",
"createdAt": "2022-11-17T21:13:37.601Z",
"createdBy": "72d6943c-2b64-43bf-8c38-93c83dc4edab",
"updatedAt": "2022-11-17T21:13:37.601Z",
"updatedBy": "72d6943c-2b64-43bf-8c38-93c83dc4edab",
"archivedAt": null,
"archivedBy": null,
"title": "Apartment A",
"capacity": 4,
"psychometry": null
}
Retrieve a single Unit
record with all the detailed pieces of information that you need, including personality
and coreValues
percentile.
xxxxxxxxxx
GET /units/:id
xxxxxxxxxx
{
"id": "c35321c0-a788-46f4-8e8a-b11007915275",
"createdAt": "2023-05-29T16:32:59.828Z",
"createdBy": "f892369b-1cab-4d8c-b24f-4603010975b9",
"updatedAt": "2023-05-29T16:32:59.828Z",
"updatedBy": "f892369b-1cab-4d8c-b24f-4603010975b9",
"archivedAt": null,
"archivedBy": null,
"title": "Highfield Avenue",
"capacity": 6,
"members": 4,
"status": "Vacant",
"psychometry": {
"completeness": 1,
"traits": {
"personality": {
"emotionalStability": 18.7255668491,
"conscientiousness": 8.3072713057,
"agreeableness": 4.339327599675,
"extroversion": 7.46677091475,
"openness": 7.54495699765
},
"coreValues": {
"selfDirection": 13.623924941350001,
"universalism": 3.479280688,
"achievement": 5.531665363575,
"benevolence": 5.668491008599999,
"conformity": 15.519937451099999,
"tradition": 29.6520719312,
"security": 6.2744331509,
"hedonism": 18.706020328374997,
"activity": 16.849100860075,
"power": 17.386630179824998
}
}
}
}
Response Example 2:
xxxxxxxxxx
GET /units/c35321c0-a788-46f4-8e8a-b11007915275?relations[]=tenants
xxxxxxxxxx
{
"id": "c35321c0-a788-46f4-8e8a-b11007915275",
"createdAt": "2023-05-29T16:32:59.828Z",
"createdBy": "f892369b-1cab-4d8c-b24f-4603010975b9",
"updatedAt": "2023-05-29T16:32:59.828Z",
"updatedBy": "f892369b-1cab-4d8c-b24f-4603010975b9",
"archivedAt": null,
"archivedBy": null,
"title": "Highfield Avenue",
"image": null,
"capacity": 6,
"members": 2,
"status": "Vacant",
"psychometry": {
"updatedAt": "2023-05-30T18:51:43.460Z",
"traits": {
"personality": {
"emotionalStability": 18.7255668491,
"conscientiousness": 8.3072713057,
"agreeableness": 4.339327599675,
"extroversion": 7.46677091475,
"openness": 7.54495699765
},
"coreValues": {
"selfDirection": 13.623924941350001,
"universalism": 3.479280688,
"achievement": 5.531665363575,
"benevolence": 5.668491008599999,
"conformity": 15.519937451099999,
"tradition": 29.6520719312,
"security": 6.2744331509,
"hedonism": 18.706020328374997,
"activity": 16.849100860075,
"power": 17.386630179824998
}
}
},
"assignments": [
{
"assignedAt": "2023-05-29T16:33:01.043Z",
"assignedBy": "f892369b-1cab-4d8c-b24f-4603010975b9",
"moveInAt": "2023-05-31T16:33:01.043Z",
"tenant": {
"id": "7dc424e6-f29f-4043-b2ce-41bddebad81a",
"createdAt": "2023-04-12T16:33:01.043Z",
"createdBy": "f892369b-1cab-4d8c-b24f-4603010975b9",
"updatedAt": "2023-10-12T16:33:01.043Z",
"updatedBy": "f892369b-1cab-4d8c-b24f-4603010975b9",
"archivedAt": null,
"archivedBy": null,
"firstname": "Kristine",
"lastname": "Hess"
// ... etc
}
},
{
"assignedAt": "2023-06-02T16:33:01.043Z",
"assignedBy": "f892369b-1cab-4d8c-b24f-4603010975b9",
"moveInAt": "2023-06-05T16:33:01.043Z",
"tenant": {
"id": "03bb42d4-e9f3-43e7-9dd3-777434f7d1a5",
"createdAt": "2023-05-20T12:29:01.043Z",
"createdBy": "f892369b-1cab-4d8c-b24f-4603010975b9",
"updatedAt": "2023-07-20T12:29:01.043Z",
"updatedBy": "f892369b-1cab-4d8c-b24f-4603010975b9",
"archivedAt": null,
"archivedBy": null,
"firstname": "Susannah",
"lastname": "Nesbitt"
// ... etc
}
}
]
}
Retrieves a list of Units
records, with the total number of units and detailed information about each unit.
xxxxxxxxxx
GET /units
xxxxxxxxxx
{
"total": 1,
"list": [
{
"id": "3747a4ab-a385-4215-9084-5c1479019ba6",
"createdAt": "2022-10-31T15:24:51.730Z",
"createdBy": "72d6943c-2b64-43bf-8c38-93c83dc4edab",
"updatedAt": "2022-11-01T16:01:03.485Z",
"updatedBy": "72d6943c-2b64-43bf-8c38-93c83dc4edab",
"archivedAt": null,
"archivedBy": null,
"title": "Apartment A",
"capacity": 4,
"psychometry": {
"updatedAt": "2022-11-01T09:57:01.269Z",
"traits": {
"personality": {
"emotionalStability": 0,
"conscientiousness": 27.16966379985,
"agreeableness": 2.6192337764,
"extroversion": 85.3010164191,
"openness": 30.6880375293
},
"coreValues": {
"selfDirection": 14.425332290850001,
"universalism": 15.324472243899999,
"achievement": 75.29319781075,
"benevolence": 20.60203283815,
"conformity": 36.2392494136,
"tradition": 46.1884284597,
"security": 45.19155590305,
"hedonism": 44.05785770135,
"activity": 63.6434714621,
"power": 93.6669272869
}
}
}
}
],
"isDone": true
}
Units that are empty.
xxxxxxxxxx
GET /units?status=empty
Units that are full:
xxxxxxxxxx
GET /units?status=full
Units that are vacant (i.e has one or more tenant, but also one or more available spots)
xxxxxxxxxx
GET /units?status=vacant
Combinations of these can also be provided, for example:
xxxxxxxxxx
GET /units?status[]=vacant&status[]=empty
include tenants in units with the following query param
xxxxxxxxxx
GET /units?relations[]=tenants
Updates Unit
record fields and returns it updated. You can alter the name
and the capacity
of the unit record you created.
xxxxxxxxxx
PUT /units/:id
xxxxxxxxxx
{
"title": "Apartment A1",
"capacity": 2,
}
xxxxxxxxxx
{
"id": "8291747b-f415-4854-95ff-40c43919201c",
"createdAt": "2022-11-17T21:13:37.601Z",
"createdBy": "72d6943c-2b64-43bf-8c38-93c83dc4edab",
"updatedAt": "2022-11-17T21:13:37.601Z",
"updatedBy": "72d6943c-2b64-43bf-8c38-93c83dc4edab",
"archivedAt": null,
"archivedBy": null,
"title": "Apartment A1",
"capacity": 2,
"psychometry": null
}
Archive Unit
record status.
xxxxxxxxxx
PATCH /units/:id/archive
xxxxxxxxxx
{
"id": "8291747b-f415-4854-95ff-40c43919201c",
"createdAt": "2022-11-17T21:13:37.601Z",
"createdBy": "72d6943c-2b64-43bf-8c38-93c83dc4edab",
"updatedAt": "2022-11-17T22:40:37.575Z",
"updatedBy": "72d6943c-2b64-43bf-8c38-93c83dc4edab",
"archivedAt": "2022-11-17T22:42:26.613Z",
"archivedBy": "72d6943c-2b64-43bf-8c38-93c83dc4edab",
"title": "Apartment A1",
"capacity": 2,
"psychometry": null
}
Restores a Unit
record from the archive.
xxxxxxxxxx
PATCH /units/:id/restore
xxxxxxxxxx
{
"id": "8291747b-f415-4854-95ff-40c43919201c",
"createdAt": "2022-11-17T21:13:37.601Z",
"createdBy": "72d6943c-2b64-43bf-8c38-93c83dc4edab",
"updatedAt": "2022-11-17T22:40:37.575Z",
"updatedBy": "72d6943c-2b64-43bf-8c38-93c83dc4edab",
"archivedAt": null,
"archivedBy": null,
"title": "Apartment A1",
"capacity": 2,
"psychometry": null
}
Disabling and deleting Unit
record from archived.
xxxxxxxxxx
DELETE /units/:id
Note that only the archived records can be deleted.
xxxxxxxxxx
Status: 204 No content
When the desired record is missing:
xxxxxxxxxx
Unit::NotFound
When creating a Unit
record, the unit's name should be unique. This includes the archived units as well:
xxxxxxxxxx
Unit::TitleUsed
For archived records, you'll need restore them before they can be used again:
xxxxxxxxxx
Unit::ArchiveStatusRestriction
For non-archived records, you would have to archive the record first to disable/delete it:
xxxxxxxxxx
Unit:ArchiveStatusRequired
In case there's an operation such as archive on a non-empty unit record:
xxxxxxxxxx
Unit::NotEmpty
If there is a case of an unknown Error, there is a high chance of server-side error. Contact us through email at dev@coly.io with detailed information about the error:
xxxxxxxxxx
Unit::Unknown
Assignments
are used for adding and removing Tenants
to and from a Unit
. Assignments are indicating the relation between Tenants
and Units
records.
Assign a Tenant
to a Unit
. You would need both unitId
and tenantId
to create assignment records.
xxxxxxxxxx
POST /assignments
xxxxxxxxxx
{
"unitId": "3747a4ab-a385-4215-9084-5c1479019ba6",
"tenantId": "11131f6e-5654-4d72-bff0-b4d60b1c9b3a"
}
The response will be an empty response, with the either pattern indicating success or failure. For example:
xxxxxxxxxx
{
"type": "success",
}
Remove a Tenant
from a Unit
. This closes the assignment for specified tenant by deleting or removing the assignment record.
xxxxxxxxxx
DELETE /assignments
xxxxxxxxxx
{
"tenantId": "11131f6e-5654-4d72-bff0-b4d60b1c9b3a"
}
Same philosophy as in the POST /assignments endpoint. For example:
xxxxxxxxxx
{
"type": "success",
}
When no vacancies are left for the unit
, attempting to assign new tenant
records will not be possible:
xxxxxxxxxx
Unit::Overflow
Tenant records are only allowed to be assigned to one unit at a time. In case of attempting to assign to multiple units:
xxxxxxxxxx
Tenant::UnitRestriction
Other error codes
These errors can also occure when attempting to assign records. Note that these are described in the tenant and unit routes above:
xxxxxxxxxx
Tenant::ArchiveStatusRestriction
xxxxxxxxxx
Tenant::NotFound
xxxxxxxxxx
Unit::ArchiveStatusRestriction
xxxxxxxxxx
Unit::NotFound
The Matching Engine provides a method for evaluating the compatibility between individuals and units within our system. Compatibility is quantified using a score ranging from 0 to 100. Detailed below are two endpoints:
The Match
function compares a single source
to multiple targets
, and generates an array of scores to indicate the level of compatibility between each source and target. source
can be a single tenant, single unit, or a an array of tenants (what we usually refer to as "virtual unit"). targets
can be an array with combinations of units, tenants, or also a virtual units.
The response includes an object with a results
field, which contains an array representing the compatibility of each match. The scores are indexed in the same order as the targets array in the request.
Request fields:
source
: Represents the single matching source.targets
: Represents the array of matching targets.type
: Indicates the type of entity being matched, with tenant
for a Tenant
, unit
for a Unit
, and virtualUnit
for an object containing a list of tenants.id
: Represents the ID of the entity.Response fields:
results
: Contains an array of matching results, provided in the same order as the request.
type
: Indicates whether the matching was successful or not, with possible values of resolved
and rejected
.
For type: resolved
:
score
: A decimal number between 0 and 100, indicating the compatibility of the matches.type
: Will have the value "resolved".For type: rejected
:
message
: Provides information about why the matching result could not be calculated.code
: Contains the rejection code specific to the reason for the matching rejection.type
: Will have the value "rejected".
xxxxxxxxxx
POST /match
xxxxxxxxxx
{
"source": {
"type": "tenant",
"id": "a601daf0-fe21-4b02-9659-21c426e9b7a4"
},
"targets": [
{
"type": "unit",
"id": "3747a4ab-a385-4215-9084-5c1479019ba6"
},
{
"type": "unit",
"id": "5295a4ab-b456-9385-1056-4a1857492cd7"
}
]
}
xxxxxxxxxx
{
"results": [
{
"score": 77.92,
"type": "resolved"
},
{
"score": 86.24,
"type": "resolved"
}
],
}
xxxxxxxxxx
{
"source": {
"type": "virtualUnit",
"list": [
{
"type": "tenant",
"id": "a601daf0-fe21-4b02-9659-21c426e9b7a4"
},
{
"type": "tenant",
"id": "1d27c0ab-9c7b-4738-a2fd-0ca013c4de10"
}
]
},
"targets": [
{
"type": "unit",
"id": "3747a4ab-a385-4215-9084-5c1479019ba6"
},
{
"type": "unit",
"id": "5295a4ab-b456-9385-1056-4a1857492cd7"
}
]
}
xxxxxxxxxx
{
"results": [
{
"score": 59.57382039583729,
"type": "resolved"
},
{
"score": 71.64483092758392,
"type": "resolved"
}
],
}
xxxxxxxxxx
{
"source": [
{
"type": "tenant",
"id": "a601daf0-fe21-4b02-9659-21c426e9b7a4"
},
{
"type": "tenant",
"id": "1d27c0ab-9c7b-4738-a2fd-0ca013c4de10"
}
],
"targets": [
{
"type": "unit",
"id": "3747a4ab-a385-4215-9084-5c1479019ba6"
},
{
"type": "tenant",
"id": "5295a4ab-b456-9385-1056-4a1857492cd7"
},
{
"type": "virtualUnit",
"list": [
{
"type": "tenant",
"id": "4df377f2-d6b0-4540-95f7-3fbc949d0015"
},
{
"type": "tenant",
"id": "6213111e-741b-43b1-a178-13ab09f62c30"
}
]
}
]
}
xxxxxxxxxx
{
"results": [
{
"score": 59.57382039583729,
"type": "resolved"
},
{
"score": 71.64483092758392,
"type": "resolved"
},
{
"score": 83.83191093758392,
"type": "resolved"
}
]
}
Example request 4: The second unit happens to be empty
xxxxxxxxxx
{
"source": {
"type": "tenant",
"id": "b601daf0-fe21-4b02-9659-21c426e9b7c7"
},
"targets": [
{
"type": "unit",
"id": "1377a4ab-a385-4215-9084-5c1479019ba6"
},
{
"type": "unit",
"id": "7201a4ab-b456-9385-1056-4a1857492vg7"
}
]
}
Example response 4: The response in case of a rejection
xxxxxxxxxx
{
"results": [
{
"score": 82.92,
"type": "resolved"
},
{
"type": "rejected",
"message": "There should be no empty source/target. Repeating tenants are ignored.",
"code": "EmptyUnit"
}
]
}
The best match endpoint enables you to locate the best matching entity across the entire workspace for a specified source.
Request fields:
source
: Specifies the single source for matching.
type
: Type of entity being matched, tenant
for a Tenant
, unit
for a Unit
, and virtualUnit
for an object containing a list of tenants (This source
field is identical to the one in the /match
endpoint)id
: Represents the ID of the entity.targetType
: This field specifies the type of entity you want to be included in your best match results. It can be either tenant
or unit
.
Response fields:
results
: This field contains an array of match results, presented in descending order from the best match first.type
: Indicates the entity type, unit
or tenant
. entity
: This field pertains to the entity of the matched item, which can be either a unit or a tenant, as dictated by the type. For the schema of Unit and Tenant entities, refer to the preceding sections.score
: The match score.As you may have noted, there are no differences between resolved
or rejected
requests - best match will exclusively contain resolved matches. At most, 20 items will be included, but this may be fewer if the system currently lacks a sufficient number of individuals or units available for matching.
xxxxxxxxxx
POST /match/best
xxxxxxxxxx
{
"source": { "type": "tenant", "id": "d805cf84-1237-4ffd-bbda-f5d66b09ce72" },
"targetType": "unit"
}
xxxxxxxxxx
{
"results": [
{
"type": "unit",
"entity": {
"id": "ce602e65-1c11-4b53-9d68-d4911c5ec4eb",
"createdAt": "2023-05-19T11:33:58.759Z",
"createdBy": "f892369b-1cab-4d8c-b24f-4603010975b9",
"title": "Apple Acre",
"status": "Vacant",
// ... etc
},
"score": 95.02
},
{
"type": "unit",
"entity": {
"id": "02982527-c090-4024-af39-a565b641c466",
"createdAt": "2023-05-19T11:33:58.827Z",
"createdBy": "f892369b-1cab-4d8c-b24f-4603010975b9",
// ... etc
},
"score": 94.63
},
// ... etc
]
}
Overlap handling is implemented for all matching requests. It takes into account situations where some individuals appearing in the source also exist in the target entities. This may happen, for example, when matching an individual with a unit in which they are already a member. The default procedure for managing such scenarios involves the following steps:
By applying these rules, the overlap handling ensures that the same tenant doesn't feature in both the source and target when a match is being calculated, thus maintaining the integrity of the matching process.
xxxxxxxxxx
Tenant::NotFound
xxxxxxxxxx
Unit::NotFound
These are described in the tenant and unit routes.
In the context of the API, there's a throttler mechanism that enforces rate limits on the number of requests a client can make to ensure that the API remains responsive and available for all clients and to prevent one client from monopolizing the resources of the API.
When a client exceeds the rate limit, the API will return a 429 error to indicate that the client has exceeded its allowed number of requests. The client should wait a certain amount of time before retrying the request. The duration of the waiting time is included in the response headers in the form of the 'Retry-After' header.
xxxxxxxxxx
A 429 error, also known as a "Too Many Requests" error, is an HTTP status code that indicates that the user has sent too many requests in a given amount of time. This type of error is typically used to prevent a client from overwhelming a server with too many requests in a short period of time.
Please note that any data found on an object that is not explicitly mentioned in this document is not officially supported. Such values are susceptible to alterations at any time without prior notice.