> 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 AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.prolific.com/_mcp/server.

# Finding the right participants

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

## Filters

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 filters via API.

For more information on the types of filters 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 filter 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 filter?"}:::decision
    F{"What is the <a href="/api-reference/filters/get-filters#response.body.results.data_type">data type</a> of the filter?"}:::decision

    I["<a href="/api-reference/filters/get-filters#response.body.results.choices">Choices</a> of this filter 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;
```

Get the list of filters

### 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 filters:

* `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

When creating a study, specify a list of filters

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

This is an optional step.

You can save combinations of filters as filter 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 domain_experts_compound
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": [
        "1"
      ]
    },
    {
      "filter_id": "age",
      "selected_values": [
        "19",
        "20",
        "21",
        "22"
      ]
    }
  ]
}'
```

```python domain_experts_compound
import requests

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

payload = {
    "workspace_id": "644aaabfaf6bbc363b9d47c6",
    "name": "Ambidextrous teenagers",
    "filters": [
        {
            "filter_id": "handedness",
            "selected_values": ["1"]
        },
        {
            "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 domain_experts_compound
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":["1"]},{"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 domain_experts_compound
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        \"1\"\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 domain_experts_compound
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        \"1\"\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 domain_experts_compound
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        \"1\"\n      ]\n    },\n    {\n      \"filter_id\": \"age\",\n      \"selected_values\": [\n        \"19\",\n        \"20\",\n        \"21\",\n        \"22\"\n      ]\n    }\n  ]\n}")
  .asString();
```

```php domain_experts_compound
<?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": [
        "1"
      ]
    },
    {
      "filter_id": "age",
      "selected_values": [
        "19",
        "20",
        "21",
        "22"
      ]
    }
  ]
}',
  'headers' => [
    'Authorization' => 'Token <token>',
    'Content-Type' => 'application/json',
  ],
]);

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

```csharp domain_experts_compound
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        \"1\"\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 domain_experts_compound
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": ["1"]
    ],
    [
      "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()
```

## In-study screening

Custom screening lets you check for participant characteristics that aren't available in our built-in filter 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).

Create the survey with 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.

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.

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.

## 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:

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

When creating a study, specify the 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()
```

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

## 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:

#### 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.

<img src="https://fdr-prod-docs-files-public.s3.us-east-1.amazonaws.com/prolific.docs.buildwithfern.com/b612324e43278517c569c57e1b90586a7cc25af736b69b06dabab62b52c8ec77/docs/assets/screen.webp?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIA6KXJSKKNFOCF7G4B%2F20260807%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20260807T220345Z&X-Amz-Expires=604800&X-Amz-Signature=df8ca76d1613fe6bce4037f48883cde0701b11cea3df2dadb841dfcd5c0f826e&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject" alt="Participant Groups" />

#### 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**.

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

<img src="https://fdr-prod-docs-files-public.s3.us-east-1.amazonaws.com/prolific.docs.buildwithfern.com/bec7d7293433ab1c9152282859061fa1cdfe8f8001c2e20c0d69555acdbde6ee/docs/assets/screen2.webp?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIA6KXJSKKNFOCF7G4B%2F20260807%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20260807T220345Z&X-Amz-Expires=604800&X-Amz-Signature=7a11786bff73367d19decf2d33e24e62cdd11cc2e08f619618d566527f613919&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject" alt="Add a completion path" />

<img src="https://fdr-prod-docs-files-public.s3.us-east-1.amazonaws.com/prolific.docs.buildwithfern.com/9d882efaa3dd3b736dd468acd271e18cd91abb9dd22b0dc3aac7327dd523c0be/docs/assets/screen3.webp?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIA6KXJSKKNFOCF7G4B%2F20260807%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20260807T220345Z&X-Amz-Expires=604800&X-Amz-Signature=cc529a88c2deb80c3f0e16eb34a6de950169932bec919a7a56feff62d160aefd&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject" alt="Add Participant Group Filter A" />

<img src="https://fdr-prod-docs-files-public.s3.us-east-1.amazonaws.com/prolific.docs.buildwithfern.com/edadc4fdb7e4812dccf61cdf2ef5c0f27fb3db2224892573d2c797266eac85bd/docs/assets/screen4.webp?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIA6KXJSKKNFOCF7G4B%2F20260807%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20260807T220345Z&X-Amz-Expires=604800&X-Amz-Signature=875d8a318c4d4a230dcd128d5a12422f5db62fbd44ff8bdd42e6a1d988120936&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject" alt="Add Participant Group Filter B" />

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!