import { WhopClient } from "@whop/sdk";
const client = new WhopClient({ token: "YOUR_TOKEN", apiVersionDate: "2026-08-21-1", idempotencyKey: "YOUR_IDEMPOTENCY_KEY" });
await client.notifications.create({
content: "Drop off at 4180 Burnet Rd. Plan on two days for the full coating.",
title: "Your ceramic coating is booked"
});
curl --request POST \
--url https://api.whop.com/api/v1/notifications \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"content": "Drop off at 4180 Burnet Rd. Plan on two days for the full coating.",
"title": "Your ceramic coating is booked",
"account_id": "biz_xxxxxxxxxxxxxx",
"experience_id": "exp_xxxxxxxxxxxxxx",
"icon_user_id": "user_xxxxxxxxxxxxxx",
"rest_path": "/bookings/upcoming",
"subtitle": "Tuesday 9:00 AM, Bay 2",
"user_ids": [
"user_xxxxxxxxxxxxxx"
]
}
'import requests
url = "https://api.whop.com/api/v1/notifications"
payload = {
"content": "Drop off at 4180 Burnet Rd. Plan on two days for the full coating.",
"title": "Your ceramic coating is booked",
"account_id": "biz_xxxxxxxxxxxxxx",
"experience_id": "exp_xxxxxxxxxxxxxx",
"icon_user_id": "user_xxxxxxxxxxxxxx",
"rest_path": "/bookings/upcoming",
"subtitle": "Tuesday 9:00 AM, Bay 2",
"user_ids": ["user_xxxxxxxxxxxxxx"]
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
content: 'Drop off at 4180 Burnet Rd. Plan on two days for the full coating.',
title: 'Your ceramic coating is booked',
account_id: 'biz_xxxxxxxxxxxxxx',
experience_id: 'exp_xxxxxxxxxxxxxx',
icon_user_id: 'user_xxxxxxxxxxxxxx',
rest_path: '/bookings/upcoming',
subtitle: 'Tuesday 9:00 AM, Bay 2',
user_ids: ['user_xxxxxxxxxxxxxx']
})
};
fetch('https://api.whop.com/api/v1/notifications', 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.whop.com/api/v1/notifications",
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([
'content' => 'Drop off at 4180 Burnet Rd. Plan on two days for the full coating.',
'title' => 'Your ceramic coating is booked',
'account_id' => 'biz_xxxxxxxxxxxxxx',
'experience_id' => 'exp_xxxxxxxxxxxxxx',
'icon_user_id' => 'user_xxxxxxxxxxxxxx',
'rest_path' => '/bookings/upcoming',
'subtitle' => 'Tuesday 9:00 AM, Bay 2',
'user_ids' => [
'user_xxxxxxxxxxxxxx'
]
]),
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.whop.com/api/v1/notifications"
payload := strings.NewReader("{\n \"content\": \"Drop off at 4180 Burnet Rd. Plan on two days for the full coating.\",\n \"title\": \"Your ceramic coating is booked\",\n \"account_id\": \"biz_xxxxxxxxxxxxxx\",\n \"experience_id\": \"exp_xxxxxxxxxxxxxx\",\n \"icon_user_id\": \"user_xxxxxxxxxxxxxx\",\n \"rest_path\": \"/bookings/upcoming\",\n \"subtitle\": \"Tuesday 9:00 AM, Bay 2\",\n \"user_ids\": [\n \"user_xxxxxxxxxxxxxx\"\n ]\n}")
req, _ := http.NewRequest("POST", 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.post("https://api.whop.com/api/v1/notifications")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"content\": \"Drop off at 4180 Burnet Rd. Plan on two days for the full coating.\",\n \"title\": \"Your ceramic coating is booked\",\n \"account_id\": \"biz_xxxxxxxxxxxxxx\",\n \"experience_id\": \"exp_xxxxxxxxxxxxxx\",\n \"icon_user_id\": \"user_xxxxxxxxxxxxxx\",\n \"rest_path\": \"/bookings/upcoming\",\n \"subtitle\": \"Tuesday 9:00 AM, Bay 2\",\n \"user_ids\": [\n \"user_xxxxxxxxxxxxxx\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.whop.com/api/v1/notifications")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"content\": \"Drop off at 4180 Burnet Rd. Plan on two days for the full coating.\",\n \"title\": \"Your ceramic coating is booked\",\n \"account_id\": \"biz_xxxxxxxxxxxxxx\",\n \"experience_id\": \"exp_xxxxxxxxxxxxxx\",\n \"icon_user_id\": \"user_xxxxxxxxxxxxxx\",\n \"rest_path\": \"/bookings/upcoming\",\n \"subtitle\": \"Tuesday 9:00 AM, Bay 2\",\n \"user_ids\": [\n \"user_xxxxxxxxxxxxxx\"\n ]\n}"
response = http.request(request)
puts response.read_body{
"success": true
}{
"error": {
"message": "account_id is required",
"type": "bad_request",
"code": "<string>"
}
}{
"error": {
"message": "account_id is required",
"type": "bad_request",
"code": "<string>"
}
}{
"error": {
"message": "account_id is required",
"type": "bad_request",
"code": "<string>"
}
}{
"error": {
"message": "account_id is required",
"type": "bad_request",
"code": "<string>"
}
}Send Notification
Queues a notification to every user of an experience or to an account’s team, processed asynchronously. Every send is attributed to an app: use an app API key, or a credential acting on behalf of an app. Narrow the audience with user_ids to send a mention.
import { WhopClient } from "@whop/sdk";
const client = new WhopClient({ token: "YOUR_TOKEN", apiVersionDate: "2026-08-21-1", idempotencyKey: "YOUR_IDEMPOTENCY_KEY" });
await client.notifications.create({
content: "Drop off at 4180 Burnet Rd. Plan on two days for the full coating.",
title: "Your ceramic coating is booked"
});
curl --request POST \
--url https://api.whop.com/api/v1/notifications \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"content": "Drop off at 4180 Burnet Rd. Plan on two days for the full coating.",
"title": "Your ceramic coating is booked",
"account_id": "biz_xxxxxxxxxxxxxx",
"experience_id": "exp_xxxxxxxxxxxxxx",
"icon_user_id": "user_xxxxxxxxxxxxxx",
"rest_path": "/bookings/upcoming",
"subtitle": "Tuesday 9:00 AM, Bay 2",
"user_ids": [
"user_xxxxxxxxxxxxxx"
]
}
'import requests
url = "https://api.whop.com/api/v1/notifications"
payload = {
"content": "Drop off at 4180 Burnet Rd. Plan on two days for the full coating.",
"title": "Your ceramic coating is booked",
"account_id": "biz_xxxxxxxxxxxxxx",
"experience_id": "exp_xxxxxxxxxxxxxx",
"icon_user_id": "user_xxxxxxxxxxxxxx",
"rest_path": "/bookings/upcoming",
"subtitle": "Tuesday 9:00 AM, Bay 2",
"user_ids": ["user_xxxxxxxxxxxxxx"]
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
content: 'Drop off at 4180 Burnet Rd. Plan on two days for the full coating.',
title: 'Your ceramic coating is booked',
account_id: 'biz_xxxxxxxxxxxxxx',
experience_id: 'exp_xxxxxxxxxxxxxx',
icon_user_id: 'user_xxxxxxxxxxxxxx',
rest_path: '/bookings/upcoming',
subtitle: 'Tuesday 9:00 AM, Bay 2',
user_ids: ['user_xxxxxxxxxxxxxx']
})
};
fetch('https://api.whop.com/api/v1/notifications', 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.whop.com/api/v1/notifications",
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([
'content' => 'Drop off at 4180 Burnet Rd. Plan on two days for the full coating.',
'title' => 'Your ceramic coating is booked',
'account_id' => 'biz_xxxxxxxxxxxxxx',
'experience_id' => 'exp_xxxxxxxxxxxxxx',
'icon_user_id' => 'user_xxxxxxxxxxxxxx',
'rest_path' => '/bookings/upcoming',
'subtitle' => 'Tuesday 9:00 AM, Bay 2',
'user_ids' => [
'user_xxxxxxxxxxxxxx'
]
]),
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.whop.com/api/v1/notifications"
payload := strings.NewReader("{\n \"content\": \"Drop off at 4180 Burnet Rd. Plan on two days for the full coating.\",\n \"title\": \"Your ceramic coating is booked\",\n \"account_id\": \"biz_xxxxxxxxxxxxxx\",\n \"experience_id\": \"exp_xxxxxxxxxxxxxx\",\n \"icon_user_id\": \"user_xxxxxxxxxxxxxx\",\n \"rest_path\": \"/bookings/upcoming\",\n \"subtitle\": \"Tuesday 9:00 AM, Bay 2\",\n \"user_ids\": [\n \"user_xxxxxxxxxxxxxx\"\n ]\n}")
req, _ := http.NewRequest("POST", 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.post("https://api.whop.com/api/v1/notifications")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"content\": \"Drop off at 4180 Burnet Rd. Plan on two days for the full coating.\",\n \"title\": \"Your ceramic coating is booked\",\n \"account_id\": \"biz_xxxxxxxxxxxxxx\",\n \"experience_id\": \"exp_xxxxxxxxxxxxxx\",\n \"icon_user_id\": \"user_xxxxxxxxxxxxxx\",\n \"rest_path\": \"/bookings/upcoming\",\n \"subtitle\": \"Tuesday 9:00 AM, Bay 2\",\n \"user_ids\": [\n \"user_xxxxxxxxxxxxxx\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.whop.com/api/v1/notifications")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"content\": \"Drop off at 4180 Burnet Rd. Plan on two days for the full coating.\",\n \"title\": \"Your ceramic coating is booked\",\n \"account_id\": \"biz_xxxxxxxxxxxxxx\",\n \"experience_id\": \"exp_xxxxxxxxxxxxxx\",\n \"icon_user_id\": \"user_xxxxxxxxxxxxxx\",\n \"rest_path\": \"/bookings/upcoming\",\n \"subtitle\": \"Tuesday 9:00 AM, Bay 2\",\n \"user_ids\": [\n \"user_xxxxxxxxxxxxxx\"\n ]\n}"
response = http.request(request)
puts response.read_body{
"success": true
}{
"error": {
"message": "account_id is required",
"type": "bad_request",
"code": "<string>"
}
}{
"error": {
"message": "account_id is required",
"type": "bad_request",
"code": "<string>"
}
}{
"error": {
"message": "account_id is required",
"type": "bad_request",
"code": "<string>"
}
}{
"error": {
"message": "account_id is required",
"type": "bad_request",
"code": "<string>"
}
}Authorizations
An App API key. Prepend the key or token with Bearer, for example Bearer ***************************. See Auth & API keys for how to get each one.
Headers
A unique key that makes this request safe to retry. See Idempotent requests.
255"d9105228-4a08-46b1-8b91-42fed586d383"
Pins the request to a dated API version.
"2026-09-25"
Body
Main body text of the notification.
"Drop off at 4180 Burnet Rd. Plan on two days for the full coating."
Headline text of the notification.
"Your ceramic coating is booked"
Account whose team members receive the notification (biz_ tag). Exactly one of experience_id or account_id is required.
"biz_xxxxxxxxxxxxxx"
Experience whose users receive the notification (exp_ tag). Exactly one of experience_id or account_id is required.
"exp_xxxxxxxxxxxxxx"
User whose profile picture is used as the notification icon. Defaults to the experience or account avatar.
"user_xxxxxxxxxxxxxx"
Path segment appended to the generated deep link that opens your app, for example /settings/billing.
"/bookings/upcoming"
Optional secondary line displayed below the title.
"Tuesday 9:00 AM, Bay 2"
Optional user_ tags narrowing the audience. When provided, only these users are notified (as a mention), provided they are in the targeted experience or account.
Response
notification queued
true

