# Retrieve a study GET https://api.prolific.com/api/v1/studies/{id}/ Retrieve a study by id. If you are polling the API for updates to a study, consider using a [Hook](#tag/Hooks). We will call your endpoint when certain events occur on your study, such as new completed submissions or changes in status. Reference: https://beta-docs.prolific.com/api-reference/studies/get-study ## OpenAPI Specification ```yaml openapi: 3.1.1 info: title: Retrieve a study version: endpoint_studies.GetStudy paths: /api/v1/studies/{id}/: get: operationId: get-study summary: Retrieve a study description: >- Retrieve a study by id. If you are polling the API for updates to a study, consider using a [Hook](#tag/Hooks). We will call your endpoint when certain events occur on your study, such as new completed submissions or changes in status. tags: - - subpackage_studies parameters: - name: id in: path description: Study id required: true schema: type: string - name: Authorization in: header description: Header authentication of the form `undefined ` required: true schema: type: string responses: '200': description: Found content: application/json: schema: $ref: '#/components/schemas/Study' '400': description: Error content: {} components: schemas: BaseStudyProlificIdOption: type: string enum: - value: question - value: url_parameters - value: not_required BaseStudyCompletionCodesItemsCodeType: type: string enum: - value: COMPLETED - value: FAILED_ATTENTION_CHECK - value: FOLLOW_UP_STUDY - value: GIVE_BONUS - value: INCOMPATIBLE_DEVICE - value: NO_CONSENT - value: OTHER - value: FIXED_SCREENOUT AutomaticallyApproveAction: type: string enum: - value: AUTOMATICALLY_APPROVE AutomaticallyApprove: type: object properties: action: $ref: '#/components/schemas/AutomaticallyApproveAction' description: >- Automatically approves submission with payment being processed immediately required: - action AddToParticipantGroupAction: type: string enum: - value: ADD_TO_PARTICIPANT_GROUP AddToParticipantGroup: type: object properties: action: $ref: '#/components/schemas/AddToParticipantGroupAction' description: Adds participants to a specific group participant_group: type: string description: The participant group to add the participant to. required: - action - participant_group RemoveFromParticipantGroupAction: type: string enum: - value: REMOVE_FROM_PARTICIPANT_GROUP RemoveFromParticipantGroup: type: object properties: action: $ref: '#/components/schemas/RemoveFromParticipantGroupAction' description: Removes participants from specific groups participant_group: type: string description: The participant group to remove the participant from. required: - action - participant_group ManuallyReviewAction: type: string enum: - value: MANUALLY_REVIEW ManuallyReview: type: object properties: action: $ref: '#/components/schemas/ManuallyReviewAction' description: Moves submission for the data collector to be manually reviewed. required: - action RequestReturnAction: type: string enum: - value: REQUEST_RETURN RequestReturn: type: object properties: action: $ref: '#/components/schemas/RequestReturnAction' description: Requests the participant to return their study return_reason: type: string description: The reason you would like to request a return required: - action - return_reason DynamicPaymentAction: type: string enum: - value: DYNAMIC_PAYMENT DynamicPayment: type: object properties: action: $ref: '#/components/schemas/DynamicPaymentAction' description: >- Use this action to set up a dynamic payment study. Only certain workspaces have access to this feature. When using this action, the actor must be "researcher". required: - action FixedScreenOutAction: type: string enum: - value: FIXED_SCREEN_OUT_PAYMENT FixedScreenOut: type: object properties: action: $ref: '#/components/schemas/FixedScreenOutAction' description: >- Use this action to set up a fixed screen out reward study. This feature is currently available to select workspaces only. - A fixed screen out reward study compensates participants with a predetermined amount when they do not qualify for the study. - This feature enables researchers to implement more precise participant screening while ensuring fair compensation for participants' time. fixed_screen_out_reward: type: integer description: >- The amount that you would like to pay for a screen-out submission (in subcurrency). This must be less that the study reward. slots: type: integer description: >- The slots field controls how many participants can be screened out of your study before it automatically pauses. #### What are slots? - Slots set a limit on screen-outs to help you budget upfront, by setting the limit to the maximum number of screen-outs you're comfortable paying for in your study. - When participants don't qualify for your study, they will receive a screen-out payment. - The slots limit prevents unexpected high costs created from too many screen-outs. - **Example**: If you set `slots: 50`, your study will pause after 50 participants are screened out, even if you still need more qualified participants. #### How slots work 1. **Participants are screened out** - When they enter the completion code linked to this action. They will automatically receive the fixed screen out reward. 2. **Study pauses automatically** - When the number of participants screened out reaches the slots limit, and there are still unfilled places in the study, the study will automatically pause. 3. **You get notified** - Via email and webhook, notifying you that you’ve reached your slot limit, and that your study has been paused. (Webhook notifications only if they’re enabled for `study.status.change` events) #### Resuming your study *To continue recruiting after hitting the slot limit:* 1. **Increase the slot limit** using the [update study](#tag/Studies/operation/UpdateStudy) endpoint. - Update the initial property to your new slot limit. - Refer `update_slots` in the example of the [UpdateStudy](#tag/Studies/operation/UpdateStudy) endpoint. - For example, if you started with 50 slots and want to add another 50 slots, set the `slots` property to 100. ```json { "completion_codes": [ { "code": "ABC123", "actions": [ { "action": "FIXED_SCREEN_OUT_PAYMENT", "slots": 100 } ] } ] } ``` 2. **Resume the study** by transitioning it back to `START` state using the [transition study](#tag/Studies/operation/PublishStudy) endpoint. ```json { "action": "START" } ``` required: - action - fixed_screen_out_reward - slots BaseStudyCompletionCodesItemsActionsItems: oneOf: - $ref: '#/components/schemas/AutomaticallyApprove' - $ref: '#/components/schemas/AddToParticipantGroup' - $ref: '#/components/schemas/RemoveFromParticipantGroup' - $ref: '#/components/schemas/ManuallyReview' - $ref: '#/components/schemas/RequestReturn' - $ref: '#/components/schemas/DynamicPayment' - $ref: '#/components/schemas/FixedScreenOut' BaseStudyCompletionCodesItemsActor: type: string enum: - value: participant - value: researcher default: participant BaseStudyCompletionCodesItems: type: object properties: code: type: - string - 'null' description: > The code the participant will either enter manually at the end of your study or be redirected as part of the return URL. If the code is null, then the participant will not be asked to submit a completion code when they return to Prolific. Null codes can only be provided when: - The actor is "participant" - There are no other completion codes with the "participant" actor - The actions array is empty The code must be unique within the study. code_type: $ref: '#/components/schemas/BaseStudyCompletionCodesItemsCodeType' description: > A name for your code to make it easier to understand its intention. Either use one of the predefined options or any other free text. actions: type: array items: $ref: '#/components/schemas/BaseStudyCompletionCodesItemsActionsItems' description: >- The actions that will be completed automatically when the submission is completed with this code by the participant. You have the ability to use one or multiple `actions` together - it's up to you and your desired automated journey. If you’re looking to keep things simple, we recommend setting the `{"action": "MANUALLY_REVIEW"}` option only, so all submissions wait for your manual approval. actor: $ref: '#/components/schemas/BaseStudyCompletionCodesItemsActor' description: The actor that can provide this completion code. required: - code - code_type - actions BaseStudyDeviceCompatibilityItems: type: string enum: - value: desktop - value: tablet - value: mobile BaseStudyPeripheralRequirementsItems: type: string enum: - value: audio - value: camera - value: download - value: microphone SelectFilter: type: object properties: filter_id: type: string description: ID of the "select" type filter. selected_values: type: array items: type: string description: >- This schema applies for filters of the `select` type, as defined in the [filter list response](\#tag/Filters/paths/~1api~1v1~1filters~1/get). Array of IDs matching the response IDs, from the `select` filter's `choices` (see response linked above). String format should match the `data_type` of the `select` filter's `choices` (see response linked above). weightings: type: object additionalProperties: type: number format: double description: >- Ratios to control the distribution of participants across the selected values. Integer percentages, floats, and exact quantities are valid inputs. required: - filter_id - selected_values RangeFilterSelectedRangeLower: oneOf: - type: integer - type: string - type: number format: double RangeFilterSelectedRangeUpper: oneOf: - type: integer - type: string - type: number format: double RangeFilterSelectedRange: type: object properties: lower: $ref: '#/components/schemas/RangeFilterSelectedRangeLower' description: Your selected lower bound for the range. upper: $ref: '#/components/schemas/RangeFilterSelectedRangeUpper' description: Your selected upper bound for the range. RangeFilterWeightingsSelectedRangeLower: oneOf: - type: integer - type: string - type: number format: double RangeFilterWeightingsSelectedRangeUpper: oneOf: - type: integer - type: string - type: number format: double RangeFilterWeightingsSelectedRange: type: object properties: lower: $ref: '#/components/schemas/RangeFilterWeightingsSelectedRangeLower' upper: $ref: '#/components/schemas/RangeFilterWeightingsSelectedRangeUpper' RangeFilterWeightings: type: object properties: selected_range: $ref: '#/components/schemas/RangeFilterWeightingsSelectedRange' weighting: type: number format: double required: - selected_range - weighting RangeFilter: type: object properties: filter_id: type: string description: ID of the "range" type filter. selected_range: $ref: '#/components/schemas/RangeFilterSelectedRange' description: >- This schema applies for filters of the `range` type, as defined in the [filter list response](\#tag/Filters/paths/~1api~1v1~1filters~1/get). A dictionary with two possible objects, 'lower' and 'upper'. At least one must be present and a non-null value. The expected data type for these values is defined by the `range` filter's `data_type` (see response linked above). If the data_type is a date, string format should be a parseable ISO8601 date string. Date values should be provided as a string in ISO 8601 format. Leaving a value as null will result in that bound being set to the lowest or highest possible value, depending on whether it is the upper or lower bound. weightings: $ref: '#/components/schemas/RangeFilterWeightings' description: >- Ratios to control the distribution of participants across the selected values. Integers and exact quantities are valid inputs. required: - filter_id - selected_range BaseStudyFiltersItems: oneOf: - $ref: '#/components/schemas/SelectFilter' - $ref: '#/components/schemas/RangeFilter' BaseStudySubmissionsConfigAutoRejectionCategoriesItems: type: string enum: - value: EXCEPTIONALLY_FAST BaseStudySubmissionsConfig: type: object properties: max_submissions_per_participant: type: - integer - 'null' default: 1 description: >- - **1** is the default Prolific experience. This means one submission, per participant, per study. If you do not specify this field, the **default is 1**. - **1+** turns your study into a multi-submission study, meaning a participant can create many submissions per study. As noted above, your survey system will need to handle providing a unique experience each time the participant takes the study. - **-1** will allow an indefinite number of submissions from a single participant, up to `total_available_places`. max_concurrent_submissions: type: - integer - 'null' default: -1 description: >- - **-1** is the default value, meaning unlimited concurrent active/reserved submissions per study. - **1+** limits the number of concurrent active/reserved submissions a study can have at one time. auto_rejection_categories: type: array items: $ref: >- #/components/schemas/BaseStudySubmissionsConfigAutoRejectionCategoriesItems description: >- List of rejection categories that trigger automatic submission rejections. **Available Categories:** - **EXCEPTIONALLY_FAST**: Automatically reject submissions completed in an exceptionally short time **Important Notes:** - **This feature is currently in an evaluation period and can be activated for your workspace upon request.** - Auto-rejections only apply to submissions in "AWAITING REVIEW" status - Submissions with return requests will not be auto-rejected - Auto-rejected submissions do not count towards your rejection limit - Set to an empty array `[]` or omit this field to disable auto-rejection BaseStudyStudyLabelsItems: type: string enum: - value: survey - value: writing_task - value: annotation - value: decision_making_task - value: interview - value: other - value: ai_annotation - value: ai_evaluation - value: ai_reasoning - value: ai_fact_checking - value: ai_safety - value: ai_data_creation_text - value: ai_data_creation_audio - value: ai_data_creation_video - value: ai_data_creation_images - value: ai_other BaseStudyContentWarningsItems: type: string enum: - value: sensitive - value: explicit BaseStudyDataCollectionMethod: type: string enum: - value: DC_TOOL - value: AI_TASK_BUILDER BaseStudyDataCollectionMetadata: type: object properties: annotators_per_task: type: integer description: >- Number of annotators required per task. Required for AI Task Builder studies to set multiple annotators. AccessDetail: type: object properties: external_url: type: string description: >- URL of the task you want to send the participant to. You can pass URL search parameters as in `external_study_url`. total_allocation: type: number format: double description: The number of places you want to be sent to this URL for taskflow. required: - external_url - total_allocation BaseStudyAccessDetailsItems: oneOf: - $ref: '#/components/schemas/AccessDetail' StudyStatus: type: string enum: - value: UNPUBLISHED - value: SCHEDULED - value: PUBLISHING - value: ACTIVE - value: AWAITING REVIEW - value: PAUSED - value: COMPLETED Study: type: object properties: name: type: string description: Public name or title of the study internal_name: type: - string - 'null' description: Internal name of the study, not shown to participants description: type: string description: >- Description of the study for the participants to read before starting the study **Supported HTML in `description`** The `description` field supports the following HTML tags for formatting participant instructions: * `` - bold * `` - italic * `` - emphasized text * `` - strong importance * `` - strikethrough * `` - underline * `

` - heading level 1 * `

` - heading level 2 * `
    ` - ordered list * `
      ` - unordered list * `
    • ` - list item * `

      ` - paragraph Other HTML tags will be stripped or escaped. Please ensure that you only use supported tags for formatting to avoid rendering issues. external_study_url: type: string description: >- URL of the survey or experiment you want participant to access. You can pass URL search parameters to your survey or experiment * Participant id {{%PROLIFIC_PID%}} * Study id {{%STUDY_ID%}} * Session id {{%SESSION_ID%}} For example `https://eggs-experriment.com?participant={{%PROLIFIC_PID%}}` prolific_id_option: $ref: '#/components/schemas/BaseStudyProlificIdOption' description: >- Use 'question' if you will add a question in your survey or experiment asking the participant ID **Recommended** Use 'url_parameters' if your survey or experiment can retrieve and store those parameters for your analysis. Use 'not_required' if you don't need to record them. completion_codes: type: array items: $ref: '#/components/schemas/BaseStudyCompletionCodesItems' description: >- Specify at least one completion code for your study. A participant will enter one of these codes when they complete your study. Each code must be unique within a study. You can specify as many actions as you like per code. However, some actions can't be used together (e.g. AutomaticallyApprove and ManuallyReview). total_available_places: type: number format: double description: >- How many participants are you looking to recruit. **Note:** This field is optional when `data_collection_method` is set to `DC_TOOL` or `AI_TASK_BUILDER` (AI Task Builder), as the total available places are automatically calculated from the batch configuration. estimated_completion_time: type: number format: double description: Estimated duration in minutes of the experiment or survey maximum_allowed_time: type: number format: double description: >- Max time in minutes for a participant to finish the submission. Submissions are timed out if it takes longer. If it is not provided the default value is set to the max value. The min value is calculated as two minutes plus two times the estimated time plus two times the square root of the estimated time reward: type: number format: double description: |- How much are you going to pay the participants in cents. We use the currency of your account. device_compatibility: type: array items: $ref: '#/components/schemas/BaseStudyDeviceCompatibilityItems' description: |- Add all devices that participants can use. You can include one or more options. An empty array indicates that all options are available. peripheral_requirements: type: array items: $ref: '#/components/schemas/BaseStudyPeripheralRequirementsItems' description: >- Add all requirements that participants have to meet. An empty array indicates that there are no extra peripheral requirements. filters: type: - array - 'null' items: $ref: '#/components/schemas/BaseStudyFiltersItems' description: |- Array of filters. Use empty array for "Everyone" filter_set_id: type: - string - 'null' description: >- The ID of a filter set, from which filters for the study will be taken. Note, this cannot be used in combination with additional filters via the `filters` field. filter_set_version: type: - integer - 'null' description: >- The version of the filter set to be used. If not provided, this will default to the latest available version at the time of applying the filter set. naivety_distribution_rate: type: - number - 'null' format: double description: >- Control the balance between speed of your studies and the naivety of the participants. If not defined, by default Prolific calculates the best rate for most studies taking into account the `filters` and the `total_available_places` needed for this study. Use 0 if your priority is speed. When this property is set to 0 all eligible participants will have access to your study at the same time, without any prioritization. You can also set this at a workspace and project level. project: type: string description: >- Project ID. When you don't specify a project in your request, Prolific automatically uses your first created project as the default. For clarity, we recommend explicitly including the project ID in your requests. submissions_config: $ref: '#/components/schemas/BaseStudySubmissionsConfig' description: >- **Advanced**: This helps with faster data collection. Your survey system will need to handle providing a unique experience each time the participant takes the study. Configuration related to study submissions. The purpose of this field is to capture any configuration options that impact the submissions made by participants in a study. study_labels: type: array items: $ref: '#/components/schemas/BaseStudyStudyLabelsItems' description: >- This field allows you to tag studies with information about the type/topic of the study and the kind of work involved in completing it. We plan to make this information available to participants for easier self-selection. At present these options are mutually exclusive and only a single option can be selected, however in the future available categories will expand. content_warnings: type: array items: $ref: '#/components/schemas/BaseStudyContentWarningsItems' description: >- Allow researchers to define content warnings for their study. At present these options are mutually exclusive and only a single option can be selected, however in the future available warnings will expand. content_warning_details: type: string description: >- Allow researchers to add further details about their content warning. metadata: type: - string - 'null' description: >- This field can be used to store extra information required for a system integration. For example, it could be some JSON, XML, an integer, or a string. Examples could include: - `123345` - An ID from your system, that helps with linkage when returning the study. - `{ \"id\": \"45\", \"type\": \"finance\"}` - Some JSON that you want to store. credential_pool_id: type: - string - 'null' description: >- The ID of the credential pool to associate with this study. Credential pools contain username/password pairs that are distributed to participants when they start the study. When provided, participants will be assigned unique credentials from the pool. Each credential can only be used once and is tracked throughout the study lifecycle. **Note:** The credential pool must: - Exist and belong to the study's workspace - Have available (unredeemed) credentials See the [Credentials endpoints](#tag/Credentials) for managing credential pools. has_credentials: type: boolean description: >- Indicates whether this study requires participants to use credentials. This field is automatically set to `true` when a `credential_pool_id` is provided, and `false` when the credential pool is removed. **Note:** This field is automatically managed based on the `credential_pool_id` field and does not need to be set manually. data_collection_method: oneOf: - $ref: '#/components/schemas/BaseStudyDataCollectionMethod' - type: 'null' description: >- **Optional.** Specifies the data collection method for the study. - `DC_TOOL`: Use AI Task Builder for data annotation and collection tasks (legacy value). - `AI_TASK_BUILDER`: Use AI Task Builder for data annotation and collection tasks. **Note:** This field is mutually exclusive with `external_study_url` and `access_details`. If not provided, you must specify one of those fields instead. data_collection_id: type: - string - 'null' description: >- The ID of the data collection batch or project from the Task Builder API. **Required when `data_collection_method` is set to `DC_TOOL` or `AI_TASK_BUILDER`.** data_collection_metadata: oneOf: - $ref: '#/components/schemas/BaseStudyDataCollectionMetadata' - type: 'null' description: >- **Optional.** Additional metadata for configuring AI Task Builder data collection behavior. Only used when `data_collection_method` is set to `DC_TOOL` or `AI_TASK_BUILDER`. **Properties:** - `annotators_per_task` (integer): Number of annotators per task. **This field must be provided if you want multiple annotators per task.** Without this field, the default value of 1 will be used. - Minimum: 1 - Default: 1 (if not provided) **Example:** ```json { "annotators_per_task": 5 } ``` **Important:** You must include `annotators_per_task` to control how many participants annotate each task. After the study is published, this value can only be increased (not decreased), which will increase the total available places on the study. access_details: type: - array - 'null' items: $ref: '#/components/schemas/BaseStudyAccessDetailsItems' description: >- Array of access_details, which integrates with taskflow. While this field is nullable, you must provide one of `access_details` or `external_study_url`. The sum of all access_details must add to the `total_available_places` field, however the values can be different for an individual access_detail. is_external_study_url_secure: type: boolean description: >- When set to true, any query parameters in the external study url will be signed with a JSON Web Token. The token will be added to the URL as a query parameter named `prolific_token`. This feature is only available to certain workspaces. **The JWT payload** Header: ```json { "alg": "RS256", "kid": "", "typ": "JWT" } ``` Where - alg is always RS256. - kid indicates the key ID that was used to secure the JWT. - typ is always JWT. Payload: ```json { "iss": "https://www.prolific.com", "iat": , "exp": , "aud": "", "sub": "", "prolific":{ "": "", "": "", ... } } ``` For example: ```json { "iss": "https://www.prolific.com", "iat": 1740496135, "exp": 1740496255, "aud": "https://x.com?STUDY_ID=1&...", "sub": "1234", "prolific":{ "STUDY_ID": "abcd", "SESSION_ID": "1234", "PROLIFIC_PID": "xyz" } } ``` **Verify the payload** When you receive the JWT, you must verify the following: - The JWT signature is authentic by verifying it with the public key from Prolific that correlates with the KID. The public keys can be retrieved from [/.well-known/study/jwks.json](#tag/Well-Known-Endpoints/paths/~1.well-known~1study~1jwks.json/get). - The JWT hasn't expired, by checking the `exp` claim. - The `aud` claim is the correct domain for your tool. - The `prolific` value matches your expected payload as set in the `external_study_url` property. id: type: string description: Study id. It is created by Prolific. **Read only**. status: $ref: '#/components/schemas/StudyStatus' description: |- Status of the study. **Read only**. To change the status you can use `/api/v1/studies/{id}/transition/` ``` ## SDK Code Examples ```python import requests url = "https://api.prolific.com/api/v1/studies/id/" headers = {"Authorization": ""} response = requests.get(url, headers=headers) print(response.json()) ``` ```javascript const url = 'https://api.prolific.com/api/v1/studies/id/'; const options = {method: 'GET', headers: {Authorization: ''}}; try { const response = await fetch(url, options); const data = await response.json(); console.log(data); } catch (error) { console.error(error); } ``` ```go package main import ( "fmt" "net/http" "io" ) func main() { url := "https://api.prolific.com/api/v1/studies/id/" req, _ := http.NewRequest("GET", url, nil) req.Header.Add("Authorization", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(res) fmt.Println(string(body)) } ``` ```ruby require 'uri' require 'net/http' url = URI("https://api.prolific.com/api/v1/studies/id/") http = Net::HTTP.new(url.host, url.port) http.use_ssl = true request = Net::HTTP::Get.new(url) request["Authorization"] = '' response = http.request(request) puts response.read_body ``` ```java HttpResponse response = Unirest.get("https://api.prolific.com/api/v1/studies/id/") .header("Authorization", "") .asString(); ``` ```php request('GET', 'https://api.prolific.com/api/v1/studies/id/', [ 'headers' => [ 'Authorization' => '', ], ]); echo $response->getBody(); ``` ```csharp var client = new RestClient("https://api.prolific.com/api/v1/studies/id/"); var request = new RestRequest(Method.GET); request.AddHeader("Authorization", ""); IRestResponse response = client.Execute(request); ``` ```swift import Foundation let headers = ["Authorization": ""] let request = NSMutableURLRequest(url: NSURL(string: "https://api.prolific.com/api/v1/studies/id/")! as URL, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0) request.httpMethod = "GET" request.allHTTPHeaderFields = headers let session = URLSession.shared let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in if (error != nil) { print(error as Any) } else { let httpResponse = response as? HTTPURLResponse print(httpResponse) } }) dataTask.resume() ```