Invite a Teammate
curl --request POST \
--url https://app.tuco.ai/api/team/invite \
--header 'Authorization: Bearer <token>'import requests
url = "https://app.tuco.ai/api/team/invite"
headers = {"Authorization": "Bearer <token>"}
response = requests.post(url, headers=headers)
print(response.text)const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
fetch('https://app.tuco.ai/api/team/invite', 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://app.tuco.ai/api/team/invite",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://app.tuco.ai/api/team/invite"
req, _ := http.NewRequest("POST", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://app.tuco.ai/api/team/invite")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.tuco.ai/api/team/invite")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_bodyWorkspace settings
Invite a Teammate
Invite someone into a Tuco workspace by email, with a role, using that workspace’s API key.
POST
/
api
/
team
/
invite
Invite a Teammate
curl --request POST \
--url https://app.tuco.ai/api/team/invite \
--header 'Authorization: Bearer <token>'import requests
url = "https://app.tuco.ai/api/team/invite"
headers = {"Authorization": "Bearer <token>"}
response = requests.post(url, headers=headers)
print(response.text)const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
fetch('https://app.tuco.ai/api/team/invite', 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://app.tuco.ai/api/team/invite",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://app.tuco.ai/api/team/invite"
req, _ := http.NewRequest("POST", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://app.tuco.ai/api/team/invite")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.tuco.ai/api/team/invite")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_bodyAdds an existing Tuco user to the workspace immediately, or emails an invitation to
someone who does not have an account yet.
Endpoint
- Method:
POST - Path:
/api/team/invite - Auth:
Authorization: Bearer tuco_xxxxxxxxxxxxx
Body
| Field | Type | Required | Notes |
|---|---|---|---|
email | string | yes | Who to invite |
role | string | no | org:member (default) or org:admin |
Example request
curl https://app.tuco.ai/api/team/invite \
-H "Authorization: Bearer tuco_xxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{"email": "owner@acmeroofing.com", "role": "org:admin"}'
Success response (200)
{
"ok": true,
"status": "invited",
"email": "owner@acmeroofing.com",
"inviteUrl": "https://accounts.tuco.ai/v1/tickets/accept?ticket=…",
"inviteId": "orginv_…"
}
status | Meaning |
|---|---|
added | They already had a Tuco account and are now a member. No email was sent — share the login link yourself |
invited | An invitation email was sent. inviteUrl is the same link if you want to deliver it your own way |
already_member | Nothing to do |
Permissions
A signed-in caller must be a workspace admin. An API key is accepted on its own: only a workspace owner or admin can mint one, and it is scoped to this workspace, so the key already carries the authority the check would test. This also means an integration keeps working when the person who created the key changes role or leaves. Agencies: use the workspace key for the workspace you are inviting into — the one returned by Create Agency Workspace. An agency key cannot invite, because “which workspace?” would be ambiguous.Error responses
| Status | When |
|---|---|
400 | email missing, or role is not org:admin / org:member, or no active workspace |
401 | Missing or invalid key |
403 | A signed-in non-admin, or an agency key (tucoagency_…) |
500 | The invitation could not be created |