curl --request POST \
--url https://api.athenahq.ai/api/v1/invites/bulk \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"invite_method": "direct",
"email": "user@example.com",
"role": "viewer",
"role_id": "789e0123-e89b-12d3-a456-426614174000",
"website_ids": [
"123e4567-e89b-12d3-a456-426614174000",
"987e6543-e21b-12d3-a456-426614174000"
],
"group_ids": [
"456e7890-e89b-12d3-a456-426614174000",
"789e0123-e89b-12d3-a456-426614174000"
],
"first_name": "John",
"last_name": "Doe"
}
'import requests
url = "https://api.athenahq.ai/api/v1/invites/bulk"
payload = {
"invite_method": "direct",
"email": "user@example.com",
"role": "viewer",
"role_id": "789e0123-e89b-12d3-a456-426614174000",
"website_ids": ["123e4567-e89b-12d3-a456-426614174000", "987e6543-e21b-12d3-a456-426614174000"],
"group_ids": ["456e7890-e89b-12d3-a456-426614174000", "789e0123-e89b-12d3-a456-426614174000"],
"first_name": "John",
"last_name": "Doe"
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
invite_method: 'direct',
email: 'user@example.com',
role: 'viewer',
role_id: '789e0123-e89b-12d3-a456-426614174000',
website_ids: ['123e4567-e89b-12d3-a456-426614174000', '987e6543-e21b-12d3-a456-426614174000'],
group_ids: ['456e7890-e89b-12d3-a456-426614174000', '789e0123-e89b-12d3-a456-426614174000'],
first_name: 'John',
last_name: 'Doe'
})
};
fetch('https://api.athenahq.ai/api/v1/invites/bulk', 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.athenahq.ai/api/v1/invites/bulk",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'invite_method' => 'direct',
'email' => 'user@example.com',
'role' => 'viewer',
'role_id' => '789e0123-e89b-12d3-a456-426614174000',
'website_ids' => [
'123e4567-e89b-12d3-a456-426614174000',
'987e6543-e21b-12d3-a456-426614174000'
],
'group_ids' => [
'456e7890-e89b-12d3-a456-426614174000',
'789e0123-e89b-12d3-a456-426614174000'
],
'first_name' => 'John',
'last_name' => 'Doe'
]),
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.athenahq.ai/api/v1/invites/bulk"
payload := strings.NewReader("{\n \"invite_method\": \"direct\",\n \"email\": \"user@example.com\",\n \"role\": \"viewer\",\n \"role_id\": \"789e0123-e89b-12d3-a456-426614174000\",\n \"website_ids\": [\n \"123e4567-e89b-12d3-a456-426614174000\",\n \"987e6543-e21b-12d3-a456-426614174000\"\n ],\n \"group_ids\": [\n \"456e7890-e89b-12d3-a456-426614174000\",\n \"789e0123-e89b-12d3-a456-426614174000\"\n ],\n \"first_name\": \"John\",\n \"last_name\": \"Doe\"\n}")
req, _ := http.NewRequest("POST", 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.post("https://api.athenahq.ai/api/v1/invites/bulk")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"invite_method\": \"direct\",\n \"email\": \"user@example.com\",\n \"role\": \"viewer\",\n \"role_id\": \"789e0123-e89b-12d3-a456-426614174000\",\n \"website_ids\": [\n \"123e4567-e89b-12d3-a456-426614174000\",\n \"987e6543-e21b-12d3-a456-426614174000\"\n ],\n \"group_ids\": [\n \"456e7890-e89b-12d3-a456-426614174000\",\n \"789e0123-e89b-12d3-a456-426614174000\"\n ],\n \"first_name\": \"John\",\n \"last_name\": \"Doe\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.athenahq.ai/api/v1/invites/bulk")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"invite_method\": \"direct\",\n \"email\": \"user@example.com\",\n \"role\": \"viewer\",\n \"role_id\": \"789e0123-e89b-12d3-a456-426614174000\",\n \"website_ids\": [\n \"123e4567-e89b-12d3-a456-426614174000\",\n \"987e6543-e21b-12d3-a456-426614174000\"\n ],\n \"group_ids\": [\n \"456e7890-e89b-12d3-a456-426614174000\",\n \"789e0123-e89b-12d3-a456-426614174000\"\n ],\n \"first_name\": \"John\",\n \"last_name\": \"Doe\"\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"results": [
{
"website_id": "123e4567-e89b-12d3-a456-426614174000",
"success": true,
"message": "User added to website",
"user_id": "abc12345-e89b-12d3-a456-426614174000"
},
{
"website_id": "987e6543-e21b-12d3-a456-426614174000",
"success": false,
"error": "User is already a member of this website"
}
]
}Bulk Invite to Websites or Groups
Invites a user to multiple websites OR multiple groups in a single request. Provide exactly one of website_ids or group_ids — the two are mutually exclusive. Each target is processed independently, so some may succeed while others fail (e.g., if the user is already a member). In ‘email’ mode a single consolidated invitation email is sent. Group invites require a global API key. Website invites with a website-scoped key also require the key’s creator to be an Admin of every listed website. Direct invites cannot create new accounts with email domains for Cuba, Iran, North Korea, Russia, Belarus, or regional domains for Crimea (including Sevastopol), Donetsk, or Luhansk. The response remains HTTP 201 with success: false and an error for each target in results. General .ua domains remain allowed. Existing accounts can still be invited.
curl --request POST \
--url https://api.athenahq.ai/api/v1/invites/bulk \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"invite_method": "direct",
"email": "user@example.com",
"role": "viewer",
"role_id": "789e0123-e89b-12d3-a456-426614174000",
"website_ids": [
"123e4567-e89b-12d3-a456-426614174000",
"987e6543-e21b-12d3-a456-426614174000"
],
"group_ids": [
"456e7890-e89b-12d3-a456-426614174000",
"789e0123-e89b-12d3-a456-426614174000"
],
"first_name": "John",
"last_name": "Doe"
}
'import requests
url = "https://api.athenahq.ai/api/v1/invites/bulk"
payload = {
"invite_method": "direct",
"email": "user@example.com",
"role": "viewer",
"role_id": "789e0123-e89b-12d3-a456-426614174000",
"website_ids": ["123e4567-e89b-12d3-a456-426614174000", "987e6543-e21b-12d3-a456-426614174000"],
"group_ids": ["456e7890-e89b-12d3-a456-426614174000", "789e0123-e89b-12d3-a456-426614174000"],
"first_name": "John",
"last_name": "Doe"
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
invite_method: 'direct',
email: 'user@example.com',
role: 'viewer',
role_id: '789e0123-e89b-12d3-a456-426614174000',
website_ids: ['123e4567-e89b-12d3-a456-426614174000', '987e6543-e21b-12d3-a456-426614174000'],
group_ids: ['456e7890-e89b-12d3-a456-426614174000', '789e0123-e89b-12d3-a456-426614174000'],
first_name: 'John',
last_name: 'Doe'
})
};
fetch('https://api.athenahq.ai/api/v1/invites/bulk', 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.athenahq.ai/api/v1/invites/bulk",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'invite_method' => 'direct',
'email' => 'user@example.com',
'role' => 'viewer',
'role_id' => '789e0123-e89b-12d3-a456-426614174000',
'website_ids' => [
'123e4567-e89b-12d3-a456-426614174000',
'987e6543-e21b-12d3-a456-426614174000'
],
'group_ids' => [
'456e7890-e89b-12d3-a456-426614174000',
'789e0123-e89b-12d3-a456-426614174000'
],
'first_name' => 'John',
'last_name' => 'Doe'
]),
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.athenahq.ai/api/v1/invites/bulk"
payload := strings.NewReader("{\n \"invite_method\": \"direct\",\n \"email\": \"user@example.com\",\n \"role\": \"viewer\",\n \"role_id\": \"789e0123-e89b-12d3-a456-426614174000\",\n \"website_ids\": [\n \"123e4567-e89b-12d3-a456-426614174000\",\n \"987e6543-e21b-12d3-a456-426614174000\"\n ],\n \"group_ids\": [\n \"456e7890-e89b-12d3-a456-426614174000\",\n \"789e0123-e89b-12d3-a456-426614174000\"\n ],\n \"first_name\": \"John\",\n \"last_name\": \"Doe\"\n}")
req, _ := http.NewRequest("POST", 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.post("https://api.athenahq.ai/api/v1/invites/bulk")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"invite_method\": \"direct\",\n \"email\": \"user@example.com\",\n \"role\": \"viewer\",\n \"role_id\": \"789e0123-e89b-12d3-a456-426614174000\",\n \"website_ids\": [\n \"123e4567-e89b-12d3-a456-426614174000\",\n \"987e6543-e21b-12d3-a456-426614174000\"\n ],\n \"group_ids\": [\n \"456e7890-e89b-12d3-a456-426614174000\",\n \"789e0123-e89b-12d3-a456-426614174000\"\n ],\n \"first_name\": \"John\",\n \"last_name\": \"Doe\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.athenahq.ai/api/v1/invites/bulk")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"invite_method\": \"direct\",\n \"email\": \"user@example.com\",\n \"role\": \"viewer\",\n \"role_id\": \"789e0123-e89b-12d3-a456-426614174000\",\n \"website_ids\": [\n \"123e4567-e89b-12d3-a456-426614174000\",\n \"987e6543-e21b-12d3-a456-426614174000\"\n ],\n \"group_ids\": [\n \"456e7890-e89b-12d3-a456-426614174000\",\n \"789e0123-e89b-12d3-a456-426614174000\"\n ],\n \"first_name\": \"John\",\n \"last_name\": \"Doe\"\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"results": [
{
"website_id": "123e4567-e89b-12d3-a456-426614174000",
"success": true,
"message": "User added to website",
"user_id": "abc12345-e89b-12d3-a456-426614174000"
},
{
"website_id": "987e6543-e21b-12d3-a456-426614174000",
"success": false,
"error": "User is already a member of this website"
}
]
}Body
Request body for inviting a user to multiple websites or multiple groups. Provide exactly one of website_ids or group_ids — the two are mutually exclusive. A single consolidated invitation email is sent in 'email' mode.
How to invite the user. 'direct' adds the user to each target immediately without sending any email — if no account exists for the email, a new user account is created automatically (with emailVerified=false). 'email' creates pending invite records and sends a single consolidated invitation email.
direct, email "direct"
Email address of the user to invite
"user@example.com"
The role to assign to the invited user on each target. Mutually exclusive with role_id.
admin, viewer "viewer"
Assign any role by ID — a system role or one of your organization's custom roles (see GET /api/v1/roles). Mutually exclusive with role. Returns 404 if the role does not exist or belongs to another organization. Defaults to Viewer when neither role nor role_id is given. System role IDs are GUID-shaped sentinels (e.g. 00000000-0000-0000-0000-000000000001), not RFC 4122 UUIDs.
^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"789e0123-e89b-12d3-a456-426614174000"
Array of website IDs to invite the user to (1-50). Mutually exclusive with group_ids.
1 - 50 elements[
"123e4567-e89b-12d3-a456-426614174000",
"987e6543-e21b-12d3-a456-426614174000"
]
Array of group IDs to invite the user to (1-50). Mutually exclusive with website_ids. Requires a global API key.
1 - 50 elements[
"456e7890-e89b-12d3-a456-426614174000",
"789e0123-e89b-12d3-a456-426614174000"
]
Optional first name of the invited user. Used when creating a new user account for 'direct' invites or populating invite records for 'email' invites.
"John"
Optional last name of the invited user. Used when creating a new user account for 'direct' invites or populating invite records for 'email' invites.
"Doe"
Response
Bulk invite processed. Check individual results for per-target outcomes.
Response from a bulk invite request. Each target (website or group) is processed independently.
Was this page helpful?