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