Ask to be told when a variant is back in stock
Records a shopper’s request for one email when a sold-out variant is available again. The email
address is the only identity needed, so it works for an anonymous visitor and a signed-in customer
alike; send customer_id with a customer credential to attach the request to a customer record.
A request is not marketing consent. It subscribes the address to nothing and results in exactly one message, sent when the variant’s stock goes from nothing to something. After that message the shopper can ask again.
The response is the same 200 whether the address has asked before, already holds the maximum number
of open requests for the store, or is new. The request is refused with 409 when the variant is in
stock, with 404 when the variant is not sold online by the store, and with 404 (not_available)
when the store has no way to deliver the message. Sandbox keys read their sandbox stock level and
never trigger a message.
Auth / key type: publishable key (tybrite_pk_*) or secret key (tybrite_sk_*). A customer
credential is needed only when customer_id is sent.
Rate limits: 20 requests per hour per IP address and 6 per hour per email address, each within one store.
curl --request POST \
--url https://api.tybritelabs.com/v1/variants/{id}/notify-when-available \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"email": "john.doe@example.com",
"consent": true,
"customer_id": "650e8400-e29b-41d4-a716-446655440000"
}
'import requests
url = "https://api.tybritelabs.com/v1/variants/{id}/notify-when-available"
payload = {
"email": "john.doe@example.com",
"consent": True,
"customer_id": "650e8400-e29b-41d4-a716-446655440000"
}
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({
email: 'john.doe@example.com',
consent: true,
customer_id: '650e8400-e29b-41d4-a716-446655440000'
})
};
fetch('https://api.tybritelabs.com/v1/variants/{id}/notify-when-available', 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.tybritelabs.com/v1/variants/{id}/notify-when-available",
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([
'email' => 'john.doe@example.com',
'consent' => true,
'customer_id' => '650e8400-e29b-41d4-a716-446655440000'
]),
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.tybritelabs.com/v1/variants/{id}/notify-when-available"
payload := strings.NewReader("{\n \"email\": \"john.doe@example.com\",\n \"consent\": true,\n \"customer_id\": \"650e8400-e29b-41d4-a716-446655440000\"\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.tybritelabs.com/v1/variants/{id}/notify-when-available")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"email\": \"john.doe@example.com\",\n \"consent\": true,\n \"customer_id\": \"650e8400-e29b-41d4-a716-446655440000\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.tybritelabs.com/v1/variants/{id}/notify-when-available")
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 \"email\": \"john.doe@example.com\",\n \"consent\": true,\n \"customer_id\": \"650e8400-e29b-41d4-a716-446655440000\"\n}"
response = http.request(request)
puts response.read_body{
"requested": true
}Authorizations
API Key Authentication
Use your API key in the Authorization header:
Authorization: Bearer tybrite_sk_live_YOUR_KEY
Key Types:
Secret Keys (Server-Side Only):
- Format:
tybrite_sk_live_*(production) ortybrite_sk_test_*(sandbox) - Full read/write access to all endpoints
- ⚠️ NEVER expose in client-side code or public repositories
- Required for: every write a shopper does not make for themselves, authentication, payment verification, AI recommendations
Publishable Keys (Client-Safe):
- Format:
tybrite_pk_live_*(production) ortybrite_pk_test_*(sandbox) - Catalogue reads, plus the actions a shopper takes for themselves
- ✅ Safe for client-side JavaScript, mobile apps, and public code
- Allowed for: browsing products, search, CMS content, pricing queries, cart and wishlist, reviews, storefront events, and the Agent API's quotes, cart drafts and checkout intents
Endpoint-Specific Requirements:
- Authentication endpoints (
/v1/auth/*): Secret key required - Payment verification (
POST /v1/payments/verify): Secret key required - AI Recommendations (
POST /v1/recommendations): Secret key required - Semantic Search (
POST /v1/search): Both key types allowed (read-only operation) - Shopper actions (cart, wishlist, reviews, storefront events, Agent API quotes, cart drafts and checkout intents): Both key types allowed
- All other write operations: Secret key required
- All read operations: Both key types allowed
Using a publishable key for restricted operations returns 403 Forbidden.
Headers
Customer session access_token from /v1/auth/login or /v1/auth/verify-otp. Needed only when customer_id is sent; the resolved customer must match it.
Bring-your-own-auth assertion for stores that manage authentication in an external identity provider (Auth0, Clerk, Cognito, Firebase, NextAuth, SSO). Needed only when customer_id is sent. Provide exactly one of x-auth-token, x-external-auth, or x-idp-token.
Format: <base64url(JSON)>.<base64url(HMAC-SHA256(JSON))> where the JSON is { "external_id": "...", "iat": <unix>, "exp": <unix> } and the HMAC is keyed on the store's signing secret. Claim lifetime capped at 300 seconds.
A raw token from the store's own identity provider (e.g. a Firebase ID token). Needed only when customer_id is sent. Verification is fail-closed: if the verifier rejects the token or is unreachable, the request is unauthenticated (401). Provide exactly one of x-auth-token, x-external-auth, or x-idp-token.
Path Parameters
Variant UUID
Body
Where to send the message. Stored lower-cased.
"john.doe@example.com"
Must be true. Records that the shopper asked for this one message.
true true
Customer UUID, when the shopper is signed in. Requires a customer credential for the same customer.
"650e8400-e29b-41d4-a716-446655440000"
Response
The request is recorded, or was already recorded.
true
curl --request POST \
--url https://api.tybritelabs.com/v1/variants/{id}/notify-when-available \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"email": "john.doe@example.com",
"consent": true,
"customer_id": "650e8400-e29b-41d4-a716-446655440000"
}
'import requests
url = "https://api.tybritelabs.com/v1/variants/{id}/notify-when-available"
payload = {
"email": "john.doe@example.com",
"consent": True,
"customer_id": "650e8400-e29b-41d4-a716-446655440000"
}
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({
email: 'john.doe@example.com',
consent: true,
customer_id: '650e8400-e29b-41d4-a716-446655440000'
})
};
fetch('https://api.tybritelabs.com/v1/variants/{id}/notify-when-available', 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.tybritelabs.com/v1/variants/{id}/notify-when-available",
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([
'email' => 'john.doe@example.com',
'consent' => true,
'customer_id' => '650e8400-e29b-41d4-a716-446655440000'
]),
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.tybritelabs.com/v1/variants/{id}/notify-when-available"
payload := strings.NewReader("{\n \"email\": \"john.doe@example.com\",\n \"consent\": true,\n \"customer_id\": \"650e8400-e29b-41d4-a716-446655440000\"\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.tybritelabs.com/v1/variants/{id}/notify-when-available")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"email\": \"john.doe@example.com\",\n \"consent\": true,\n \"customer_id\": \"650e8400-e29b-41d4-a716-446655440000\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.tybritelabs.com/v1/variants/{id}/notify-when-available")
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 \"email\": \"john.doe@example.com\",\n \"consent\": true,\n \"customer_id\": \"650e8400-e29b-41d4-a716-446655440000\"\n}"
response = http.request(request)
puts response.read_body{
"requested": true
}
