Members > Invite and activate members
Admins (and optionally Standard members) can invite new users by clicking Invite+ and entering…
POST /organizations/{org_id}/users/invite
This endpoint sends an invitation email to a new user, asking them to join your Tallyfy organization.
Replace {org_id} with your organization ID.
Authorization: Bearer {your_access_token}Accept: application/jsonX-Tallyfy-Client: APIClientContent-Type: application/json| Field | Type | Required? | Description |
|---|---|---|---|
email | string | Yes | Email address of the person to invite. |
first_name | string | Yes | First name of the invitee (max 32 characters). |
last_name | string | Yes | Last name of the invitee (max 32 characters). |
role | string | Yes | Role to assign: admin, standard, or light. |
message | string | Yes | Personal message included in the invitation email (max 5000 characters). |
Non-admin users can’t assign the
adminrole. The organization must also allow non-admin users to send invites, or the request won’t work.
Example body:
{ "email": "new.user@example.com", "first_name": "Charlie", "last_name": "Brown", "role": "standard", "message": "Welcome to the team! Looking forward to working with you."}const accessToken = 'YOUR_PERSONAL_ACCESS_TOKEN';const orgId = 'YOUR_ORGANIZATION_ID';const apiUrl = `https://go.tallyfy.com/api/organizations/${orgId}/users/invite`;
const inviteData = { email: 'charlie.brown@example.com', first_name: 'Charlie', last_name: 'Brown', role: 'standard', message: 'Welcome to the team!'};
const headers = new Headers();headers.append('Authorization', `Bearer ${accessToken}`);headers.append('Accept', 'application/json');headers.append('X-Tallyfy-Client', 'APIClient');headers.append('Content-Type', 'application/json');
fetch(apiUrl, { method: 'POST', headers: headers, body: JSON.stringify(inviteData)}).then(response => { return response.json().then(data => { if (!response.ok) { console.error('Failed to invite member:', data); throw new Error(`HTTP ${response.status}: ${data.message || JSON.stringify(data)}`); } return data; });}).then(data => { console.log('Successfully invited member:'); console.log(JSON.stringify(data, null, 2));}).catch(error => { console.error('Error inviting member:', 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')api_url = f'https://go.tallyfy.com/api/organizations/{org_id}/users/invite'
headers = { 'Authorization': f'Bearer {access_token}', 'Accept': 'application/json', 'X-Tallyfy-Client': 'APIClient', 'Content-Type': 'application/json'}
invite_payload = { 'email': 'lucy.vanpelt@example.com', 'first_name': 'Lucy', 'last_name': 'Van Pelt', 'role': 'light', 'message': 'Join us on Tallyfy to collaborate on our workflows.'}
response = Nonetry: response = requests.post(api_url, headers=headers, json=invite_payload) response.raise_for_status()
invite_response = response.json() print('Successfully invited member:') print(json.dumps(invite_response, indent=4))
except requests.exceptions.HTTPError as http_err: error_details = '' if response is not None: try: error_details = response.json() except json.JSONDecodeError: error_details = response.text print(f'HTTP error inviting member: {http_err}') print(f'Response: {error_details}')
except requests.exceptions.RequestException as req_err: print(f'Request failed: {req_err}')import java.net.URI;import java.net.http.HttpClient;import java.net.http.HttpRequest;import java.net.http.HttpResponse;import java.io.IOException;
public class InviteMember { 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"); String apiUrl = "https://go.tallyfy.com/api/organizations/" + orgId + "/users/invite";
String jsonPayload = """ { "email": "linus@example.com", "first_name": "Linus", "last_name": "Van Pelt", "role": "standard", "message": "Welcome aboard!" } """;
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") .header("Content-Type", "application/json") .POST(HttpRequest.BodyPublishers.ofString(jsonPayload)) .build();
try { HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() == 200) { System.out.println("Successfully invited member:"); System.out.println(response.body()); } else { System.err.println("Failed to invite member. Status: " + response.statusCode()); System.err.println("Response: " + response.body()); } } catch (IOException | InterruptedException e) { System.err.println("Request failed: " + e.getMessage()); Thread.currentThread().interrupt(); } }}package main
import ( "bytes" "encoding/json" "fmt" "io" "net/http" "os" "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" } apiUrl := fmt.Sprintf("https://go.tallyfy.com/api/organizations/%s/users/invite", orgId)
inviteData := map[string]interface{}{ "email": "snoopy@example.com", "first_name": "Snoopy", "last_name": "Dog", "role": "light", "message": "Join us on Tallyfy!", }
jsonData, err := json.Marshal(inviteData) if err != nil { fmt.Printf("Error marshalling JSON: %v\n", err) return }
client := &http.Client{Timeout: 15 * time.Second} req, err := http.NewRequest(http.MethodPost, apiUrl, bytes.NewBuffer(jsonData)) 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") req.Header.Set("Content-Type", "application/json")
resp, err := client.Do(req) if err != nil { fmt.Printf("Error sending request: %v\n", err) return } defer resp.Body.Close()
body, err := io.ReadAll(resp.Body) if err != nil { fmt.Printf("Error reading response: %v\n", err) return }
if resp.StatusCode != http.StatusOK { fmt.Printf("Failed to invite member. Status: %d\nBody: %s\n", resp.StatusCode, string(body)) return }
fmt.Println("Successfully invited member:") var prettyJSON bytes.Buffer if err := json.Indent(&prettyJSON, body, "", " "); err == nil { fmt.Println(prettyJSON.String()) } else { fmt.Println(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;using namespace web::json;
pplx::task<void> InviteTallyfyMember(const value& invitePayload){ utility::string_t accessToken = U("YOUR_PERSONAL_ACCESS_TOKEN"); utility::string_t orgId = U("YOUR_ORGANIZATION_ID"); utility::string_t apiUrl = U("https://go.tallyfy.com/api/organizations/") + orgId + U("/users/invite");
http_client client(apiUrl); http_request request(methods::POST);
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")); request.headers().set_content_type(U("application/json")); request.set_body(invitePayload);
return client.request(request).then([](http_response response) { return response.extract_json().then([response](pplx::task<value> task) { try { value const & body = task.get(); if (response.status_code() == status_codes::OK) { std::wcout << L"Successfully invited member:\n" << body.serialize() << std::endl; } else { std::wcerr << L"Failed to invite member. Status: " << response.status_code() << L"\nResponse: " << body.serialize() << std::endl; } } catch (const std::exception& e) { std::wcerr << L"Exception: " << e.what() << std::endl; } }); });}
int main() { try { value payload = value::object(); payload[U("email")] = value::string(U("peppermint.patty@example.com")); payload[U("first_name")] = value::string(U("Peppermint")); payload[U("last_name")] = value::string(U("Patty")); payload[U("role")] = value::string(U("standard")); payload[U("message")] = value::string(U("Welcome to Tallyfy!"));
InviteTallyfyMember(payload).wait(); } 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.Text;using System.Text.Json;using System.Threading.Tasks;
public class TallyfyMemberInviter{ private static readonly HttpClient client = new HttpClient();
public static async Task InviteMemberAsync() { var accessToken = Environment.GetEnvironmentVariable("TALLYFY_ACCESS_TOKEN") ?? "YOUR_PERSONAL_ACCESS_TOKEN"; var orgId = Environment.GetEnvironmentVariable("TALLYFY_ORG_ID") ?? "YOUR_ORGANIZATION_ID"; var apiUrl = $"https://go.tallyfy.com/api/organizations/{orgId}/users/invite";
var payload = new { email = "marcie@example.com", first_name = "Marcie", last_name = "Johnson", role = "light", message = "Join our team on Tallyfy!" };
try { using var request = new HttpRequestMessage(HttpMethod.Post, apiUrl); request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); request.Headers.Add("X-Tallyfy-Client", "APIClient");
string jsonPayload = JsonSerializer.Serialize(payload); request.Content = new StringContent(jsonPayload, Encoding.UTF8, "application/json");
HttpResponseMessage response = await client.SendAsync(request); string responseBody = await response.Content.ReadAsStringAsync();
if (response.IsSuccessStatusCode) { Console.WriteLine("Successfully invited member:"); using var doc = JsonDocument.Parse(responseBody); Console.WriteLine(JsonSerializer.Serialize(doc.RootElement, new JsonSerializerOptions { WriteIndented = true })); } else { Console.WriteLine($"Failed to invite member. Status: {response.StatusCode}"); Console.WriteLine($"Response: {responseBody}"); } } catch (HttpRequestException e) { Console.WriteLine($"Request error: {e.Message}"); } }}A successful request returns a 200 OK status. The response body contains the invited user’s profile wrapped in a data object, with a status of invited until they accept.
{ "data": { "id": 1005, "email": "charlie.brown@example.com", "username": null, "first_name": "Charlie", "last_name": "Brown", "full_name": "Charlie Brown", "profile_pic": null, "country_id": 1, "is_active": false, "last_login_at": null, "activated_at": null, "type": null, "created_at": "2025-01-15T10:00:00Z", "updated_at": "2025-01-15T10:00:00Z", "timezone": "America/New_York", "UTC_offset": "-05:00", "status": "invited", "role": "standard", "invited_by": 501, "approved_at": "2025-01-15T10:00:00Z" }}If the email already belongs to an existing member, you’ll get a 422 Unprocessable Entity error.
Members > Invite and activate members
Code Samples > Managing members (users)
/users endpoints to invite, list…