Overview
The LifeLoop REST API is organized around resources: facilities, residents, connections, activities, registrations, and messages. All requests are made over HTTPS to api.lifeloop.com and return JSON. List endpoints are paginated with pageSize and cursor. Every request needs a bearer token plus the X-Acting-User-Id / X-Acting-User-Tenant header pair. Endpoints marked Planned belong to the v2.0 Priority-2 contract draft and are not yet available.
Health Check
Health Check
/pingReturns health status and build information for the service
curl https://api.lifeloop.com/ping \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001""string"Facilities
List facilities
/api/v1/{tenant}/facilitiesReturns facilities (communities) for the tenant. Use this endpoint to discover LifeLoop facility IDs and map them to your own community identifiers. Requires X-Acting-User-Id (v1.15): a resident/connection identity filters the result to that user's own facility, as before; an Enterprise system-actor identity (LIFELOOP-6215) returns every facility in the tenant.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
curl https://api.lifeloop.com/api/v1/sunrise-001/facilities \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"{
"data": [
{
"id": "obj-001",
"name": "Physical Therapy",
"bedCount": 1,
"careSetting": "adultDay"
}
]
}Get facility
/api/v1/{tenant}/facilities/{facilityId}Returns a single facility by its ID.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
facilityId stringrequired | Unique facility identifier |
curl https://api.lifeloop.com/api/v1/sunrise-001/facilities/fac-001 \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"{
"id": "obj-001",
"name": "Physical Therapy",
"bedCount": 1,
"careSetting": "adultDay"
}Residents
List residents
/api/v1/{tenant}/facilities/{facilityId}/residentsReturns all residents for a specific facility. Supports optional filtering for reconciliation and search use cases.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
facilityId stringrequired |
Query parameters
email string<email>optional | Filter by email address (exact match) |
phone stringoptional | Filter by phone number (exact match) |
status enum(active, inactive, deleted, onLeave)optional | Filter by resident status |
externalId stringoptional | Filter by external identifier for cross-system reconciliation |
pccId stringoptional | Filter by PointClickCare identifier |
cursor stringoptional | Opaque cursor for the next page, taken from the previous response's nextCursor. Omit to fetch the first page. Treat as an opaque token — its encoding may change between releases. |
pageSize integeroptionaldefault: 50 | Number of items to return (default 50, max 100). |
curl https://api.lifeloop.com/api/v1/sunrise-001/facilities/fac-001/residents \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"{
"data": [
{
"id": "obj-001",
"externalId": "ext-001",
"pccId": "pcc-001",
"firstName": "Aileen",
"lastName": "Edmond",
"fullName": "Physical Therapy",
"nickname": "Physical Therapy",
"email": "sarah@example.com",
"phone": "+1-555-0100",
"roomNumber": "roomNumber",
"status": "active",
"moveInDate": "2026-06-18T10:00:00Z",
"dob": "2026-06-18T10:00:00Z",
"gender": "M",
"profilePhotoUrl": "https://cdn.lifeloop.com/profilePhotoUrl",
"facilityId": "fac-001",
"about": {
"bio": null,
"likes": null,
"dislikes": null,
"veteranDetail": null,
"anniversary": null,
"directoryOptOut": null,
"diagnoses": null,
"isVeteran": null
},
"created": "2026-06-18T10:00:00Z",
"modified": "2026-06-18T10:00:00Z"
}
],
"nextCursor": null,
"hasMore": true
}Create resident
/api/v1/{tenant}/facilities/{facilityId}/residentsCreates a new resident in the specified facility
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
facilityId stringrequired |
Request body
externalId stringoptional | External identifier supplied by the integrating system (e.g. Sunrise) for cross-system correlation |
pccId stringoptional | PointClickCare identifier for cross-system correlation |
firstName stringrequired | |
lastName stringrequired | |
nickname stringoptional | |
email string<email>optional | |
phone stringoptional | |
roomNumber stringoptional | |
status enum(active, inactive, onLeave)optional | |
moveInDate string<date-time>optional | |
dob string<date-time>optional | |
gender enum(M, F)optional | |
about objectoptional |
curl -X POST https://api.lifeloop.com/api/v1/sunrise-001/facilities/fac-001/residents \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001" \
-H "Content-Type: application/json" \
-d '{
"externalId": "ext-001",
"pccId": "pcc-001",
"firstName": "Aileen",
"lastName": "Edmond",
"nickname": "Physical Therapy",
"email": "sarah@example.com",
"phone": "+1-555-0100",
"roomNumber": "roomNumber",
"status": "active",
"moveInDate": "2026-06-18T10:00:00Z",
"dob": "2026-06-18T10:00:00Z",
"gender": "M",
"about": {
"bio": "bio",
"likes": [
"likes"
],
"dislikes": [
"dislikes"
],
"veteranDetail": "veteranDetail",
"anniversary": "2026-06-18T10:00:00Z",
"directoryOptOut": true,
"diagnoses": [
"diagnoses"
],
"isVeteran": false
}
}'{
"data": {
"id": "obj-001",
"externalId": "ext-001",
"pccId": "pcc-001",
"firstName": "Aileen",
"lastName": "Edmond",
"fullName": "Physical Therapy",
"nickname": "Physical Therapy",
"email": "sarah@example.com",
"phone": "+1-555-0100",
"roomNumber": "roomNumber",
"status": "active",
"moveInDate": "2026-06-18T10:00:00Z",
"dob": "2026-06-18T10:00:00Z",
"gender": "M",
"profilePhotoUrl": "https://cdn.lifeloop.com/profilePhotoUrl",
"facilityId": "fac-001",
"about": {
"bio": "bio",
"likes": [
"likes"
],
"dislikes": [
"dislikes"
],
"veteranDetail": "veteranDetail",
"anniversary": "2026-06-18T10:00:00Z",
"directoryOptOut": true,
"diagnoses": [
"diagnoses"
],
"isVeteran": false
},
"created": "2026-06-18T10:00:00Z",
"modified": "2026-06-18T10:00:00Z"
}
}Get resident
/api/v1/{tenant}/residents/{residentId}Returns a single resident by ID
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
residentId stringrequired |
curl https://api.lifeloop.com/api/v1/sunrise-001/residents/res-001 \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"{
"data": {
"id": "obj-001",
"externalId": "ext-001",
"pccId": "pcc-001",
"firstName": "Aileen",
"lastName": "Edmond",
"fullName": "Physical Therapy",
"nickname": "Physical Therapy",
"email": "sarah@example.com",
"phone": "+1-555-0100",
"roomNumber": "roomNumber",
"status": "active",
"moveInDate": "2026-06-18T10:00:00Z",
"dob": "2026-06-18T10:00:00Z",
"gender": "M",
"profilePhotoUrl": "https://cdn.lifeloop.com/profilePhotoUrl",
"facilityId": "fac-001",
"about": {
"bio": "bio",
"likes": [
"likes"
],
"dislikes": [
"dislikes"
],
"veteranDetail": "veteranDetail",
"anniversary": "2026-06-18T10:00:00Z",
"directoryOptOut": true,
"diagnoses": [
"diagnoses"
],
"isVeteran": false
},
"created": "2026-06-18T10:00:00Z",
"modified": "2026-06-18T10:00:00Z"
}
}Update resident
/api/v1/{tenant}/residents/{residentId}Updates an existing resident. This is a full replacement operation (PUT semantics). Read-only fields like id, created, modified are ignored if included.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
residentId stringrequired |
Request body
firstName stringrequired | |
lastName stringrequired | |
nickname stringoptional | |
email string<email>optional | |
phone stringoptional | |
roomNumber stringoptional | |
status enum(active, inactive, deleted, onLeave)optional | |
moveInDate string<date-time>optional | |
dob string<date-time>optional | |
gender enum(M, F)optional | |
about objectoptional |
curl -X PUT https://api.lifeloop.com/api/v1/sunrise-001/residents/res-001 \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001" \
-H "Content-Type: application/json" \
-d '{
"firstName": "Aileen",
"lastName": "Edmond",
"nickname": "Physical Therapy",
"email": "sarah@example.com",
"phone": "+1-555-0100",
"roomNumber": "roomNumber",
"status": "active",
"moveInDate": "2026-06-18T10:00:00Z",
"dob": "2026-06-18T10:00:00Z",
"gender": "M",
"about": {
"bio": "bio",
"likes": [
"likes"
],
"dislikes": [
"dislikes"
],
"veteranDetail": "veteranDetail",
"anniversary": "2026-06-18T10:00:00Z",
"directoryOptOut": true,
"diagnoses": [
"diagnoses"
],
"isVeteran": false
}
}'{
"data": {
"id": "obj-001",
"externalId": "ext-001",
"pccId": "pcc-001",
"firstName": "Aileen",
"lastName": "Edmond",
"fullName": "Physical Therapy",
"nickname": "Physical Therapy",
"email": "sarah@example.com",
"phone": "+1-555-0100",
"roomNumber": "roomNumber",
"status": "active",
"moveInDate": "2026-06-18T10:00:00Z",
"dob": "2026-06-18T10:00:00Z",
"gender": "M",
"profilePhotoUrl": "https://cdn.lifeloop.com/profilePhotoUrl",
"facilityId": "fac-001",
"about": {
"bio": "bio",
"likes": [
"likes"
],
"dislikes": [
"dislikes"
],
"veteranDetail": "veteranDetail",
"anniversary": "2026-06-18T10:00:00Z",
"directoryOptOut": true,
"diagnoses": [
"diagnoses"
],
"isVeteran": false
},
"created": "2026-06-18T10:00:00Z",
"modified": "2026-06-18T10:00:00Z"
}
}Delete resident
/api/v1/{tenant}/residents/{residentId}Soft-deletes a resident by ID. The resident record is not physically removed but marked as deleted.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
residentId stringrequired |
curl -X DELETE https://api.lifeloop.com/api/v1/sunrise-001/residents/res-001 \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"// 204 No ContentUpload resident avatar
/api/v1/{tenant}/residents/{residentId}/avatarUploads or replaces the avatar image for a resident. Accepted file formats and maximum upload size are TBD — to be confirmed by engineering.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
residentId stringrequired |
Request body
file string<binary>required | Image file. Accepted formats and maximum size TBD — to be confirmed by engineering. |
curl -X POST https://api.lifeloop.com/api/v1/sunrise-001/residents/res-001/avatar \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"{
"data": {
"avatarUrl": "https://cdn.lifeloop.com/avatarUrl",
"thumbUrl": "https://cdn.lifeloop.com/thumbUrl"
}
}Delete resident avatar
/api/v1/{tenant}/residents/{residentId}/avatarRemoves the avatar image from a resident
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
residentId stringrequired |
curl -X DELETE https://api.lifeloop.com/api/v1/sunrise-001/residents/res-001/avatar \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"// 204 No ContentAssessments
List resident assessments
/api/v1/{tenant}/residents/{residentId}/assessmentsReturns lightweight assessment metadata (AssessmentSummaryDTO) for all assessments (interviews/life stories) for a resident, ordered by completion date descending. Does not include question/answer content — use the single-get endpoint to fetch full Q/A content for a specific assessment.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
residentId stringrequired |
Query parameters
category stringoptional | Filter by assessment category (exact match, case-sensitive). Currently the only recognized value is lifeStory; assessments without a category are omitted from the results when this filter is applied. An unrecognized value returns 400 naming the recognized values, rather than an empty list — an… |
curl https://api.lifeloop.com/api/v1/sunrise-001/residents/res-001/assessments \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"{
"data": [
{
"id": "obj-001",
"assessmentId": "asm-001",
"assessmentName": "Physical Therapy",
"assessmentTemplateId": "ass-001",
"facilityId": "fac-001",
"facilityName": "Physical Therapy",
"type": "Initial",
"category": "lifeStory",
"isCompleted": false,
"isMostRecent": false,
"dateStarted": "2026-06-18T10:00:00Z",
"dateCompleted": "2026-06-18T10:00:00Z",
"dateLastUpdated": "2026-06-18T10:00:00Z",
"createdBy": {
"id": "obj-001",
"name": "Physical Therapy"
},
"completedBy": {
"id": "obj-001",
"name": "Physical Therapy"
}
}
]
}Get assessment with Q/A content
/api/v1/{tenant}/residents/{residentId}/assessments/{assessmentId}Returns the full AssessmentDTO — all metadata fields plus the complete ordered list of questions with the resident's selected answers. Use the /questions endpoint to get the question catalogue with all available answer options for rendering the form.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
residentId stringrequired | |
assessmentId stringrequired |
curl https://api.lifeloop.com/api/v1/sunrise-001/residents/res-001/assessments/asm-001 \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"{
"data": {
"id": "obj-001",
"assessmentId": "asm-001",
"assessmentName": "Physical Therapy",
"assessmentTemplateId": "ass-001",
"facilityId": "fac-001",
"facilityName": "Physical Therapy",
"type": "Initial",
"category": "lifeStory",
"isCompleted": false,
"isMostRecent": false,
"dateStarted": "2026-06-18T10:00:00Z",
"dateCompleted": "2026-06-18T10:00:00Z",
"dateLastUpdated": "2026-06-18T10:00:00Z",
"createdBy": {
"id": "obj-001",
"name": "Physical Therapy"
},
"completedBy": {
"id": "obj-001",
"name": "Physical Therapy"
},
"questions": [
{
"questionGuid": null,
"questionText": null,
"questionType": null,
"answerType": null,
"order": null,
"helper": null,
"isRequired": null,
"isAllowMultipleSelection": null,
"isAllowCustomAnswer": null,
"hasAdditionalComments": null,
"comment": null,
"answers": null,
"followUpQuestions": null
}
]
}
}Delete assessment
/api/v1/{tenant}/residents/{residentId}/assessments/{assessmentId}Soft-deletes an assessment by ID
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
residentId stringrequired | |
assessmentId stringrequired |
curl -X DELETE https://api.lifeloop.com/api/v1/sunrise-001/residents/res-001/assessments/asm-001 \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"// 204 No ContentDownload assessment as PDF
/api/v1/{tenant}/residents/{residentId}/assessments/{assessmentId}/pdfGenerates and returns a PDF containing the complete assessment with all questions and answers
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
residentId stringrequired | |
assessmentId stringrequired |
curl https://api.lifeloop.com/api/v1/sunrise-001/residents/res-001/assessments/asm-001/pdf \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001""<binary>"Get assessment question catalogue
/api/v1/{tenant}/residents/{residentId}/assessments/{assessmentId}/questionsReturns the full question catalogue for an assessment — all questions with their available answer options. Use this to render consistent question prompts and answer choices in the app. The questionGuid and answerGuid fields map directly to the selected answers returned by the assessment GET endpoint.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
residentId stringrequired | |
assessmentId stringrequired |
curl https://api.lifeloop.com/api/v1/sunrise-001/residents/res-001/assessments/asm-001/questions \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"{
"assessmentId": "asm-001",
"assessmentName": "Physical Therapy",
"questions": [
{
"guid": "gui-001",
"text": "text",
"questionType": "questionType",
"answerType": "answerType",
"order": 1,
"helper": "helper",
"isRequired": false,
"isAllowMultipleSelection": false,
"isAllowCustomAnswer": false,
"hasAdditionalComments": true,
"answerOptions": [
{
"guid": null,
"text": null,
"order": null,
"value": null,
"isCustom": null,
"isExclusive": null
}
],
"followUpQuestions": [
{
"guid": null,
"text": null,
"order": null,
"answerType": null,
"applyToParentAnswerGuids": null,
"answerOptions": null
}
]
}
]
}Connections
List connections
/api/v1/{tenant}/connectionsReturns connections (family members and community contacts) filtered by query parameters
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
Query parameters
facilityId stringoptional | Filter by facility |
residentId stringoptional | Filter by linked resident |
email stringoptional | Exact email match lookup |
externalId stringoptional | Filter by external identifier for cross-system reconciliation |
curl https://api.lifeloop.com/api/v1/sunrise-001/connections \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"{
"data": [
{
"id": "obj-001",
"firstName": "Aileen",
"lastName": "Edmond",
"email": "sarah@example.com",
"phoneNumber": 1,
"relationship": "relationship",
"contactType": "resident",
"status": "active",
"facilities": [
{
"id": null,
"name": null
}
],
"residents": [
{
"id": null,
"firstName": null,
"lastName": null,
"facilityId": null
}
],
"groups": [
"groups"
],
"disableNotifications": true,
"disableSMS": true,
"disableInvites": true,
"additionalInfo": "additionalInfo",
"externalId": "ext-001",
"pccId": 1,
"avatarUrl": "https://cdn.lifeloop.com/avatarUrl",
"thumbUrl": "https://cdn.lifeloop.com/thumbUrl",
"created": "2026-06-18T10:00:00Z",
"updated": "2026-06-18T10:00:00Z"
}
]
}Create connection
/api/v1/{tenant}/connectionsCreates a new connection (family member or community contact). If email matches existing connection, merges residents arrays and updates record.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
Request body
firstName stringrequired | |
lastName stringrequired | |
email string<email>optional | |
phoneNumber numberoptional | |
relationship stringoptional | |
residents array<string>required | |
facilities array<string>required | |
groups array<string>optional | |
disableNotifications booleanoptional | |
disableSMS booleanoptional | |
disableInvites booleanoptional | |
additionalInfo stringoptional | |
externalId stringoptional | External identifier supplied by the integrating system (e.g. Sunrise) for cross-system correlation |
pccId numberoptional | PointClickCare identifier for cross-system correlation |
curl -X POST https://api.lifeloop.com/api/v1/sunrise-001/connections \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001" \
-H "Content-Type: application/json" \
-d '{
"firstName": "Aileen",
"lastName": "Edmond",
"email": "sarah@example.com",
"phoneNumber": 1,
"relationship": "relationship",
"residents": [
"residents"
],
"facilities": [
"facilities"
],
"groups": [
"groups"
],
"disableNotifications": true,
"disableSMS": true,
"disableInvites": true,
"additionalInfo": "additionalInfo",
"externalId": "ext-001",
"pccId": 1
}'{
"data": {
"id": "obj-001",
"firstName": "Aileen",
"lastName": "Edmond",
"email": "sarah@example.com",
"phoneNumber": 1,
"relationship": "relationship",
"contactType": "resident",
"status": "active",
"facilities": [
{
"id": "obj-001",
"name": "Physical Therapy"
}
],
"residents": [
{
"id": "obj-001",
"firstName": "Aileen",
"lastName": "Edmond",
"facilityId": "fac-001"
}
],
"groups": [
"groups"
],
"disableNotifications": true,
"disableSMS": true,
"disableInvites": true,
"additionalInfo": "additionalInfo",
"externalId": "ext-001",
"pccId": 1,
"avatarUrl": "https://cdn.lifeloop.com/avatarUrl",
"thumbUrl": "https://cdn.lifeloop.com/thumbUrl",
"created": "2026-06-18T10:00:00Z",
"updated": "2026-06-18T10:00:00Z"
}
}Get connection
/api/v1/{tenant}/connections/{connectionId}Returns a single connection by ID with full details
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
connectionId stringrequired |
curl https://api.lifeloop.com/api/v1/sunrise-001/connections/con-001 \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"{
"data": {
"id": "obj-001",
"firstName": "Aileen",
"lastName": "Edmond",
"email": "sarah@example.com",
"phoneNumber": 1,
"relationship": "relationship",
"contactType": "resident",
"status": "active",
"facilities": [
{
"id": "obj-001",
"name": "Physical Therapy"
}
],
"residents": [
{
"id": "obj-001",
"firstName": "Aileen",
"lastName": "Edmond",
"facilityId": "fac-001"
}
],
"groups": [
"groups"
],
"disableNotifications": true,
"disableSMS": true,
"disableInvites": true,
"additionalInfo": "additionalInfo",
"externalId": "ext-001",
"pccId": 1,
"avatarUrl": "https://cdn.lifeloop.com/avatarUrl",
"thumbUrl": "https://cdn.lifeloop.com/thumbUrl",
"created": "2026-06-18T10:00:00Z",
"updated": "2026-06-18T10:00:00Z"
}
}Update connection
/api/v1/{tenant}/connections/{connectionId}Updates an existing connection. This is a full replacement operation (PUT semantics).
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
connectionId stringrequired |
Request body
firstName stringrequired | |
lastName stringrequired | |
email string<email>optional | |
phoneNumber numberoptional | |
relationship stringoptional | |
residents array<string>required | |
facilities array<string>required | |
groups array<string>optional | |
disableNotifications booleanoptional | |
disableSMS booleanoptional | |
disableInvites booleanoptional | |
additionalInfo stringoptional | |
status enum(active, inactive, deleted, onLeave)optional |
curl -X PUT https://api.lifeloop.com/api/v1/sunrise-001/connections/con-001 \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001" \
-H "Content-Type: application/json" \
-d '{
"firstName": "Aileen",
"lastName": "Edmond",
"email": "sarah@example.com",
"phoneNumber": 1,
"relationship": "relationship",
"residents": [
"residents"
],
"facilities": [
"facilities"
],
"groups": [
"groups"
],
"disableNotifications": true,
"disableSMS": true,
"disableInvites": true,
"additionalInfo": "additionalInfo",
"status": "active"
}'{
"data": {
"id": "obj-001",
"firstName": "Aileen",
"lastName": "Edmond",
"email": "sarah@example.com",
"phoneNumber": 1,
"relationship": "relationship",
"contactType": "resident",
"status": "active",
"facilities": [
{
"id": "obj-001",
"name": "Physical Therapy"
}
],
"residents": [
{
"id": "obj-001",
"firstName": "Aileen",
"lastName": "Edmond",
"facilityId": "fac-001"
}
],
"groups": [
"groups"
],
"disableNotifications": true,
"disableSMS": true,
"disableInvites": true,
"additionalInfo": "additionalInfo",
"externalId": "ext-001",
"pccId": 1,
"avatarUrl": "https://cdn.lifeloop.com/avatarUrl",
"thumbUrl": "https://cdn.lifeloop.com/thumbUrl",
"created": "2026-06-18T10:00:00Z",
"updated": "2026-06-18T10:00:00Z"
}
}Delete connection
/api/v1/{tenant}/connections/{connectionId}Soft-deletes a connection by ID
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
connectionId stringrequired |
curl -X DELETE https://api.lifeloop.com/api/v1/sunrise-001/connections/con-001 \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"// 204 No ContentUpload connection avatar
/api/v1/{tenant}/connections/{connectionId}/avatarUploads or updates an avatar image for a connection
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
connectionId stringrequired |
Request body
file string<binary>optional |
curl -X POST https://api.lifeloop.com/api/v1/sunrise-001/connections/con-001/avatar \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"{
"data": {
"avatarUrl": "https://cdn.lifeloop.com/avatarUrl",
"thumbUrl": "https://cdn.lifeloop.com/thumbUrl"
}
}Delete connection avatar
/api/v1/{tenant}/connections/{connectionId}/avatarRemoves the avatar image from a connection
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
connectionId stringrequired |
curl -X DELETE https://api.lifeloop.com/api/v1/sunrise-001/connections/con-001/avatar \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"// 204 No ContentList resident's connections
/api/v1/{tenant}/residents/{residentId}/connectionsConvenience endpoint that returns all connections linked to a specific resident
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
residentId stringrequired |
curl https://api.lifeloop.com/api/v1/sunrise-001/residents/res-001/connections \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"{
"data": [
{
"id": "obj-001",
"firstName": "Aileen",
"lastName": "Edmond",
"email": "sarah@example.com",
"phoneNumber": 1,
"relationship": "relationship",
"contactType": "resident",
"status": "active",
"facilities": [
{
"id": null,
"name": null
}
],
"residents": [
{
"id": null,
"firstName": null,
"lastName": null,
"facilityId": null
}
],
"groups": [
"groups"
],
"disableNotifications": true,
"disableSMS": true,
"disableInvites": true,
"additionalInfo": "additionalInfo",
"externalId": "ext-001",
"pccId": 1,
"avatarUrl": "https://cdn.lifeloop.com/avatarUrl",
"thumbUrl": "https://cdn.lifeloop.com/thumbUrl",
"created": "2026-06-18T10:00:00Z",
"updated": "2026-06-18T10:00:00Z"
}
]
}Calendars
List facility calendars
/api/v1/{tenant}/facilities/{facilityId}/calendarsReturns all calendars associated with a facility, including shared calendars
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
facilityId stringrequired |
curl https://api.lifeloop.com/api/v1/sunrise-001/facilities/fac-001/calendars \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"{
"data": [
{
"id": "obj-001",
"name": "Physical Therapy",
"category": "activity",
"facilityIds": [
"facilityIds"
],
"facilityNames": [
"Physical Therapy"
],
"private": true,
"created": "2026-06-18T10:00:00Z"
}
]
}Activities
List facility activities
/api/v1/{tenant}/facilities/{facilityId}/activitiesReturns activities for a facility within the specified date range. Each ActivityDTO includes isRecurring, and when true, a recurrence object describing the series (read-only — see ActivityDTO/RecurrenceDTO). Known limitation: each unmaterialized occurrence of a recurring series shares the same id, distinguishable only by startDate. Use id together with startDate as the occurrenceDate query parameter on GET /activities/{activityId} to fetch that specific occurrence. See LIFELOOP-5806.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
facilityId stringrequired |
Query parameters
startDate string<date-time>required | Start of date range (ISO 8601 format) |
endDate string<date-time>required | End of date range (ISO 8601 format). Day 1 of the window is startDate's own calendar date (its time-of-day is ignored); the window runs through day 45's end (23:59:59) — equivalently, endDate must fall before day 46's midnight. A bare date and an end-of-day timestamp for the same calendar day are… |
type stringoptional | Filter by activity type (e.g. social, physical, intellectual) |
location stringoptional | Filter by activity location (exact or partial match) |
actingUserId stringoptional | LifeLoop user ID of the acting resident or connection. When provided, each ActivityDTO in the response will include actingUserRegistrationStatus. |
curl https://api.lifeloop.com/api/v1/sunrise-001/facilities/fac-001/activities?startDate=value&endDate=value \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"{
"data": [
{
"id": "obj-001",
"name": "Physical Therapy",
"type": "type",
"startDate": "2026-06-18T10:00:00Z",
"endDate": "2026-06-18T10:00:00Z",
"startTime": "10:00",
"endTime": "10:00",
"timeType": "exactTime",
"location": "location",
"description": "description",
"capacity": {
"residents": {
"max": null,
"registered": null,
"available": null,
"isFull": null,
"isOpen": null,
"waitlisted": null
},
"connections": {
"max": null,
"registered": null,
"available": null,
"isFull": null,
"isOpen": null
}
},
"allowConnections": true,
"calendarId": "cal-001",
"calendarName": "Physical Therapy",
"facilityId": "fac-001",
"attachments": [
{
"id": null,
"name": null,
"url": null,
"type": null,
"size": null,
"publicToFamily": null
}
],
"creator": {
"id": "obj-001",
"name": "Physical Therapy"
},
"created": "2026-06-18T10:00:00Z",
"modified": "2026-06-18T10:00:00Z",
"isPastActivity": false,
"isCancelled": false,
"actingUserRegistrationStatus": "registered",
"isRecurring": false,
"recurrence": {
"frequency": null,
"interval": null,
"daysOfWeek": null,
"weekOfMonth": null,
"dayOfWeek": null,
"dayOfMonth": null,
"seriesStartDate": null,
"seriesEndDate": null,
"exceptionDates": null
}
}
]
}Get activity
/api/v1/{tenant}/activities/{activityId}Returns a single activity by ID with capacity and registration information. Provide actingUserId to include the acting user's registration status in the response. Includes isRecurring / recurrence (read-only) when the activity belongs to a recurring series. For a recurring series, pass occurrenceDate to retrieve a specific unmaterialized occurrence's own startDate/endDate rather than the master's — see LIFELOOP-5806.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
activityId stringrequired |
Query parameters
occurrenceDate string<date>optional | For a recurring series' activityId, selects a specific occurrence by date (matches the startDate returned for that occurrence by the list endpoint). Must fall within the series' seriesStartDate/seriesEndDate and not be in exceptionDates, or 404. Ignored (with a warning, or 400 — TBD) if activityId… |
actingUserId stringoptional | LifeLoop user ID of the acting resident or connection. When provided, the response includes actingUserRegistrationStatus. |
curl https://api.lifeloop.com/api/v1/sunrise-001/activities/act-001 \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"{
"data": {
"id": "obj-001",
"name": "Physical Therapy",
"type": "type",
"startDate": "2026-06-18T10:00:00Z",
"endDate": "2026-06-18T10:00:00Z",
"startTime": "10:00",
"endTime": "10:00",
"timeType": "exactTime",
"location": "location",
"description": "description",
"capacity": {
"residents": {
"max": 1,
"registered": 1,
"available": 1,
"isFull": false,
"isOpen": false,
"waitlisted": 1
},
"connections": {
"max": 1,
"registered": 1,
"available": 1,
"isFull": false,
"isOpen": false
}
},
"allowConnections": true,
"calendarId": "cal-001",
"calendarName": "Physical Therapy",
"facilityId": "fac-001",
"attachments": [
{
"id": "obj-001",
"name": "Physical Therapy",
"url": "https://cdn.lifeloop.com/url",
"type": "type",
"size": 1,
"publicToFamily": true
}
],
"creator": {
"id": "obj-001",
"name": "Physical Therapy"
},
"created": "2026-06-18T10:00:00Z",
"modified": "2026-06-18T10:00:00Z",
"isPastActivity": false,
"isCancelled": false,
"actingUserRegistrationStatus": "registered",
"isRecurring": false,
"recurrence": {
"frequency": "daily",
"interval": 1,
"daysOfWeek": [],
"weekOfMonth": "first",
"dayOfWeek": "monday",
"dayOfMonth": null,
"seriesStartDate": "2026-06-18T10:00:00Z",
"seriesEndDate": "2026-06-18T10:00:00Z",
"exceptionDates": []
}
}
}Update activity
/api/v1/{tenant}/activities/{activityId}Updates an existing activity. Full replacement (PUT semantics). Cannot change calendar or modify past activities.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
activityId stringrequired |
Request body
name stringrequired | |
type stringrequired | |
startDate string<date-time>required | |
endDate string<date-time>optional | |
startTime stringrequired | |
endTime stringoptional | |
timeType enum(exactTime, allDay, morning, afternoon, evening)optional | Time-of-day type for this activity (internal field: 'special'; internal 'none' maps to 'exactTime'). Defaults to 'exactTime' to preserve existing behavior for callers that don't send it. Unlike PersonalActivityDTO/PersonalVisitDTO, startTime/endTime remain required regardless of timeType for group… |
location stringoptional | |
description stringoptional | |
maxRegistered integeroptional | |
maxRegisteredConnections integeroptional | |
allowConnections booleanoptional | |
attachments array<object>optional |
curl -X PUT https://api.lifeloop.com/api/v1/sunrise-001/activities/act-001 \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001" \
-H "Content-Type: application/json" \
-d '{
"name": "Physical Therapy",
"type": "type",
"startDate": "2026-06-18T10:00:00Z",
"endDate": "2026-06-18T10:00:00Z",
"startTime": "10:00",
"endTime": "10:00",
"timeType": "exactTime",
"location": "location",
"description": "description",
"maxRegistered": 1,
"maxRegisteredConnections": 1,
"allowConnections": true,
"attachments": [
{
"attachmentId": "att-001",
"publicToFamily": true
}
]
}'{
"data": {
"id": "obj-001",
"name": "Physical Therapy",
"type": "type",
"startDate": "2026-06-18T10:00:00Z",
"endDate": "2026-06-18T10:00:00Z",
"startTime": "10:00",
"endTime": "10:00",
"timeType": "exactTime",
"location": "location",
"description": "description",
"capacity": {
"residents": {
"max": 1,
"registered": 1,
"available": 1,
"isFull": false,
"isOpen": false,
"waitlisted": 1
},
"connections": {
"max": 1,
"registered": 1,
"available": 1,
"isFull": false,
"isOpen": false
}
},
"allowConnections": true,
"calendarId": "cal-001",
"calendarName": "Physical Therapy",
"facilityId": "fac-001",
"attachments": [
{
"id": "obj-001",
"name": "Physical Therapy",
"url": "https://cdn.lifeloop.com/url",
"type": "type",
"size": 1,
"publicToFamily": true
}
],
"creator": {
"id": "obj-001",
"name": "Physical Therapy"
},
"created": "2026-06-18T10:00:00Z",
"modified": "2026-06-18T10:00:00Z",
"isPastActivity": false,
"isCancelled": false,
"actingUserRegistrationStatus": "registered",
"isRecurring": false,
"recurrence": {
"frequency": "daily",
"interval": 1,
"daysOfWeek": [],
"weekOfMonth": "first",
"dayOfWeek": "monday",
"dayOfMonth": null,
"seriesStartDate": "2026-06-18T10:00:00Z",
"seriesEndDate": "2026-06-18T10:00:00Z",
"exceptionDates": []
}
}
}Delete activity
/api/v1/{tenant}/activities/{activityId}Soft-deletes an activity. Cannot delete if there are active registrations without confirmation.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
activityId stringrequired |
curl -X DELETE https://api.lifeloop.com/api/v1/sunrise-001/activities/act-001 \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"// 204 No ContentDownload activity attachment
/api/v1/{tenant}/activities/{activityId}/attachments/{attachmentId}Documented ahead of deployment (LIFELOOP-6551) — the backend is in development as of v1.18; this endpoint is not available until that ships. Downloads the file of one activity attachment. attachmentId is attachments[].id from GET /api/v1/{tenant}/activities/{activityId} or an activity list. The response Content-Type is the file's own type (for example image/png), or application/octet-stream when it is unknown; Content-Disposition carries the file name. Who can download, by X-Acting-User-Id: - Staff: the same rules as GET /api/v1/{tenant}/activities/{activityId}, including its 403 without the permission or outside the activity's facility. - Resident: only activities the resident is registered for or has attended (the ones GET /api/v1/{tenant}/residents/{residentId}/activities returns). - Connection: activities the connection is registered for, and activities on the activity and meal calendars of their linked residents' facilities. Attachments with publicToFamily: false are not available to a connection. Returns 404 when the activity does not exist or the attachment is not in that activity's attachments[], and to a resident or connection who may not see it. See LIFELOOP-6551.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
activityId stringrequired | |
attachmentId stringrequired |
curl https://api.lifeloop.com/api/v1/sunrise-001/activities/act-001/attachments/att-001 \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001""<binary>"Create activity
/api/v1/{tenant}/calendars/{calendarId}/activitiesCreates a new activity in the specified calendar. MVP supports simple one-time activities only (no recurring patterns or time slots). Recurrence metadata is read-only in this API (see ActivityDTO.recurrence) — a recurring series cannot be created or edited via this endpoint.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
calendarId stringrequired |
Request body
name stringrequired | |
type stringrequired | |
startDate string<date-time>required | |
endDate string<date-time>optional | |
startTime stringrequired | |
endTime stringoptional | |
timeType enum(exactTime, allDay, morning, afternoon, evening)optional | Time-of-day type for this activity (internal field: 'special'; internal 'none' maps to 'exactTime'). Defaults to 'exactTime' to preserve existing behavior for callers that don't send it. Unlike PersonalActivityDTO/PersonalVisitDTO, startTime/endTime remain required regardless of timeType for group… |
location stringoptional | |
description stringoptional | |
maxRegistered integeroptional | |
maxRegisteredConnections integeroptional | |
allowConnections booleanoptional | |
attachments array<object>optional |
curl -X POST https://api.lifeloop.com/api/v1/sunrise-001/calendars/cal-001/activities \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001" \
-H "Content-Type: application/json" \
-d '{
"name": "Physical Therapy",
"type": "type",
"startDate": "2026-06-18T10:00:00Z",
"endDate": "2026-06-18T10:00:00Z",
"startTime": "10:00",
"endTime": "10:00",
"timeType": "exactTime",
"location": "location",
"description": "description",
"maxRegistered": 1,
"maxRegisteredConnections": 1,
"allowConnections": true,
"attachments": [
{
"attachmentId": "att-001",
"publicToFamily": true
}
]
}'{
"data": {
"id": "obj-001",
"name": "Physical Therapy",
"type": "type",
"startDate": "2026-06-18T10:00:00Z",
"endDate": "2026-06-18T10:00:00Z",
"startTime": "10:00",
"endTime": "10:00",
"timeType": "exactTime",
"location": "location",
"description": "description",
"capacity": {
"residents": {
"max": 1,
"registered": 1,
"available": 1,
"isFull": false,
"isOpen": false,
"waitlisted": 1
},
"connections": {
"max": 1,
"registered": 1,
"available": 1,
"isFull": false,
"isOpen": false
}
},
"allowConnections": true,
"calendarId": "cal-001",
"calendarName": "Physical Therapy",
"facilityId": "fac-001",
"attachments": [
{
"id": "obj-001",
"name": "Physical Therapy",
"url": "https://cdn.lifeloop.com/url",
"type": "type",
"size": 1,
"publicToFamily": true
}
],
"creator": {
"id": "obj-001",
"name": "Physical Therapy"
},
"created": "2026-06-18T10:00:00Z",
"modified": "2026-06-18T10:00:00Z",
"isPastActivity": false,
"isCancelled": false,
"actingUserRegistrationStatus": "registered",
"isRecurring": false,
"recurrence": {
"frequency": "daily",
"interval": 1,
"daysOfWeek": [],
"weekOfMonth": "first",
"dayOfWeek": "monday",
"dayOfMonth": null,
"seriesStartDate": "2026-06-18T10:00:00Z",
"seriesEndDate": "2026-06-18T10:00:00Z",
"exceptionDates": []
}
}
}List activity types
/api/v1/{tenant}/activity-typesReturns the catalog of available activity types for filtering and creating activities. Requires X-Acting-User-Id (v1.15) of any identity type; the header is not forwarded to the underlying service (see MiddlewareClientConfig), so its value doesn't affect the result — only its presence is required.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
curl https://api.lifeloop.com/api/v1/sunrise-001/activity-types \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"{
"data": [
{
"id": "obj-001",
"name": "Physical Therapy",
"category": "category"
}
]
}List resident personal activities
/api/v1/{tenant}/residents/{residentId}/personal-activitiesReturns personal activities (type: personal) for a given resident within the specified date range. Personal activities are one-on-one activities not associated with any facility calendar. Excludes check-ins — use GET /residents/{residentId}/check-ins for those.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
residentId stringrequired |
Query parameters
startDate string<date-time>required | Start of date range (ISO 8601 format) |
endDate string<date-time>required | End of date range (ISO 8601 format). Day 1 of the window is startDate's own calendar date (its time-of-day is ignored); the window runs through day 45's end (23:59:59) — equivalently, endDate must fall before day 46's midnight. A bare date and an end-of-day timestamp for the same calendar day are… |
curl https://api.lifeloop.com/api/v1/sunrise-001/residents/res-001/personal-activities?startDate=value&endDate=value \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"{
"data": [
{
"id": "obj-001",
"name": "Physical Therapy",
"startDate": "2026-06-18T10:00:00Z",
"startTime": "10:00",
"endTime": "10:00",
"timeType": "exactTime",
"durationInMinutes": 30,
"attendedResidentIds": [
"attendedResidentIds"
],
"location": "location",
"description": "description",
"confirmed": true,
"photos": [
{
"id": null,
"name": null,
"url": null,
"type": null,
"size": null,
"publicToFamily": null
}
],
"created": "2026-06-18T10:00:00Z",
"modified": "2026-06-18T10:00:00Z"
}
]
}Create resident personal activity
/api/v1/{tenant}/residents/{residentId}/personal-activitiesCreates a new personal activity for a resident. The resident specified in the path is automatically included as an attendee.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
residentId stringrequired |
Request body
name stringrequired | Activity name, typically chosen from facility-configured personal activity presets |
startDate string<date-time>required | |
startTime stringoptional | Start time in HH:mm format. Required when timeType is 'exactTime' (the default when omitted). |
endTime stringoptional | End time in HH:mm format. Required when timeType is 'exactTime' (the default when omitted); derived from durationInMinutes if omitted while exactTime. |
timeType enum(exactTime, allDay, morning, afternoon, evening)optional | Time-of-day type for this activity (internal field: 'special'; internal 'none' maps to 'exactTime'). When 'exactTime' (the default), startTime/endTime are required and durationInMinutes reflects their gap. For any other value, durationInMinutes is used directly and startTime/endTime are not… |
durationInMinutes integerrequired | Duration of the activity in minutes. Always required regardless of timeType. |
additionalAttendeeResidentIds array<string>optional | IDs of additional residents to include as attendees beyond the primary resident specified in the path |
location stringoptional | |
description stringoptional |
curl -X POST https://api.lifeloop.com/api/v1/sunrise-001/residents/res-001/personal-activities \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001" \
-H "Content-Type: application/json" \
-d '{
"name": "Physical Therapy",
"startDate": "2026-06-18T10:00:00Z",
"startTime": "10:00",
"endTime": "10:00",
"timeType": "exactTime",
"durationInMinutes": 30,
"additionalAttendeeResidentIds": [
"additionalAttendeeResidentIds"
],
"location": "location",
"description": "description"
}'{
"data": {
"id": "obj-001",
"name": "Physical Therapy",
"startDate": "2026-06-18T10:00:00Z",
"startTime": "10:00",
"endTime": "10:00",
"timeType": "exactTime",
"durationInMinutes": 30,
"attendedResidentIds": [
"attendedResidentIds"
],
"location": "location",
"description": "description",
"confirmed": true,
"photos": [
{
"id": "obj-001",
"name": "Physical Therapy",
"url": "https://cdn.lifeloop.com/url",
"type": "type",
"size": 1,
"publicToFamily": true
}
],
"created": "2026-06-18T10:00:00Z",
"modified": "2026-06-18T10:00:00Z"
}
}Get resident personal activity
/api/v1/{tenant}/residents/{residentId}/personal-activities/{activityId}Returns a single personal activity by ID for a given resident.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
residentId stringrequired | |
activityId stringrequired |
curl https://api.lifeloop.com/api/v1/sunrise-001/residents/res-001/personal-activities/act-001 \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"{
"data": {
"id": "obj-001",
"name": "Physical Therapy",
"startDate": "2026-06-18T10:00:00Z",
"startTime": "10:00",
"endTime": "10:00",
"timeType": "exactTime",
"durationInMinutes": 30,
"attendedResidentIds": [
"attendedResidentIds"
],
"location": "location",
"description": "description",
"confirmed": true,
"photos": [
{
"id": "obj-001",
"name": "Physical Therapy",
"url": "https://cdn.lifeloop.com/url",
"type": "type",
"size": 1,
"publicToFamily": true
}
],
"created": "2026-06-18T10:00:00Z",
"modified": "2026-06-18T10:00:00Z"
}
}Update resident personal activity
/api/v1/{tenant}/residents/{residentId}/personal-activities/{activityId}Updates an existing personal activity for a resident.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
residentId stringrequired | |
activityId stringrequired |
Request body
name stringrequired | |
startDate string<date-time>required | |
startTime stringoptional | Required when timeType is 'exactTime' (the default when omitted). |
endTime stringoptional | Required when timeType is 'exactTime' (the default when omitted). |
timeType enum(exactTime, allDay, morning, afternoon, evening)optional | Time-of-day type for this activity (internal field: 'special'; internal 'none' maps to 'exactTime'). |
durationInMinutes integerrequired | Always required regardless of timeType. |
additionalAttendeeResidentIds array<string>optional | |
location stringoptional | |
description stringoptional |
curl -X PUT https://api.lifeloop.com/api/v1/sunrise-001/residents/res-001/personal-activities/act-001 \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001" \
-H "Content-Type: application/json" \
-d '{
"name": "Physical Therapy",
"startDate": "2026-06-18T10:00:00Z",
"startTime": "10:00",
"endTime": "10:00",
"timeType": "exactTime",
"durationInMinutes": 30,
"additionalAttendeeResidentIds": [
"additionalAttendeeResidentIds"
],
"location": "location",
"description": "description"
}'{
"data": {
"id": "obj-001",
"name": "Physical Therapy",
"startDate": "2026-06-18T10:00:00Z",
"startTime": "10:00",
"endTime": "10:00",
"timeType": "exactTime",
"durationInMinutes": 30,
"attendedResidentIds": [
"attendedResidentIds"
],
"location": "location",
"description": "description",
"confirmed": true,
"photos": [
{
"id": "obj-001",
"name": "Physical Therapy",
"url": "https://cdn.lifeloop.com/url",
"type": "type",
"size": 1,
"publicToFamily": true
}
],
"created": "2026-06-18T10:00:00Z",
"modified": "2026-06-18T10:00:00Z"
}
}Delete resident personal activity
/api/v1/{tenant}/residents/{residentId}/personal-activities/{activityId}Deletes a personal activity for a resident.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
residentId stringrequired | |
activityId stringrequired |
curl -X DELETE https://api.lifeloop.com/api/v1/sunrise-001/residents/res-001/personal-activities/act-001 \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"// 204 No ContentList resident group activities
/api/v1/{tenant}/residents/{residentId}/activitiesReturns community/calendar activities that the resident is attending or registered for within the specified date range. Does not include personal activities.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
residentId stringrequired |
Query parameters
startDate string<date-time>required | Start of date range (ISO 8601 format) |
endDate string<date-time>required | End of date range (ISO 8601 format). Day 1 of the window is startDate's own calendar date (its time-of-day is ignored); the window runs through day 45's end (23:59:59) — equivalently, endDate must fall before day 46's midnight. A bare date and an end-of-day timestamp for the same calendar day are… |
curl https://api.lifeloop.com/api/v1/sunrise-001/residents/res-001/activities?startDate=value&endDate=value \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"{
"data": [
{
"id": "obj-001",
"name": "Physical Therapy",
"type": "type",
"startDate": "2026-06-18T10:00:00Z",
"endDate": "2026-06-18T10:00:00Z",
"startTime": "10:00",
"endTime": "10:00",
"timeType": "exactTime",
"location": "location",
"description": "description",
"capacity": {
"residents": {
"max": null,
"registered": null,
"available": null,
"isFull": null,
"isOpen": null,
"waitlisted": null
},
"connections": {
"max": null,
"registered": null,
"available": null,
"isFull": null,
"isOpen": null
}
},
"allowConnections": true,
"calendarId": "cal-001",
"calendarName": "Physical Therapy",
"facilityId": "fac-001",
"attachments": [
{
"id": null,
"name": null,
"url": null,
"type": null,
"size": null,
"publicToFamily": null
}
],
"creator": {
"id": "obj-001",
"name": "Physical Therapy"
},
"created": "2026-06-18T10:00:00Z",
"modified": "2026-06-18T10:00:00Z",
"isPastActivity": false,
"isCancelled": false,
"actingUserRegistrationStatus": "registered",
"isRecurring": false,
"recurrence": {
"frequency": null,
"interval": null,
"daysOfWeek": null,
"weekOfMonth": null,
"dayOfWeek": null,
"dayOfMonth": null,
"seriesStartDate": null,
"seriesEndDate": null,
"exceptionDates": null
}
}
]
}List connection group activities
/api/v1/{tenant}/connections/{connectionId}/activitiesReturns community/calendar activities that the connection is registered for within the specified date range.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
connectionId stringrequired |
Query parameters
startDate string<date-time>required | Start of date range (ISO 8601 format) |
endDate string<date-time>required | End of date range (ISO 8601 format). Day 1 of the window is startDate's own calendar date (its time-of-day is ignored); the window runs through day 45's end (23:59:59) — equivalently, endDate must fall before day 46's midnight. A bare date and an end-of-day timestamp for the same calendar day are… |
curl https://api.lifeloop.com/api/v1/sunrise-001/connections/con-001/activities?startDate=value&endDate=value \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"{
"data": [
{
"id": "obj-001",
"name": "Physical Therapy",
"type": "type",
"startDate": "2026-06-18T10:00:00Z",
"endDate": "2026-06-18T10:00:00Z",
"startTime": "10:00",
"endTime": "10:00",
"timeType": "exactTime",
"location": "location",
"description": "description",
"capacity": {
"residents": {
"max": null,
"registered": null,
"available": null,
"isFull": null,
"isOpen": null,
"waitlisted": null
},
"connections": {
"max": null,
"registered": null,
"available": null,
"isFull": null,
"isOpen": null
}
},
"allowConnections": true,
"calendarId": "cal-001",
"calendarName": "Physical Therapy",
"facilityId": "fac-001",
"attachments": [
{
"id": null,
"name": null,
"url": null,
"type": null,
"size": null,
"publicToFamily": null
}
],
"creator": {
"id": "obj-001",
"name": "Physical Therapy"
},
"created": "2026-06-18T10:00:00Z",
"modified": "2026-06-18T10:00:00Z",
"isPastActivity": false,
"isCancelled": false,
"actingUserRegistrationStatus": "registered",
"isRecurring": false,
"recurrence": {
"frequency": null,
"interval": null,
"daysOfWeek": null,
"weekOfMonth": null,
"dayOfWeek": null,
"dayOfMonth": null,
"seriesStartDate": null,
"seriesEndDate": null,
"exceptionDates": null
}
}
]
}Registrations
List activity registrations
/api/v1/{tenant}/activities/{activityId}/registrationsReturns all registrations (residents and connections) for an activity with capacity information. For a recurring series, pass occurrenceDate to list registrations for one specific occurrence rather than the master — see LIFELOOP-5806/LIFELOOP-6108.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
activityId stringrequired |
Query parameters
occurrenceDate string<date>optional | For a recurring series' activityId, selects a specific occurrence by date (matches the startDate returned for that occurrence by the activities list endpoint) rather than returning the master's own registrations. Needed because an occurrence's registrations may live on a materialized occurrence… |
curl https://api.lifeloop.com/api/v1/sunrise-001/activities/act-001/registrations \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"{
"data": {
"activityId": "act-001",
"activityName": "Physical Therapy",
"activityStartDate": "2026-06-18T10:00:00Z",
"capacity": {
"residents": {
"max": 1,
"registered": 1,
"available": 1,
"isFull": false,
"isOpen": false,
"waitlisted": 1
},
"connections": {
"max": 1,
"registered": 1,
"available": 1,
"isFull": false,
"isOpen": false
}
},
"allowConnections": true,
"registrations": [
{
"activityId": "act-001",
"activityName": "Physical Therapy",
"activityType": "activityType",
"activityStartDate": "2026-06-18T10:00:00Z",
"activityEndDate": "2026-06-18T10:00:00Z",
"activityLocation": "activityLocation",
"facilityId": "fac-001",
"facilityName": "Physical Therapy",
"userId": "use-001",
"userType": "resident",
"userName": "Physical Therapy",
"relationship": "relationship",
"registeredAt": "2026-06-18T10:00:00Z",
"status": "registered",
"position": 1
}
]
}
}Register for activity
/api/v1/{tenant}/activities/{activityId}/registrationsRegisters a user (resident or connection) for an activity. For userType=resident: registering at capacity succeeds (201) with status=waitlisted rather than rejecting — see RegistrationDTO.status/position and LIFELOOP-5812. For userType=connection: capacity is still a hard limit (409 CAPACITY_REACHED/CONNECTION_CAPACITY_REACHED) — waitlisting is not yet supported for connections. 409 ALREADY_REGISTERED applies to both. For a recurring series, pass occurrenceDate to register for one specific occurrence rather than the series as a whole — see LIFELOOP-6108.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
activityId stringrequired |
Query parameters
occurrenceDate string<date>optional | For a recurring series' activityId, registers for a specific occurrence by date (matches the startDate returned for that occurrence by the activities list endpoint) instead of the series as a whole. If that occurrence isn't yet materialized as its own document, it's materialized first (same… |
Request body
userId stringrequired | For userType=resident, the resident's id. For userType=connection: which identifier is correct is currently unconfirmed. A connection's own id (as returned by GET /connections) does not work; a connection's externalId has worked in testing, but this is not yet a confirmed, stable contract — see… |
userType enum(resident, connection)required |
curl -X POST https://api.lifeloop.com/api/v1/sunrise-001/activities/act-001/registrations \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001" \
-H "Content-Type: application/json" \
-d '{
"userId": "use-001",
"userType": "resident"
}'{
"data": {
"activityId": "act-001",
"activityName": "Physical Therapy",
"activityType": "activityType",
"activityStartDate": "2026-06-18T10:00:00Z",
"activityEndDate": "2026-06-18T10:00:00Z",
"activityLocation": "activityLocation",
"facilityId": "fac-001",
"facilityName": "Physical Therapy",
"userId": "use-001",
"userType": "resident",
"userName": "Physical Therapy",
"relationship": "relationship",
"registeredAt": "2026-06-18T10:00:00Z",
"status": "registered",
"position": 1
}
}Cancel registration
/api/v1/{tenant}/activities/{activityId}/registrations/{userId}Cancels a user's registration for an activity and frees up capacity. For userType=resident: cancelling a status=registered entry automatically promotes the earliest-registered status=waitlisted entry (if any) to registered — see RegistrationDTO.status and LIFELOOP-5812. Cancelling a status=waitlisted entry does not trigger a promotion (no slot was freed). A promotion fires a registration.created webhook for the promoted user, in addition to the registration.deleted webhook fired for this cancellation (see LIFELOOP-5710). For a recurring series, pass occurrenceDate to cancel the registration for one specific occurrence only — other occurrences are unaffected. See LIFELOOP-6108.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
activityId stringrequired | |
userId stringrequired | For userType=resident, the resident's id. For userType=connection: the correct identifier is currently unconfirmed — a connection's own id (as returned by GET /connections) does not work here. Under investigation; see LIFELOOP-5822 and the connection-identity architecture ticket before assuming any… |
Query parameters
occurrenceDate string<date>optional | For a recurring series' activityId, cancels the registration for one specific occurrence by date (matches the startDate returned for that occurrence by the activities list endpoint), resolving to that occurrence's own materialized document rather than the master. Other occurrences' registrations… |
curl -X DELETE https://api.lifeloop.com/api/v1/sunrise-001/activities/act-001/registrations/use-001 \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"// 204 No ContentList resident's registrations
/api/v1/{tenant}/residents/{residentId}/registrationsReturns activity registrations for a resident within the specified date range
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
residentId stringrequired |
Query parameters
startDate string<date-time>required | Start of date range (ISO 8601 format) |
endDate string<date-time>required | End of date range (ISO 8601 format) |
curl https://api.lifeloop.com/api/v1/sunrise-001/residents/res-001/registrations?startDate=value&endDate=value \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"{
"data": [
{
"activityId": "act-001",
"activityName": "Physical Therapy",
"activityType": "activityType",
"activityStartDate": "2026-06-18T10:00:00Z",
"activityEndDate": "2026-06-18T10:00:00Z",
"activityLocation": "activityLocation",
"facilityId": "fac-001",
"facilityName": "Physical Therapy",
"userId": "use-001",
"userType": "resident",
"userName": "Physical Therapy",
"relationship": "relationship",
"registeredAt": "2026-06-18T10:00:00Z",
"status": "registered",
"position": 1
}
]
}List connection's registrations
/api/v1/{tenant}/connections/{connectionId}/registrationsReturns activity registrations for a connection within the specified date range
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
connectionId stringrequired |
Query parameters
startDate string<date-time>required | Start of date range (ISO 8601 format) |
endDate string<date-time>required | End of date range (ISO 8601 format) |
curl https://api.lifeloop.com/api/v1/sunrise-001/connections/con-001/registrations?startDate=value&endDate=value \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"{
"data": [
{
"activityId": "act-001",
"activityName": "Physical Therapy",
"activityType": "activityType",
"activityStartDate": "2026-06-18T10:00:00Z",
"activityEndDate": "2026-06-18T10:00:00Z",
"activityLocation": "activityLocation",
"facilityId": "fac-001",
"facilityName": "Physical Therapy",
"userId": "use-001",
"userType": "resident",
"userName": "Physical Therapy",
"relationship": "relationship",
"registeredAt": "2026-06-18T10:00:00Z",
"status": "registered",
"position": 1
}
]
}Check-Ins
List resident check-ins
/api/v1/{tenant}/residents/{residentId}/check-insReturns check-ins for a given resident within the specified date range.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
residentId stringrequired |
Query parameters
startDate string<date-time>required | Start of date range (ISO 8601 format) |
endDate string<date-time>required | End of date range (ISO 8601 format). Day 1 of the window is startDate's own calendar date (its time-of-day is ignored); the window runs through day 45's end (23:59:59) — equivalently, endDate must fall before day 46's midnight. A bare date and an end-of-day timestamp for the same calendar day are… |
curl https://api.lifeloop.com/api/v1/sunrise-001/residents/res-001/check-ins?startDate=value&endDate=value \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"{
"data": [
{
"id": "obj-001",
"startDate": "2026-06-18T10:00:00Z",
"durationInMinutes": 30,
"checkInStaff": {
"id": "obj-001",
"firstName": "Aileen",
"lastName": "Edmond"
},
"description": "description",
"created": "2026-06-18T10:00:00Z",
"modified": "2026-06-18T10:00:00Z"
}
]
}Create resident check-in
/api/v1/{tenant}/residents/{residentId}/check-insRecords a new check-in for a resident. Only one check-in per resident per calendar day is allowed; a second check-in on the same day returns 409 Conflict.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
residentId stringrequired |
Request body
startDate string<date-time>required | Date of the check-in. There is no time-of-day component. |
checkInStaffId stringrequired | ID of the staff member who performed the check-in. Phase 1 has no acting-user context, so this must be supplied explicitly. |
durationInMinutes integerrequired | Duration of the check-in in minutes. The UI offers a fixed quick-pick set (5/10/15/30/45/60/90/120, plus 0 for 'Unknown') but the backend field is an unconstrained number. Defaults to 15 in the UI. |
description stringoptional | Notes |
curl -X POST https://api.lifeloop.com/api/v1/sunrise-001/residents/res-001/check-ins \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001" \
-H "Content-Type: application/json" \
-d '{
"startDate": "2026-06-18T10:00:00Z",
"checkInStaffId": "che-001",
"durationInMinutes": 30,
"description": "description"
}'{
"data": {
"id": "obj-001",
"startDate": "2026-06-18T10:00:00Z",
"durationInMinutes": 30,
"checkInStaff": {
"id": "obj-001",
"firstName": "Aileen",
"lastName": "Edmond"
},
"description": "description",
"created": "2026-06-18T10:00:00Z",
"modified": "2026-06-18T10:00:00Z"
}
}Get resident check-in
/api/v1/{tenant}/residents/{residentId}/check-ins/{checkInId}Returns a single check-in by ID for a given resident.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
residentId stringrequired | |
checkInId stringrequired |
curl https://api.lifeloop.com/api/v1/sunrise-001/residents/res-001/check-ins/chk-001 \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"{
"data": {
"id": "obj-001",
"startDate": "2026-06-18T10:00:00Z",
"durationInMinutes": 30,
"checkInStaff": {
"id": "obj-001",
"firstName": "Aileen",
"lastName": "Edmond"
},
"description": "description",
"created": "2026-06-18T10:00:00Z",
"modified": "2026-06-18T10:00:00Z"
}
}Update resident check-in
/api/v1/{tenant}/residents/{residentId}/check-ins/{checkInId}Updates an existing check-in for a resident.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
residentId stringrequired | |
checkInId stringrequired |
Request body
startDate string<date-time>required | |
checkInStaffId stringrequired | |
durationInMinutes integerrequired | |
description stringoptional |
curl -X PUT https://api.lifeloop.com/api/v1/sunrise-001/residents/res-001/check-ins/chk-001 \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001" \
-H "Content-Type: application/json" \
-d '{
"startDate": "2026-06-18T10:00:00Z",
"checkInStaffId": "che-001",
"durationInMinutes": 30,
"description": "description"
}'{
"data": {
"id": "obj-001",
"startDate": "2026-06-18T10:00:00Z",
"durationInMinutes": 30,
"checkInStaff": {
"id": "obj-001",
"firstName": "Aileen",
"lastName": "Edmond"
},
"description": "description",
"created": "2026-06-18T10:00:00Z",
"modified": "2026-06-18T10:00:00Z"
}
}Delete resident check-in
/api/v1/{tenant}/residents/{residentId}/check-ins/{checkInId}Deletes a check-in for a resident.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
residentId stringrequired | |
checkInId stringrequired |
curl -X DELETE https://api.lifeloop.com/api/v1/sunrise-001/residents/res-001/check-ins/chk-001 \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"// 204 No ContentPersonal Visits
List resident personal visits
/api/v1/{tenant}/residents/{residentId}/personal-visitsReturns social and care visits for a given resident within the specified date range.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
residentId stringrequired |
Query parameters
startDate string<date-time>required | Start of date range (ISO 8601 format) |
endDate string<date-time>required | End of date range (ISO 8601 format). Day 1 of the window is startDate's own calendar date (its time-of-day is ignored); the window runs through day 45's end (23:59:59) — equivalently, endDate must fall before day 46's midnight. A bare date and an end-of-day timestamp for the same calendar day are… |
visitType enum(social, care)optional | Filter to a single visit type |
curl https://api.lifeloop.com/api/v1/sunrise-001/residents/res-001/personal-visits?startDate=value&endDate=value \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"{
"data": [
{
"id": "obj-001",
"name": "Physical Therapy",
"visitType": "care",
"startDate": "2026-06-18T10:00:00Z",
"startTime": "10:00",
"endTime": "10:00",
"timeType": "exactTime",
"durationInMinutes": 30,
"attendedResidentIds": [
"attendedResidentIds"
],
"connectionVisitors": [
{
"connectionId": null
}
],
"manualVisitors": [
{
"name": null,
"relationship": null
}
],
"description": "description",
"creator": {
"id": "obj-001",
"name": "Physical Therapy"
},
"created": "2026-06-18T10:00:00Z",
"modified": "2026-06-18T10:00:00Z"
}
]
}Create resident personal visit
/api/v1/{tenant}/residents/{residentId}/personal-visitsCreates a new social or care visit for a resident.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
residentId stringrequired |
Request body
name stringrequired | |
visitType enum(care, social)required | |
startDate string<date-time>required | |
startTime stringoptional | Required when timeType is 'exactTime' (the default when omitted). |
endTime stringoptional | Required when timeType is 'exactTime' (the default when omitted). |
timeType enum(exactTime, allDay, morning, afternoon, evening)optional | When 'exactTime' (the default), startTime/endTime are required and durationInMinutes reflects their gap. For any other value, durationInMinutes is used directly and startTime/endTime are not required. |
durationInMinutes integerrequired | Always required regardless of timeType. |
additionalAttendeeResidentIds array<string>optional | IDs of additional residents to include on the visit beyond the primary resident specified in the path |
connectionVisitors array<object>optional | Visitors selected from the resident's existing Connections. At least one visitor, combined across this and manualVisitors, is required regardless of visitType. |
manualVisitors array<object>optional | Visitors entered as free text, not tied to a Connection. At least one visitor, combined across this and connectionVisitors, is required regardless of visitType. |
description stringoptional |
curl -X POST https://api.lifeloop.com/api/v1/sunrise-001/residents/res-001/personal-visits \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001" \
-H "Content-Type: application/json" \
-d '{
"name": "Physical Therapy",
"visitType": "care",
"startDate": "2026-06-18T10:00:00Z",
"startTime": "10:00",
"endTime": "10:00",
"timeType": "exactTime",
"durationInMinutes": 30,
"additionalAttendeeResidentIds": [
"additionalAttendeeResidentIds"
],
"connectionVisitors": [
{
"connectionId": "con-001"
}
],
"manualVisitors": [
{
"name": "Physical Therapy",
"relationship": "relationship"
}
],
"description": "description"
}'{
"data": {
"id": "obj-001",
"name": "Physical Therapy",
"visitType": "care",
"startDate": "2026-06-18T10:00:00Z",
"startTime": "10:00",
"endTime": "10:00",
"timeType": "exactTime",
"durationInMinutes": 30,
"attendedResidentIds": [
"attendedResidentIds"
],
"connectionVisitors": [
{
"connectionId": "con-001"
}
],
"manualVisitors": [
{
"name": "Physical Therapy",
"relationship": "relationship"
}
],
"description": "description",
"creator": {
"id": "obj-001",
"name": "Physical Therapy"
},
"created": "2026-06-18T10:00:00Z",
"modified": "2026-06-18T10:00:00Z"
}
}Get resident personal visit
/api/v1/{tenant}/residents/{residentId}/personal-visits/{visitId}Returns a single personal visit by ID for a given resident.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
residentId stringrequired | |
visitId stringrequired |
curl https://api.lifeloop.com/api/v1/sunrise-001/residents/res-001/personal-visits/vis-001 \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"{
"data": {
"id": "obj-001",
"name": "Physical Therapy",
"visitType": "care",
"startDate": "2026-06-18T10:00:00Z",
"startTime": "10:00",
"endTime": "10:00",
"timeType": "exactTime",
"durationInMinutes": 30,
"attendedResidentIds": [
"attendedResidentIds"
],
"connectionVisitors": [
{
"connectionId": "con-001"
}
],
"manualVisitors": [
{
"name": "Physical Therapy",
"relationship": "relationship"
}
],
"description": "description",
"creator": {
"id": "obj-001",
"name": "Physical Therapy"
},
"created": "2026-06-18T10:00:00Z",
"modified": "2026-06-18T10:00:00Z"
}
}Update resident personal visit
/api/v1/{tenant}/residents/{residentId}/personal-visits/{visitId}Updates an existing personal visit for a resident.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
residentId stringrequired | |
visitId stringrequired |
Request body
name stringrequired | |
visitType enum(care, social)required | |
startDate string<date-time>required | |
startTime stringoptional | |
endTime stringoptional | |
timeType enum(exactTime, allDay, morning, afternoon, evening)optional | |
durationInMinutes integerrequired | |
additionalAttendeeResidentIds array<string>optional | |
connectionVisitors array<object>optional | At least one visitor, combined across this and manualVisitors, is required regardless of visitType. |
manualVisitors array<object>optional | At least one visitor, combined across this and connectionVisitors, is required regardless of visitType. |
description stringoptional |
curl -X PUT https://api.lifeloop.com/api/v1/sunrise-001/residents/res-001/personal-visits/vis-001 \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001" \
-H "Content-Type: application/json" \
-d '{
"name": "Physical Therapy",
"visitType": "care",
"startDate": "2026-06-18T10:00:00Z",
"startTime": "10:00",
"endTime": "10:00",
"timeType": "exactTime",
"durationInMinutes": 30,
"additionalAttendeeResidentIds": [
"additionalAttendeeResidentIds"
],
"connectionVisitors": [
{
"connectionId": "con-001"
}
],
"manualVisitors": [
{
"name": "Physical Therapy",
"relationship": "relationship"
}
],
"description": "description"
}'{
"data": {
"id": "obj-001",
"name": "Physical Therapy",
"visitType": "care",
"startDate": "2026-06-18T10:00:00Z",
"startTime": "10:00",
"endTime": "10:00",
"timeType": "exactTime",
"durationInMinutes": 30,
"attendedResidentIds": [
"attendedResidentIds"
],
"connectionVisitors": [
{
"connectionId": "con-001"
}
],
"manualVisitors": [
{
"name": "Physical Therapy",
"relationship": "relationship"
}
],
"description": "description",
"creator": {
"id": "obj-001",
"name": "Physical Therapy"
},
"created": "2026-06-18T10:00:00Z",
"modified": "2026-06-18T10:00:00Z"
}
}Delete resident personal visit
/api/v1/{tenant}/residents/{residentId}/personal-visits/{visitId}Deletes a personal visit for a resident.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
residentId stringrequired | |
visitId stringrequired |
curl -X DELETE https://api.lifeloop.com/api/v1/sunrise-001/residents/res-001/personal-visits/vis-001 \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"// 204 No ContentAttendance
List activity attendance
/api/v1/{tenant}/activities/{activityId}/attendanceReturns all attendance records (residents and connections) for an activity
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
activityId stringrequired |
curl https://api.lifeloop.com/api/v1/sunrise-001/activities/act-001/attendance \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"{
"data": {
"activityId": "act-001",
"activityName": "Physical Therapy",
"activityStartDate": "2026-06-18T10:00:00Z",
"attendanceRecords": [
{
"userId": "use-001",
"userType": "resident",
"userName": "Physical Therapy",
"relationship": "relationship",
"status": "attended",
"markedAt": "2026-06-18T10:00:00Z",
"declineReason": "declineReason",
"duration": 30
}
]
}
}Mark attendance
/api/v1/{tenant}/activities/{activityId}/attendanceMarks attendance for a user (attended or declined) with timestamp and optional quality rating or decline reason.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
activityId stringrequired |
Request body
userId stringrequired | |
userType enum(resident, connection)required | |
status enum(attended, declined)required | |
declineReason stringoptional | Required when status is declined. Known values: 'Sleeping', 'Feeling ill', 'Not interested', 'Out of facility', 'Other'. |
duration integeroptional | Duration in minutes (optional) |
curl -X POST https://api.lifeloop.com/api/v1/sunrise-001/activities/act-001/attendance \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001" \
-H "Content-Type: application/json" \
-d '{
"userId": "use-001",
"userType": "resident",
"status": "attended",
"declineReason": "declineReason",
"duration": 30
}'{
"data": {
"activityId": "act-001",
"activityName": "Physical Therapy",
"activityType": "activityType",
"activityStartDate": "2026-06-18T10:00:00Z",
"activityEndDate": "2026-06-18T10:00:00Z",
"activityLocation": "activityLocation",
"facilityId": "fac-001",
"facilityName": "Physical Therapy",
"userId": "use-001",
"userType": "resident",
"userName": "Physical Therapy",
"relationship": "relationship",
"status": "attended",
"markedAt": "2026-06-18T10:00:00Z",
"declineReason": "declineReason",
"duration": 30
}
}Update attendance
/api/v1/{tenant}/activities/{activityId}/attendance/{userId}Updates an existing attendance record (e.g., change rating or decline reason).
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
activityId stringrequired | |
userId stringrequired | Can be resident ID or connection ID |
Request body
declineReason stringoptional | |
duration integeroptional |
curl -X PUT https://api.lifeloop.com/api/v1/sunrise-001/activities/act-001/attendance/use-001 \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001" \
-H "Content-Type: application/json" \
-d '{
"declineReason": "declineReason",
"duration": 30
}'{
"data": {
"activityId": "act-001",
"activityName": "Physical Therapy",
"activityType": "activityType",
"activityStartDate": "2026-06-18T10:00:00Z",
"activityEndDate": "2026-06-18T10:00:00Z",
"activityLocation": "activityLocation",
"facilityId": "fac-001",
"facilityName": "Physical Therapy",
"userId": "use-001",
"userType": "resident",
"userName": "Physical Therapy",
"relationship": "relationship",
"status": "attended",
"markedAt": "2026-06-18T10:00:00Z",
"declineReason": "declineReason",
"duration": 30
}
}Delete attendance
/api/v1/{tenant}/activities/{activityId}/attendance/{userId}Removes an attendance record for a user
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
activityId stringrequired | |
userId stringrequired | Can be resident ID or connection ID |
curl -X DELETE https://api.lifeloop.com/api/v1/sunrise-001/activities/act-001/attendance/use-001 \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"// 204 No ContentList resident's attendance
/api/v1/{tenant}/residents/{residentId}/attendanceReturns attendance records for a resident within the specified date range
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
residentId stringrequired |
Query parameters
startDate string<date-time>required | Start of date range (ISO 8601 format) |
endDate string<date-time>required | End of date range (ISO 8601 format) |
curl https://api.lifeloop.com/api/v1/sunrise-001/residents/res-001/attendance?startDate=value&endDate=value \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"{
"data": [
{
"activityId": "act-001",
"activityName": "Physical Therapy",
"activityType": "activityType",
"activityStartDate": "2026-06-18T10:00:00Z",
"activityEndDate": "2026-06-18T10:00:00Z",
"activityLocation": "activityLocation",
"facilityId": "fac-001",
"facilityName": "Physical Therapy",
"userId": "use-001",
"userType": "resident",
"userName": "Physical Therapy",
"relationship": "relationship",
"status": "attended",
"markedAt": "2026-06-18T10:00:00Z",
"declineReason": "declineReason",
"duration": 30
}
]
}Albums
List facility albums
/api/v1/{tenant}/facilities/{facilityId}/albumsReturns all albums for a facility. NOTE: Album creation and management is a staff-only operation performed in the LifeLoop staff platform. This endpoint is read-only, intended for Sunrise to list available albums so residents and connections can browse photos grouped by album.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
facilityId stringrequired |
curl https://api.lifeloop.com/api/v1/sunrise-001/facilities/fac-001/albums \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"{
"data": [
{
"id": "obj-001",
"title": "Physical Therapy",
"type": "all",
"facilities": [
"facilities"
],
"sharedAcrossCommunities": true,
"createdAt": "2026-06-18T10:00:00Z"
}
]
}Get album
/api/v1/{tenant}/facilities/{facilityId}/albums/{albumId}Returns a single album by ID for the given facility.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
facilityId stringrequired | |
albumId stringrequired |
curl https://api.lifeloop.com/api/v1/sunrise-001/facilities/fac-001/albums/alb-001 \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"{
"id": "obj-001",
"title": "Physical Therapy",
"type": "all",
"facilities": [
"facilities"
],
"sharedAcrossCommunities": true,
"createdAt": "2026-06-18T10:00:00Z"
}Photos
List facility photos
/api/v1/{tenant}/facilities/{facilityId}/photosReturns photos for a facility with optional filtering and pagination
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
facilityId stringrequired |
Query parameters
cursor stringoptional | Opaque cursor for the next page, taken from the previous response's nextCursor. Omit to fetch the first page. Treat as an opaque token — its encoding may change between releases. |
pageSize integeroptionaldefault: 50 | Number of items to return (default 50, max 100). |
albumId stringoptional | Filter by album ID |
tags stringoptional | Comma-separated list of tag IDs |
residentId stringoptional | Filter by tagged resident |
captionSearch stringoptional | Text search in captions |
curl https://api.lifeloop.com/api/v1/sunrise-001/facilities/fac-001/photos \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"{
"data": [
{
"id": "obj-001",
"url": "https://cdn.lifeloop.com/url",
"thumbUrl": "https://cdn.lifeloop.com/thumbUrl",
"type": "gallery",
"caption": {
"text": null,
"creatorId": null,
"created": null
},
"creatorId": "cre-001",
"creatorName": "Physical Therapy",
"facilities": [],
"users": [],
"tags": [],
"albumIds": [],
"created": "2026-06-18T10:00:00Z",
"deleted": true
}
],
"nextCursor": null,
"hasMore": true
}List resident photos
/api/v1/{tenant}/residents/{residentId}/photosReturns photos where the resident is tagged with optional filtering and pagination
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
residentId stringrequired |
Query parameters
cursor stringoptional | Opaque cursor for the next page, taken from the previous response's nextCursor. Omit to fetch the first page. Treat as an opaque token — its encoding may change between releases. |
pageSize integeroptionaldefault: 50 | Number of items to return (default 50, max 100). |
albumId stringoptional | Filter by album ID |
tags stringoptional | Comma-separated list of tag IDs |
captionSearch stringoptional | Text search in captions |
curl https://api.lifeloop.com/api/v1/sunrise-001/residents/res-001/photos \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"{
"data": [
{
"id": "obj-001",
"url": "https://cdn.lifeloop.com/url",
"thumbUrl": "https://cdn.lifeloop.com/thumbUrl",
"type": "gallery",
"caption": {
"text": null,
"creatorId": null,
"created": null
},
"creatorId": "cre-001",
"creatorName": "Physical Therapy",
"facilities": [],
"users": [],
"tags": [],
"albumIds": [],
"created": "2026-06-18T10:00:00Z",
"deleted": true
}
],
"nextCursor": null,
"hasMore": true
}Upload photo
/api/v1/{tenant}/photosUploads a new photo with multipart/form-data
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
Request body
file string<binary>required | Image file to upload |
facilities stringrequired | Comma-separated facility IDs |
users stringoptional | Comma-separated user IDs to tag (optional) |
albumId stringoptional | Album ID (optional) |
type enum(gallery, activity, family, dining, designer, postcard)optional | Photo type (optional, defaults to gallery) |
caption stringoptional | Caption text (optional) |
curl -X POST https://api.lifeloop.com/api/v1/sunrise-001/photos \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"{
"data": {
"id": "obj-001",
"url": "https://cdn.lifeloop.com/url",
"thumbUrl": "https://cdn.lifeloop.com/thumbUrl",
"type": "gallery",
"caption": {
"text": "text",
"creatorId": "cre-001",
"created": "2026-06-18T10:00:00Z"
},
"creatorId": "cre-001",
"creatorName": "Physical Therapy",
"facilities": [
"facilities"
],
"users": [
"users"
],
"tags": [
"tags"
],
"albumIds": [
"albumIds"
],
"created": "2026-06-18T10:00:00Z",
"deleted": true
}
}Get photo
/api/v1/{tenant}/photos/{photoId}Returns a single photo by ID including CDN URLs, caption and tags
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
photoId stringrequired |
curl https://api.lifeloop.com/api/v1/sunrise-001/photos/pho-001 \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"{
"data": {
"id": "obj-001",
"url": "https://cdn.lifeloop.com/url",
"thumbUrl": "https://cdn.lifeloop.com/thumbUrl",
"type": "gallery",
"caption": {
"text": "text",
"creatorId": "cre-001",
"created": "2026-06-18T10:00:00Z"
},
"creatorId": "cre-001",
"creatorName": "Physical Therapy",
"facilities": [
"facilities"
],
"users": [
"users"
],
"tags": [
"tags"
],
"albumIds": [
"albumIds"
],
"created": "2026-06-18T10:00:00Z",
"deleted": true
}
}Update photo
/api/v1/{tenant}/photos/{photoId}Updates a photo's caption, tags or tagged users
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
photoId stringrequired |
Request body
caption stringoptional | Update caption text |
users array<string>optional | Update tagged user IDs |
tags array<string>optional | Update tag IDs |
curl -X PUT https://api.lifeloop.com/api/v1/sunrise-001/photos/pho-001 \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001" \
-H "Content-Type: application/json" \
-d '{
"caption": "caption",
"users": [
"users"
],
"tags": [
"tags"
]
}'{
"data": {
"id": "obj-001",
"url": "https://cdn.lifeloop.com/url",
"thumbUrl": "https://cdn.lifeloop.com/thumbUrl",
"type": "gallery",
"caption": {
"text": "text",
"creatorId": "cre-001",
"created": "2026-06-18T10:00:00Z"
},
"creatorId": "cre-001",
"creatorName": "Physical Therapy",
"facilities": [
"facilities"
],
"users": [
"users"
],
"tags": [
"tags"
],
"albumIds": [
"albumIds"
],
"created": "2026-06-18T10:00:00Z",
"deleted": true
}
}Delete photo
/api/v1/{tenant}/photos/{photoId}Soft-deletes a photo by ID
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
photoId stringrequired |
curl -X DELETE https://api.lifeloop.com/api/v1/sunrise-001/photos/pho-001 \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"// 204 No ContentList activity photos
/api/v1/{tenant}/activities/{activityId}/photosReturns photos for an activity with optional pagination
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
activityId stringrequired |
Query parameters
cursor stringoptional | Opaque cursor for the next page, taken from the previous response's nextCursor. Omit to fetch the first page. Treat as an opaque token — its encoding may change between releases. |
pageSize integeroptionaldefault: 50 | Number of items to return (default 50, max 100). |
captionSearch stringoptional | Text search in captions |
curl https://api.lifeloop.com/api/v1/sunrise-001/activities/act-001/photos \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"{
"data": [
{
"id": "obj-001",
"url": "https://cdn.lifeloop.com/url",
"thumbUrl": "https://cdn.lifeloop.com/thumbUrl",
"type": "gallery",
"caption": {
"text": null,
"creatorId": null,
"created": null
},
"creatorId": "cre-001",
"creatorName": "Physical Therapy",
"facilities": [],
"users": [],
"tags": [],
"albumIds": [],
"created": "2026-06-18T10:00:00Z",
"deleted": true
}
],
"nextCursor": null,
"hasMore": true
}Upload activity photo
/api/v1/{tenant}/activities/{activityId}/photosUploads a photo for an activity with multipart/form-data.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
activityId stringrequired |
Request body
file string<binary>required | Image file to upload |
facilities stringrequired | Comma-separated facility IDs |
users stringoptional | Comma-separated user IDs to tag (optional) |
caption stringoptional | Caption text (optional) |
curl -X POST https://api.lifeloop.com/api/v1/sunrise-001/activities/act-001/photos \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"{
"data": {
"id": "obj-001",
"url": "https://cdn.lifeloop.com/url",
"thumbUrl": "https://cdn.lifeloop.com/thumbUrl",
"type": "gallery",
"caption": {
"text": "text",
"creatorId": "cre-001",
"created": "2026-06-18T10:00:00Z"
},
"creatorId": "cre-001",
"creatorName": "Physical Therapy",
"facilities": [
"facilities"
],
"users": [
"users"
],
"tags": [
"tags"
],
"albumIds": [
"albumIds"
],
"created": "2026-06-18T10:00:00Z",
"deleted": true
}
}Messages
List conversations
/api/v1/{tenant}/messages/threadsReturns all message threads/conversations for the current user with optional filters
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
Query parameters
filter enum(archived, active)optional | Filter by archived or active conversations |
searchValue stringoptional | Free-text search in conversation titles |
cursor stringoptional | Opaque cursor for the next page, taken from the previous response's nextCursor. Omit to fetch the first page. Treat as an opaque token — its encoding may change between releases. |
pageSize integeroptionaldefault: 50 | Number of items to return (default 50, max 100). |
curl https://api.lifeloop.com/api/v1/sunrise-001/messages/threads \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"{
"data": [
{
"id": "obj-001",
"title": "Physical Therapy",
"participants": [],
"lastMessageAt": "2026-06-18T10:00:00Z",
"lastMessage": "lastMessage",
"unreadCount": 1,
"isArchived": false,
"isMuted": false,
"hasRead": true,
"createdAt": "2026-06-18T10:00:00Z"
}
],
"nextCursor": null,
"hasMore": true
}Create conversation
/api/v1/{tenant}/messages/threadsCreates a new conversation with specified participants. As of v1.8, creatorId is required and recipient permissions are enforced server-side: if the creator is a resident or family/connection user, every staff participant must have opted into family/resident messaging (MESSAGE_FAMILY_RESIDENTS permission), or the request is rejected with 403.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
Request body
participantIds array<string>required | Array of user IDs to include in the conversation. The creator (creatorId) is added automatically if not already present. |
creatorId stringrequired | LifeLoop user ID of the person starting the thread. Required as of v1.8 — used to enforce recipient permissions server-side (e.g. a resident/family creator may only include staff who've opted into family messaging). See LIFELOOP-5704 change note. |
title stringoptional | Optional thread title |
curl -X POST https://api.lifeloop.com/api/v1/sunrise-001/messages/threads \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001" \
-H "Content-Type: application/json" \
-d '{
"participantIds": [
"participantIds"
],
"creatorId": "cre-001",
"title": "Physical Therapy"
}'{
"data": {
"id": "obj-001",
"title": "Physical Therapy",
"participants": [
{
"id": "obj-001",
"fullName": "Physical Therapy",
"type": "resident",
"thumbUrl": "https://cdn.lifeloop.com/thumbUrl",
"declinedPhotoRelease": true,
"status": "status"
}
],
"lastMessageAt": "2026-06-18T10:00:00Z",
"lastMessage": "lastMessage",
"unreadCount": 1,
"isArchived": false,
"isMuted": false,
"hasRead": true,
"createdAt": "2026-06-18T10:00:00Z"
}
}Search conversations
/api/v1/{tenant}/messages/threads/searchSearch threads by criteria with optional message content search
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
Request body
searchValue stringoptional | Search in thread titles or message content |
participantId stringoptional | Filter by participant user ID |
isArchived booleanoptional | Filter by archived status |
curl -X POST https://api.lifeloop.com/api/v1/sunrise-001/messages/threads/search \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001" \
-H "Content-Type: application/json" \
-d '{
"searchValue": "searchValue",
"participantId": "par-001",
"isArchived": false
}'{
"data": [
{
"id": "obj-001",
"title": "Physical Therapy",
"participants": [],
"lastMessageAt": "2026-06-18T10:00:00Z",
"lastMessage": "lastMessage",
"unreadCount": 1,
"isArchived": false,
"isMuted": false,
"hasRead": true,
"createdAt": "2026-06-18T10:00:00Z"
}
],
"nextCursor": null,
"hasMore": true
}Get conversation
/api/v1/{tenant}/messages/threads/{threadId}Returns a single conversation by ID with full participant list
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
threadId stringrequired |
curl https://api.lifeloop.com/api/v1/sunrise-001/messages/threads/thr-001 \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"{
"data": {
"id": "obj-001",
"title": "Physical Therapy",
"participants": [
{
"id": "obj-001",
"fullName": "Physical Therapy",
"type": "resident",
"thumbUrl": "https://cdn.lifeloop.com/thumbUrl",
"declinedPhotoRelease": true,
"status": "status"
}
],
"lastMessageAt": "2026-06-18T10:00:00Z",
"lastMessage": "lastMessage",
"unreadCount": 1,
"isArchived": false,
"isMuted": false,
"hasRead": true,
"createdAt": "2026-06-18T10:00:00Z"
}
}Rename conversation
/api/v1/{tenant}/messages/threads/{threadId}Updates the title of a conversation
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
threadId stringrequired |
Request body
title stringoptional | Updated thread title |
curl -X PUT https://api.lifeloop.com/api/v1/sunrise-001/messages/threads/thr-001 \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001" \
-H "Content-Type: application/json" \
-d '{
"title": "Physical Therapy"
}'{
"data": {
"id": "obj-001",
"title": "Physical Therapy",
"participants": [
{
"id": "obj-001",
"fullName": "Physical Therapy",
"type": "resident",
"thumbUrl": "https://cdn.lifeloop.com/thumbUrl",
"declinedPhotoRelease": true,
"status": "status"
}
],
"lastMessageAt": "2026-06-18T10:00:00Z",
"lastMessage": "lastMessage",
"unreadCount": 1,
"isArchived": false,
"isMuted": false,
"hasRead": true,
"createdAt": "2026-06-18T10:00:00Z"
}
}Hide/archive conversation
/api/v1/{tenant}/messages/threads/{threadId}Hides/archives a conversation for the current user (per-actor; auto-clears on next inbound message)
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
threadId stringrequired |
curl -X DELETE https://api.lifeloop.com/api/v1/sunrise-001/messages/threads/thr-001 \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"// 204 No ContentLeave conversation
/api/v1/{tenant}/messages/threads/{threadId}/leavePermanently leaves a conversation
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
threadId stringrequired |
curl -X PUT https://api.lifeloop.com/api/v1/sunrise-001/messages/threads/thr-001/leave \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"// 204 No ContentMute/unmute conversation
/api/v1/{tenant}/messages/threads/{threadId}/muteMutes or unmutes notifications for a conversation. Pass isMuted=true to mute, isMuted=false to unmute.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
threadId stringrequired |
Query parameters
isMuted booleanrequired | True to mute, false to unmute |
curl -X PUT https://api.lifeloop.com/api/v1/sunrise-001/messages/threads/thr-001/mute?isMuted=value \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"// 204 No ContentMark thread as read
/api/v1/{tenant}/messages/threads/{threadId}/readUpdates the read receipt for the acting user on this thread, setting their lastRead timestamp to now. The hasRead field on the thread response will reflect this change on the next fetch.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
threadId stringrequired |
curl -X PUT https://api.lifeloop.com/api/v1/sunrise-001/messages/threads/thr-001/read \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"// 204 No ContentList messages in conversation
/api/v1/{tenant}/messages/threads/{threadId}/messagesReturns messages in a conversation, newest first. As of v1.9, use cursor for infinite scroll. The previously-documented before parameter was never actually implemented in the backend and has been removed. page has also been removed outright — no dual-support transition window, consistent with the rest of the v1.9 pagination cutover.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
threadId stringrequired |
Query parameters
cursor stringoptional | Opaque cursor for the next page, taken from the previous response's nextCursor. Omit to fetch the first page. Treat as an opaque token — its encoding may change between releases. |
pageSize integeroptionaldefault: 50 | Number of items to return (default 50, max 100). |
searchValue stringoptional | Filter messages to those whose body contains this search string (case-insensitive) |
curl https://api.lifeloop.com/api/v1/sunrise-001/messages/threads/thr-001/messages \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"{
"data": [
{
"id": "obj-001",
"threadId": "thr-001",
"body": "body",
"author": {
"id": null,
"fullName": null,
"type": null,
"thumbUrl": null,
"declinedPhotoRelease": null,
"status": null
},
"status": "sent",
"attachment": {
"id": null,
"url": null,
"type": null,
"name": null,
"size": null
},
"createdAt": "2026-06-18T10:00:00Z",
"scheduledAt": "2026-06-18T10:00:00Z",
"isDeleted": false
}
],
"nextCursor": null,
"hasMore": true
}Send message
/api/v1/{tenant}/messages/threads/{threadId}/messagesSends a message in a conversation with optional attachment and scheduled send time
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
threadId stringrequired |
Request body
body stringrequired | Message text |
file string<binary>optional | Optional file attachment |
scheduledAt string<date-time>optional | Optional scheduled send time |
curl -X POST https://api.lifeloop.com/api/v1/sunrise-001/messages/threads/thr-001/messages \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"{
"data": {
"id": "obj-001",
"threadId": "thr-001",
"body": "body",
"author": {
"id": "obj-001",
"fullName": "Physical Therapy",
"type": "resident",
"thumbUrl": "https://cdn.lifeloop.com/thumbUrl",
"declinedPhotoRelease": true,
"status": "status"
},
"status": "sent",
"attachment": {
"id": "obj-001",
"url": "https://cdn.lifeloop.com/url",
"type": "type",
"name": "Physical Therapy",
"size": 1
},
"createdAt": "2026-06-18T10:00:00Z",
"scheduledAt": "2026-06-18T10:00:00Z",
"isDeleted": false
}
}Stream message attachment
/api/v1/{tenant}/messages/threads/{threadId}/attachments/{attachmentId}Streams (downloads) a file attachment associated with a message in this thread. Returns the file as a binary stream. attachmentId is the id field of the message's attachment object (see MessageAttachmentDTO). Requires an acting user: send X-Acting-User-Id (or the legacy X-User-Id); without one the request is rejected with 400.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
threadId stringrequired | |
attachmentId stringrequired |
curl https://api.lifeloop.com/api/v1/sunrise-001/messages/threads/thr-001/attachments/att-001 \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001""<binary>"Get message
/api/v1/{tenant}/messages/threads/{threadId}/messages/{messageId}Returns a single message by ID within a thread.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
threadId stringrequired | |
messageId stringrequired |
curl https://api.lifeloop.com/api/v1/sunrise-001/messages/threads/thr-001/messages/msg-001 \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"{
"data": {
"id": "obj-001",
"threadId": "thr-001",
"body": "body",
"author": {
"id": "obj-001",
"fullName": "Physical Therapy",
"type": "resident",
"thumbUrl": "https://cdn.lifeloop.com/thumbUrl",
"declinedPhotoRelease": true,
"status": "status"
},
"status": "sent",
"attachment": {
"id": "obj-001",
"url": "https://cdn.lifeloop.com/url",
"type": "type",
"name": "Physical Therapy",
"size": 1
},
"createdAt": "2026-06-18T10:00:00Z",
"scheduledAt": "2026-06-18T10:00:00Z",
"isDeleted": false
}
}Update message
/api/v1/{tenant}/messages/threads/{threadId}/messages/{messageId}Edits the body or scheduled time of an existing message (sender only)
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
threadId stringrequired | |
messageId stringrequired |
Request body
body stringoptional | Updated message text |
scheduledAt string<date-time>optional | Updated scheduled send time |
curl -X PUT https://api.lifeloop.com/api/v1/sunrise-001/messages/threads/thr-001/messages/msg-001 \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001" \
-H "Content-Type: application/json" \
-d '{
"body": "body",
"scheduledAt": "2026-06-18T10:00:00Z"
}'{
"data": {
"id": "obj-001",
"threadId": "thr-001",
"body": "body",
"author": {
"id": "obj-001",
"fullName": "Physical Therapy",
"type": "resident",
"thumbUrl": "https://cdn.lifeloop.com/thumbUrl",
"declinedPhotoRelease": true,
"status": "status"
},
"status": "sent",
"attachment": {
"id": "obj-001",
"url": "https://cdn.lifeloop.com/url",
"type": "type",
"name": "Physical Therapy",
"size": 1
},
"createdAt": "2026-06-18T10:00:00Z",
"scheduledAt": "2026-06-18T10:00:00Z",
"isDeleted": false
}
}Delete message
/api/v1/{tenant}/messages/threads/{threadId}/messages/{messageId}Soft-deletes a message (sender only)
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
threadId stringrequired | |
messageId stringrequired |
curl -X DELETE https://api.lifeloop.com/api/v1/sunrise-001/messages/threads/thr-001/messages/msg-001 \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"// 204 No ContentList possible message recipients for resident
/api/v1/{tenant}/residents/{residentId}/messages/recipientsReturns people the resident can select as recipients when starting a new message thread — the picker backing a 'New Message' screen with Residents/Connections/Staff tabs. Excludes the resident themselves. Staff are only included if they've opted into family/resident messaging (MESSAGE_FAMILY_RESIDENTS permission) — this filtering is enforced server-side, not left to the client.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
residentId stringrequired |
Query parameters
type enum(resident, family, staff)optional | Filter to a single recipient-picker tab. Omit to return all three types in one paginated list. |
facilityId stringoptional | Filter to a specific facility. Defaults to the resident's own facility if omitted. |
search stringoptional | Case-insensitive substring match against recipient name |
cursor stringoptional | Opaque cursor for the next page, taken from the previous response's nextCursor. Omit to fetch the first page. Treat as an opaque token — its encoding may change between releases. |
pageSize integeroptionaldefault: 50 | Number of items to return (default 50, max 100). |
curl https://api.lifeloop.com/api/v1/sunrise-001/residents/res-001/messages/recipients \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"{
"data": [
{
"id": "obj-001",
"name": "Physical Therapy",
"type": "resident",
"facilityId": "fac-001",
"facilityName": "Physical Therapy",
"thumbUrl": "https://cdn.lifeloop.com/thumbUrl"
}
],
"nextCursor": null,
"hasMore": true
}List possible message recipients for connection
/api/v1/{tenant}/connections/{connectionId}/messages/recipientsReturns people the connection can select as recipients when starting a new message thread. Excludes the connection themselves. Staff are only included if they've opted into family/resident messaging (MESSAGE_FAMILY_RESIDENTS permission) — enforced server-side. Residents are scoped to the residents this connection is associated with.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
connectionId stringrequired |
Query parameters
type enum(resident, family, staff)optional | Filter to a single recipient-picker tab. Omit to return all three types in one paginated list. |
facilityId stringoptional | Filter to a specific facility. Defaults to the facilities of the connection's associated residents if omitted. |
search stringoptional | Case-insensitive substring match against recipient name |
cursor stringoptional | Opaque cursor for the next page, taken from the previous response's nextCursor. Omit to fetch the first page. Treat as an opaque token — its encoding may change between releases. |
pageSize integeroptionaldefault: 50 | Number of items to return (default 50, max 100). |
curl https://api.lifeloop.com/api/v1/sunrise-001/connections/con-001/messages/recipients \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"{
"data": [
{
"id": "obj-001",
"name": "Physical Therapy",
"type": "resident",
"facilityId": "fac-001",
"facilityName": "Physical Therapy",
"thumbUrl": "https://cdn.lifeloop.com/thumbUrl"
}
],
"nextCursor": null,
"hasMore": true
}Announcements
List announcements for resident
/api/v1/{tenant}/residents/{residentId}/announcementsReturns announcements visible to a specific resident based on facility and recipient groups. Requires X-Acting-User-Id (v1.15) resolving to this same resident, or an Enterprise system-actor identity.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
residentId stringrequired |
Query parameters
status enum(pending, sent, canceled)optional | Filter by announcement status |
isRead booleanoptional | Filter by read status |
cursor stringoptional | Opaque cursor for the next page, taken from the previous response's nextCursor. Omit to fetch the first page. Treat as an opaque token — its encoding may change between releases. |
pageSize integeroptionaldefault: 50 | Number of items to return (default 50, max 100). |
curl https://api.lifeloop.com/api/v1/sunrise-001/residents/res-001/announcements \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"{
"data": [
{
"id": "obj-001",
"from": "from",
"subject": "subject",
"message": "message",
"smsMessage": "smsMessage",
"recipientGroups": [],
"facilities": [],
"status": "pending",
"scheduledAt": "2026-06-18T10:00:00Z",
"createdBy": "createdBy",
"createdAt": "2026-06-18T10:00:00Z",
"attachments": [],
"isRead": false,
"isArchived": false
}
],
"nextCursor": null,
"hasMore": true
}Get announcement for resident
/api/v1/{tenant}/residents/{residentId}/announcements/{announcementId}Returns a single announcement by ID for a specific resident. Requires X-Acting-User-Id (v1.15) resolving to this same resident, or an Enterprise system-actor identity.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
residentId stringrequired | |
announcementId stringrequired |
curl https://api.lifeloop.com/api/v1/sunrise-001/residents/res-001/announcements/ann-001 \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"{
"data": {
"id": "obj-001",
"from": "from",
"subject": "subject",
"message": "message",
"smsMessage": "smsMessage",
"recipientGroups": [
"recipientGroups"
],
"facilities": [
"facilities"
],
"status": "pending",
"scheduledAt": "2026-06-18T10:00:00Z",
"createdBy": "createdBy",
"createdAt": "2026-06-18T10:00:00Z",
"attachments": [
{
"id": "obj-001",
"name": "Physical Therapy",
"size": 1,
"extension": "extension"
}
],
"isRead": false,
"isArchived": false
}
}Archive announcement for resident
/api/v1/{tenant}/residents/{residentId}/announcements/{announcementId}/archiveArchives an announcement for the resident. Requires X-Acting-User-Id (v1.15) resolving to this same resident, or an Enterprise system-actor identity.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
residentId stringrequired | |
announcementId stringrequired |
curl -X POST https://api.lifeloop.com/api/v1/sunrise-001/residents/res-001/announcements/ann-001/archive \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"// 204 No ContentUnarchive announcement for resident
/api/v1/{tenant}/residents/{residentId}/announcements/{announcementId}/unarchiveRemoves an announcement from archive for the resident. Requires X-Acting-User-Id (v1.15) resolving to this same resident, or an Enterprise system-actor identity.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
residentId stringrequired | |
announcementId stringrequired |
curl -X POST https://api.lifeloop.com/api/v1/sunrise-001/residents/res-001/announcements/ann-001/unarchive \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"// 204 No ContentList announcements for connection
/api/v1/{tenant}/connections/{connectionId}/announcementsReturns announcements visible to a specific connection based on recipient groups. Requires X-Acting-User-Id (v1.15) resolving to this same connection, or an Enterprise system-actor identity.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
connectionId stringrequired |
Query parameters
status enum(pending, sent, canceled)optional | Filter by announcement status |
isRead booleanoptional | Filter by read status |
cursor stringoptional | Opaque cursor for the next page, taken from the previous response's nextCursor. Omit to fetch the first page. Treat as an opaque token — its encoding may change between releases. |
pageSize integeroptionaldefault: 50 | Number of items to return (default 50, max 100). |
curl https://api.lifeloop.com/api/v1/sunrise-001/connections/con-001/announcements \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"{
"data": [
{
"id": "obj-001",
"from": "from",
"subject": "subject",
"message": "message",
"smsMessage": "smsMessage",
"recipientGroups": [],
"facilities": [],
"status": "pending",
"scheduledAt": "2026-06-18T10:00:00Z",
"createdBy": "createdBy",
"createdAt": "2026-06-18T10:00:00Z",
"attachments": [],
"isRead": false,
"isArchived": false
}
],
"nextCursor": null,
"hasMore": true
}Get announcement for connection
/api/v1/{tenant}/connections/{connectionId}/announcements/{announcementId}Returns a single announcement by ID for a specific connection. Requires X-Acting-User-Id (v1.15) resolving to this same connection, or an Enterprise system-actor identity.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
connectionId stringrequired | |
announcementId stringrequired |
curl https://api.lifeloop.com/api/v1/sunrise-001/connections/con-001/announcements/ann-001 \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"{
"data": {
"id": "obj-001",
"from": "from",
"subject": "subject",
"message": "message",
"smsMessage": "smsMessage",
"recipientGroups": [
"recipientGroups"
],
"facilities": [
"facilities"
],
"status": "pending",
"scheduledAt": "2026-06-18T10:00:00Z",
"createdBy": "createdBy",
"createdAt": "2026-06-18T10:00:00Z",
"attachments": [
{
"id": "obj-001",
"name": "Physical Therapy",
"size": 1,
"extension": "extension"
}
],
"isRead": false,
"isArchived": false
}
}Archive announcement for connection
/api/v1/{tenant}/connections/{connectionId}/announcements/{announcementId}/archiveArchives an announcement for the connection. Requires X-Acting-User-Id (v1.15) resolving to this same connection, or an Enterprise system-actor identity.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
connectionId stringrequired | |
announcementId stringrequired |
curl -X POST https://api.lifeloop.com/api/v1/sunrise-001/connections/con-001/announcements/ann-001/archive \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"// 204 No ContentUnarchive announcement for connection
/api/v1/{tenant}/connections/{connectionId}/announcements/{announcementId}/unarchiveRemoves an announcement from archive for the connection. Requires X-Acting-User-Id (v1.15) resolving to this same connection, or an Enterprise system-actor identity.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
connectionId stringrequired | |
announcementId stringrequired |
curl -X POST https://api.lifeloop.com/api/v1/sunrise-001/connections/con-001/announcements/ann-001/unarchive \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"// 204 No ContentDownload announcement attachment
/api/v1/{tenant}/announcements/{announcementId}/attachments/{attachmentId}Streams/downloads an attachment file from an announcement. Has no resident/connection path scoping, so requires an Enterprise system-actor X-Acting-User-Id (v1.15, LIFELOOP-6215) specifically — a resident/connection identity is not accepted here; use the resident/connection-nested Announcements routes instead.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
announcementId stringrequired | |
attachmentId stringrequired |
curl https://api.lifeloop.com/api/v1/sunrise-001/announcements/ann-001/attachments/att-001 \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001""<binary>"Get announcement (flat)
/api/v1/{tenant}/announcements/{announcementId}Returns a single announcement by ID without recipient scoping. Intended for use by webhook consumers — after receiving an announcement.sent event, call this endpoint with the resourceId to retrieve the full announcement details including subject, message body, recipient groups, and attachments. Has no resident/connection path scoping, so requires an Enterprise system-actor X-Acting-User-Id (v1.15, LIFELOOP-6215) specifically — a resident/connection identity is not accepted here.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
announcementId stringrequired | The announcement ID |
curl https://api.lifeloop.com/api/v1/sunrise-001/announcements/ann-001 \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"{
"data": {
"id": "obj-001",
"from": "from",
"subject": "subject",
"message": "message",
"smsMessage": "smsMessage",
"recipientGroups": [
"recipientGroups"
],
"facilities": [
"facilities"
],
"status": "pending",
"scheduledAt": "2026-06-18T10:00:00Z",
"createdBy": "createdBy",
"createdAt": "2026-06-18T10:00:00Z",
"attachments": [
{
"id": "obj-001",
"name": "Physical Therapy",
"size": 1,
"extension": "extension"
}
],
"isRead": false,
"isArchived": false
}
}Newsletters
Transportation
Get transportation settings for a facilityPlanned
/api/v1/{tenant}/facilities/{facilityId}/transportation-settingsReturns what a client needs to build a transportation request form for this community: the trip types it offers, whether a destination address is required, the minimum lead time, and hours of operation. The API enforces the same rules on create and update. Vehicles and drivers are not included. The acting user must be a resident of this facility, or a connection linked to one.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
facilityId stringrequired |
curl https://api.lifeloop.com/api/v1/sunrise-001/facilities/fac-001/transportation-settings \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"{
"data": {
"facilityId": "fac-001",
"timezone": "10:00",
"transportationTypes": [
"transportationTypes"
],
"requireDestinationAddress": true,
"minimumLeadTimeHours": 1,
"hoursOfOperation": [
{
"dayOfWeek": null,
"date": null,
"notAvailable": true,
"startTime": null,
"endTime": null
}
]
}
}List a resident's transportation requestsPlanned
/api/v1/{tenant}/residents/{residentId}/transportation-requestsReturns the resident's transportation requests whose trip date falls in the date range, sorted by date and appointment time. Occurrences of recurring requests (set up by staff) are returned one per date, each with occurrenceDate set; they are read-only through this API. Unpaginated, capped at a 45-day range like the Activities endpoints. Access (matches the LifeLoop resident and family apps): the acting user (X-Acting-User-Id) must be a resident or connection — staff and Enterprise system-actor identities get 403. A resident sees every transportation request they are a passenger on, whoever created it. A connection sees only requests for a linked resident that were created by a connection (any family member, not just themselves) — requests the resident or staff created are not visible to connections. Anything outside those rules returns 404. The resident's community must have both the Transportation module and Family & Resident Transportation enabled, otherwise 403.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
residentId stringrequired | The resident the request belongs to. The acting user must be this resident, or a connection linked to them. |
Query parameters
startDate string<date>required | First trip date to include (facility-local calendar date). |
endDate string<date>required | Last trip date to include. At most 45 calendar days after startDate counting startDate as day 1; a longer range returns 400. |
status array<enum(pending, approved, denied, cancelled, completed)>optional | Comma-separated statuses to include. Default: all. |
curl https://api.lifeloop.com/api/v1/sunrise-001/residents/res-001/transportation-requests?startDate=value&endDate=value \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"{
"data": [
{
"id": "obj-001",
"referenceNumber": "referenceNumber",
"residentId": "res-001",
"facilityId": "fac-001",
"status": "pending",
"tripType": "roundtrip",
"date": "2026-06-18",
"timezone": "10:00",
"appointmentTime": "10:00",
"pickupTime": null,
"returnTime": null,
"pickupLocation": null,
"destination": "destination",
"destinationAddress": null,
"transportationType": null,
"mobilityNeeds": null,
"notes": null,
"mileage": null,
"driver": {
"id": "obj-001",
"name": "Physical Therapy",
"phone": null
},
"vehicle": {
"id": "obj-001",
"name": "Physical Therapy"
},
"isRecurring": false,
"occurrenceDate": null,
"creator": {
"id": "obj-001",
"name": "Physical Therapy",
"phone": null
},
"canEdit": true,
"canCancel": true,
"created": "2026-06-18T10:00:00Z",
"modified": null
}
]
}Create a transportation requestPlanned
/api/v1/{tenant}/residents/{residentId}/transportation-requestsCreates a one-off transportation request for the resident, created by the acting user. It starts as pending until staff approve or deny it in LifeLoop; staff assign the driver and vehicle. Recurring requests cannot be created through this API. Validation (400): the appointment must be at least minimumLeadTimeHours (3) from now in the community's time zone; the date and times must fall within the community's hours of operation; returnTime is required for round trips; destinationAddress is required when the community's requireDestinationAddress is on; transportationType, if sent, must be one of the community's types. See GET /facilities/{facilityId}/transportation-settings. Access (matches the LifeLoop resident and family apps): the acting user (X-Acting-User-Id) must be a resident or connection — staff and Enterprise system-actor identities get 403. A resident sees every transportation request they are a passenger on, whoever created it. A connection sees only requests for a linked resident that were created by a connection (any family member, not just themselves) — requests the resident or staff created are not visible to connections. Anything outside those rules returns 404. The resident's community must have both the Transportation module and Family & Resident Transportation enabled, otherwise 403.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
residentId stringrequired | The resident the request belongs to. The acting user must be this resident, or a connection linked to them. |
Request body
date string<date>required | |
appointmentTime stringrequired | HH:mm (24-hour), community-local. |
tripType enum(roundtrip, oneway, willcall)required | roundtrip: taken there and back (returnTime required). oneway: taken there only. willcall: taken there; the resident calls when ready to be picked up. |
returnTime string | nulloptional | Required when tripType is roundtrip. |
pickupTime string | nulloptional | Optional time to leave. |
pickupLocation string | nulloptional | |
destination stringrequired | |
destinationAddress string | nulloptional | Required when the community's requireDestinationAddress is on. |
transportationType string | nulloptional | One of transportationTypes from transportation-settings. |
mobilityNeeds string | nulloptional | |
notes string | nulloptional |
curl -X POST https://api.lifeloop.com/api/v1/sunrise-001/residents/res-001/transportation-requests \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001" \
-H "Content-Type: application/json" \
-d '{
"date": "2026-06-18",
"appointmentTime": "10:00",
"tripType": "roundtrip",
"returnTime": null,
"pickupTime": null,
"pickupLocation": null,
"destination": "destination",
"destinationAddress": null,
"transportationType": null,
"mobilityNeeds": null,
"notes": null
}'{
"data": {
"id": "obj-001",
"referenceNumber": "referenceNumber",
"residentId": "res-001",
"facilityId": "fac-001",
"status": "pending",
"tripType": "roundtrip",
"date": "2026-06-18",
"timezone": "10:00",
"appointmentTime": "10:00",
"pickupTime": null,
"returnTime": null,
"pickupLocation": null,
"destination": "destination",
"destinationAddress": null,
"transportationType": null,
"mobilityNeeds": null,
"notes": null,
"mileage": null,
"driver": {
"id": "obj-001",
"name": "Physical Therapy",
"phone": null
},
"vehicle": {
"id": "obj-001",
"name": "Physical Therapy"
},
"isRecurring": false,
"occurrenceDate": null,
"creator": {
"id": "obj-001",
"name": "Physical Therapy",
"phone": null
},
"canEdit": true,
"canCancel": true,
"created": "2026-06-18T10:00:00Z",
"modified": null
}
}Get a transportation requestPlanned
/api/v1/{tenant}/residents/{residentId}/transportation-requests/{requestId}Returns one transportation request, including its status and any assigned driver and vehicle. Access (matches the LifeLoop resident and family apps): the acting user (X-Acting-User-Id) must be a resident or connection — staff and Enterprise system-actor identities get 403. A resident sees every transportation request they are a passenger on, whoever created it. A connection sees only requests for a linked resident that were created by a connection (any family member, not just themselves) — requests the resident or staff created are not visible to connections. Anything outside those rules returns 404. The resident's community must have both the Transportation module and Family & Resident Transportation enabled, otherwise 403.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
residentId stringrequired | The resident the request belongs to. The acting user must be this resident, or a connection linked to them. |
requestId stringrequired | The transportation request's id (not its referenceNumber). Same id as the resourceId of transportation_request.* and notification.transportation_* webhooks. |
Query parameters
occurrenceDate string<date>optional | For an occurrence of a recurring request, the occurrence's date (its occurrenceDate in the list response). Omit for non-recurring requests. 404 if the date is not an occurrence of the series. |
curl https://api.lifeloop.com/api/v1/sunrise-001/residents/res-001/transportation-requests/req-001 \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"{
"data": {
"id": "obj-001",
"referenceNumber": "referenceNumber",
"residentId": "res-001",
"facilityId": "fac-001",
"status": "pending",
"tripType": "roundtrip",
"date": "2026-06-18",
"timezone": "10:00",
"appointmentTime": "10:00",
"pickupTime": null,
"returnTime": null,
"pickupLocation": null,
"destination": "destination",
"destinationAddress": null,
"transportationType": null,
"mobilityNeeds": null,
"notes": null,
"mileage": null,
"driver": {
"id": "obj-001",
"name": "Physical Therapy",
"phone": null
},
"vehicle": {
"id": "obj-001",
"name": "Physical Therapy"
},
"isRecurring": false,
"occurrenceDate": null,
"creator": {
"id": "obj-001",
"name": "Physical Therapy",
"phone": null
},
"canEdit": true,
"canCancel": true,
"created": "2026-06-18T10:00:00Z",
"modified": null
}
}Update a transportation requestPlanned
/api/v1/{tenant}/residents/{residentId}/transportation-requests/{requestId}Replaces the editable details of a request. Only the user who created the request can edit it, and only while it is pending — once staff approve or deny it, cancel it (if still pending) or create a new one instead. canEdit on the request says whether the acting user may edit it. 403 if the acting user is not the creator; 409 if the request is no longer pending or is an occurrence of a recurring request. Same validation as create. Access (matches the LifeLoop resident and family apps): the acting user (X-Acting-User-Id) must be a resident or connection — staff and Enterprise system-actor identities get 403. A resident sees every transportation request they are a passenger on, whoever created it. A connection sees only requests for a linked resident that were created by a connection (any family member, not just themselves) — requests the resident or staff created are not visible to connections. Anything outside those rules returns 404. The resident's community must have both the Transportation module and Family & Resident Transportation enabled, otherwise 403.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
residentId stringrequired | The resident the request belongs to. The acting user must be this resident, or a connection linked to them. |
requestId stringrequired | The transportation request's id (not its referenceNumber). Same id as the resourceId of transportation_request.* and notification.transportation_* webhooks. |
Request body
date string<date>required | |
appointmentTime stringrequired | HH:mm (24-hour), community-local. |
tripType enum(roundtrip, oneway, willcall)required | roundtrip: taken there and back (returnTime required). oneway: taken there only. willcall: taken there; the resident calls when ready to be picked up. |
returnTime string | nulloptional | Required when tripType is roundtrip. |
pickupTime string | nulloptional | Optional time to leave. |
pickupLocation string | nulloptional | |
destination stringrequired | |
destinationAddress string | nulloptional | Required when the community's requireDestinationAddress is on. |
transportationType string | nulloptional | One of transportationTypes from transportation-settings. |
mobilityNeeds string | nulloptional | |
notes string | nulloptional |
curl -X PUT https://api.lifeloop.com/api/v1/sunrise-001/residents/res-001/transportation-requests/req-001 \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001" \
-H "Content-Type: application/json" \
-d '{
"date": "2026-06-18",
"appointmentTime": "10:00",
"tripType": "roundtrip",
"returnTime": null,
"pickupTime": null,
"pickupLocation": null,
"destination": "destination",
"destinationAddress": null,
"transportationType": null,
"mobilityNeeds": null,
"notes": null
}'{
"data": {
"id": "obj-001",
"referenceNumber": "referenceNumber",
"residentId": "res-001",
"facilityId": "fac-001",
"status": "pending",
"tripType": "roundtrip",
"date": "2026-06-18",
"timezone": "10:00",
"appointmentTime": "10:00",
"pickupTime": null,
"returnTime": null,
"pickupLocation": null,
"destination": "destination",
"destinationAddress": null,
"transportationType": null,
"mobilityNeeds": null,
"notes": null,
"mileage": null,
"driver": {
"id": "obj-001",
"name": "Physical Therapy",
"phone": null
},
"vehicle": {
"id": "obj-001",
"name": "Physical Therapy"
},
"isRecurring": false,
"occurrenceDate": null,
"creator": {
"id": "obj-001",
"name": "Physical Therapy",
"phone": null
},
"canEdit": true,
"canCancel": true,
"created": "2026-06-18T10:00:00Z",
"modified": null
}
}Cancel a transportation requestPlanned
/api/v1/{tenant}/residents/{residentId}/transportation-requests/{requestId}/cancelSets the request's status to cancelled. The request is kept, not deleted. Only the user who created it can cancel it, and only while it is pending. canCancel on the request says whether the acting user may cancel it. 403 if the acting user is not the creator; 409 if the request is not pending or is an occurrence of a recurring request. Access (matches the LifeLoop resident and family apps): the acting user (X-Acting-User-Id) must be a resident or connection — staff and Enterprise system-actor identities get 403. A resident sees every transportation request they are a passenger on, whoever created it. A connection sees only requests for a linked resident that were created by a connection (any family member, not just themselves) — requests the resident or staff created are not visible to connections. Anything outside those rules returns 404. The resident's community must have both the Transportation module and Family & Resident Transportation enabled, otherwise 403.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
residentId stringrequired | The resident the request belongs to. The acting user must be this resident, or a connection linked to them. |
requestId stringrequired | The transportation request's id (not its referenceNumber). Same id as the resourceId of transportation_request.* and notification.transportation_* webhooks. |
curl -X POST https://api.lifeloop.com/api/v1/sunrise-001/residents/res-001/transportation-requests/req-001/cancel \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"{
"data": {
"id": "obj-001",
"referenceNumber": "referenceNumber",
"residentId": "res-001",
"facilityId": "fac-001",
"status": "pending",
"tripType": "roundtrip",
"date": "2026-06-18",
"timezone": "10:00",
"appointmentTime": "10:00",
"pickupTime": null,
"returnTime": null,
"pickupLocation": null,
"destination": "destination",
"destinationAddress": null,
"transportationType": null,
"mobilityNeeds": null,
"notes": null,
"mileage": null,
"driver": {
"id": "obj-001",
"name": "Physical Therapy",
"phone": null
},
"vehicle": {
"id": "obj-001",
"name": "Physical Therapy"
},
"isRecurring": false,
"occurrenceDate": null,
"creator": {
"id": "obj-001",
"name": "Physical Therapy",
"phone": null
},
"canEdit": true,
"canCancel": true,
"created": "2026-06-18T10:00:00Z",
"modified": null
}
}List comments on a transportation requestPlanned
/api/v1/{tenant}/residents/{residentId}/transportation-requests/{requestId}/commentsReturns comments from residents and connections, plus staff comments that staff marked as visible to family. Staff-only comments are never returned. Oldest first. Access (matches the LifeLoop resident and family apps): the acting user (X-Acting-User-Id) must be a resident or connection — staff and Enterprise system-actor identities get 403. A resident sees every transportation request they are a passenger on, whoever created it. A connection sees only requests for a linked resident that were created by a connection (any family member, not just themselves) — requests the resident or staff created are not visible to connections. Anything outside those rules returns 404. The resident's community must have both the Transportation module and Family & Resident Transportation enabled, otherwise 403.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
residentId stringrequired | The resident the request belongs to. The acting user must be this resident, or a connection linked to them. |
requestId stringrequired | The transportation request's id (not its referenceNumber). Same id as the resourceId of transportation_request.* and notification.transportation_* webhooks. |
curl https://api.lifeloop.com/api/v1/sunrise-001/residents/res-001/transportation-requests/req-001/comments \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"{
"data": [
{
"id": "obj-001",
"text": "text",
"author": {
"id": "obj-001",
"name": "Physical Therapy",
"userType": "resident"
},
"attachments": [
{
"id": null,
"name": null,
"type": null,
"size": null
}
],
"created": "2026-06-18T10:00:00Z",
"modified": null
}
]
}Add a comment to a transportation requestPlanned
/api/v1/{tenant}/residents/{residentId}/transportation-requests/{requestId}/commentsAdds a comment from the acting user, optionally with attached files. Comments from residents and connections are always visible to the resident's family and to staff. Staff (the request's creator and driver) are notified as they are today. Comments cannot be added to an occurrence of a recurring request (409). Access (matches the LifeLoop resident and family apps): the acting user (X-Acting-User-Id) must be a resident or connection — staff and Enterprise system-actor identities get 403. A resident sees every transportation request they are a passenger on, whoever created it. A connection sees only requests for a linked resident that were created by a connection (any family member, not just themselves) — requests the resident or staff created are not visible to connections. Anything outside those rules returns 404. The resident's community must have both the Transportation module and Family & Resident Transportation enabled, otherwise 403.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
residentId stringrequired | The resident the request belongs to. The acting user must be this resident, or a connection linked to them. |
requestId stringrequired | The transportation request's id (not its referenceNumber). Same id as the resourceId of transportation_request.* and notification.transportation_* webhooks. |
Request body
text stringrequired | Comment text. |
files array<string<binary>>optional | Optional files (for example photos) to attach. Up to 5 files, 10 MB each. |
curl -X POST https://api.lifeloop.com/api/v1/sunrise-001/residents/res-001/transportation-requests/req-001/comments \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"{
"data": {
"id": "obj-001",
"text": "text",
"author": {
"id": "obj-001",
"name": "Physical Therapy",
"userType": "resident"
},
"attachments": [
{
"id": "obj-001",
"name": "Physical Therapy",
"type": "type",
"size": null
}
],
"created": "2026-06-18T10:00:00Z",
"modified": null
}
}Download a transportation comment attachmentPlanned
/api/v1/{tenant}/residents/{residentId}/transportation-requests/{requestId}/attachments/{attachmentId}Downloads a file attached to one of the request's comments. 404 if the attachment is not on a comment the acting user can see. Access (matches the LifeLoop resident and family apps): the acting user (X-Acting-User-Id) must be a resident or connection — staff and Enterprise system-actor identities get 403. A resident sees every transportation request they are a passenger on, whoever created it. A connection sees only requests for a linked resident that were created by a connection (any family member, not just themselves) — requests the resident or staff created are not visible to connections. Anything outside those rules returns 404. The resident's community must have both the Transportation module and Family & Resident Transportation enabled, otherwise 403.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
residentId stringrequired | The resident the request belongs to. The acting user must be this resident, or a connection linked to them. |
requestId stringrequired | The transportation request's id (not its referenceNumber). Same id as the resourceId of transportation_request.* and notification.transportation_* webhooks. |
attachmentId stringrequired | attachments[].id from a comment (or, for work requests, from the request itself). |
curl https://api.lifeloop.com/api/v1/sunrise-001/residents/res-001/transportation-requests/req-001/attachments/att-001 \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001""<binary>"Work Requests
Get work request settings for a facilityPlanned
/api/v1/{tenant}/facilities/{facilityId}/work-request-settingsReturns what a client needs to build a work request form for this community: teams, request types and locations. The acting user must be a resident of this facility, or a connection linked to one.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
facilityId stringrequired |
curl https://api.lifeloop.com/api/v1/sunrise-001/facilities/fac-001/work-request-settings \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"{
"data": {
"facilityId": "fac-001",
"teams": [
{
"key": "key",
"name": "Physical Therapy"
}
],
"types": [
"types"
],
"locations": [
"locations"
]
}
}List a resident's work requestsPlanned
/api/v1/{tenant}/residents/{residentId}/work-requestsReturns the resident's work requests, newest first. Recurring maintenance schedules are not included. Cursor-paginated. Access (matches the LifeLoop resident and family apps): the acting user (X-Acting-User-Id) must be a resident or connection — staff and Enterprise system-actor identities get 403. A resident sees every work request filed for them, whoever created it. A connection sees only work requests for a linked resident that were created by a connection (any family member, not just themselves). Anything outside those rules returns 404. The resident's community must have both the Work Requests module and Family & Resident Work Requests enabled, otherwise 403.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
residentId stringrequired | The resident the request belongs to. The acting user must be this resident, or a connection linked to them. |
Query parameters
status array<enum(open, in_progress, completed, cancelled)>optional | Comma-separated statuses to include. open,in_progress gives the app's 'Open Requests' view; completed,cancelled gives 'Closed Requests'. Default: all. |
type stringoptional | Only requests of this type (one of the community's types). |
cursor stringoptional | Opaque cursor for the next page, taken from the previous response's nextCursor. Omit to fetch the first page. Treat as an opaque token — its encoding may change between releases. |
pageSize integeroptionaldefault: 50 | Number of items to return (default 50, max 100). |
curl https://api.lifeloop.com/api/v1/sunrise-001/residents/res-001/work-requests \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"{
"data": [
{
"id": "obj-001",
"referenceNumber": "referenceNumber",
"residentId": "res-001",
"facilityId": "fac-001",
"title": "Physical Therapy",
"description": null,
"location": null,
"team": "team",
"type": null,
"urgency": "none",
"status": "open",
"statusHistory": [],
"crew": [],
"scheduledDate": null,
"completedDate": null,
"attachments": [],
"creator": {
"id": null,
"name": null,
"phone": null
},
"canCancel": true,
"created": "2026-06-18T10:00:00Z",
"modified": null
}
],
"nextCursor": null,
"hasMore": true
}Create a work requestPlanned
/api/v1/{tenant}/residents/{residentId}/work-requestsCreates a work request for the resident, created by the acting user, optionally with photos or other files attached. It starts as open; staff triage, schedule and assign it in LifeLoop. Urgency is always none for requests created through this API (only staff set urgency). Defaults and validation (400): location defaults to the resident's room number; team may be omitted when the tenant has only one team, otherwise it is required and must be one of the teams from GET /facilities/{facilityId}/work-request-settings; type, if sent, must be one of the community's types. Access (matches the LifeLoop resident and family apps): the acting user (X-Acting-User-Id) must be a resident or connection — staff and Enterprise system-actor identities get 403. A resident sees every work request filed for them, whoever created it. A connection sees only work requests for a linked resident that were created by a connection (any family member, not just themselves). Anything outside those rules returns 404. The resident's community must have both the Work Requests module and Family & Resident Work Requests enabled, otherwise 403.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
residentId stringrequired | The resident the request belongs to. The acting user must be this resident, or a connection linked to them. |
Request body
title stringrequired | |
description stringoptional | What needs doing. |
location stringoptional | Where the work is needed. Defaults to the resident's room number. |
team stringoptional | Team key from work-request-settings. Optional only when the tenant has a single team. |
type stringoptional | Request type from work-request-settings. |
files array<string<binary>>optional | Optional files (for example photos) to attach. Up to 5 files, 10 MB each. |
curl -X POST https://api.lifeloop.com/api/v1/sunrise-001/residents/res-001/work-requests \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"{
"data": {
"id": "obj-001",
"referenceNumber": "referenceNumber",
"residentId": "res-001",
"facilityId": "fac-001",
"title": "Physical Therapy",
"description": null,
"location": null,
"team": "team",
"type": null,
"urgency": "none",
"status": "open",
"statusHistory": [
{
"status": "open",
"date": "2026-06-18T10:00:00Z",
"changedBy": {
"id": null,
"name": null
}
}
],
"crew": [
{
"id": "obj-001",
"name": "Physical Therapy"
}
],
"scheduledDate": null,
"completedDate": null,
"attachments": [
{
"id": "obj-001",
"name": "Physical Therapy",
"type": "type",
"size": null
}
],
"creator": {
"id": "obj-001",
"name": "Physical Therapy",
"phone": null
},
"canCancel": true,
"created": "2026-06-18T10:00:00Z",
"modified": null
}
}Get a work requestPlanned
/api/v1/{tenant}/residents/{residentId}/work-requests/{workRequestId}Returns one work request, including its status history and the assigned crew. Access (matches the LifeLoop resident and family apps): the acting user (X-Acting-User-Id) must be a resident or connection — staff and Enterprise system-actor identities get 403. A resident sees every work request filed for them, whoever created it. A connection sees only work requests for a linked resident that were created by a connection (any family member, not just themselves). Anything outside those rules returns 404. The resident's community must have both the Work Requests module and Family & Resident Work Requests enabled, otherwise 403.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
residentId stringrequired | The resident the request belongs to. The acting user must be this resident, or a connection linked to them. |
workRequestId stringrequired | The work request's id (not its referenceNumber). Same id as the resourceId of work_request.* and notification.work_request_* webhooks. |
curl https://api.lifeloop.com/api/v1/sunrise-001/residents/res-001/work-requests/wor-001 \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"{
"data": {
"id": "obj-001",
"referenceNumber": "referenceNumber",
"residentId": "res-001",
"facilityId": "fac-001",
"title": "Physical Therapy",
"description": null,
"location": null,
"team": "team",
"type": null,
"urgency": "none",
"status": "open",
"statusHistory": [
{
"status": "open",
"date": "2026-06-18T10:00:00Z",
"changedBy": {
"id": null,
"name": null
}
}
],
"crew": [
{
"id": "obj-001",
"name": "Physical Therapy"
}
],
"scheduledDate": null,
"completedDate": null,
"attachments": [
{
"id": "obj-001",
"name": "Physical Therapy",
"type": "type",
"size": null
}
],
"creator": {
"id": "obj-001",
"name": "Physical Therapy",
"phone": null
},
"canCancel": true,
"created": "2026-06-18T10:00:00Z",
"modified": null
}
}Cancel a work requestPlanned
/api/v1/{tenant}/residents/{residentId}/work-requests/{workRequestId}/cancelSets the work request's status to cancelled. Only the user who created it can cancel it, and only while it is open or in_progress; completed and cancelled requests are final. Work requests cannot otherwise be edited through this API — add a comment instead. canCancel on the request says whether the acting user may cancel it. 403 if the acting user is not the creator; 409 if the request is completed or cancelled. Access (matches the LifeLoop resident and family apps): the acting user (X-Acting-User-Id) must be a resident or connection — staff and Enterprise system-actor identities get 403. A resident sees every work request filed for them, whoever created it. A connection sees only work requests for a linked resident that were created by a connection (any family member, not just themselves). Anything outside those rules returns 404. The resident's community must have both the Work Requests module and Family & Resident Work Requests enabled, otherwise 403.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
residentId stringrequired | The resident the request belongs to. The acting user must be this resident, or a connection linked to them. |
workRequestId stringrequired | The work request's id (not its referenceNumber). Same id as the resourceId of work_request.* and notification.work_request_* webhooks. |
curl -X POST https://api.lifeloop.com/api/v1/sunrise-001/residents/res-001/work-requests/wor-001/cancel \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"{
"data": {
"id": "obj-001",
"referenceNumber": "referenceNumber",
"residentId": "res-001",
"facilityId": "fac-001",
"title": "Physical Therapy",
"description": null,
"location": null,
"team": "team",
"type": null,
"urgency": "none",
"status": "open",
"statusHistory": [
{
"status": "open",
"date": "2026-06-18T10:00:00Z",
"changedBy": {
"id": null,
"name": null
}
}
],
"crew": [
{
"id": "obj-001",
"name": "Physical Therapy"
}
],
"scheduledDate": null,
"completedDate": null,
"attachments": [
{
"id": "obj-001",
"name": "Physical Therapy",
"type": "type",
"size": null
}
],
"creator": {
"id": "obj-001",
"name": "Physical Therapy",
"phone": null
},
"canCancel": true,
"created": "2026-06-18T10:00:00Z",
"modified": null
}
}List comments on a work requestPlanned
/api/v1/{tenant}/residents/{residentId}/work-requests/{workRequestId}/commentsReturns comments from residents and connections, plus staff comments that staff marked as visible to family. Staff-only comments are never returned. Oldest first. Access (matches the LifeLoop resident and family apps): the acting user (X-Acting-User-Id) must be a resident or connection — staff and Enterprise system-actor identities get 403. A resident sees every work request filed for them, whoever created it. A connection sees only work requests for a linked resident that were created by a connection (any family member, not just themselves). Anything outside those rules returns 404. The resident's community must have both the Work Requests module and Family & Resident Work Requests enabled, otherwise 403.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
residentId stringrequired | The resident the request belongs to. The acting user must be this resident, or a connection linked to them. |
workRequestId stringrequired | The work request's id (not its referenceNumber). Same id as the resourceId of work_request.* and notification.work_request_* webhooks. |
curl https://api.lifeloop.com/api/v1/sunrise-001/residents/res-001/work-requests/wor-001/comments \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"{
"data": [
{
"id": "obj-001",
"text": "text",
"author": {
"id": "obj-001",
"name": "Physical Therapy",
"userType": "resident"
},
"attachments": [
{
"id": null,
"name": null,
"type": null,
"size": null
}
],
"created": "2026-06-18T10:00:00Z",
"modified": null
}
]
}Add a comment to a work requestPlanned
/api/v1/{tenant}/residents/{residentId}/work-requests/{workRequestId}/commentsAdds a comment from the acting user, optionally with attached files. Comments from residents and connections are always visible to the resident's family and to staff; the assigned crew and the request's creator are notified as they are today. Access (matches the LifeLoop resident and family apps): the acting user (X-Acting-User-Id) must be a resident or connection — staff and Enterprise system-actor identities get 403. A resident sees every work request filed for them, whoever created it. A connection sees only work requests for a linked resident that were created by a connection (any family member, not just themselves). Anything outside those rules returns 404. The resident's community must have both the Work Requests module and Family & Resident Work Requests enabled, otherwise 403.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
residentId stringrequired | The resident the request belongs to. The acting user must be this resident, or a connection linked to them. |
workRequestId stringrequired | The work request's id (not its referenceNumber). Same id as the resourceId of work_request.* and notification.work_request_* webhooks. |
Request body
text stringrequired | Comment text. |
files array<string<binary>>optional | Optional files (for example photos) to attach. Up to 5 files, 10 MB each. |
curl -X POST https://api.lifeloop.com/api/v1/sunrise-001/residents/res-001/work-requests/wor-001/comments \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001"{
"data": {
"id": "obj-001",
"text": "text",
"author": {
"id": "obj-001",
"name": "Physical Therapy",
"userType": "resident"
},
"attachments": [
{
"id": "obj-001",
"name": "Physical Therapy",
"type": "type",
"size": null
}
],
"created": "2026-06-18T10:00:00Z",
"modified": null
}
}Download a work request attachmentPlanned
/api/v1/{tenant}/residents/{residentId}/work-requests/{workRequestId}/attachments/{attachmentId}Downloads a file attached to the work request or to one of its comments. 404 if the attachment is not on the request or on a comment the acting user can see. Access (matches the LifeLoop resident and family apps): the acting user (X-Acting-User-Id) must be a resident or connection — staff and Enterprise system-actor identities get 403. A resident sees every work request filed for them, whoever created it. A connection sees only work requests for a linked resident that were created by a connection (any family member, not just themselves). Anything outside those rules returns 404. The resident's community must have both the Work Requests module and Family & Resident Work Requests enabled, otherwise 403.
Path parameters
tenant stringrequired | Tenant identifier — the unique slug for your LifeLoop organisation |
residentId stringrequired | The resident the request belongs to. The acting user must be this resident, or a connection linked to them. |
workRequestId stringrequired | The work request's id (not its referenceNumber). Same id as the resourceId of work_request.* and notification.work_request_* webhooks. |
attachmentId stringrequired | attachments[].id from a comment (or, for work requests, from the request itself). |
curl https://api.lifeloop.com/api/v1/sunrise-001/residents/res-001/work-requests/wor-001/attachments/att-001 \
-H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
-H "X-Acting-User-Id: ACTING_USER_ID" \
-H "X-Acting-User-Tenant: sunrise-001""<binary>"