Add a message to a dispute
Adds a message from the shopper to the dispute’s conversation thread, so the shopper can add detail or respond to the operator or merchant while the dispute is being reviewed. Messages cannot be added once the dispute is closed.
Authentication: API key and a customer session (x-auth-token or
x-external-auth).
curl --request POST \
--url https://api.tybritelabs.com/v1/disputes/{id}/messages \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data @- <<EOF
{
"message": "I've attached the tracking screenshot showing no movement for 10 days."
}
EOFimport requests
url = "https://api.tybritelabs.com/v1/disputes/{id}/messages"
payload = { "message": "I've attached the tracking screenshot showing no movement for 10 days." }
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({
message: 'I\'ve attached the tracking screenshot showing no movement for 10 days.'
})
};
fetch('https://api.tybritelabs.com/v1/disputes/{id}/messages', 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/disputes/{id}/messages",
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([
'message' => 'I\'ve attached the tracking screenshot showing no movement for 10 days.'
]),
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/disputes/{id}/messages"
payload := strings.NewReader("{\n \"message\": \"I've attached the tracking screenshot showing no movement for 10 days.\"\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/disputes/{id}/messages")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"message\": \"I've attached the tracking screenshot showing no movement for 10 days.\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.tybritelabs.com/v1/disputes/{id}/messages")
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 \"message\": \"I've attached the tracking screenshot showing no movement for 10 days.\"\n}"
response = http.request(request)
puts response.read_body{
"data": {
"thread_id": "5f0d2a11-3c9e-4b7a-9d21-6d0f2c8b4a10",
"sent": true
}
}{
"error": {
"code": "invalid_request",
"message": "Invalid request parameters",
"details": "The 'email' field is required"
}
}{
"error": {
"code": "unauthorized",
"message": "Missing or invalid Authorization header"
}
}{
"error": {
"code": "not_found",
"message": "Resource not found"
}
}{
"error": {
"code": "conflict",
"message": "A customer with this email already exists for this store"
}
}{
"error": {
"code": "server_error",
"message": "An unexpected error occurred"
}
}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 token. Provide exactly one of x-auth-token, x-external-auth, or x-idp-token.
Bring-your-own-auth assertion. Provide exactly one of x-auth-token, x-external-auth, or x-idp-token.
A raw token from the store's own identity provider (e.g. a Firebase ID token). Galactic Core forwards it to the store's configured Auth verifier, which validates it and returns the identity.
Verification is fail-closed: if the verifier rejects the token or is unreachable, the request is unauthenticated (401). Requires an Auth verifier to be configured for the store. Provide exactly one of x-auth-token, x-external-auth, or x-idp-token.
Path Parameters
The dispute id.
Query Parameters
Marketplace operator key only. The merchant the shopper is acting at.
Body
The message body.
Response
Message added successfully
Show child attributes
Show child attributes
curl --request POST \
--url https://api.tybritelabs.com/v1/disputes/{id}/messages \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data @- <<EOF
{
"message": "I've attached the tracking screenshot showing no movement for 10 days."
}
EOFimport requests
url = "https://api.tybritelabs.com/v1/disputes/{id}/messages"
payload = { "message": "I've attached the tracking screenshot showing no movement for 10 days." }
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({
message: 'I\'ve attached the tracking screenshot showing no movement for 10 days.'
})
};
fetch('https://api.tybritelabs.com/v1/disputes/{id}/messages', 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/disputes/{id}/messages",
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([
'message' => 'I\'ve attached the tracking screenshot showing no movement for 10 days.'
]),
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/disputes/{id}/messages"
payload := strings.NewReader("{\n \"message\": \"I've attached the tracking screenshot showing no movement for 10 days.\"\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/disputes/{id}/messages")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"message\": \"I've attached the tracking screenshot showing no movement for 10 days.\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.tybritelabs.com/v1/disputes/{id}/messages")
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 \"message\": \"I've attached the tracking screenshot showing no movement for 10 days.\"\n}"
response = http.request(request)
puts response.read_body{
"data": {
"thread_id": "5f0d2a11-3c9e-4b7a-9d21-6d0f2c8b4a10",
"sent": true
}
}{
"error": {
"code": "invalid_request",
"message": "Invalid request parameters",
"details": "The 'email' field is required"
}
}{
"error": {
"code": "unauthorized",
"message": "Missing or invalid Authorization header"
}
}{
"error": {
"code": "not_found",
"message": "Resource not found"
}
}{
"error": {
"code": "conflict",
"message": "A customer with this email already exists for this store"
}
}{
"error": {
"code": "server_error",
"message": "An unexpected error occurred"
}
}
