Castor Users API
List the users the authenticated account can see, retrieve a single user, and list the users who are members of a given study. Used to reconcile study membership and site staff with external identity and CTMS systems.
List the users the authenticated account can see, retrieve a single user, and list the users who are members of a given study. Used to reconcile study membership and site staff with external identity and CTMS systems.
openapi: 3.0.3
info:
title: Castor EDC / CDMS API
description: >-
The Castor EDC / CDMS API is a RESTful interface to Castor's cloud electronic
data capture (EDC) and clinical data management platform. It exposes study
configuration and collected data - studies, participants (records), institutes
(sites), users, fields and field metadata, study data points, repeating data
(reports), surveys and survey packages, the audit trail, and batch data export.
Authentication is OAuth2 with the Client Credentials flow: request an access
token from POST /oauth/token using an API Client ID and Client Secret generated
in Castor User Settings, then send it as a Bearer token. Access tokens are valid
for 5 hours. Most identifiers (study, field, report / repeating-data instance,
survey package instance) are uppercase GUIDs in 8-4-4-4-12 format; the
participant ID is the exception.
Endpoint status: paths that this document marks with `x-endpoint-status:
confirmed` were observed directly in Castor's published API reference and
helpdesk documentation. Paths marked `x-endpoint-status: modeled` reflect the
documented resource model and the coverage of the official R and Python wrapper
packages, but the exact path or shape was inferred and should be verified
against https://data.castoredc.com/api during reconciliation.
version: '1.0'
contact:
name: Castor
url: https://www.castoredc.com
license:
name: Proprietary
url: https://www.castoredc.com/legal/
servers:
- url: https://data.castoredc.com/api
description: Castor EU (default)
- url: https://us.castoredc.com/api
description: Castor US region
security:
- oauth2ClientCredentials: []
tags:
- name: Studies
description: Studies accessible to the API client.
- name: Participants
description: Participants (records / subjects) enrolled in a study.
- name: Institutes
description: Institutes (sites / centers) participating in a study.
- name: Users
description: Users and study membership.
- name: Fields
description: Study fields and their metadata (dependencies, option groups, validations).
- name: Study Data Points
description: Collected values for study forms.
- name: Reports
description: Reports / repeating data and their instances.
- name: Surveys
description: Surveys, survey packages, and ePRO.
- name: Audit Trail
description: Immutable audit trail of study changes.
- name: Data Export
description: Bulk export of study data, structure, and option groups.
- name: Metadata
description: Reference metadata such as countries.
paths:
/oauth/token:
post:
operationId: getAccessToken
tags:
- Studies
summary: Obtain an OAuth2 access token
description: >-
Exchange an API Client ID and Client Secret for a Bearer access token using
the client_credentials grant. The returned token is valid for 5 hours.
security: []
x-endpoint-status: confirmed
requestBody:
required: true
content:
application/x-www-form-urlencoded:
schema:
type: object
required:
- client_id
- client_secret
- grant_type
properties:
client_id:
type: string
client_secret:
type: string
grant_type:
type: string
enum:
- client_credentials
responses:
'200':
description: An access token.
content:
application/json:
schema:
type: object
properties:
access_token:
type: string
token_type:
type: string
example: Bearer
expires_in:
type: integer
example: 18000
'401':
$ref: '#/components/responses/Unauthorized'
/study:
get:
operationId: listStudies
tags:
- Studies
summary: List studies
description: Lists all studies the authenticated API client has access to.
x-endpoint-status: confirmed
parameters:
- $ref: '#/components/parameters/Page'
responses:
'200':
description: A paginated list of studies.
content:
application/json:
schema:
$ref: '#/components/schemas/StudyCollection'
'401':
$ref: '#/components/responses/Unauthorized'
/study/{study_id}:
get:
operationId: getStudy
tags:
- Studies
summary: Retrieve a study
description: Retrieves a single study by its GUID.
x-endpoint-status: confirmed
parameters:
- $ref: '#/components/parameters/StudyId'
responses:
'200':
description: A study.
content:
application/json:
schema:
$ref: '#/components/schemas/Study'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
/study/{study_id}/participant:
get:
operationId: listParticipants
tags:
- Participants
summary: List participants
description: Lists the participants (records) enrolled in a study.
x-endpoint-status: confirmed
parameters:
- $ref: '#/components/parameters/StudyId'
- $ref: '#/components/parameters/Page'
responses:
'200':
description: A paginated list of participants.
content:
application/json:
schema:
$ref: '#/components/schemas/ParticipantCollection'
'401':
$ref: '#/components/responses/Unauthorized'
post:
operationId: createParticipant
tags:
- Participants
summary: Create a participant
description: Creates a new participant (record) in a study.
x-endpoint-status: confirmed
parameters:
- $ref: '#/components/parameters/StudyId'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ParticipantInput'
responses:
'201':
description: The created participant.
content:
application/json:
schema:
$ref: '#/components/schemas/Participant'
'401':
$ref: '#/components/responses/Unauthorized'
/study/{study_id}/participant/{participant_id}:
get:
operationId: getParticipant
tags:
- Participants
summary: Retrieve a participant
description: Retrieves a single participant by ID.
x-endpoint-status: confirmed
parameters:
- $ref: '#/components/parameters/StudyId'
- $ref: '#/components/parameters/ParticipantId'
responses:
'200':
description: A participant.
content:
application/json:
schema:
$ref: '#/components/schemas/Participant'
'404':
$ref: '#/components/responses/NotFound'
/study/{study_id}/institute:
get:
operationId: listInstitutes
tags:
- Institutes
summary: List institutes
description: Lists the institutes (sites) participating in a study.
x-endpoint-status: confirmed
parameters:
- $ref: '#/components/parameters/StudyId'
responses:
'200':
description: A list of institutes.
content:
application/json:
schema:
$ref: '#/components/schemas/InstituteCollection'
'401':
$ref: '#/components/responses/Unauthorized'
post:
operationId: createInstitute
tags:
- Institutes
summary: Create an institute
description: Creates a new institute (site) in a study.
x-endpoint-status: modeled
parameters:
- $ref: '#/components/parameters/StudyId'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/InstituteInput'
responses:
'201':
description: The created institute.
content:
application/json:
schema:
$ref: '#/components/schemas/Institute'
/study/{study_id}/institute/{institute_id}:
get:
operationId: getInstitute
tags:
- Institutes
summary: Retrieve an institute
description: Retrieves a single institute by ID.
x-endpoint-status: confirmed
parameters:
- $ref: '#/components/parameters/StudyId'
- $ref: '#/components/parameters/InstituteId'
responses:
'200':
description: An institute.
content:
application/json:
schema:
$ref: '#/components/schemas/Institute'
'404':
$ref: '#/components/responses/NotFound'
/user:
get:
operationId: listUsers
tags:
- Users
summary: List users
description: Lists the users the authenticated account can access.
x-endpoint-status: confirmed
responses:
'200':
description: A list of users.
content:
application/json:
schema:
$ref: '#/components/schemas/UserCollection'
'401':
$ref: '#/components/responses/Unauthorized'
/user/{user_id}:
get:
operationId: getUser
tags:
- Users
summary: Retrieve a user
description: Retrieves a single user by ID.
x-endpoint-status: confirmed
parameters:
- $ref: '#/components/parameters/UserId'
responses:
'200':
description: A user.
content:
application/json:
schema:
$ref: '#/components/schemas/User'
'404':
$ref: '#/components/responses/NotFound'
/study/{study_id}/user:
get:
operationId: listStudyUsers
tags:
- Users
summary: List study users
description: Lists the users who are members of a given study.
x-endpoint-status: confirmed
parameters:
- $ref: '#/components/parameters/StudyId'
responses:
'200':
description: A list of study users.
content:
application/json:
schema:
$ref: '#/components/schemas/UserCollection'
/study/{study_id}/field:
get:
operationId: listFields
tags:
- Fields
summary: List fields
description: Lists all data-capture fields defined in a study.
x-endpoint-status: confirmed
parameters:
- $ref: '#/components/parameters/StudyId'
- $ref: '#/components/parameters/Page'
responses:
'200':
description: A paginated list of fields.
content:
application/json:
schema:
$ref: '#/components/schemas/FieldCollection'
'401':
$ref: '#/components/responses/Unauthorized'
/study/{study_id}/field/{field_id}:
get:
operationId: getField
tags:
- Fields
summary: Retrieve a field
description: Retrieves a single field by ID.
x-endpoint-status: confirmed
parameters:
- $ref: '#/components/parameters/StudyId'
- $ref: '#/components/parameters/FieldId'
responses:
'200':
description: A field.
content:
application/json:
schema:
$ref: '#/components/schemas/Field'
'404':
$ref: '#/components/responses/NotFound'
/study/{study_id}/field-dependency:
get:
operationId: listFieldDependencies
tags:
- Fields
summary: List field dependencies
description: Lists conditional-logic dependencies between fields in a study.
x-endpoint-status: confirmed
parameters:
- $ref: '#/components/parameters/StudyId'
responses:
'200':
description: A list of field dependencies.
content:
application/json:
schema:
type: object
/study/{study_id}/field-optiongroup:
get:
operationId: listFieldOptionGroups
tags:
- Fields
summary: List field option groups
description: Lists the option groups (answer choices) used by fields in a study.
x-endpoint-status: confirmed
parameters:
- $ref: '#/components/parameters/StudyId'
responses:
'200':
description: A list of option groups.
content:
application/json:
schema:
type: object
/study/{study_id}/field-validation:
get:
operationId: listFieldValidations
tags:
- Fields
summary: List field validations
description: Lists validation rules attached to fields in a study.
x-endpoint-status: modeled
parameters:
- $ref: '#/components/parameters/StudyId'
responses:
'200':
description: A list of field validations.
content:
application/json:
schema:
type: object
/study/{study_id}/data-points/study:
get:
operationId: listStudyDataPoints
tags:
- Study Data Points
summary: List all study data points
description: Retrieves all study-form data points collected across a study.
x-endpoint-status: confirmed
parameters:
- $ref: '#/components/parameters/StudyId'
- $ref: '#/components/parameters/Page'
responses:
'200':
description: A paginated list of study data points.
content:
application/json:
schema:
$ref: '#/components/schemas/DataPointCollection'
/study/{study_id}/participant/{participant_id}/data-points/study:
get:
operationId: listParticipantStudyDataPoints
tags:
- Study Data Points
summary: List a participant's study data points
description: Retrieves the study-form data points for a single participant.
x-endpoint-status: confirmed
parameters:
- $ref: '#/components/parameters/StudyId'
- $ref: '#/components/parameters/ParticipantId'
responses:
'200':
description: A list of study data points.
content:
application/json:
schema:
$ref: '#/components/schemas/DataPointCollection'
post:
operationId: updateParticipantStudyDataPoints
tags:
- Study Data Points
summary: Create or update a participant's study data points
description: >-
Creates or updates study-form data points for a single participant. Accepts
a batch of field_id / value pairs.
x-endpoint-status: confirmed
parameters:
- $ref: '#/components/parameters/StudyId'
- $ref: '#/components/parameters/ParticipantId'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/DataPointWriteRequest'
responses:
'200':
description: The updated data points.
content:
application/json:
schema:
$ref: '#/components/schemas/DataPointCollection'
/study/{study_id}/report:
get:
operationId: listReports
tags:
- Reports
summary: List reports (repeating data)
description: Lists the report / repeating-data definitions configured in a study.
x-endpoint-status: confirmed
parameters:
- $ref: '#/components/parameters/StudyId'
responses:
'200':
description: A list of reports.
content:
application/json:
schema:
type: object
/study/{study_id}/report/{report_id}:
get:
operationId: getReport
tags:
- Reports
summary: Retrieve a report
description: Retrieves a single report / repeating-data definition by ID.
x-endpoint-status: modeled
parameters:
- $ref: '#/components/parameters/StudyId'
- name: report_id
in: path
required: true
schema:
type: string
responses:
'200':
description: A report.
content:
application/json:
schema:
type: object
/study/{study_id}/participant/{participant_id}/data-points/repeating-data-instance:
get:
operationId: listRepeatingDataInstances
tags:
- Reports
summary: List a participant's repeating-data instances
description: Retrieves the repeating-data (report) instances for a participant.
x-endpoint-status: confirmed
parameters:
- $ref: '#/components/parameters/StudyId'
- $ref: '#/components/parameters/ParticipantId'
responses:
'200':
description: A list of repeating-data instances.
content:
application/json:
schema:
type: object
/study/{study_id}/participant/{participant_id}/data-points/repeating-data-instance/{repeating_data_instance_id}:
post:
operationId: updateRepeatingDataInstance
tags:
- Reports
summary: Update a repeating-data instance's data points
description: Creates or updates the data points of a repeating-data instance.
x-endpoint-status: confirmed
parameters:
- $ref: '#/components/parameters/StudyId'
- $ref: '#/components/parameters/ParticipantId'
- name: repeating_data_instance_id
in: path
required: true
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/DataPointWriteRequest'
responses:
'200':
description: The updated data points.
content:
application/json:
schema:
$ref: '#/components/schemas/DataPointCollection'
/study/{study_id}/survey:
get:
operationId: listSurveys
tags:
- Surveys
summary: List surveys
description: Lists the survey and ePRO definitions configured in a study.
x-endpoint-status: confirmed
parameters:
- $ref: '#/components/parameters/StudyId'
responses:
'200':
description: A list of surveys.
content:
application/json:
schema:
type: object
/study/{study_id}/participant/{participant_id}/data-points/survey-instance:
get:
operationId: listSurveyInstances
tags:
- Surveys
summary: List a participant's survey instances
description: Retrieves the survey instances (and their data points) for a participant.
x-endpoint-status: confirmed
parameters:
- $ref: '#/components/parameters/StudyId'
- $ref: '#/components/parameters/ParticipantId'
responses:
'200':
description: A list of survey instances.
content:
application/json:
schema:
type: object
/study/{study_id}/participant/{participant_id}/data-points/survey-package-instance:
post:
operationId: createSurveyPackageInstance
tags:
- Surveys
summary: Send a survey package to a participant
description: >-
Creates a survey-package instance, sending one or more surveys to a
participant (for example, by email invitation).
x-endpoint-status: confirmed
parameters:
- $ref: '#/components/parameters/StudyId'
- $ref: '#/components/parameters/ParticipantId'
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
survey_package_id:
type: string
email_address:
type: string
responses:
'201':
description: The created survey-package instance.
content:
application/json:
schema:
type: object
/study/{study_id}/compliance:
post:
operationId: getSurveyCompliance
tags:
- Surveys
summary: Retrieve participant survey compliance
description: Returns survey compliance information for participants in a study.
x-endpoint-status: confirmed
parameters:
- $ref: '#/components/parameters/StudyId'
responses:
'200':
description: Survey compliance information.
content:
application/json:
schema:
type: object
/study/{study_id}/audit-trail:
get:
operationId: getAuditTrail
tags:
- Audit Trail
summary: Retrieve the audit trail
description: >-
Retrieves audit trail entries for a study - every data and configuration
change, with actor and timestamp. Supports date range filtering.
x-endpoint-status: confirmed
parameters:
- $ref: '#/components/parameters/StudyId'
- name: date_from
in: query
schema:
type: string
format: date
- name: date_to
in: query
schema:
type: string
format: date
- $ref: '#/components/parameters/Page'
responses:
'200':
description: A paginated list of audit trail entries.
content:
application/json:
schema:
type: object
/study/{study_id}/export/data:
get:
operationId: exportStudyData
tags:
- Data Export
summary: Export study data
description: Exports the collected data of a study (CSV).
x-endpoint-status: confirmed
parameters:
- $ref: '#/components/parameters/StudyId'
responses:
'200':
description: The exported study data.
content:
text/csv:
schema:
type: string
/study/{study_id}/export/structure:
get:
operationId: exportStudyStructure
tags:
- Data Export
summary: Export study structure
description: Exports the structure (forms, fields, phases) of a study.
x-endpoint-status: confirmed
parameters:
- $ref: '#/components/parameters/StudyId'
responses:
'200':
description: The exported study structure.
content:
text/csv:
schema:
type: string
/study/{study_id}/export/optiongroups:
get:
operationId: exportOptionGroups
tags:
- Data Export
summary: Export option groups
description: Exports the option groups (answer choices) of a study.
x-endpoint-status: confirmed
parameters:
- $ref: '#/components/parameters/StudyId'
responses:
'200':
description: The exported option groups.
content:
text/csv:
schema:
type: string
/country:
get:
operationId: listCountries
tags:
- Metadata
summary: List countries
description: Lists all countries known to Castor (reference metadata).
x-endpoint-status: confirmed
responses:
'200':
description: A list of countries.
content:
application/json:
schema:
type: object
/country/{country_id}:
get:
operationId: getCountry
tags:
- Metadata
summary: Retrieve a country
description: Retrieves a single country by ID.
x-endpoint-status: confirmed
parameters:
- name: country_id
in: path
required: true
schema:
type: string
responses:
'200':
description: A country.
content:
application/json:
schema:
type: object
components:
securitySchemes:
oauth2ClientCredentials:
type: oauth2
flows:
clientCredentials:
tokenUrl: https://data.castoredc.com/api/oauth/token
scopes: {}
parameters:
StudyId:
name: study_id
in: path
required: true
description: The study GUID (uppercase, 8-4-4-4-12 format).
schema:
type: string
ParticipantId:
name: participant_id
in: path
required: true
description: The participant (record) ID.
schema:
type: string
InstituteId:
name: institute_id
in: path
required: true
description: The institute GUID.
schema:
type: string
FieldId:
name: field_id
in: path
required: true
description: The field GUID.
schema:
type: string
UserId:
name: user_id
in: path
required: true
description: The user GUID.
schema:
type: string
Page:
name: page
in: query
required: false
description: Page number for paginated (HAL) collections.
schema:
type: integer
minimum: 1
responses:
Unauthorized:
description: Missing or invalid access token.
NotFound:
description: The requested resource was not found.
schemas:
Study:
type: object
properties:
study_id:
type: string
format: uuid
name:
type: string
created_by:
type: string
live:
type: boolean
randomization_enabled:
type: boolean
surveys_enabled:
type: boolean
created_on:
type: string
format: date-time
StudyCollection:
type: object
properties:
_embedded:
type: object
properties:
study:
type: array
items:
$ref: '#/components/schemas/Study'
page_count:
type: integer
total_items:
type: integer
ParticipantInput:
type: object
properties:
participant_id:
type: string
institute_id:
type: string
format: uuid
email_address:
type: string
Participant:
allOf:
- $ref: '#/components/schemas/ParticipantInput'
- type: object
properties:
status:
type: string
randomized_id:
type: string
progress:
type: integer
created_on:
type: string
format: date-time
ParticipantCollection:
type: object
properties:
_embedded:
type: object
properties:
participants:
type: array
items:
$ref: '#/components/schemas/Participant'
page_count:
type: integer
total_items:
type: integer
InstituteInput:
type: object
properties:
name:
type: string
abbreviation:
type: string
country_id:
type: integer
Institute:
allOf:
- $ref: '#/components/schemas/InstituteInput'
- type: object
properties:
institute_id:
type: string
format: uuid
code:
type: string
InstituteCollection:
type: object
properties:
_embedded:
type: object
properties:
institutes:
type: array
items:
$ref: '#/components/schemas/Institute'
User:
type: object
properties:
id:
type: string
format: uuid
name:
type: string
email_address:
type: string
institute:
type: string
UserCollection:
type: object
properties:
_embedded:
type: object
properties:
user:
type: array
items:
$ref: '#/components/schemas/User'
Field:
type: object
properties:
id:
type: string
format: uuid
field_id:
type: string
format: uuid
field_variable_name:
type: string
field_label:
type: string
field_type:
type: string
field_required:
type: boolean
option_group:
type: string
FieldCollection:
type: object
properties:
_embedded:
type: object
properties:
fields:
type: array
items:
$ref: '#/components/schemas/Field'
page_count:
type: integer
total_items:
type: integer
DataPoint:
type: object
properties:
field_id:
type: string
format: uuid
field_value:
type: string
participant_id:
type: string
updated_on:
type: string
format: date-time
DataPointCollection:
type: object
properties:
_embedded:
type: object
properties:
items:
type: array
items:
$ref: '#/components/schemas/DataPoint'
page_count:
type: integer
total_items:
type: integer
DataPointWriteRequest:
type: object
required:
- data
properties:
common:
type: object
properties:
change_reason:
type: string
data:
type: array
items:
type: object
properties:
field_id:
type: string
format: uuid
field_value:
type: string