Set Default Team Members
curl --request POST \
--url https://api.projectdiscovery.io/v1/user/team/default-members \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--header 'X-Team-Id: <x-team-id>' \
--data '
{
"members": [
{
"email": "<string>"
}
]
}
'import requests
url = "https://api.projectdiscovery.io/v1/user/team/default-members"
payload = { "members": [{ "email": "<string>" }] }
headers = {
"X-Team-Id": "<x-team-id>",
"X-API-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'X-Team-Id': '<x-team-id>',
'X-API-Key': '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({members: [{email: '<string>'}]})
};
fetch('https://api.projectdiscovery.io/v1/user/team/default-members', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.projectdiscovery.io/v1/user/team/default-members",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'members' => [
[
'email' => '<string>'
]
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-Key: <api-key>",
"X-Team-Id: <x-team-id>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.projectdiscovery.io/v1/user/team/default-members"
payload := strings.NewReader("{\n \"members\": [\n {\n \"email\": \"<string>\"\n }\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-Team-Id", "<x-team-id>")
req.Header.Add("X-API-Key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.projectdiscovery.io/v1/user/team/default-members")
.header("X-Team-Id", "<x-team-id>")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"members\": [\n {\n \"email\": \"<string>\"\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.projectdiscovery.io/v1/user/team/default-members")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-Team-Id"] = '<x-team-id>'
request["X-API-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"members\": [\n {\n \"email\": \"<string>\"\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"message": "<string>"
}{
"message": "<string>"
}{
"message": "<string>"
}{
"message": "<string>"
}{
"message": "<string>"
}{
"message": "<string>",
"kind": "<string>",
"code": "<string>",
"error": "<string>",
"error_id": "<string>",
"param": "<string>",
"status": 123
}Users & Authentication
Set Default Team Members
Set (replace) the list of default team members
POST
/
v1
/
user
/
team
/
default-members
Set Default Team Members
curl --request POST \
--url https://api.projectdiscovery.io/v1/user/team/default-members \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--header 'X-Team-Id: <x-team-id>' \
--data '
{
"members": [
{
"email": "<string>"
}
]
}
'import requests
url = "https://api.projectdiscovery.io/v1/user/team/default-members"
payload = { "members": [{ "email": "<string>" }] }
headers = {
"X-Team-Id": "<x-team-id>",
"X-API-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'X-Team-Id': '<x-team-id>',
'X-API-Key': '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({members: [{email: '<string>'}]})
};
fetch('https://api.projectdiscovery.io/v1/user/team/default-members', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.projectdiscovery.io/v1/user/team/default-members",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'members' => [
[
'email' => '<string>'
]
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-Key: <api-key>",
"X-Team-Id: <x-team-id>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.projectdiscovery.io/v1/user/team/default-members"
payload := strings.NewReader("{\n \"members\": [\n {\n \"email\": \"<string>\"\n }\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-Team-Id", "<x-team-id>")
req.Header.Add("X-API-Key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.projectdiscovery.io/v1/user/team/default-members")
.header("X-Team-Id", "<x-team-id>")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"members\": [\n {\n \"email\": \"<string>\"\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.projectdiscovery.io/v1/user/team/default-members")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-Team-Id"] = '<x-team-id>'
request["X-API-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"members\": [\n {\n \"email\": \"<string>\"\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"message": "<string>"
}{
"message": "<string>"
}{
"message": "<string>"
}{
"message": "<string>"
}{
"message": "<string>"
}{
"message": "<string>",
"kind": "<string>",
"code": "<string>",
"error": "<string>",
"error_id": "<string>",
"param": "<string>",
"status": 123
}Configure a list of members that will be automatically added to any new team/workspace you create. This endpoint replaces any existing default member configuration.
Response:
Response:
How It Works
When you set default members:- Replaces any existing default member configuration
- Validates each member against your workspace plan limits
- Deduplicates members by email (keeps first occurrence)
- Applies to all future teams created by the owner
This operation replaces the entire default members list. To add or remove individual members, retrieve the current list, modify it, and send the updated version.
Request Body
Send an array of member objects, each containing:email(string, required): Member’s email addressrole(string, required): One ofADMIN,MEMBER,VIEWER, orGUEST
The
OWNER role cannot be assigned as a default member. Owner is always assigned automatically during team creation.Examples
Set Multiple Default Members
curl -X POST "https://api.projectdiscovery.io/v1/user/team/default-members" \
-H "Content-Type: application/json" \
-H "X-Api-Key: YOUR_API_KEY" \
-H "X-Team-Id: YOUR_TEAM_ID" \
-d '{
"members": [
{ "email": "security-lead@example.com", "role": "ADMIN" },
{ "email": "team-member@example.com", "role": "MEMBER" },
{ "email": "auditor@example.com", "role": "VIEWER" }
]
}'
{
"message": "default team members updated successfully (3 members)"
}
Clear All Default Members
curl -X POST "https://api.projectdiscovery.io/v1/user/team/default-members" \
-H "Content-Type: application/json" \
-H "X-Api-Key: YOUR_API_KEY" \
-H "X-Team-Id: YOUR_TEAM_ID" \
-d '{ "members": [] }'
{
"message": "default team members updated successfully (0 members)"
}
Validation Rules
Email Validation
- Must be valid email format
- Invalid emails return
400error:"invalid email format: bad-email"
Role Validation
- Must be one of:
ADMIN,MEMBER,VIEWER,GUEST - Invalid roles return
400error:"invalid role: INVALID. Valid roles are: ADMIN, MEMBER, VIEWER, GUEST"
Plan Limits
- Default members count is validated against your workspace plan’s
MaxTeamMemberslimit (minus 1 for owner) - Exceeding limit returns
400error:"default members count (15) exceeds your plan limit of 10 members"
Common Errors
| Status | Scenario | Solution |
|---|---|---|
400 | Invalid email format | Verify email addresses are properly formatted |
400 | Invalid role | Use only: ADMIN, MEMBER, VIEWER, GUEST |
400 | Exceeds plan limit | Reduce number of default members or upgrade plan |
403 | Not owner/admin | Only team owners and admins can configure defaults |
Behavior During Team Creation
When a new team is created:- System checks if the owner has configured default members
- Each default member’s email must exist in the system
- If any email doesn’t correspond to an existing user, team creation returns
400error - Default members are directly added to the new team (no invitation flow)
- Owner is automatically skipped if present in default members list
Default members streamline team provisioning, especially when creating multiple teams or workspaces with consistent access patterns.
Authorizations
Headers
Retrieve the Team ID from: https://cloud.projectdiscovery.io/settings/team
Body
application/json
Show child attributes
Show child attributes
Response
Example response
Was this page helpful?