Get customer details
Returns the authenticated customer’s profile + store-level metrics.
Customer-self authentication required. Provide exactly one of:
x-auth-token— Galactic Core customer session JWT (issued by/v1/auth/loginor/v1/auth/verify-otp). The token must resolve to a customer whoseidequals the{id}path parameter.x-external-auth— bring-your-own-auth assertion: a base64url-encoded JSON claim{external_id, iat, exp}followed by.and the base64url HMAC-SHA256 signature of the claim using the store’shmac_secret. Theexternal_idmust resolve to a customer whoseidequals the{id}path parameter. The claim’s lifetime (exp - iat) must not exceed 300s.x-idp-token— a raw token from the store’s own identity provider. Galactic Core forwards it to the store’s configured Auth verifier, which validates it and returns the identity; the resolved customer must equal the{id}path parameter. Verification is fail-closed — if the verifier rejects the token or is unreachable, the request is unauthenticated (401). Requires the store to have an Auth verifier configured.
Mismatch returns 403. Providing more than one of these headers returns 400.
curl --request GET \
--url https://api.tybritelabs.com/v1/customers/{id} \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.tybritelabs.com/v1/customers/{id}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.tybritelabs.com/v1/customers/{id}', 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/customers/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
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://api.tybritelabs.com/v1/customers/{id}"
req, _ := http.NewRequest("GET", 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.get("https://api.tybritelabs.com/v1/customers/{id}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.tybritelabs.com/v1/customers/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"id": "de11e44b-78e5-4940-ad54-cac237d5d30d",
"name": "John Doe",
"email": "john.doe@example.com",
"phone": "+12125550142",
"status": "active",
"join_date": "2026-06-20",
"external_id": null,
"marketing_consent": true,
"total_purchases": 0,
"store_credit_balance": 0,
"created_at": "2026-06-20T13:47:38.831799+00:00",
"updated_at": "2026-06-20T13:47:38.831799+00:00"
}{
"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": "forbidden",
"message": "This operation requires a secret key. Publishable keys cover catalogue reads and the actions a shopper takes for themselves."
}
}{
"error": {
"code": "not_found",
"message": "Resource not found"
}
}{
"error": {
"code": "rate_limited",
"message": "Too many requests for this API key. Please slow down and try again shortly.",
"remaining": 0,
"reset": 1706198400
}
}{
"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
Galactic Core customer session access_token from /v1/auth/login or /v1/auth/verify-otp. The resolved customer must match the {id} path parameter. Provide exactly one of x-auth-token, x-external-auth, or x-idp-token.
Bring-your-own-auth assertion for stores that manage authentication in an external identity provider (Auth0, Clerk, Cognito, Firebase, NextAuth, SSO).
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 hmac_secret. Claim lifetime capped at 300 seconds. 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 against the provider and returns the identity; the resolved customer must match the {id} path parameter.
Use this when the store wants Galactic Core to verify tokens on its behalf rather than signing an assertion itself. 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
Query Parameters
Comma-separated list of fields to include in the response.
Allowed Fields:
id,name,email,phone,address,statusjoin_date,total_purchases,last_purchasecreated_at,updated_atstore_metrics,store_metrics.*
Response
Success
The customer's address, or null if not on file.
active, inactive The merchant's own fields on this record, with their values. Only fields the merchant published appear here. The merchant controls the names and how many exist, so render the array rather than reading fixed keys.
Show child attributes
Show child attributes
The customer's loyalty/spend tier, derived from their purchase history. New
customers start at bronze.
bronze, silver, gold, platinum "bronze"
Optional identifier from an external identity provider (Auth0, Clerk, Cognito, Firebase, NextAuth, etc). Unique per store + environment. Set this when you manage authentication outside Galactic Core and need a stable handle to map your upstream user back to the Galactic Core customer record.
"auth0|66a3f8c2b1d9c204a1f7e3d1"
Whether the customer has opted in to marketing communications. Defaults to false (opt-in). Set this from your storefront's marketing opt-in checkbox at sign-up, checkout, or in the customer's account preferences. When true, the customer is eligible to be subscribed to the store's connected marketing tools.
true
Timestamp of the customer's most recent purchase, or null if they have not purchased yet.
The customer's total redeemable store-credit balance. Store credit is
issued when a customer accepts a store-credit offer on a return, and can
be applied at checkout (see apply_store_credit on POST /v1/orders).
25
Aggregated purchase metrics for the customer, or null until they have purchase history.
Show child attributes
Show child attributes
Whether this customer record belongs to the live or test environment.
production, sandbox "production"
curl --request GET \
--url https://api.tybritelabs.com/v1/customers/{id} \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.tybritelabs.com/v1/customers/{id}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.tybritelabs.com/v1/customers/{id}', 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/customers/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
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://api.tybritelabs.com/v1/customers/{id}"
req, _ := http.NewRequest("GET", 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.get("https://api.tybritelabs.com/v1/customers/{id}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.tybritelabs.com/v1/customers/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"id": "de11e44b-78e5-4940-ad54-cac237d5d30d",
"name": "John Doe",
"email": "john.doe@example.com",
"phone": "+12125550142",
"status": "active",
"join_date": "2026-06-20",
"external_id": null,
"marketing_consent": true,
"total_purchases": 0,
"store_credit_balance": 0,
"created_at": "2026-06-20T13:47:38.831799+00:00",
"updated_at": "2026-06-20T13:47:38.831799+00:00"
}{
"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": "forbidden",
"message": "This operation requires a secret key. Publishable keys cover catalogue reads and the actions a shopper takes for themselves."
}
}{
"error": {
"code": "not_found",
"message": "Resource not found"
}
}{
"error": {
"code": "rate_limited",
"message": "Too many requests for this API key. Please slow down and try again shortly.",
"remaining": 0,
"reset": 1706198400
}
}{
"error": {
"code": "server_error",
"message": "An unexpected error occurred"
}
}
