Sites

A site is a place a trial runs — a hospital, a clinic, a research centre. Participants are members of sites, staff can be restricted to the sites they work at with site permissions (site.*), and each site has a message board, monitoring visits and its own files.

Reading sites needs trial.read or trial.readSites on the trial (or site.access on the individual site); creating, updating and deleting them needs trial.write or trial.writeSites.

Endpoints

Method Path Description
GET /trials/<trialId>/sites The trial's sites, as {"sites": [...]}. A site-restricted account sees only its own.
POST /trials/<trialId>/sites Create a site.
GET /sites/<siteId> One site.
PUT /sites/<siteId> Update a site.
DELETE /sites/<siteId> Delete a site. Its participants keep their data and lose the membership.
PUT /sites/<siteId>/memberships/<participantId> Add a participant to the site.
DELETE /sites/<siteId>/memberships/<participantId> Remove a participant from the site.
GET /sites/<siteId>/site-monitoring Monitoring visits at the site, as {"siteMonitoring": [...]}.
POST /sites/<siteId>/site-monitoring Record a monitoring visit.
PUT DELETE /site-monitoring/<visitId> Update or delete a visit.
GET /site-monitoring/<visitId>/site-issues Issues found on a visit, as {"siteMonitoringIssues": [...]}.
POST /site-monitoring/<visitId>/site-issues Record an issue.
PUT DELETE /site-issues/<issueId> Update or delete an issue.
GET /sites/<siteId>/messages The site's message board.
POST /sites/<siteId>/messages Post to the board. 30 requests per minute.
PUT /sites/<siteId>/messages/read Mark the board read for your account.
POST /trials/<trialId>/messages/broadcast Post the same message to every site's board. 10 requests per minute.
GET /trials/<trialId>/messages/unread Unread message counts per site.

Membership can also be changed for many participants at once with PATCH /trials/<trialId>/participants — see Participant management. Adding or removing a member needs trial.write, trial.writeSites or site.write on that site.

Site fields

POST /trials/<trialId>/sites and PUT /sites/<siteId>:

Field Type Notes
name string 2–100 characters.
id string 2–100 characters. The site's own identifier, e.g. SITE-01, used in exports.
description string Up to 2000 characters.
image string Stored file name of a picture.
contactName, contactEmail, contactPhone string Site contact.
addressLine1, addressLine2, addressCity, addressPostCode, addressCountry string Address.
irb none, local, central Ethics review arrangement.
approvalStatus pending, onHold, selected, rejected Site selection.
activityStatus pendingSelection, selected, activeRecruiting, activeNotRecruiting, closedToRecruitment, closed Where the site is in its lifecycle.

Monitoring visits and issues

Visits and issues need trial.admin.

A visit (POST /sites/<siteId>/site-monitoring, PUT /site-monitoring/<visitId>):

Field Type Notes
id string 2–100 characters. Your reference for the visit.
category mv, ssv Monitoring visit or site selection visit.
priority low, medium, high
status pending, completed
scheduledAt, completedAt datetime
duration integer Minutes, up to 1000.
assignees list of user _ids
notes string Up to 1000 characters.

An issue (POST /site-monitoring/<visitId>/site-issues, PUT /site-issues/<issueId>):

Field Type Notes
name string 3–1000 characters.
category informedConsent, eSource, ePro
severity minor, major, critical
status resolved, unresolved
gcpNonCompliance, protocolNonCompliance boolean
assignees list of user _ids

Message boards

Each site has a board that its staff and the trial team share. Reading a board needs site.readSiteMessages on the site or trial.readSiteMessages on the trial; posting needs site.writeSiteMessages or trial.writeSiteMessages.

GET /sites/<siteId>/messages?page=1&page_size=30 returns {"site": {...}, "messages": [...], "page": 1, "nextPageAvailable": false}, newest first. POST /sites/<siteId>/messages takes a message (up to 2000 characters) and optional attachments — stored file names from an upload with forType=site. The broadcast endpoint takes the same body and posts it to every board you can write to, with forType=trial for its attachments.