Update a team member
curl --request PATCH \
--url https://api.cal.id/teams/{teamId}/memberships/{membershipId} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"role": "ADMIN"
}
'import requests
url = "https://api.cal.id/teams/{teamId}/memberships/{membershipId}"
payload = { "role": "ADMIN" }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({role: 'ADMIN'})
};
fetch('https://api.cal.id/teams/{teamId}/memberships/{membershipId}', 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.cal.id/teams/{teamId}/memberships/{membershipId}",
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' => 'ADMIN'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$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.cal.id/teams/{teamId}/memberships/{membershipId}"
payload := strings.NewReader("{\n \"role\": \"ADMIN\"\n}")
req, _ := http.NewRequest("PATCH", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
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.cal.id/teams/{teamId}/memberships/{membershipId}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"role\": \"ADMIN\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.cal.id/teams/{teamId}/memberships/{membershipId}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"role\": \"ADMIN\"\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"data": {
"id": 9103,
"teamId": 812,
"userId": 4152,
"acceptedInvitation": true,
"role": "ADMIN",
"impersonation": false,
"createdAt": "2026-01-22T08:15:00.000Z",
"updatedAt": "2026-03-04T09:02:44.000Z",
"user": {
"id": 4152,
"name": "Sam Okafor",
"email": "sam.okafor@example.com",
"username": "sam-okafor",
"avatarUrl": "https://cal.id/avatar/sam-okafor.png",
"timeZone": "Africa/Lagos"
},
"team": {
"id": 812,
"name": "Acme Sales",
"slug": "acme-sales"
}
},
"message": "Team membership updated successfully"
}{
"success": false,
"message": "<string>",
"error": {
"code": "<string>",
"message": "<string>",
"details": "<unknown>"
}
}{
"success": false,
"message": "<string>",
"error": {
"code": "<string>",
"message": "<string>",
"details": "<unknown>"
}
}{
"success": false,
"message": "<string>",
"error": {
"code": "<string>",
"message": "<string>",
"details": "<unknown>"
}
}{
"success": false,
"message": "<string>",
"error": {
"code": "<string>",
"message": "<string>",
"details": "<unknown>"
}
}{
"success": false,
"message": "<string>",
"error": {
"code": "<string>",
"message": "<string>",
"details": "<unknown>"
}
}{
"success": false,
"message": "Rate limit exceeded",
"error": {
"code": "TOO_MANY_REQUESTS",
"message": "Too many requests. Please retry after the rate limit window resets."
}
}Team Memberships
Update a team member
Changes a membership — typically its role, but also acceptedInvitation and the impersonation flag. Only the fields you send are applied and the updated membership is returned. Role changes take effect immediately for permission checks on the other team endpoints. Requires ADMIN or OWNER; a membership from another team returns 409.
PATCH
/
teams
/
{teamId}
/
memberships
/
{membershipId}
Update a team member
curl --request PATCH \
--url https://api.cal.id/teams/{teamId}/memberships/{membershipId} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"role": "ADMIN"
}
'import requests
url = "https://api.cal.id/teams/{teamId}/memberships/{membershipId}"
payload = { "role": "ADMIN" }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({role: 'ADMIN'})
};
fetch('https://api.cal.id/teams/{teamId}/memberships/{membershipId}', 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.cal.id/teams/{teamId}/memberships/{membershipId}",
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' => 'ADMIN'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$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.cal.id/teams/{teamId}/memberships/{membershipId}"
payload := strings.NewReader("{\n \"role\": \"ADMIN\"\n}")
req, _ := http.NewRequest("PATCH", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
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.cal.id/teams/{teamId}/memberships/{membershipId}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"role\": \"ADMIN\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.cal.id/teams/{teamId}/memberships/{membershipId}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"role\": \"ADMIN\"\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"data": {
"id": 9103,
"teamId": 812,
"userId": 4152,
"acceptedInvitation": true,
"role": "ADMIN",
"impersonation": false,
"createdAt": "2026-01-22T08:15:00.000Z",
"updatedAt": "2026-03-04T09:02:44.000Z",
"user": {
"id": 4152,
"name": "Sam Okafor",
"email": "sam.okafor@example.com",
"username": "sam-okafor",
"avatarUrl": "https://cal.id/avatar/sam-okafor.png",
"timeZone": "Africa/Lagos"
},
"team": {
"id": 812,
"name": "Acme Sales",
"slug": "acme-sales"
}
},
"message": "Team membership updated successfully"
}{
"success": false,
"message": "<string>",
"error": {
"code": "<string>",
"message": "<string>",
"details": "<unknown>"
}
}{
"success": false,
"message": "<string>",
"error": {
"code": "<string>",
"message": "<string>",
"details": "<unknown>"
}
}{
"success": false,
"message": "<string>",
"error": {
"code": "<string>",
"message": "<string>",
"details": "<unknown>"
}
}{
"success": false,
"message": "<string>",
"error": {
"code": "<string>",
"message": "<string>",
"details": "<unknown>"
}
}{
"success": false,
"message": "<string>",
"error": {
"code": "<string>",
"message": "<string>",
"details": "<unknown>"
}
}{
"success": false,
"message": "Rate limit exceeded",
"error": {
"code": "TOO_MANY_REQUESTS",
"message": "Too many requests. Please retry after the rate limit window resets."
}
}Authorizations
Use the Authorization header with Bearer scheme.
Examples:
- API Key: Authorization: Bearer calid_xxxxx
Path Parameters
Numeric team identifier.
Required range:
x > 1Example:
42
Numeric team membership identifier.
Required range:
x > 1Example:
1001
Body
application/json
Was this page helpful?