> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.prolific.com/llms.txt.
> For full documentation content, see https://docs.prolific.com/llms-full.txt.

# Finding the right participants

This guide demonstrates how to find and select the right participants for your studies using Prolific's API.

## Pre-screeners

Pre-screeners (also called Filters) allow you to restrict access to your study based on a wide variety of criteria. This guide will demonstrate how to select and use pre-screeners via API.

For more information on the types of screeners we have, please read the help center article [here](https://researcher-help.prolific.com/en/articles/445159-how-do-i-use-prolific-s-demographic-prescreening).

```mermaid
%%{init: {
  "theme": "base",
  "flowchart": {
    "htmlLabels": true,
    "curve": "stepAfter"
  },
  "themeVariables": {
    "primaryColor": "#fafafa",
    "primaryBorderColor": "#e7e7ea",
    "primaryTextColor": "#0f2ac9",
    "fontFamily": "Inter, system-ui, sans-serif",
    "fontSize": "15px",
    "lineColor": "#bfc1c7",
    "lineWidth": 2,
    "defaultLinkColor": "#0f2ac9"
  },
  "themeCSS": ".node.finish a, .node.start a { color: currentColor !important; }"
}}%%
flowchart TD

    A["List the <a href="/api-reference/filters/get-filters">filters</a>"]:::start
    B["Find the pre-screener or filter set to use"]:::note

    C{"What is the <a href="/api-reference/filters/get-filters#response.body.results.type">type</a> of the pre-screener?"}:::decision
    F{"What is the <a href="/api-reference/filters/get-filters#response.body.results.data_type">data type</a> of the pre-screener?"}:::decision

    I["<a href="/api-reference/filters/get-filters#response.body.results.choices">Choices</a> of this pre-screener are in the response"]:::note

    J["Provide the <a href="/api-reference/studies/create-study#request.body.filters.filter_id">filter_id</a> and the IDs of your <a href="/api-reference/studies/create-study#request.body.filters.selected_values">selected values</a>"]:::finish

    K["Provide the <a href="/api-reference/studies/create-study#request.body.filters.filter_id">filter_id</a> and the <a href="/api-reference/studies/create-study#request.body.filters.selected_values">selected values</a> as described by the <a href="/api-reference/filters/get-filters#response.body.results.data_type">data type</a>"]:::finish

    L["<a href="/api-reference/filters/get-filters#response.body.results.min">Minimum</a> and <a href="/api-reference/filters/get-filters#response.body.results.max">maximum</a> values are inclusive"]:::note

    M["Provide the <a href="/api-reference/studies/create-study#request.body.filters.filter_id">filter_id</a> and <a href="/api-reference/studies/create-study#request.body.filters.selected_range">selected_range</a>, containing the inclusive <a href="/api-reference/studies/create-study#request.body.filters.selected_range.lower">lower</a> and <a href="/api-reference/studies/create-study#request.body.filters.selected_range.upper">upper</a> bounds"]:::finish

    A --> B --> C
    C -- "<span>&nbsp;&nbsp;<b>Select</b>&nbsp;&nbsp;</span>" --> F
    C -- "<span>&nbsp;&nbsp;<b>Range</b>&nbsp;&nbsp;</span>" --> L --> M
    F -- "<span>&nbsp;&nbsp;<b>Choice ID</b>&nbsp;&nbsp;</span>" --> I --> J
    F -- "<span>&nbsp;&nbsp;<b>Other</b>&nbsp;&nbsp;</span>" --> K

    classDef start fill:#0f2ac9,color:#ffffff,stroke:#0f2ac9,stroke-width:4px;
    classDef decision stroke:#bfc1c7,color:#4b5563,stroke-width:4px;
    classDef note stroke:#e7e7ea,color:#4b5563,stroke-width:4px,stroke-dasharray:4;
    classDef finish fill:#0f2ac9,color:#ffffff,stroke:#0f2ac9,stroke-width:4px;
```

<Steps>
  <Step>
    Get the list of pre-screeners

    ### Request

    GET [https://api.prolific.com/api/v1/filters/](https://api.prolific.com/api/v1/filters/)

    ```curl Custom groups
    curl -G https://api.prolific.com/api/v1/filters/ \
         -H "Authorization: Token <token>" \
         -d filter_tag=custom-group
    ```

    ```python Custom groups
    import requests

    url = "https://api.prolific.com/api/v1/filters/"

    querystring = {"filter_tag":"custom-group"}

    headers = {"Authorization": "Token <token>"}

    response = requests.get(url, headers=headers, params=querystring)

    print(response.json())
    ```

    ```javascript Custom groups
    const url = 'https://api.prolific.com/api/v1/filters/?filter_tag=custom-group';
    const options = {method: 'GET', headers: {Authorization: 'Token <token>'}};

    try {
      const response = await fetch(url, options);
      const data = await response.json();
      console.log(data);
    } catch (error) {
      console.error(error);
    }
    ```

    ```go Custom groups
    package main

    import (
    	"fmt"
    	"net/http"
    	"io"
    )

    func main() {

    	url := "https://api.prolific.com/api/v1/filters/?filter_tag=custom-group"

    	req, _ := http.NewRequest("GET", url, nil)

    	req.Header.Add("Authorization", "Token <token>")

    	res, _ := http.DefaultClient.Do(req)

    	defer res.Body.Close()
    	body, _ := io.ReadAll(res.Body)

    	fmt.Println(res)
    	fmt.Println(string(body))

    }
    ```

    ```ruby Custom groups
    require 'uri'
    require 'net/http'

    url = URI("https://api.prolific.com/api/v1/filters/?filter_tag=custom-group")

    http = Net::HTTP.new(url.host, url.port)
    http.use_ssl = true

    request = Net::HTTP::Get.new(url)
    request["Authorization"] = 'Token <token>'

    response = http.request(request)
    puts response.read_body
    ```

    ```java Custom groups
    import com.mashape.unirest.http.HttpResponse;
    import com.mashape.unirest.http.Unirest;

    HttpResponse<String> response = Unirest.get("https://api.prolific.com/api/v1/filters/?filter_tag=custom-group")
      .header("Authorization", "Token <token>")
      .asString();
    ```

    ```php Custom groups
    <?php
    require_once('vendor/autoload.php');

    $client = new \GuzzleHttp\Client();

    $response = $client->request('GET', 'https://api.prolific.com/api/v1/filters/?filter_tag=custom-group', [
      'headers' => [
        'Authorization' => 'Token <token>',
      ],
    ]);

    echo $response->getBody();
    ```

    ```csharp Custom groups
    using RestSharp;

    var client = new RestClient("https://api.prolific.com/api/v1/filters/?filter_tag=custom-group");
    var request = new RestRequest(Method.GET);
    request.AddHeader("Authorization", "Token <token>");
    IRestResponse response = client.Execute(request);
    ```

    ```swift Custom groups
    import Foundation

    let headers = ["Authorization": "Token <token>"]

    let request = NSMutableURLRequest(url: NSURL(string: "https://api.prolific.com/api/v1/filters/?filter_tag=custom-group")! 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()
    ```

    There are 2 types of pre-screeners:

    * `select`: select from one of more options from a list of pre-defined choices e.g., first language
    * `range`: specify an upper and/or a lower bound e.g., age
  </Step>

  <Step>
    When creating a study, specify a list of pre-screeners

    ### Request

    POST [https://api.prolific.com/api/v1/studies/](https://api.prolific.com/api/v1/studies/)

    ```curl study_with_select_filters
    curl -X POST https://api.prolific.com/api/v1/studies/ \
         -H "Authorization: Token <token>" \
         -H "Content-Type: application/json" \
         -d '{
      "name": "Test",
      "description": "test",
      "external_study_url": "https://google.com",
      "prolific_id_option": "question",
      "total_available_places": 500,
      "estimated_completion_time": 1,
      "reward": 13,
      "completion_codes": [
        {
          "code": "ABC123",
          "code_type": "COMPLETED",
          "actions": [
            {
              "action": "MANUALLY_REVIEW"
            }
          ]
        }
      ],
      "device_compatibility": [
        "mobile",
        "desktop",
        "tablet"
      ],
      "peripheral_requirements": [],
      "filters": [
        {
          "filter_id": "handedness",
          "selected_values": [
            "2"
          ]
        }
      ],
      "submissions_config": {
        "max_submissions_per_participant": 1
      },
      "completion_code": "ABC123"
    }'
    ```

    ```python study_with_select_filters
    import requests

    url = "https://api.prolific.com/api/v1/studies/"

    payload = {
        "name": "Test",
        "description": "test",
        "external_study_url": "https://google.com",
        "prolific_id_option": "question",
        "total_available_places": 500,
        "estimated_completion_time": 1,
        "reward": 13,
        "completion_codes": [
            {
                "code": "ABC123",
                "code_type": "COMPLETED",
                "actions": [{ "action": "MANUALLY_REVIEW" }]
            }
        ],
        "device_compatibility": ["mobile", "desktop", "tablet"],
        "peripheral_requirements": [],
        "filters": [
            {
                "filter_id": "handedness",
                "selected_values": ["2"]
            }
        ],
        "submissions_config": { "max_submissions_per_participant": 1 },
        "completion_code": "ABC123"
    }
    headers = {
        "Authorization": "Token <token>",
        "Content-Type": "application/json"
    }

    response = requests.post(url, json=payload, headers=headers)

    print(response.json())
    ```

    ```javascript study_with_select_filters
    const url = 'https://api.prolific.com/api/v1/studies/';
    const options = {
      method: 'POST',
      headers: {Authorization: 'Token <token>', 'Content-Type': 'application/json'},
      body: '{"name":"Test","description":"test","external_study_url":"https://google.com","prolific_id_option":"question","total_available_places":500,"estimated_completion_time":1,"reward":13,"completion_codes":[{"code":"ABC123","code_type":"COMPLETED","actions":[{"action":"MANUALLY_REVIEW"}]}],"device_compatibility":["mobile","desktop","tablet"],"peripheral_requirements":[],"filters":[{"filter_id":"handedness","selected_values":["2"]}],"submissions_config":{"max_submissions_per_participant":1},"completion_code":"ABC123"}'
    };

    try {
      const response = await fetch(url, options);
      const data = await response.json();
      console.log(data);
    } catch (error) {
      console.error(error);
    }
    ```

    ```go study_with_select_filters
    package main

    import (
    	"fmt"
    	"strings"
    	"net/http"
    	"io"
    )

    func main() {

    	url := "https://api.prolific.com/api/v1/studies/"

    	payload := strings.NewReader("{\n  \"name\": \"Test\",\n  \"description\": \"test\",\n  \"external_study_url\": \"https://google.com\",\n  \"prolific_id_option\": \"question\",\n  \"total_available_places\": 500,\n  \"estimated_completion_time\": 1,\n  \"reward\": 13,\n  \"completion_codes\": [\n    {\n      \"code\": \"ABC123\",\n      \"code_type\": \"COMPLETED\",\n      \"actions\": [\n        {\n          \"action\": \"MANUALLY_REVIEW\"\n        }\n      ]\n    }\n  ],\n  \"device_compatibility\": [\n    \"mobile\",\n    \"desktop\",\n    \"tablet\"\n  ],\n  \"peripheral_requirements\": [],\n  \"filters\": [\n    {\n      \"filter_id\": \"handedness\",\n      \"selected_values\": [\n        \"2\"\n      ]\n    }\n  ],\n  \"submissions_config\": {\n    \"max_submissions_per_participant\": 1\n  },\n  \"completion_code\": \"ABC123\"\n}")

    	req, _ := http.NewRequest("POST", url, payload)

    	req.Header.Add("Authorization", "Token <token>")
    	req.Header.Add("Content-Type", "application/json")

    	res, _ := http.DefaultClient.Do(req)

    	defer res.Body.Close()
    	body, _ := io.ReadAll(res.Body)

    	fmt.Println(res)
    	fmt.Println(string(body))

    }
    ```

    ```ruby study_with_select_filters
    require 'uri'
    require 'net/http'

    url = URI("https://api.prolific.com/api/v1/studies/")

    http = Net::HTTP.new(url.host, url.port)
    http.use_ssl = true

    request = Net::HTTP::Post.new(url)
    request["Authorization"] = 'Token <token>'
    request["Content-Type"] = 'application/json'
    request.body = "{\n  \"name\": \"Test\",\n  \"description\": \"test\",\n  \"external_study_url\": \"https://google.com\",\n  \"prolific_id_option\": \"question\",\n  \"total_available_places\": 500,\n  \"estimated_completion_time\": 1,\n  \"reward\": 13,\n  \"completion_codes\": [\n    {\n      \"code\": \"ABC123\",\n      \"code_type\": \"COMPLETED\",\n      \"actions\": [\n        {\n          \"action\": \"MANUALLY_REVIEW\"\n        }\n      ]\n    }\n  ],\n  \"device_compatibility\": [\n    \"mobile\",\n    \"desktop\",\n    \"tablet\"\n  ],\n  \"peripheral_requirements\": [],\n  \"filters\": [\n    {\n      \"filter_id\": \"handedness\",\n      \"selected_values\": [\n        \"2\"\n      ]\n    }\n  ],\n  \"submissions_config\": {\n    \"max_submissions_per_participant\": 1\n  },\n  \"completion_code\": \"ABC123\"\n}"

    response = http.request(request)
    puts response.read_body
    ```

    ```java study_with_select_filters
    import com.mashape.unirest.http.HttpResponse;
    import com.mashape.unirest.http.Unirest;

    HttpResponse<String> response = Unirest.post("https://api.prolific.com/api/v1/studies/")
      .header("Authorization", "Token <token>")
      .header("Content-Type", "application/json")
      .body("{\n  \"name\": \"Test\",\n  \"description\": \"test\",\n  \"external_study_url\": \"https://google.com\",\n  \"prolific_id_option\": \"question\",\n  \"total_available_places\": 500,\n  \"estimated_completion_time\": 1,\n  \"reward\": 13,\n  \"completion_codes\": [\n    {\n      \"code\": \"ABC123\",\n      \"code_type\": \"COMPLETED\",\n      \"actions\": [\n        {\n          \"action\": \"MANUALLY_REVIEW\"\n        }\n      ]\n    }\n  ],\n  \"device_compatibility\": [\n    \"mobile\",\n    \"desktop\",\n    \"tablet\"\n  ],\n  \"peripheral_requirements\": [],\n  \"filters\": [\n    {\n      \"filter_id\": \"handedness\",\n      \"selected_values\": [\n        \"2\"\n      ]\n    }\n  ],\n  \"submissions_config\": {\n    \"max_submissions_per_participant\": 1\n  },\n  \"completion_code\": \"ABC123\"\n}")
      .asString();
    ```

    ```php study_with_select_filters
    <?php
    require_once('vendor/autoload.php');

    $client = new \GuzzleHttp\Client();

    $response = $client->request('POST', 'https://api.prolific.com/api/v1/studies/', [
      'body' => '{
      "name": "Test",
      "description": "test",
      "external_study_url": "https://google.com",
      "prolific_id_option": "question",
      "total_available_places": 500,
      "estimated_completion_time": 1,
      "reward": 13,
      "completion_codes": [
        {
          "code": "ABC123",
          "code_type": "COMPLETED",
          "actions": [
            {
              "action": "MANUALLY_REVIEW"
            }
          ]
        }
      ],
      "device_compatibility": [
        "mobile",
        "desktop",
        "tablet"
      ],
      "peripheral_requirements": [],
      "filters": [
        {
          "filter_id": "handedness",
          "selected_values": [
            "2"
          ]
        }
      ],
      "submissions_config": {
        "max_submissions_per_participant": 1
      },
      "completion_code": "ABC123"
    }',
      'headers' => [
        'Authorization' => 'Token <token>',
        'Content-Type' => 'application/json',
      ],
    ]);

    echo $response->getBody();
    ```

    ```csharp study_with_select_filters
    using RestSharp;

    var client = new RestClient("https://api.prolific.com/api/v1/studies/");
    var request = new RestRequest(Method.POST);
    request.AddHeader("Authorization", "Token <token>");
    request.AddHeader("Content-Type", "application/json");
    request.AddParameter("application/json", "{\n  \"name\": \"Test\",\n  \"description\": \"test\",\n  \"external_study_url\": \"https://google.com\",\n  \"prolific_id_option\": \"question\",\n  \"total_available_places\": 500,\n  \"estimated_completion_time\": 1,\n  \"reward\": 13,\n  \"completion_codes\": [\n    {\n      \"code\": \"ABC123\",\n      \"code_type\": \"COMPLETED\",\n      \"actions\": [\n        {\n          \"action\": \"MANUALLY_REVIEW\"\n        }\n      ]\n    }\n  ],\n  \"device_compatibility\": [\n    \"mobile\",\n    \"desktop\",\n    \"tablet\"\n  ],\n  \"peripheral_requirements\": [],\n  \"filters\": [\n    {\n      \"filter_id\": \"handedness\",\n      \"selected_values\": [\n        \"2\"\n      ]\n    }\n  ],\n  \"submissions_config\": {\n    \"max_submissions_per_participant\": 1\n  },\n  \"completion_code\": \"ABC123\"\n}", ParameterType.RequestBody);
    IRestResponse response = client.Execute(request);
    ```

    ```swift study_with_select_filters
    import Foundation

    let headers = [
      "Authorization": "Token <token>",
      "Content-Type": "application/json"
    ]
    let parameters = [
      "name": "Test",
      "description": "test",
      "external_study_url": "https://google.com",
      "prolific_id_option": "question",
      "total_available_places": 500,
      "estimated_completion_time": 1,
      "reward": 13,
      "completion_codes": [
        [
          "code": "ABC123",
          "code_type": "COMPLETED",
          "actions": [["action": "MANUALLY_REVIEW"]]
        ]
      ],
      "device_compatibility": ["mobile", "desktop", "tablet"],
      "peripheral_requirements": [],
      "filters": [
        [
          "filter_id": "handedness",
          "selected_values": ["2"]
        ]
      ],
      "submissions_config": ["max_submissions_per_participant": 1],
      "completion_code": "ABC123"
    ] as [String : Any]

    let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

    let request = NSMutableURLRequest(url: NSURL(string: "https://api.prolific.com/api/v1/studies/")! as URL,
                                            cachePolicy: .useProtocolCachePolicy,
                                        timeoutInterval: 10.0)
    request.httpMethod = "POST"
    request.allHTTPHeaderFields = headers
    request.httpBody = postData as Data

    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()
    ```
  </Step>

  <Step>
    <Note>
      This is an optional step.
    </Note>

    You can save combinations of pre-screeners as screener sets, to reuse across studies. These are useful if you're
    running multiple studies with the same audience criteria.

    ### Request

    POST [https://api.prolific.com/api/v1/filter-sets/](https://api.prolific.com/api/v1/filter-sets/)

    ```curl
    curl -X POST https://api.prolific.com/api/v1/filter-sets/ \
         -H "Authorization: Token <token>" \
         -H "Content-Type: application/json" \
         -d '{
      "workspace_id": "644aaabfaf6bbc363b9d47c6",
      "name": "Ambidextrous teenagers",
      "filters": [
        {
          "filter_id": "handedness",
          "selected_values": [
            "2"
          ]
        },
        {
          "filter_id": "age",
          "selected_values": [
            "19",
            "20",
            "21",
            "22"
          ]
        }
      ]
    }'
    ```

    ```python
    import requests

    url = "https://api.prolific.com/api/v1/filter-sets/"

    payload = {
        "workspace_id": "644aaabfaf6bbc363b9d47c6",
        "name": "Ambidextrous teenagers",
        "filters": [
            {
                "filter_id": "handedness",
                "selected_values": ["2"]
            },
            {
                "filter_id": "age",
                "selected_values": ["19", "20", "21", "22"]
            }
        ]
    }
    headers = {
        "Authorization": "Token <token>",
        "Content-Type": "application/json"
    }

    response = requests.post(url, json=payload, headers=headers)

    print(response.json())
    ```

    ```javascript
    const url = 'https://api.prolific.com/api/v1/filter-sets/';
    const options = {
      method: 'POST',
      headers: {Authorization: 'Token <token>', 'Content-Type': 'application/json'},
      body: '{"workspace_id":"644aaabfaf6bbc363b9d47c6","name":"Ambidextrous teenagers","filters":[{"filter_id":"handedness","selected_values":["2"]},{"filter_id":"age","selected_values":["19","20","21","22"]}]}'
    };

    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"
    	"strings"
    	"net/http"
    	"io"
    )

    func main() {

    	url := "https://api.prolific.com/api/v1/filter-sets/"

    	payload := strings.NewReader("{\n  \"workspace_id\": \"644aaabfaf6bbc363b9d47c6\",\n  \"name\": \"Ambidextrous teenagers\",\n  \"filters\": [\n    {\n      \"filter_id\": \"handedness\",\n      \"selected_values\": [\n        \"2\"\n      ]\n    },\n    {\n      \"filter_id\": \"age\",\n      \"selected_values\": [\n        \"19\",\n        \"20\",\n        \"21\",\n        \"22\"\n      ]\n    }\n  ]\n}")

    	req, _ := http.NewRequest("POST", url, payload)

    	req.Header.Add("Authorization", "Token <token>")
    	req.Header.Add("Content-Type", "application/json")

    	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/filter-sets/")

    http = Net::HTTP.new(url.host, url.port)
    http.use_ssl = true

    request = Net::HTTP::Post.new(url)
    request["Authorization"] = 'Token <token>'
    request["Content-Type"] = 'application/json'
    request.body = "{\n  \"workspace_id\": \"644aaabfaf6bbc363b9d47c6\",\n  \"name\": \"Ambidextrous teenagers\",\n  \"filters\": [\n    {\n      \"filter_id\": \"handedness\",\n      \"selected_values\": [\n        \"2\"\n      ]\n    },\n    {\n      \"filter_id\": \"age\",\n      \"selected_values\": [\n        \"19\",\n        \"20\",\n        \"21\",\n        \"22\"\n      ]\n    }\n  ]\n}"

    response = http.request(request)
    puts response.read_body
    ```

    ```java
    import com.mashape.unirest.http.HttpResponse;
    import com.mashape.unirest.http.Unirest;

    HttpResponse<String> response = Unirest.post("https://api.prolific.com/api/v1/filter-sets/")
      .header("Authorization", "Token <token>")
      .header("Content-Type", "application/json")
      .body("{\n  \"workspace_id\": \"644aaabfaf6bbc363b9d47c6\",\n  \"name\": \"Ambidextrous teenagers\",\n  \"filters\": [\n    {\n      \"filter_id\": \"handedness\",\n      \"selected_values\": [\n        \"2\"\n      ]\n    },\n    {\n      \"filter_id\": \"age\",\n      \"selected_values\": [\n        \"19\",\n        \"20\",\n        \"21\",\n        \"22\"\n      ]\n    }\n  ]\n}")
      .asString();
    ```

    ```php
    <?php
    require_once('vendor/autoload.php');

    $client = new \GuzzleHttp\Client();

    $response = $client->request('POST', 'https://api.prolific.com/api/v1/filter-sets/', [
      'body' => '{
      "workspace_id": "644aaabfaf6bbc363b9d47c6",
      "name": "Ambidextrous teenagers",
      "filters": [
        {
          "filter_id": "handedness",
          "selected_values": [
            "2"
          ]
        },
        {
          "filter_id": "age",
          "selected_values": [
            "19",
            "20",
            "21",
            "22"
          ]
        }
      ]
    }',
      'headers' => [
        'Authorization' => 'Token <token>',
        'Content-Type' => 'application/json',
      ],
    ]);

    echo $response->getBody();
    ```

    ```csharp
    using RestSharp;

    var client = new RestClient("https://api.prolific.com/api/v1/filter-sets/");
    var request = new RestRequest(Method.POST);
    request.AddHeader("Authorization", "Token <token>");
    request.AddHeader("Content-Type", "application/json");
    request.AddParameter("application/json", "{\n  \"workspace_id\": \"644aaabfaf6bbc363b9d47c6\",\n  \"name\": \"Ambidextrous teenagers\",\n  \"filters\": [\n    {\n      \"filter_id\": \"handedness\",\n      \"selected_values\": [\n        \"2\"\n      ]\n    },\n    {\n      \"filter_id\": \"age\",\n      \"selected_values\": [\n        \"19\",\n        \"20\",\n        \"21\",\n        \"22\"\n      ]\n    }\n  ]\n}", ParameterType.RequestBody);
    IRestResponse response = client.Execute(request);
    ```

    ```swift
    import Foundation

    let headers = [
      "Authorization": "Token <token>",
      "Content-Type": "application/json"
    ]
    let parameters = [
      "workspace_id": "644aaabfaf6bbc363b9d47c6",
      "name": "Ambidextrous teenagers",
      "filters": [
        [
          "filter_id": "handedness",
          "selected_values": ["2"]
        ],
        [
          "filter_id": "age",
          "selected_values": ["19", "20", "21", "22"]
        ]
      ]
    ] as [String : Any]

    let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

    let request = NSMutableURLRequest(url: NSURL(string: "https://api.prolific.com/api/v1/filter-sets/")! as URL,
                                            cachePolicy: .useProtocolCachePolicy,
                                        timeoutInterval: 10.0)
    request.httpMethod = "POST"
    request.allHTTPHeaderFields = headers
    request.httpBody = postData as Data

    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()
    ```
  </Step>
</Steps>

## In-study screening

Custom screening lets you check for participant characteristics that aren't available in our built-in pre-screening options. This guide will demonstrate how to create and manage in-study screening via API.

For more detail on custom screening, including a video demo, see the [help center article](https://researcher-help.prolific.com/en/articles/445155-how-to-use-custom-screening-to-recruit-specific-participants).

<Steps>
  <Step>
    Create the survey with pre-screening questions. Set up the survey to take different paths, for example:

    * If someone answers "Yes" they'll continue to your main survey
    * If it's a "No" they'll be directed to your end of survey message

    When participants are screened out, the survey must redirect them to Prolific with the appropriate completion code
    (or provide them with the code to enter manually).

    Check out our [integration guides](https://researcher-help.prolific.com/en/articles/445179-survey-software-integration-guides) for how to
    set up these paths, including how to create your end of survey message in your software.
  </Step>

  <Step>
    Create a custom screening study on Prolific, with a screened out completion path

    ### Request

    POST [https://api.prolific.com/api/v1/studies/](https://api.prolific.com/api/v1/studies/)

    ```curl study_with_custom_screening
    curl -X POST https://api.prolific.com/api/v1/studies/ \
         -H "Authorization: Token <token>" \
         -H "Content-Type: application/json" \
         -d '{
      "name": "A study with custom screening",
      "description": "A short survey with in-study screening questions",
      "external_study_url": "https://google.com",
      "prolific_id_option": "question",
      "total_available_places": 10,
      "estimated_completion_time": 1,
      "reward": 160,
      "completion_codes": [
        {
          "code": "M3J9OF",
          "code_type": "SCREENED_IN",
          "actions": [
            {
              "action": "AUTOMATICALLY_APPROVE"
            }
          ]
        },
        {
          "code": "L7X9G4",
          "code_type": "SCREENED_OUT",
          "actions": [
            {
              "action": "FIXED_SCREEN_OUT_PAYMENT",
              "fixed_screen_out_reward": 150,
              "slots": 2
            }
          ]
        }
      ],
      "device_compatibility": [
        "mobile",
        "desktop",
        "tablet"
      ],
      "peripheral_requirements": [],
      "filters": [],
      "submissions_config": {
        "max_submissions_per_participant": 1
      },
      "completion_code": "M3J9OF"
    }'
    ```

    ```python study_with_custom_screening
    import requests

    url = "https://api.prolific.com/api/v1/studies/"

    payload = {
        "name": "A study with custom screening",
        "description": "A short survey with in-study screening questions",
        "external_study_url": "https://google.com",
        "prolific_id_option": "question",
        "total_available_places": 10,
        "estimated_completion_time": 1,
        "reward": 160,
        "completion_codes": [
            {
                "code": "M3J9OF",
                "code_type": "SCREENED_IN",
                "actions": [{ "action": "AUTOMATICALLY_APPROVE" }]
            },
            {
                "code": "L7X9G4",
                "code_type": "SCREENED_OUT",
                "actions": [
                    {
                        "action": "FIXED_SCREEN_OUT_PAYMENT",
                        "fixed_screen_out_reward": 150,
                        "slots": 2
                    }
                ]
            }
        ],
        "device_compatibility": ["mobile", "desktop", "tablet"],
        "peripheral_requirements": [],
        "filters": [],
        "submissions_config": { "max_submissions_per_participant": 1 },
        "completion_code": "M3J9OF"
    }
    headers = {
        "Authorization": "Token <token>",
        "Content-Type": "application/json"
    }

    response = requests.post(url, json=payload, headers=headers)

    print(response.json())
    ```

    ```javascript study_with_custom_screening
    const url = 'https://api.prolific.com/api/v1/studies/';
    const options = {
      method: 'POST',
      headers: {Authorization: 'Token <token>', 'Content-Type': 'application/json'},
      body: '{"name":"A study with custom screening","description":"A short survey with in-study screening questions","external_study_url":"https://google.com","prolific_id_option":"question","total_available_places":10,"estimated_completion_time":1,"reward":160,"completion_codes":[{"code":"M3J9OF","code_type":"SCREENED_IN","actions":[{"action":"AUTOMATICALLY_APPROVE"}]},{"code":"L7X9G4","code_type":"SCREENED_OUT","actions":[{"action":"FIXED_SCREEN_OUT_PAYMENT","fixed_screen_out_reward":150,"slots":2}]}],"device_compatibility":["mobile","desktop","tablet"],"peripheral_requirements":[],"filters":[],"submissions_config":{"max_submissions_per_participant":1},"completion_code":"M3J9OF"}'
    };

    try {
      const response = await fetch(url, options);
      const data = await response.json();
      console.log(data);
    } catch (error) {
      console.error(error);
    }
    ```

    ```go study_with_custom_screening
    package main

    import (
    	"fmt"
    	"strings"
    	"net/http"
    	"io"
    )

    func main() {

    	url := "https://api.prolific.com/api/v1/studies/"

    	payload := strings.NewReader("{\n  \"name\": \"A study with custom screening\",\n  \"description\": \"A short survey with in-study screening questions\",\n  \"external_study_url\": \"https://google.com\",\n  \"prolific_id_option\": \"question\",\n  \"total_available_places\": 10,\n  \"estimated_completion_time\": 1,\n  \"reward\": 160,\n  \"completion_codes\": [\n    {\n      \"code\": \"M3J9OF\",\n      \"code_type\": \"SCREENED_IN\",\n      \"actions\": [\n        {\n          \"action\": \"AUTOMATICALLY_APPROVE\"\n        }\n      ]\n    },\n    {\n      \"code\": \"L7X9G4\",\n      \"code_type\": \"SCREENED_OUT\",\n      \"actions\": [\n        {\n          \"action\": \"FIXED_SCREEN_OUT_PAYMENT\",\n          \"fixed_screen_out_reward\": 150,\n          \"slots\": 2\n        }\n      ]\n    }\n  ],\n  \"device_compatibility\": [\n    \"mobile\",\n    \"desktop\",\n    \"tablet\"\n  ],\n  \"peripheral_requirements\": [],\n  \"filters\": [],\n  \"submissions_config\": {\n    \"max_submissions_per_participant\": 1\n  },\n  \"completion_code\": \"M3J9OF\"\n}")

    	req, _ := http.NewRequest("POST", url, payload)

    	req.Header.Add("Authorization", "Token <token>")
    	req.Header.Add("Content-Type", "application/json")

    	res, _ := http.DefaultClient.Do(req)

    	defer res.Body.Close()
    	body, _ := io.ReadAll(res.Body)

    	fmt.Println(res)
    	fmt.Println(string(body))

    }
    ```

    ```ruby study_with_custom_screening
    require 'uri'
    require 'net/http'

    url = URI("https://api.prolific.com/api/v1/studies/")

    http = Net::HTTP.new(url.host, url.port)
    http.use_ssl = true

    request = Net::HTTP::Post.new(url)
    request["Authorization"] = 'Token <token>'
    request["Content-Type"] = 'application/json'
    request.body = "{\n  \"name\": \"A study with custom screening\",\n  \"description\": \"A short survey with in-study screening questions\",\n  \"external_study_url\": \"https://google.com\",\n  \"prolific_id_option\": \"question\",\n  \"total_available_places\": 10,\n  \"estimated_completion_time\": 1,\n  \"reward\": 160,\n  \"completion_codes\": [\n    {\n      \"code\": \"M3J9OF\",\n      \"code_type\": \"SCREENED_IN\",\n      \"actions\": [\n        {\n          \"action\": \"AUTOMATICALLY_APPROVE\"\n        }\n      ]\n    },\n    {\n      \"code\": \"L7X9G4\",\n      \"code_type\": \"SCREENED_OUT\",\n      \"actions\": [\n        {\n          \"action\": \"FIXED_SCREEN_OUT_PAYMENT\",\n          \"fixed_screen_out_reward\": 150,\n          \"slots\": 2\n        }\n      ]\n    }\n  ],\n  \"device_compatibility\": [\n    \"mobile\",\n    \"desktop\",\n    \"tablet\"\n  ],\n  \"peripheral_requirements\": [],\n  \"filters\": [],\n  \"submissions_config\": {\n    \"max_submissions_per_participant\": 1\n  },\n  \"completion_code\": \"M3J9OF\"\n}"

    response = http.request(request)
    puts response.read_body
    ```

    ```java study_with_custom_screening
    import com.mashape.unirest.http.HttpResponse;
    import com.mashape.unirest.http.Unirest;

    HttpResponse<String> response = Unirest.post("https://api.prolific.com/api/v1/studies/")
      .header("Authorization", "Token <token>")
      .header("Content-Type", "application/json")
      .body("{\n  \"name\": \"A study with custom screening\",\n  \"description\": \"A short survey with in-study screening questions\",\n  \"external_study_url\": \"https://google.com\",\n  \"prolific_id_option\": \"question\",\n  \"total_available_places\": 10,\n  \"estimated_completion_time\": 1,\n  \"reward\": 160,\n  \"completion_codes\": [\n    {\n      \"code\": \"M3J9OF\",\n      \"code_type\": \"SCREENED_IN\",\n      \"actions\": [\n        {\n          \"action\": \"AUTOMATICALLY_APPROVE\"\n        }\n      ]\n    },\n    {\n      \"code\": \"L7X9G4\",\n      \"code_type\": \"SCREENED_OUT\",\n      \"actions\": [\n        {\n          \"action\": \"FIXED_SCREEN_OUT_PAYMENT\",\n          \"fixed_screen_out_reward\": 150,\n          \"slots\": 2\n        }\n      ]\n    }\n  ],\n  \"device_compatibility\": [\n    \"mobile\",\n    \"desktop\",\n    \"tablet\"\n  ],\n  \"peripheral_requirements\": [],\n  \"filters\": [],\n  \"submissions_config\": {\n    \"max_submissions_per_participant\": 1\n  },\n  \"completion_code\": \"M3J9OF\"\n}")
      .asString();
    ```

    ```php study_with_custom_screening
    <?php
    require_once('vendor/autoload.php');

    $client = new \GuzzleHttp\Client();

    $response = $client->request('POST', 'https://api.prolific.com/api/v1/studies/', [
      'body' => '{
      "name": "A study with custom screening",
      "description": "A short survey with in-study screening questions",
      "external_study_url": "https://google.com",
      "prolific_id_option": "question",
      "total_available_places": 10,
      "estimated_completion_time": 1,
      "reward": 160,
      "completion_codes": [
        {
          "code": "M3J9OF",
          "code_type": "SCREENED_IN",
          "actions": [
            {
              "action": "AUTOMATICALLY_APPROVE"
            }
          ]
        },
        {
          "code": "L7X9G4",
          "code_type": "SCREENED_OUT",
          "actions": [
            {
              "action": "FIXED_SCREEN_OUT_PAYMENT",
              "fixed_screen_out_reward": 150,
              "slots": 2
            }
          ]
        }
      ],
      "device_compatibility": [
        "mobile",
        "desktop",
        "tablet"
      ],
      "peripheral_requirements": [],
      "filters": [],
      "submissions_config": {
        "max_submissions_per_participant": 1
      },
      "completion_code": "M3J9OF"
    }',
      'headers' => [
        'Authorization' => 'Token <token>',
        'Content-Type' => 'application/json',
      ],
    ]);

    echo $response->getBody();
    ```

    ```csharp study_with_custom_screening
    using RestSharp;

    var client = new RestClient("https://api.prolific.com/api/v1/studies/");
    var request = new RestRequest(Method.POST);
    request.AddHeader("Authorization", "Token <token>");
    request.AddHeader("Content-Type", "application/json");
    request.AddParameter("application/json", "{\n  \"name\": \"A study with custom screening\",\n  \"description\": \"A short survey with in-study screening questions\",\n  \"external_study_url\": \"https://google.com\",\n  \"prolific_id_option\": \"question\",\n  \"total_available_places\": 10,\n  \"estimated_completion_time\": 1,\n  \"reward\": 160,\n  \"completion_codes\": [\n    {\n      \"code\": \"M3J9OF\",\n      \"code_type\": \"SCREENED_IN\",\n      \"actions\": [\n        {\n          \"action\": \"AUTOMATICALLY_APPROVE\"\n        }\n      ]\n    },\n    {\n      \"code\": \"L7X9G4\",\n      \"code_type\": \"SCREENED_OUT\",\n      \"actions\": [\n        {\n          \"action\": \"FIXED_SCREEN_OUT_PAYMENT\",\n          \"fixed_screen_out_reward\": 150,\n          \"slots\": 2\n        }\n      ]\n    }\n  ],\n  \"device_compatibility\": [\n    \"mobile\",\n    \"desktop\",\n    \"tablet\"\n  ],\n  \"peripheral_requirements\": [],\n  \"filters\": [],\n  \"submissions_config\": {\n    \"max_submissions_per_participant\": 1\n  },\n  \"completion_code\": \"M3J9OF\"\n}", ParameterType.RequestBody);
    IRestResponse response = client.Execute(request);
    ```

    ```swift study_with_custom_screening
    import Foundation

    let headers = [
      "Authorization": "Token <token>",
      "Content-Type": "application/json"
    ]
    let parameters = [
      "name": "A study with custom screening",
      "description": "A short survey with in-study screening questions",
      "external_study_url": "https://google.com",
      "prolific_id_option": "question",
      "total_available_places": 10,
      "estimated_completion_time": 1,
      "reward": 160,
      "completion_codes": [
        [
          "code": "M3J9OF",
          "code_type": "SCREENED_IN",
          "actions": [["action": "AUTOMATICALLY_APPROVE"]]
        ],
        [
          "code": "L7X9G4",
          "code_type": "SCREENED_OUT",
          "actions": [
            [
              "action": "FIXED_SCREEN_OUT_PAYMENT",
              "fixed_screen_out_reward": 150,
              "slots": 2
            ]
          ]
        ]
      ],
      "device_compatibility": ["mobile", "desktop", "tablet"],
      "peripheral_requirements": [],
      "filters": [],
      "submissions_config": ["max_submissions_per_participant": 1],
      "completion_code": "M3J9OF"
    ] as [String : Any]

    let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

    let request = NSMutableURLRequest(url: NSURL(string: "https://api.prolific.com/api/v1/studies/")! as URL,
                                            cachePolicy: .useProtocolCachePolicy,
                                        timeoutInterval: 10.0)
    request.httpMethod = "POST"
    request.allHTTPHeaderFields = headers
    request.httpBody = postData as Data

    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()
    ```

    **Screen-out slots**: The maximum number of participants that can be screened out. This is separate from your
    study's total number of places. Once the maximum screen-out slots are filled, your study automatically pauses.

    **Screen-out reward amount**: The fixed payment for screened-out participants (minimum £0.10/\$0.14). This must be
    less than the study reward and cannot be changed after publishing your study.
  </Step>

  <Step>
    Publish the study

    ### Request

    POST [https://api.prolific.com/api/v1/studies/\{id}/transition/](https://api.prolific.com/api/v1/studies/\{id}/transition/)

    ```curl Publish a draft study
    curl -X POST https://api.prolific.com/api/v1/studies/60d9aadeb86739de712faee0/transition/ \
         -H "Authorization: Token <token>" \
         -H "Content-Type: application/json" \
         -d '{
      "action": "PUBLISH"
    }'
    ```

    ```python Publish a draft study
    import requests

    url = "https://api.prolific.com/api/v1/studies/60d9aadeb86739de712faee0/transition/"

    payload = { "action": "PUBLISH" }
    headers = {
        "Authorization": "Token <token>",
        "Content-Type": "application/json"
    }

    response = requests.post(url, json=payload, headers=headers)

    print(response.json())
    ```

    ```javascript Publish a draft study
    const url = 'https://api.prolific.com/api/v1/studies/60d9aadeb86739de712faee0/transition/';
    const options = {
      method: 'POST',
      headers: {Authorization: 'Token <token>', 'Content-Type': 'application/json'},
      body: '{"action":"PUBLISH"}'
    };

    try {
      const response = await fetch(url, options);
      const data = await response.json();
      console.log(data);
    } catch (error) {
      console.error(error);
    }
    ```

    ```go Publish a draft study
    package main

    import (
    	"fmt"
    	"strings"
    	"net/http"
    	"io"
    )

    func main() {

    	url := "https://api.prolific.com/api/v1/studies/60d9aadeb86739de712faee0/transition/"

    	payload := strings.NewReader("{\n  \"action\": \"PUBLISH\"\n}")

    	req, _ := http.NewRequest("POST", url, payload)

    	req.Header.Add("Authorization", "Token <token>")
    	req.Header.Add("Content-Type", "application/json")

    	res, _ := http.DefaultClient.Do(req)

    	defer res.Body.Close()
    	body, _ := io.ReadAll(res.Body)

    	fmt.Println(res)
    	fmt.Println(string(body))

    }
    ```

    ```ruby Publish a draft study
    require 'uri'
    require 'net/http'

    url = URI("https://api.prolific.com/api/v1/studies/60d9aadeb86739de712faee0/transition/")

    http = Net::HTTP.new(url.host, url.port)
    http.use_ssl = true

    request = Net::HTTP::Post.new(url)
    request["Authorization"] = 'Token <token>'
    request["Content-Type"] = 'application/json'
    request.body = "{\n  \"action\": \"PUBLISH\"\n}"

    response = http.request(request)
    puts response.read_body
    ```

    ```java Publish a draft study
    import com.mashape.unirest.http.HttpResponse;
    import com.mashape.unirest.http.Unirest;

    HttpResponse<String> response = Unirest.post("https://api.prolific.com/api/v1/studies/60d9aadeb86739de712faee0/transition/")
      .header("Authorization", "Token <token>")
      .header("Content-Type", "application/json")
      .body("{\n  \"action\": \"PUBLISH\"\n}")
      .asString();
    ```

    ```php Publish a draft study
    <?php
    require_once('vendor/autoload.php');

    $client = new \GuzzleHttp\Client();

    $response = $client->request('POST', 'https://api.prolific.com/api/v1/studies/60d9aadeb86739de712faee0/transition/', [
      'body' => '{
      "action": "PUBLISH"
    }',
      'headers' => [
        'Authorization' => 'Token <token>',
        'Content-Type' => 'application/json',
      ],
    ]);

    echo $response->getBody();
    ```

    ```csharp Publish a draft study
    using RestSharp;

    var client = new RestClient("https://api.prolific.com/api/v1/studies/60d9aadeb86739de712faee0/transition/");
    var request = new RestRequest(Method.POST);
    request.AddHeader("Authorization", "Token <token>");
    request.AddHeader("Content-Type", "application/json");
    request.AddParameter("application/json", "{\n  \"action\": \"PUBLISH\"\n}", ParameterType.RequestBody);
    IRestResponse response = client.Execute(request);
    ```

    ```swift Publish a draft study
    import Foundation

    let headers = [
      "Authorization": "Token <token>",
      "Content-Type": "application/json"
    ]
    let parameters = ["action": "PUBLISH"] as [String : Any]

    let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

    let request = NSMutableURLRequest(url: NSURL(string: "https://api.prolific.com/api/v1/studies/60d9aadeb86739de712faee0/transition/")! as URL,
                                            cachePolicy: .useProtocolCachePolicy,
                                        timeoutInterval: 10.0)
    request.httpMethod = "POST"
    request.allHTTPHeaderFields = headers
    request.httpBody = postData as Data

    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()
    ```

    When participants return to Prolific with a screened out completion code, the submission status is set to
    `SCREENED_OUT` and they are automatically paid the screen out reward specified.
  </Step>
</Steps>

## Find specialist and domain experts

Prolific creates and manages custom participant groups of specially curated experts, e.g., STEM experts and Language specialists. [Click here](https://researcher-help.prolific.com/en/articles/445228-domain-experts) to understand what domain experts are available and how they are verified.

Follow these steps to recruit domain experts for your studies via API:

<Steps>
  <Step>
    Identify the custom group associated with the expert

    ### Request

    GET [https://api.prolific.com/api/v1/filters/](https://api.prolific.com/api/v1/filters/)

    ```curl Custom groups
    curl -G https://api.prolific.com/api/v1/filters/ \
         -H "Authorization: Token <token>" \
         -d filter_tag=custom-group
    ```

    ```python Custom groups
    import requests

    url = "https://api.prolific.com/api/v1/filters/"

    querystring = {"filter_tag":"custom-group"}

    headers = {"Authorization": "Token <token>"}

    response = requests.get(url, headers=headers, params=querystring)

    print(response.json())
    ```

    ```javascript Custom groups
    const url = 'https://api.prolific.com/api/v1/filters/?filter_tag=custom-group';
    const options = {method: 'GET', headers: {Authorization: 'Token <token>'}};

    try {
      const response = await fetch(url, options);
      const data = await response.json();
      console.log(data);
    } catch (error) {
      console.error(error);
    }
    ```

    ```go Custom groups
    package main

    import (
    	"fmt"
    	"net/http"
    	"io"
    )

    func main() {

    	url := "https://api.prolific.com/api/v1/filters/?filter_tag=custom-group"

    	req, _ := http.NewRequest("GET", url, nil)

    	req.Header.Add("Authorization", "Token <token>")

    	res, _ := http.DefaultClient.Do(req)

    	defer res.Body.Close()
    	body, _ := io.ReadAll(res.Body)

    	fmt.Println(res)
    	fmt.Println(string(body))

    }
    ```

    ```ruby Custom groups
    require 'uri'
    require 'net/http'

    url = URI("https://api.prolific.com/api/v1/filters/?filter_tag=custom-group")

    http = Net::HTTP.new(url.host, url.port)
    http.use_ssl = true

    request = Net::HTTP::Get.new(url)
    request["Authorization"] = 'Token <token>'

    response = http.request(request)
    puts response.read_body
    ```

    ```java Custom groups
    import com.mashape.unirest.http.HttpResponse;
    import com.mashape.unirest.http.Unirest;

    HttpResponse<String> response = Unirest.get("https://api.prolific.com/api/v1/filters/?filter_tag=custom-group")
      .header("Authorization", "Token <token>")
      .asString();
    ```

    ```php Custom groups
    <?php
    require_once('vendor/autoload.php');

    $client = new \GuzzleHttp\Client();

    $response = $client->request('GET', 'https://api.prolific.com/api/v1/filters/?filter_tag=custom-group', [
      'headers' => [
        'Authorization' => 'Token <token>',
      ],
    ]);

    echo $response->getBody();
    ```

    ```csharp Custom groups
    using RestSharp;

    var client = new RestClient("https://api.prolific.com/api/v1/filters/?filter_tag=custom-group");
    var request = new RestRequest(Method.GET);
    request.AddHeader("Authorization", "Token <token>");
    IRestResponse response = client.Execute(request);
    ```

    ```swift Custom groups
    import Foundation

    let headers = ["Authorization": "Token <token>"]

    let request = NSMutableURLRequest(url: NSURL(string: "https://api.prolific.com/api/v1/filters/?filter_tag=custom-group")! 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()
    ```
  </Step>

  <Step>
    When creating a study, specify the pre-screening filter ID

    ### Request

    POST [https://api.prolific.com/api/v1/studies/](https://api.prolific.com/api/v1/studies/)

    ```curl study_with_custom_group
    curl -X POST https://api.prolific.com/api/v1/studies/ \
         -H "Authorization: Token <token>" \
         -H "Content-Type: application/json" \
         -d '{
      "name": "Programming Survey",
      "description": "A survey for Javascript developers",
      "external_study_url": "https://example.com/study",
      "prolific_id_option": "question",
      "total_available_places": 500,
      "estimated_completion_time": 1,
      "reward": 13,
      "completion_codes": [
        {
          "code": "ABC123",
          "code_type": "COMPLETED",
          "actions": [
            {
              "action": "MANUALLY_REVIEW"
            }
          ]
        }
      ],
      "device_compatibility": [
        "mobile",
        "desktop",
        "tablet"
      ],
      "peripheral_requirements": [],
      "filters": [
        {
          "filter_id": "javascript",
          "selected_values": [
            "0"
          ]
        }
      ],
      "submissions_config": {
        "max_submissions_per_participant": 1
      },
      "completion_code": "ABC123"
    }'
    ```

    ```python study_with_custom_group
    import requests

    url = "https://api.prolific.com/api/v1/studies/"

    payload = {
        "name": "Programming Survey",
        "description": "A survey for Javascript developers",
        "external_study_url": "https://example.com/study",
        "prolific_id_option": "question",
        "total_available_places": 500,
        "estimated_completion_time": 1,
        "reward": 13,
        "completion_codes": [
            {
                "code": "ABC123",
                "code_type": "COMPLETED",
                "actions": [{ "action": "MANUALLY_REVIEW" }]
            }
        ],
        "device_compatibility": ["mobile", "desktop", "tablet"],
        "peripheral_requirements": [],
        "filters": [
            {
                "filter_id": "javascript",
                "selected_values": ["0"]
            }
        ],
        "submissions_config": { "max_submissions_per_participant": 1 },
        "completion_code": "ABC123"
    }
    headers = {
        "Authorization": "Token <token>",
        "Content-Type": "application/json"
    }

    response = requests.post(url, json=payload, headers=headers)

    print(response.json())
    ```

    ```javascript study_with_custom_group
    const url = 'https://api.prolific.com/api/v1/studies/';
    const options = {
      method: 'POST',
      headers: {Authorization: 'Token <token>', 'Content-Type': 'application/json'},
      body: '{"name":"Programming Survey","description":"A survey for Javascript developers","external_study_url":"https://example.com/study","prolific_id_option":"question","total_available_places":500,"estimated_completion_time":1,"reward":13,"completion_codes":[{"code":"ABC123","code_type":"COMPLETED","actions":[{"action":"MANUALLY_REVIEW"}]}],"device_compatibility":["mobile","desktop","tablet"],"peripheral_requirements":[],"filters":[{"filter_id":"javascript","selected_values":["0"]}],"submissions_config":{"max_submissions_per_participant":1},"completion_code":"ABC123"}'
    };

    try {
      const response = await fetch(url, options);
      const data = await response.json();
      console.log(data);
    } catch (error) {
      console.error(error);
    }
    ```

    ```go study_with_custom_group
    package main

    import (
    	"fmt"
    	"strings"
    	"net/http"
    	"io"
    )

    func main() {

    	url := "https://api.prolific.com/api/v1/studies/"

    	payload := strings.NewReader("{\n  \"name\": \"Programming Survey\",\n  \"description\": \"A survey for Javascript developers\",\n  \"external_study_url\": \"https://example.com/study\",\n  \"prolific_id_option\": \"question\",\n  \"total_available_places\": 500,\n  \"estimated_completion_time\": 1,\n  \"reward\": 13,\n  \"completion_codes\": [\n    {\n      \"code\": \"ABC123\",\n      \"code_type\": \"COMPLETED\",\n      \"actions\": [\n        {\n          \"action\": \"MANUALLY_REVIEW\"\n        }\n      ]\n    }\n  ],\n  \"device_compatibility\": [\n    \"mobile\",\n    \"desktop\",\n    \"tablet\"\n  ],\n  \"peripheral_requirements\": [],\n  \"filters\": [\n    {\n      \"filter_id\": \"javascript\",\n      \"selected_values\": [\n        \"0\"\n      ]\n    }\n  ],\n  \"submissions_config\": {\n    \"max_submissions_per_participant\": 1\n  },\n  \"completion_code\": \"ABC123\"\n}")

    	req, _ := http.NewRequest("POST", url, payload)

    	req.Header.Add("Authorization", "Token <token>")
    	req.Header.Add("Content-Type", "application/json")

    	res, _ := http.DefaultClient.Do(req)

    	defer res.Body.Close()
    	body, _ := io.ReadAll(res.Body)

    	fmt.Println(res)
    	fmt.Println(string(body))

    }
    ```

    ```ruby study_with_custom_group
    require 'uri'
    require 'net/http'

    url = URI("https://api.prolific.com/api/v1/studies/")

    http = Net::HTTP.new(url.host, url.port)
    http.use_ssl = true

    request = Net::HTTP::Post.new(url)
    request["Authorization"] = 'Token <token>'
    request["Content-Type"] = 'application/json'
    request.body = "{\n  \"name\": \"Programming Survey\",\n  \"description\": \"A survey for Javascript developers\",\n  \"external_study_url\": \"https://example.com/study\",\n  \"prolific_id_option\": \"question\",\n  \"total_available_places\": 500,\n  \"estimated_completion_time\": 1,\n  \"reward\": 13,\n  \"completion_codes\": [\n    {\n      \"code\": \"ABC123\",\n      \"code_type\": \"COMPLETED\",\n      \"actions\": [\n        {\n          \"action\": \"MANUALLY_REVIEW\"\n        }\n      ]\n    }\n  ],\n  \"device_compatibility\": [\n    \"mobile\",\n    \"desktop\",\n    \"tablet\"\n  ],\n  \"peripheral_requirements\": [],\n  \"filters\": [\n    {\n      \"filter_id\": \"javascript\",\n      \"selected_values\": [\n        \"0\"\n      ]\n    }\n  ],\n  \"submissions_config\": {\n    \"max_submissions_per_participant\": 1\n  },\n  \"completion_code\": \"ABC123\"\n}"

    response = http.request(request)
    puts response.read_body
    ```

    ```java study_with_custom_group
    import com.mashape.unirest.http.HttpResponse;
    import com.mashape.unirest.http.Unirest;

    HttpResponse<String> response = Unirest.post("https://api.prolific.com/api/v1/studies/")
      .header("Authorization", "Token <token>")
      .header("Content-Type", "application/json")
      .body("{\n  \"name\": \"Programming Survey\",\n  \"description\": \"A survey for Javascript developers\",\n  \"external_study_url\": \"https://example.com/study\",\n  \"prolific_id_option\": \"question\",\n  \"total_available_places\": 500,\n  \"estimated_completion_time\": 1,\n  \"reward\": 13,\n  \"completion_codes\": [\n    {\n      \"code\": \"ABC123\",\n      \"code_type\": \"COMPLETED\",\n      \"actions\": [\n        {\n          \"action\": \"MANUALLY_REVIEW\"\n        }\n      ]\n    }\n  ],\n  \"device_compatibility\": [\n    \"mobile\",\n    \"desktop\",\n    \"tablet\"\n  ],\n  \"peripheral_requirements\": [],\n  \"filters\": [\n    {\n      \"filter_id\": \"javascript\",\n      \"selected_values\": [\n        \"0\"\n      ]\n    }\n  ],\n  \"submissions_config\": {\n    \"max_submissions_per_participant\": 1\n  },\n  \"completion_code\": \"ABC123\"\n}")
      .asString();
    ```

    ```php study_with_custom_group
    <?php
    require_once('vendor/autoload.php');

    $client = new \GuzzleHttp\Client();

    $response = $client->request('POST', 'https://api.prolific.com/api/v1/studies/', [
      'body' => '{
      "name": "Programming Survey",
      "description": "A survey for Javascript developers",
      "external_study_url": "https://example.com/study",
      "prolific_id_option": "question",
      "total_available_places": 500,
      "estimated_completion_time": 1,
      "reward": 13,
      "completion_codes": [
        {
          "code": "ABC123",
          "code_type": "COMPLETED",
          "actions": [
            {
              "action": "MANUALLY_REVIEW"
            }
          ]
        }
      ],
      "device_compatibility": [
        "mobile",
        "desktop",
        "tablet"
      ],
      "peripheral_requirements": [],
      "filters": [
        {
          "filter_id": "javascript",
          "selected_values": [
            "0"
          ]
        }
      ],
      "submissions_config": {
        "max_submissions_per_participant": 1
      },
      "completion_code": "ABC123"
    }',
      'headers' => [
        'Authorization' => 'Token <token>',
        'Content-Type' => 'application/json',
      ],
    ]);

    echo $response->getBody();
    ```

    ```csharp study_with_custom_group
    using RestSharp;

    var client = new RestClient("https://api.prolific.com/api/v1/studies/");
    var request = new RestRequest(Method.POST);
    request.AddHeader("Authorization", "Token <token>");
    request.AddHeader("Content-Type", "application/json");
    request.AddParameter("application/json", "{\n  \"name\": \"Programming Survey\",\n  \"description\": \"A survey for Javascript developers\",\n  \"external_study_url\": \"https://example.com/study\",\n  \"prolific_id_option\": \"question\",\n  \"total_available_places\": 500,\n  \"estimated_completion_time\": 1,\n  \"reward\": 13,\n  \"completion_codes\": [\n    {\n      \"code\": \"ABC123\",\n      \"code_type\": \"COMPLETED\",\n      \"actions\": [\n        {\n          \"action\": \"MANUALLY_REVIEW\"\n        }\n      ]\n    }\n  ],\n  \"device_compatibility\": [\n    \"mobile\",\n    \"desktop\",\n    \"tablet\"\n  ],\n  \"peripheral_requirements\": [],\n  \"filters\": [\n    {\n      \"filter_id\": \"javascript\",\n      \"selected_values\": [\n        \"0\"\n      ]\n    }\n  ],\n  \"submissions_config\": {\n    \"max_submissions_per_participant\": 1\n  },\n  \"completion_code\": \"ABC123\"\n}", ParameterType.RequestBody);
    IRestResponse response = client.Execute(request);
    ```

    ```swift study_with_custom_group
    import Foundation

    let headers = [
      "Authorization": "Token <token>",
      "Content-Type": "application/json"
    ]
    let parameters = [
      "name": "Programming Survey",
      "description": "A survey for Javascript developers",
      "external_study_url": "https://example.com/study",
      "prolific_id_option": "question",
      "total_available_places": 500,
      "estimated_completion_time": 1,
      "reward": 13,
      "completion_codes": [
        [
          "code": "ABC123",
          "code_type": "COMPLETED",
          "actions": [["action": "MANUALLY_REVIEW"]]
        ]
      ],
      "device_compatibility": ["mobile", "desktop", "tablet"],
      "peripheral_requirements": [],
      "filters": [
        [
          "filter_id": "javascript",
          "selected_values": ["0"]
        ]
      ],
      "submissions_config": ["max_submissions_per_participant": 1],
      "completion_code": "ABC123"
    ] as [String : Any]

    let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

    let request = NSMutableURLRequest(url: NSURL(string: "https://api.prolific.com/api/v1/studies/")! as URL,
                                            cachePolicy: .useProtocolCachePolicy,
                                        timeoutInterval: 10.0)
    request.httpMethod = "POST"
    request.allHTTPHeaderFields = headers
    request.httpBody = postData as Data

    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()
    ```
  </Step>

  <Step>
    Publish the study

    ### Request

    POST [https://api.prolific.com/api/v1/studies/\{id}/transition/](https://api.prolific.com/api/v1/studies/\{id}/transition/)

    ```curl Publish a draft study
    curl -X POST https://api.prolific.com/api/v1/studies/60d9aadeb86739de712faee0/transition/ \
         -H "Authorization: Token <token>" \
         -H "Content-Type: application/json" \
         -d '{
      "action": "PUBLISH"
    }'
    ```

    ```python Publish a draft study
    import requests

    url = "https://api.prolific.com/api/v1/studies/60d9aadeb86739de712faee0/transition/"

    payload = { "action": "PUBLISH" }
    headers = {
        "Authorization": "Token <token>",
        "Content-Type": "application/json"
    }

    response = requests.post(url, json=payload, headers=headers)

    print(response.json())
    ```

    ```javascript Publish a draft study
    const url = 'https://api.prolific.com/api/v1/studies/60d9aadeb86739de712faee0/transition/';
    const options = {
      method: 'POST',
      headers: {Authorization: 'Token <token>', 'Content-Type': 'application/json'},
      body: '{"action":"PUBLISH"}'
    };

    try {
      const response = await fetch(url, options);
      const data = await response.json();
      console.log(data);
    } catch (error) {
      console.error(error);
    }
    ```

    ```go Publish a draft study
    package main

    import (
    	"fmt"
    	"strings"
    	"net/http"
    	"io"
    )

    func main() {

    	url := "https://api.prolific.com/api/v1/studies/60d9aadeb86739de712faee0/transition/"

    	payload := strings.NewReader("{\n  \"action\": \"PUBLISH\"\n}")

    	req, _ := http.NewRequest("POST", url, payload)

    	req.Header.Add("Authorization", "Token <token>")
    	req.Header.Add("Content-Type", "application/json")

    	res, _ := http.DefaultClient.Do(req)

    	defer res.Body.Close()
    	body, _ := io.ReadAll(res.Body)

    	fmt.Println(res)
    	fmt.Println(string(body))

    }
    ```

    ```ruby Publish a draft study
    require 'uri'
    require 'net/http'

    url = URI("https://api.prolific.com/api/v1/studies/60d9aadeb86739de712faee0/transition/")

    http = Net::HTTP.new(url.host, url.port)
    http.use_ssl = true

    request = Net::HTTP::Post.new(url)
    request["Authorization"] = 'Token <token>'
    request["Content-Type"] = 'application/json'
    request.body = "{\n  \"action\": \"PUBLISH\"\n}"

    response = http.request(request)
    puts response.read_body
    ```

    ```java Publish a draft study
    import com.mashape.unirest.http.HttpResponse;
    import com.mashape.unirest.http.Unirest;

    HttpResponse<String> response = Unirest.post("https://api.prolific.com/api/v1/studies/60d9aadeb86739de712faee0/transition/")
      .header("Authorization", "Token <token>")
      .header("Content-Type", "application/json")
      .body("{\n  \"action\": \"PUBLISH\"\n}")
      .asString();
    ```

    ```php Publish a draft study
    <?php
    require_once('vendor/autoload.php');

    $client = new \GuzzleHttp\Client();

    $response = $client->request('POST', 'https://api.prolific.com/api/v1/studies/60d9aadeb86739de712faee0/transition/', [
      'body' => '{
      "action": "PUBLISH"
    }',
      'headers' => [
        'Authorization' => 'Token <token>',
        'Content-Type' => 'application/json',
      ],
    ]);

    echo $response->getBody();
    ```

    ```csharp Publish a draft study
    using RestSharp;

    var client = new RestClient("https://api.prolific.com/api/v1/studies/60d9aadeb86739de712faee0/transition/");
    var request = new RestRequest(Method.POST);
    request.AddHeader("Authorization", "Token <token>");
    request.AddHeader("Content-Type", "application/json");
    request.AddParameter("application/json", "{\n  \"action\": \"PUBLISH\"\n}", ParameterType.RequestBody);
    IRestResponse response = client.Execute(request);
    ```

    ```swift Publish a draft study
    import Foundation

    let headers = [
      "Authorization": "Token <token>",
      "Content-Type": "application/json"
    ]
    let parameters = ["action": "PUBLISH"] as [String : Any]

    let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

    let request = NSMutableURLRequest(url: NSURL(string: "https://api.prolific.com/api/v1/studies/60d9aadeb86739de712faee0/transition/")! as URL,
                                            cachePolicy: .useProtocolCachePolicy,
                                        timeoutInterval: 10.0)
    request.httpMethod = "POST"
    request.allHTTPHeaderFields = headers
    request.httpBody = postData as Data

    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()
    ```
  </Step>
</Steps>

## Dynamically manage participant eligibility

Within study setup, you can use a participant's **first submission as a decision point**, and automatically block them from re-entering your study if they ***don’t*** meet certain criteria or fail an attention check.

Here’s how to do it:

<Steps>
  <Step title="Create a Participant Group">
    Create a group where screened-out participants will be added. For more information on how to do this [Create a new
    participant group](/api-reference/participant-groups/create-participant-group).
    Save the `participant_group_id` – you’ll use this in the next step.

    <Frame caption="Screen in Researcher UI | Section: ‘Participants’">
      <img src="https://files.buildwithfern.com/prolific.docs.buildwithfern.com/b612324e43278517c569c57e1b90586a7cc25af736b69b06dabab62b52c8ec77/docs/assets/screen.webp" alt="Participant Groups" />
    </Frame>
  </Step>

  <Step title="Set up your study to dynamically block future entries">
    Use a **completion code with an action** to add disqualified participants to the group, and **block that group from
    participating again**.

    <Note>
      Participants who use this completion code will be added to the participant group and automatically blocked from
      entering the study again.
    </Note>

    <Frame caption="Screen in Researcher UI | Section: ‘Add a completion path’">
      <img src="https://files.buildwithfern.com/prolific.docs.buildwithfern.com/bec7d7293433ab1c9152282859061fa1cdfe8f8001c2e20c0d69555acdbde6ee/docs/assets/screen2.webp" alt="Add a completion path" />
    </Frame>

    <Frame caption="Screen in Researcher UI | Section: ‘Add Participant Group Screener A’">
      <img src="https://files.buildwithfern.com/prolific.docs.buildwithfern.com/9d882efaa3dd3b736dd468acd271e18cd91abb9dd22b0dc3aac7327dd523c0be/docs/assets/screen3.webp" alt="Add Participant Group Screener A" />
    </Frame>

    <Frame caption="Screen in Researcher UI | Section: ‘Add Participant Group Screener B’">
      <img src="https://files.buildwithfern.com/prolific.docs.buildwithfern.com/edadc4fdb7e4812dccf61cdf2ef5c0f27fb3db2224892573d2c797266eac85bd/docs/assets/screen4.webp" alt="Add Participant Group Screener B" />
    </Frame>

    In the request body, `completion_codes` should contain a code with an “ADD\_TO\_PARTICIPANT\_GROUP” action:

    ```json
    "completion_codes": [
    {
      "code": "GHIJKL",
      "code_type": "SCREENED_OUT",
      "actions": [
    {
      "action": "MANUALLY_REVIEW"
    },
    {
      "action": "ADD_TO_PARTICIPANT_GROUP",
      "participant_group": "<insert participant group ID>"
    }
      ]
    }
    ]

    ```

    And include this `completion_codes` filter in your study setup:

    ```json
    {
      "filter_id": "participant_group_blocklist",
      "selected_values": [
      "<insert participant group ID>"
      ]
    }

    ```

    ✨ **Result:** You now have an **adaptive eligibility flow**, letting you use early responses to control who
    continues — without needing to pause or reconfigure your study!
  </Step>
</Steps>