Members > Disable, enable or delete member
Remove member
Removing a member via API
Section titled “Removing a member via API”DELETE /organizations/{org_id}/users/{user_id}
This deactivates a member in your Tallyfy organization. They lose access to this organization, but their Tallyfy account itself isn’t touched. You can also hand their tasks to another member as part of the removal.
You’ll need admin permissions. Bot users can’t be removed through this endpoint.
Separate permanent deletion flow
Section titled “Separate permanent deletion flow”Tallyfy also has a separate way to delete a member for good. It takes two steps and uses different endpoints:
- Disable:
DELETE /organizations/{org_id}/users/{user_id}/disable - Permanently delete:
DELETE /organizations/{org_id}/users/{user_id}/delete
The permanent delete endpoint only works on a member you’ve already disabled. Skip that step and you’ll get an error. The main DELETE /organizations/{org_id}/users/{user_id} endpoint on this page doesn’t need the member disabled first. It never deletes the member for good. To do that, see disable, enable or delete member.
Request
Section titled “Request”Replace {org_id} with your organization ID. Replace {user_id} with the member’s numeric ID.
Headers
Section titled “Headers”Authorization: Bearer {your_access_token}Accept: application/jsonX-Tallyfy-Client: APIClient
Query parameters (optional)
Section titled “Query parameters (optional)”with_reassignment(boolean) - Set totrueto reassign the member’s tasks before removal.to(integer) - Required whenwith_reassignment=true. The user ID receiving reassigned tasks.
Example: ?with_reassignment=true&to=1002
You don’t need a request body.
Code samples
Section titled “Code samples”const accessToken = 'YOUR_PERSONAL_ACCESS_TOKEN';const orgId = 'YOUR_ORGANIZATION_ID';const userId = 12345;const reassignToUserId = null; // Set to a user ID to reassign tasks
const params = new URLSearchParams();if (reassignToUserId != null) { params.append('with_reassignment', 'true'); params.append('to', reassignToUserId.toString());}const queryStr = params.toString();const apiUrl = `https://go.tallyfy.com/api/organizations/${orgId}/users/${userId}${queryStr ? '?' + queryStr : ''}`;
fetch(apiUrl, { method: 'DELETE', headers: { 'Authorization': `Bearer ${accessToken}`, 'Accept': 'application/json', 'X-Tallyfy-Client': 'APIClient' }}).then(response => { if (!response.ok) { return response.json().then(err => { throw new Error(JSON.stringify(err)); }); } return response.json();}).then(data => { console.log('Member removed:', JSON.stringify(data, null, 2));}).catch(error => { console.error(`Error removing member ${userId}:`, error.message);});import requestsimport jsonimport os
access_token = os.environ.get('TALLYFY_ACCESS_TOKEN', 'YOUR_PERSONAL_ACCESS_TOKEN')org_id = os.environ.get('TALLYFY_ORG_ID', 'YOUR_ORGANIZATION_ID')user_id = 12345reassign_to_user_id = None # Set to a user ID to reassign tasks
api_url = f'https://go.tallyfy.com/api/organizations/{org_id}/users/{user_id}'
headers = { 'Authorization': f'Bearer {access_token}', 'Accept': 'application/json', 'X-Tallyfy-Client': 'APIClient'}
params = {}if reassign_to_user_id is not None: params['with_reassignment'] = 'true' params['to'] = reassign_to_user_id
try: response = requests.delete(api_url, headers=headers, params=params) response.raise_for_status() print(f'Member {user_id} removed. Status: {response.status_code}') if response.content: print(json.dumps(response.json(), indent=4))except requests.exceptions.RequestException as e: print(f"Error removing member {user_id}: {e}") if hasattr(e, 'response') and e.response is not None: print(f"Response: {e.response.text}")import java.net.URI;import java.net.URLEncoder;import java.net.http.HttpClient;import java.net.http.HttpRequest;import java.net.http.HttpResponse;import java.io.IOException;import java.nio.charset.StandardCharsets;import java.util.HashMap;import java.util.Map;import java.util.stream.Collectors;
public class RemoveMember { public static void main(String[] args) { String accessToken = System.getenv().getOrDefault("TALLYFY_ACCESS_TOKEN", "YOUR_PERSONAL_ACCESS_TOKEN"); String orgId = System.getenv().getOrDefault("TALLYFY_ORG_ID", "YOUR_ORGANIZATION_ID"); int userId = 12345; Integer reassignToUserId = null; // Set to user ID to reassign tasks String baseUrl = String.format("https://go.tallyfy.com/api/organizations/%s/users/%d", orgId, userId);
Map<String, String> queryParamsMap = new HashMap<>(); if (reassignToUserId != null) { queryParamsMap.put("with_reassignment", "true"); queryParamsMap.put("to", String.valueOf(reassignToUserId)); } String queryParamsString = queryParamsMap.entrySet().stream() .map(e -> URLEncoder.encode(e.getKey(), StandardCharsets.UTF_8) + "=" + URLEncoder.encode(e.getValue(), StandardCharsets.UTF_8)) .collect(Collectors.joining("&", "?", ""));
String apiUrl = baseUrl + (queryParamsMap.isEmpty() ? "" : queryParamsString);
HttpClient client = HttpClient.newHttpClient(); HttpRequest request = HttpRequest.newBuilder() .uri(URI.create(apiUrl)) .header("Authorization", "Bearer " + accessToken) .header("Accept", "application/json") .header("X-Tallyfy-Client", "APIClient") .DELETE() .build();
try { HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); if (response.statusCode() == 200) { System.out.println("Member removed. Response: " + response.body()); } else { System.err.println("Failed: " + response.statusCode() + " - " + response.body()); } } catch (IOException | InterruptedException e) { System.err.println("Request failed: " + e.getMessage()); Thread.currentThread().interrupt(); } }}package main
import ( "encoding/json" "fmt" "io/ioutil" "net/http" "net/url" "os" "strconv" "time")
func main() { accessToken := os.Getenv("TALLYFY_ACCESS_TOKEN") if accessToken == "" { accessToken = "YOUR_PERSONAL_ACCESS_TOKEN" } orgId := os.Getenv("TALLYFY_ORG_ID") if orgId == "" { orgId = "YOUR_ORGANIZATION_ID" } userId := 12345 reassignToUserId := 0 // Set to user ID to reassign tasks
baseUrl := fmt.Sprintf("https://go.tallyfy.com/api/organizations/%s/users/%s", orgId, strconv.Itoa(userId))
queryParams := url.Values{} if reassignToUserId > 0 { queryParams.Set("with_reassignment", "true") queryParams.Set("to", strconv.Itoa(reassignToUserId)) }
apiUrl := baseUrl if len(queryParams) > 0 { apiUrl += "?" + queryParams.Encode() }
client := &http.Client{Timeout: 15 * time.Second} req, err := http.NewRequest(http.MethodDelete, apiUrl, nil) if err != nil { fmt.Printf("Error creating request: %v\n", err) return }
req.Header.Set("Authorization", "Bearer "+accessToken) req.Header.Set("Accept", "application/json") req.Header.Set("X-Tallyfy-Client", "APIClient")
resp, err := client.Do(req) if err != nil { fmt.Printf("Error executing request: %v\n", err) return } defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
if resp.StatusCode == http.StatusOK { fmt.Printf("Member %d removed successfully.\n", userId) var result map[string]interface{} if json.Unmarshal(body, &result) == nil { pretty, _ := json.MarshalIndent(result, "", " ") fmt.Println(string(pretty)) } } else { fmt.Printf("Failed: %d - %s\n", resp.StatusCode, string(body)) }}#include <iostream>#include <string>#include <cpprest/http_client.h>#include <cpprest/json.h>
using namespace web;using namespace web::http;using namespace web::http::client;
pplx::task<void> RemoveTallyfyMember(int userId, int reassignToUserId = 0){ utility::string_t accessToken = U("YOUR_PERSONAL_ACCESS_TOKEN"); utility::string_t orgId = U("YOUR_ORGANIZATION_ID");
uri_builder builder(U("https://go.tallyfy.com/api/organizations/")); builder.append_path(orgId); builder.append_path(U("users")); builder.append_path(utility::conversions::to_string_t(std::to_string(userId)));
if (reassignToUserId > 0) { builder.append_query(U("with_reassignment"), U("true")); builder.append_query(U("to"), utility::conversions::to_string_t(std::to_string(reassignToUserId))); }
http_client client(builder.to_string()); http_request request(methods::DEL); request.headers().add(U("Authorization"), U("Bearer ") + accessToken); request.headers().add(U("Accept"), U("application/json")); request.headers().add(U("X-Tallyfy-Client"), U("APIClient"));
return client.request(request).then([userId](http_response response) { return response.extract_string().then([userId, status = response.status_code()](utility::string_t body) { if (status == status_codes::OK) { std::wcout << L"Member " << userId << L" removed. Response:\n" << body << std::endl; } else { std::wcerr << L"Failed: " << status << L" - " << body << std::endl; } }); });}
int main() { try { RemoveTallyfyMember(12345).wait(); // RemoveTallyfyMember(12346, 1002).wait(); // With reassignment } catch (const std::exception &e) { std::cerr << "Error: " << e.what() << std::endl; } return 0;}// Requires C++ REST SDK (Casablanca)using System;using System.Net.Http;using System.Net.Http.Headers;using System.Threading.Tasks;using System.Text.Json;using System.Web;
public class TallyfyMemberRemover{ private static readonly HttpClient client = new HttpClient();
public static async Task RemoveMemberAsync(int userId, int? reassignToUserId = null) { var accessToken = Environment.GetEnvironmentVariable("TALLYFY_ACCESS_TOKEN") ?? "YOUR_PERSONAL_ACCESS_TOKEN"; var orgId = Environment.GetEnvironmentVariable("TALLYFY_ORG_ID") ?? "YOUR_ORGANIZATION_ID";
var query = HttpUtility.ParseQueryString(string.Empty); if (reassignToUserId.HasValue) { query["with_reassignment"] = "true"; query["to"] = reassignToUserId.Value.ToString(); } string queryString = query.ToString(); var apiUrl = $"https://go.tallyfy.com/api/organizations/{orgId}/users/{userId}"; if (!string.IsNullOrEmpty(queryString)) apiUrl += "?" + queryString;
using var request = new HttpRequestMessage(HttpMethod.Delete, apiUrl); request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); request.Headers.Add("X-Tallyfy-Client", "APIClient");
var response = await client.SendAsync(request); string responseBody = await response.Content.ReadAsStringAsync();
if (response.IsSuccessStatusCode) { Console.WriteLine($"Member {userId} removed. Status: {response.StatusCode}"); if (!string.IsNullOrWhiteSpace(responseBody)) { using var doc = JsonDocument.Parse(responseBody); Console.WriteLine(JsonSerializer.Serialize(doc.RootElement, new JsonSerializerOptions { WriteIndented = true })); } } else { Console.WriteLine($"Failed: {response.StatusCode} - {responseBody}"); } }
// static async Task Main(string[] args) => await RemoveMemberAsync(12345);}Response
Section titled “Response”You’ll get 200 OK. The removed member’s data comes back in a data object.
Success response example
Section titled “Success response example”{ "data": { "id": 12345, "email": "john.doe@example.com", "first_name": "John", "last_name": "Doe", "role": "standard", "status": "disabled" }}Error responses
Section titled “Error responses”| Status | Error message | What to do |
|---|---|---|
| 422 | You can't remove a bot user from this organization! | Bot users can’t be removed through this endpoint. |
| 422 | Cannot modify the default administrator. Please assign another member as default administrator first. | Assign the default admin role to someone else before removing this member. |
| 404 | User not found | Check that the user ID exists in this organization. |
Related articles
Section titled “Related articles”Org Settings > Member deletion
Org Settings > Remove a member
Was this helpful?
- 2026 Tallyfy, Inc.
- Privacy Policy
- Terms of Use
- Report Issue
- Trademarks