curl --request PATCH \
--url https://api.tomorro.com/v2/members/{id} \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"role": "MANAGER",
"status": "active",
"groupIds": [
"550e8400-e29b-41d4-a716-446655440000",
"6ba7b810-9dad-11d1-80b4-00c04fd430c8"
],
"folderIds": [
"550e8400-e29b-41d4-a716-446655440000"
],
"firstname": "John",
"lastname": "Doe",
"email": "john.doe@example.com",
"resendInvitation": true,
"substituteId": "7c9e6679-7425-40de-944b-e07fc1f90ae7"
}
'import requests
url = "https://api.tomorro.com/v2/members/{id}"
payload = {
"role": "MANAGER",
"status": "active",
"groupIds": ["550e8400-e29b-41d4-a716-446655440000", "6ba7b810-9dad-11d1-80b4-00c04fd430c8"],
"folderIds": ["550e8400-e29b-41d4-a716-446655440000"],
"firstname": "John",
"lastname": "Doe",
"email": "john.doe@example.com",
"resendInvitation": True,
"substituteId": "7c9e6679-7425-40de-944b-e07fc1f90ae7"
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
role: 'MANAGER',
status: 'active',
groupIds: ['550e8400-e29b-41d4-a716-446655440000', '6ba7b810-9dad-11d1-80b4-00c04fd430c8'],
folderIds: ['550e8400-e29b-41d4-a716-446655440000'],
firstname: 'John',
lastname: 'Doe',
email: 'john.doe@example.com',
resendInvitation: true,
substituteId: '7c9e6679-7425-40de-944b-e07fc1f90ae7'
})
};
fetch('https://api.tomorro.com/v2/members/{id}', 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.tomorro.com/v2/members/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'role' => 'MANAGER',
'status' => 'active',
'groupIds' => [
'550e8400-e29b-41d4-a716-446655440000',
'6ba7b810-9dad-11d1-80b4-00c04fd430c8'
],
'folderIds' => [
'550e8400-e29b-41d4-a716-446655440000'
],
'firstname' => 'John',
'lastname' => 'Doe',
'email' => 'john.doe@example.com',
'resendInvitation' => true,
'substituteId' => '7c9e6679-7425-40de-944b-e07fc1f90ae7'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>"
],
]);
$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.tomorro.com/v2/members/{id}"
payload := strings.NewReader("{\n \"role\": \"MANAGER\",\n \"status\": \"active\",\n \"groupIds\": [\n \"550e8400-e29b-41d4-a716-446655440000\",\n \"6ba7b810-9dad-11d1-80b4-00c04fd430c8\"\n ],\n \"folderIds\": [\n \"550e8400-e29b-41d4-a716-446655440000\"\n ],\n \"firstname\": \"John\",\n \"lastname\": \"Doe\",\n \"email\": \"john.doe@example.com\",\n \"resendInvitation\": true,\n \"substituteId\": \"7c9e6679-7425-40de-944b-e07fc1f90ae7\"\n}")
req, _ := http.NewRequest("PATCH", url, payload)
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.patch("https://api.tomorro.com/v2/members/{id}")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"role\": \"MANAGER\",\n \"status\": \"active\",\n \"groupIds\": [\n \"550e8400-e29b-41d4-a716-446655440000\",\n \"6ba7b810-9dad-11d1-80b4-00c04fd430c8\"\n ],\n \"folderIds\": [\n \"550e8400-e29b-41d4-a716-446655440000\"\n ],\n \"firstname\": \"John\",\n \"lastname\": \"Doe\",\n \"email\": \"john.doe@example.com\",\n \"resendInvitation\": true,\n \"substituteId\": \"7c9e6679-7425-40de-944b-e07fc1f90ae7\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.tomorro.com/v2/members/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"role\": \"MANAGER\",\n \"status\": \"active\",\n \"groupIds\": [\n \"550e8400-e29b-41d4-a716-446655440000\",\n \"6ba7b810-9dad-11d1-80b4-00c04fd430c8\"\n ],\n \"folderIds\": [\n \"550e8400-e29b-41d4-a716-446655440000\"\n ],\n \"firstname\": \"John\",\n \"lastname\": \"Doe\",\n \"email\": \"john.doe@example.com\",\n \"resendInvitation\": true,\n \"substituteId\": \"7c9e6679-7425-40de-944b-e07fc1f90ae7\"\n}"
response = http.request(request)
puts response.read_body{
"id": "550e8400-e29b-41d4-a716-446655440000",
"role": "ADMIN",
"status": "active",
"user": {
"email": "john.doe@example.com"
},
"groupIds": [
"550e8400-e29b-41d4-a716-446655440000"
],
"createdAt": "2024-01-01T00:00:00.000Z",
"updatedAt": "2024-01-02T00:00:00.000Z"
}Update member
Updates an existing member’s role, group assignments, or other properties. All fields are optional — only include the fields you want to change.
Moving a member to a lower role (VIEWER < USER < MANAGER < ADMIN) requires a substituteId: another member who takes over what the new role cannot hold, such as pending approvals and signatures. Without a valid substitute, the request answers 400 InvalidRoleSubstitute.
curl --request PATCH \
--url https://api.tomorro.com/v2/members/{id} \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"role": "MANAGER",
"status": "active",
"groupIds": [
"550e8400-e29b-41d4-a716-446655440000",
"6ba7b810-9dad-11d1-80b4-00c04fd430c8"
],
"folderIds": [
"550e8400-e29b-41d4-a716-446655440000"
],
"firstname": "John",
"lastname": "Doe",
"email": "john.doe@example.com",
"resendInvitation": true,
"substituteId": "7c9e6679-7425-40de-944b-e07fc1f90ae7"
}
'import requests
url = "https://api.tomorro.com/v2/members/{id}"
payload = {
"role": "MANAGER",
"status": "active",
"groupIds": ["550e8400-e29b-41d4-a716-446655440000", "6ba7b810-9dad-11d1-80b4-00c04fd430c8"],
"folderIds": ["550e8400-e29b-41d4-a716-446655440000"],
"firstname": "John",
"lastname": "Doe",
"email": "john.doe@example.com",
"resendInvitation": True,
"substituteId": "7c9e6679-7425-40de-944b-e07fc1f90ae7"
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
role: 'MANAGER',
status: 'active',
groupIds: ['550e8400-e29b-41d4-a716-446655440000', '6ba7b810-9dad-11d1-80b4-00c04fd430c8'],
folderIds: ['550e8400-e29b-41d4-a716-446655440000'],
firstname: 'John',
lastname: 'Doe',
email: 'john.doe@example.com',
resendInvitation: true,
substituteId: '7c9e6679-7425-40de-944b-e07fc1f90ae7'
})
};
fetch('https://api.tomorro.com/v2/members/{id}', 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.tomorro.com/v2/members/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'role' => 'MANAGER',
'status' => 'active',
'groupIds' => [
'550e8400-e29b-41d4-a716-446655440000',
'6ba7b810-9dad-11d1-80b4-00c04fd430c8'
],
'folderIds' => [
'550e8400-e29b-41d4-a716-446655440000'
],
'firstname' => 'John',
'lastname' => 'Doe',
'email' => 'john.doe@example.com',
'resendInvitation' => true,
'substituteId' => '7c9e6679-7425-40de-944b-e07fc1f90ae7'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>"
],
]);
$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.tomorro.com/v2/members/{id}"
payload := strings.NewReader("{\n \"role\": \"MANAGER\",\n \"status\": \"active\",\n \"groupIds\": [\n \"550e8400-e29b-41d4-a716-446655440000\",\n \"6ba7b810-9dad-11d1-80b4-00c04fd430c8\"\n ],\n \"folderIds\": [\n \"550e8400-e29b-41d4-a716-446655440000\"\n ],\n \"firstname\": \"John\",\n \"lastname\": \"Doe\",\n \"email\": \"john.doe@example.com\",\n \"resendInvitation\": true,\n \"substituteId\": \"7c9e6679-7425-40de-944b-e07fc1f90ae7\"\n}")
req, _ := http.NewRequest("PATCH", url, payload)
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.patch("https://api.tomorro.com/v2/members/{id}")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"role\": \"MANAGER\",\n \"status\": \"active\",\n \"groupIds\": [\n \"550e8400-e29b-41d4-a716-446655440000\",\n \"6ba7b810-9dad-11d1-80b4-00c04fd430c8\"\n ],\n \"folderIds\": [\n \"550e8400-e29b-41d4-a716-446655440000\"\n ],\n \"firstname\": \"John\",\n \"lastname\": \"Doe\",\n \"email\": \"john.doe@example.com\",\n \"resendInvitation\": true,\n \"substituteId\": \"7c9e6679-7425-40de-944b-e07fc1f90ae7\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.tomorro.com/v2/members/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"role\": \"MANAGER\",\n \"status\": \"active\",\n \"groupIds\": [\n \"550e8400-e29b-41d4-a716-446655440000\",\n \"6ba7b810-9dad-11d1-80b4-00c04fd430c8\"\n ],\n \"folderIds\": [\n \"550e8400-e29b-41d4-a716-446655440000\"\n ],\n \"firstname\": \"John\",\n \"lastname\": \"Doe\",\n \"email\": \"john.doe@example.com\",\n \"resendInvitation\": true,\n \"substituteId\": \"7c9e6679-7425-40de-944b-e07fc1f90ae7\"\n}"
response = http.request(request)
puts response.read_body{
"id": "550e8400-e29b-41d4-a716-446655440000",
"role": "ADMIN",
"status": "active",
"user": {
"email": "john.doe@example.com"
},
"groupIds": [
"550e8400-e29b-41d4-a716-446655440000"
],
"createdAt": "2024-01-01T00:00:00.000Z",
"updatedAt": "2024-01-02T00:00:00.000Z"
}Authorizations
API key for authentication. Get your key at https://app.tomorro.com/settings/integrations?integration=api-key
Path Parameters
The unique identifier (UUID) of the member to update
"550e8400-e29b-41d4-a716-446655440000"
Body
New role for the member: a standard role or the UUID of a custom role defined in your organization. USER: Standard user. MANAGER: Can manage contracts. ADMIN: Full access. VIEWER: Read-only access. The VIEWER role requires it to be enabled on your organization plan. Custom roles require the custom roles feature to be enabled for your organization.
USER, MANAGER, ADMIN, VIEWER "MANAGER"
New status for the member. active: Can access the platform. disabled: Cannot access. pending: Awaiting invitation acceptance.
active, disabled, pending "active"
List of group UUIDs to assign the member to. Replaces existing group assignments.
[
"550e8400-e29b-41d4-a716-446655440000",
"6ba7b810-9dad-11d1-80b4-00c04fd430c8"
]
List of folder UUIDs to assign the member to. Replaces existing folder assignments.
["550e8400-e29b-41d4-a716-446655440000"]
First name of the member
"John"
Last name of the member
"Doe"
Email address of the member
"john.doe@example.com"
Resend invitation email to a pending member
true
UUID of the member who takes over when role moves the member to a lower role (VIEWER < USER < MANAGER < ADMIN), for example from USER to VIEWER. The substitute must belong to the organization and hold at least the member's current role; they take over what the new role cannot hold, such as pending approvals and signatures. Required for such a downgrade (400 InvalidRoleSubstitute otherwise), ignored for any other change. Out-of-office periods are managed with PUT /members/{id}/out-of-office, not this field.
"7c9e6679-7425-40de-944b-e07fc1f90ae7"
Response
Updated member details
Unique identifier for the member.
"550e8400-e29b-41d4-a716-446655440000"
The role assigned to this member, which determines their permissions.
USER: Standard user with basic access to view and interact with contracts.VIEWER: Read-only access to contracts.MANAGER: Can create, edit, and manage contracts and workflows.ADMIN: Full administrative access including member management and organization settings.- A UUID: the id of a custom role defined in your organization.
USER, MANAGER, ADMIN, VIEWER "ADMIN"
The current status of the member.
active: The member has accepted their invitation and can access the platform.disabled: The member has been deactivated and cannot access the platform.pending: The member has been invited but has not yet accepted.
active, disabled, pending "active"
The user account associated with this member.
Show child attributes
Show child attributes
{ "email": "john.doe@example.com" }
List of group UUIDs the member belongs to.
["550e8400-e29b-41d4-a716-446655440000"]
Time at which the member was created. Formatted as an ISO 8601 date-time string.
"2024-01-01T00:00:00.000Z"
Time at which the member was last updated. Formatted as an ISO 8601 date-time string.
"2024-01-02T00:00:00.000Z"