People

The directory, one person's record, new starters, removing people, and emergency contacts.

MethodPathSummary
GET/api/meWho you are: the signed-in person and what they can do here
GET/api/peopleThe directory
GET/api/people/:idGet a person's HR record
PATCH/api/people/:idUpdate a person's HR record
POST/api/peopleNew starter (before their account exists) — HR admins only
DELETE/api/people/:idRemove someone from HR (a mistake, a duplicate, a service account)
POST/api/people/:id/contactsAdd an emergency contact
PUT/api/people/:id/contacts/:cidUpdate an emergency contact
DELETE/api/people/:id/contacts/:cidRemove an emergency contact
GET/api/activityRecent HR activity

#Who you are: the signed-in person and what they can do here

GET/api/me
Address
https://<your-org>.brambleit.cloud/hr/api/me
Requires
Signed-in browser session (the sso_session / session_id cookies from Bramble sign-in).
Licence: HR.

Response 200

FieldTypeDescription
userobject
user.idinteger
user.namestring
user.first_namestring
user.emailstring
meany
is_adminboolean
is_managerboolean
team_sizeinteger
settingsobject
settings.year_start_monthany
settings.bank_holidaysarray of any
settings.regionany
settings.region_namestring
settings.half_daysboolean
settings.show_leave_typesboolean
settings.default_allowanceany
settings.carry_over_maxany
settings.overlap_modeany
leave_typesarray of any
countsobject
counts.approvalsinteger
counts.tasksinteger
counts.to_ackany
todayany
Example response
JSON
{
  "user": {
    "id": 42,
    "name": "Example name",
    "first_name": "Alex",
    "email": "alex@example.com"
  },
  "me": null,
  "is_admin": true,
  "is_manager": true,
  "team_size": 1,
  "settings": {
    "year_start_month": null,
    "bank_holidays": [],
    "region": null,
    "region_name": "Example region name",
    "half_days": false,
    "show_leave_types": false,
    "default_allowance": null,
    "carry_over_max": null,
    "overlap_mode": null
  },
  "leave_types": [],
  "counts": {
    "approvals": 1,
    "tasks": 1,
    "to_ack": null
  },
  "today": null
}

Example request

JavaScript
// From a page served by Bramble (uses the signed-in session)
const res = await fetch('/hr/api/me', {
  method: 'GET',
  credentials: 'include',
});
const data = await res.json();

#The directory

GET/api/people
Address
https://<your-org>.brambleit.cloud/hr/api/people
Requires
Signed-in browser session (the sso_session / session_id cookies from Bramble sign-in).
Licence: HR.

Response 200

FieldTypeDescription
peoplearray of any
Example response
JSON
{
  "people": []
}

Example request

JavaScript
// From a page served by Bramble (uses the signed-in session)
const res = await fetch('/hr/api/people', {
  method: 'GET',
  credentials: 'include',
});
const data = await res.json();

#Get a person's HR record

GET/api/people/:id

What you see depends on who you are — HR admins see everything, managers see their reports' work details, everyone sees the directory card.

Address
https://<your-org>.brambleit.cloud/hr/api/people/:id
Requires
Signed-in browser session (the sso_session / session_id cookies from Bramble sign-in).
Licence: HR.

Path parameters

NameTypeDescription
idrequiredinteger

Response 200

Example request

JavaScript
// From a page served by Bramble (uses the signed-in session)
const res = await fetch('/hr/api/people/42', {
  method: 'GET',
  credentials: 'include',
});
const data = await res.json();

#Update a person's HR record

PATCH/api/people/:id

Send only the fields to change. People can change their own preferred_name, pronouns, personal_email, personal_phone, work_phone, date_of_birth, address, ni_number and bio. HR admins can also change first_name, last_name, work_email, job_title, department, location, manager_id, employee_number, start_date, end_date, leaving_reason, probation_end, employment_type, contract_type, work_days, hours_per_week and hr_notes. Allowances change through POST /api/leave/allowance-changes.

Address
https://<your-org>.brambleit.cloud/hr/api/people/:id
Requires
Signed-in browser session (the sso_session / session_id cookies from Bramble sign-in).
Licence: HR.

Path parameters

NameTypeDescription
idrequiredinteger

Request body JSON

NameTypeDescription
kany

Response 200

FieldTypeDescription
okboolean
Example response
JSON
{
  "ok": true
}

Errors

StatusMessage
400That … isn't valid
400Someone can't report to themselves or to someone who reports to them
400The last day is before their start date
403You can't change this person's details
403Only HR can change …

Example request

JavaScript
// From a page served by Bramble (uses the signed-in session)
const res = await fetch('/hr/api/people/42', {
  method: 'PATCH',
  credentials: 'include',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({"k":"…"}),
});
const data = await res.json();

#New starter (before their account exists) — HR admins only

POST/api/people
Address
https://<your-org>.brambleit.cloud/hr/api/people
Requires
Signed-in browser session (the sso_session / session_id cookies from Bramble sign-in).
Licence: HR.

Request body JSON

NameTypeDescription
first_namestring
last_namestring
work_emailstring
manager_idnumber
personal_emailstring
job_titlestring
departmentstring
locationstring
start_datestring (date)
employment_typestring
contract_typestring
work_daysinteger

Response 201

FieldTypeDescription
idinteger
Example response
JSON
{
  "id": 42
}

Errors

StatusMessage
400Give their first and last name
400Someone already has that work email
403Only HR admins can add people

Example request

JavaScript
// From a page served by Bramble (uses the signed-in session)
const res = await fetch('/hr/api/people', {
  method: 'POST',
  credentials: 'include',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({"first_name":"Alex","last_name":"Morgan","work_email":"alex@example.com","manager_id":12.5,"personal_email":"alex@example.com","job_title":"Example job title","department":"string","location":"string","start_date":"2026-11-12","employment_type":"string","contract_type":"string","work_days":1}),
});
const data = await res.json();

#Remove someone from HR (a mistake, a duplicate, a service account)

DELETE/api/people/:id

Remove someone from HR (a mistake, a duplicate, a service account). Their account isn't touched and the sync won't add them back; BRM-Admin → HR can. Leavers should get a last day instead, which keeps them listed.

Address
https://<your-org>.brambleit.cloud/hr/api/people/:id
Requires
Signed-in browser session (the sso_session / session_id cookies from Bramble sign-in).
Licence: HR.

Path parameters

NameTypeDescription
idrequiredinteger

Response 200

FieldTypeDescription
okboolean
Example response
JSON
{
  "ok": true
}

Errors

StatusMessage
400You can't remove yourself from HR
403Only HR admins can remove people

Example request

JavaScript
// From a page served by Bramble (uses the signed-in session)
const res = await fetch('/hr/api/people/42', {
  method: 'DELETE',
  credentials: 'include',
});
const data = await res.json();

#Add an emergency contact

POST/api/people/:id/contacts
Address
https://<your-org>.brambleit.cloud/hr/api/people/:id/contacts
Requires
Signed-in browser session (the sso_session / session_id cookies from Bramble sign-in).
Licence: HR.

Path parameters

NameTypeDescription
idrequiredinteger

Request body JSON

NameTypeDescription
namestring
phonerequiredstring
emailrequiredstring
relationshipstring

Response 201

FieldTypeDescription
idinteger
Example response
JSON
{
  "id": 42
}

Errors

StatusMessage
400Give their name
400Give a phone number or email

Example request

JavaScript
// From a page served by Bramble (uses the signed-in session)
const res = await fetch('/hr/api/people/42/contacts', {
  method: 'POST',
  credentials: 'include',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({"name":"Example name","phone":"string","email":"alex@example.com","relationship":"string"}),
});
const data = await res.json();

#Update an emergency contact

PUT/api/people/:id/contacts/:cid
Address
https://<your-org>.brambleit.cloud/hr/api/people/:id/contacts/:cid
Requires
Signed-in browser session (the sso_session / session_id cookies from Bramble sign-in).
Licence: HR.

Path parameters

NameTypeDescription
idrequiredinteger
cidrequirednumber

Request body JSON

NameTypeDescription
namestring
relationshipstring
phonestring
emailstring

Response 200

FieldTypeDescription
okboolean
Example response
JSON
{
  "ok": true
}

Errors

StatusMessage
400Give their name

Example request

JavaScript
// From a page served by Bramble (uses the signed-in session)
const res = await fetch('/hr/api/people/42/contacts/12.5', {
  method: 'PUT',
  credentials: 'include',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({"name":"Example name","relationship":"string","phone":"string","email":"alex@example.com"}),
});
const data = await res.json();

#Remove an emergency contact

DELETE/api/people/:id/contacts/:cid
Address
https://<your-org>.brambleit.cloud/hr/api/people/:id/contacts/:cid
Requires
Signed-in browser session (the sso_session / session_id cookies from Bramble sign-in).
Licence: HR.

Path parameters

NameTypeDescription
idrequiredinteger
cidrequirednumber

Response 200

FieldTypeDescription
okboolean
Example response
JSON
{
  "ok": true
}

Example request

JavaScript
// From a page served by Bramble (uses the signed-in session)
const res = await fetch('/hr/api/people/42/contacts/12.5', {
  method: 'DELETE',
  credentials: 'include',
});
const data = await res.json();

#Recent HR activity

GET/api/activity
Address
https://<your-org>.brambleit.cloud/hr/api/activity
Requires
Signed-in browser session (the sso_session / session_id cookies from Bramble sign-in).
Licence: HR.

Response 200

FieldTypeDescription
activityarray of object
activity[].employee_idany
activity[].actor_nameany
activity[].actionstring
activity[].detailstring, or null
activity[].created_atstring (date-time)
Example response
JSON
{
  "activity": [
    {
      "employee_id": null,
      "actor_name": null,
      "action": "string",
      "detail": "string",
      "created_at": "2026-11-12T09:30:00.000Z"
    }
  ]
}

Errors

StatusMessage
403HR admins only

Example request

JavaScript
// From a page served by Bramble (uses the signed-in session)
const res = await fetch('/hr/api/activity', {
  method: 'GET',
  credentials: 'include',
});
const data = await res.json();