Storefront loyalty
The signed-in shopper’s loyalty programme on a storefront: status (points, tier and progress, referral link), enrolment, rewards to redeem, referral info, social-share bonuses and paid membership plans. Every call needs the sales-channel id (vc_*) in the path and the browser Origin header. All of them except the public referral-link lookup (GET loyalty/referral-info, which takes a share code and no token) also need the shopper’s customer token (Authorization: Bearer) and act only on that shopper’s own account.
My loyalty status (includes referral share code + badges + paid membership)
Returns the signed-in customer loyalty status: points, tier and progress, referral share code and welcome coupon, badges and paid membership. Requires customers:auth.
Path Parameters
Sales channel ID (vc_*), the canonical salesChannelId. connectionId is the deprecated name of the same value and is still the literal path segment.
Header Parameters
Origin of the storefront page making the call, for example https://shop.example.com. Required: a request with no Origin header is refused with 403. On a LIVE channel its host must equal the channel's registered domain (or one of its subdomains) or match an allowed origin. A TEST channel with no domain accepts any origin; once a domain is set it is matched as on LIVE.
Customer token as Bearer <token>, returned by customers/login, customers/register or the OAuth callback. Expires after 7 days. It is a customer token, never an API key.
Version of the calling SDK (the Brainerce SDK sends it automatically). Informational: it is recorded on the channel and never changes the response.
curl -X GET "https://api.brainerce.com/api/vc/string/loyalty/me" \ -H "origin: string" \ -H "authorization: string" \ -H "X-SDK-Version: string"{
"enrolled": true,
"pointsBalance": 120,
"pendingPoints": 0,
"pendingPointsConfirmAt": "2019-08-24T14:15:22Z",
"lifetimeEarned": 340,
"program": {
"pointsName": "string",
"currencyRatio": 100,
"pendingDays": 14,
"status": "DRAFT"
},
"tier": {
"id": "string",
"name": "Gold",
"level": 2,
"pointsMultiplier": 1.5
},
"nextTier": {
"id": "string",
"name": "Gold",
"level": 2,
"pointsMultiplier": 1.5,
"qualificationType": "SPEND",
"qualificationThreshold": 500
},
"progressToNextTier": 0.4,
"pointsToNextTier": 0,
"paidMembership": {
"status": "ACTIVE",
"cancelAtPeriodEnd": true,
"nextBillingAt": "2019-08-24T14:15:22Z",
"subscribedAt": "2019-08-24T14:15:22Z",
"plan": {
"id": "string",
"name": "string",
"perksDescription": "string",
"priceAmount": 9.9,
"billingIntervalDays": 30,
"pointsMultiplier": 2
}
},
"referralCode": "string",
"referralWelcomeCoupon": {
"code": "string",
"type": "PERCENTAGE",
"value": 10
},
"badges": [
{
"id": "string",
"name": "string",
"description": "string",
"iconUrl": "string",
"awardedAt": "2019-08-24T14:15:22Z"
}
]
}{
"statusCode": 401,
"code": "UNAUTHORIZED",
"message": "Invalid or expired credential",
"timestamp": "2026-08-23T10:15:00.000Z",
"path": "/api/vc/{connectionId}/loyalty/me"
}{
"statusCode": 403,
"code": "INSUFFICIENT_SCOPE",
"message": "API key does not have the required scope: products:write",
"timestamp": "2026-08-23T10:15:00.000Z",
"path": "/api/vc/{connectionId}/loyalty/me"
}{
"statusCode": 404,
"code": "RESOURCE_NOT_FOUND",
"message": "Resource not found",
"timestamp": "2026-08-23T10:15:00.000Z",
"path": "/api/vc/{connectionId}/loyalty/me"
}{
"statusCode": 429,
"code": "RATE_LIMITED",
"message": "Too many requests",
"details": {
"retryAfterSeconds": 12
},
"timestamp": "2026-08-23T10:15:00.000Z",
"path": "/api/vc/{connectionId}/loyalty/me"
}Public referral-link lookup: referrer first name + welcome reward for a share code (no PII, no auth)
Looks up a referral share code from a referral link: the referrer first name and the welcome reward, or valid: false for an unknown code. No customer token and no PII. Limited to 10 requests per minute per IP. Checks no scope.
Path Parameters
Sales channel ID (vc_*), the canonical salesChannelId. connectionId is the deprecated name of the same value and is still the literal path segment.
Query Parameters
Referral share code from the link (REF-XXXXXXXX). Longer than 40 characters is invalid.
Header Parameters
Origin of the storefront page making the call, for example https://shop.example.com. Required: a request with no Origin header is refused with 403. On a LIVE channel its host must equal the channel's registered domain (or one of its subdomains) or match an allowed origin. A TEST channel with no domain accepts any origin; once a domain is set it is matched as on LIVE.
Version of the calling SDK (the Brainerce SDK sends it automatically). Informational: it is recorded on the channel and never changes the response.
curl -X GET "https://api.brainerce.com/api/vc/string/loyalty/referral-info?code=REF-ABCD1234" \ -H "origin: string" \ -H "X-SDK-Version: string"{
"valid": true,
"referrerFirstName": "string",
"reward": {
"name": "string",
"type": "FIXED_DISCOUNT",
"value": 10,
"minOrderAmount": 0
}
}{
"statusCode": 403,
"code": "INSUFFICIENT_SCOPE",
"message": "API key does not have the required scope: products:write",
"timestamp": "2026-08-23T10:15:00.000Z",
"path": "/api/vc/{connectionId}/loyalty/referral-info"
}{
"statusCode": 404,
"code": "RESOURCE_NOT_FOUND",
"message": "Resource not found",
"timestamp": "2026-08-23T10:15:00.000Z",
"path": "/api/vc/{connectionId}/loyalty/referral-info"
}{
"statusCode": 429,
"code": "RATE_LIMITED",
"message": "Too many requests",
"details": {
"retryAfterSeconds": 12
},
"timestamp": "2026-08-23T10:15:00.000Z",
"path": "/api/vc/{connectionId}/loyalty/referral-info"
}Enroll in the loyalty program (returns the same shape as GET /loyalty/me)
Enrolls the signed-in customer in the loyalty program (idempotent) and returns the same status as loyalty/me. Requires customers:auth.
Path Parameters
Sales channel ID (vc_*), the canonical salesChannelId. connectionId is the deprecated name of the same value and is still the literal path segment.
Header Parameters
Origin of the storefront page making the call, for example https://shop.example.com. Required: a request with no Origin header is refused with 403. On a LIVE channel its host must equal the channel's registered domain (or one of its subdomains) or match an allowed origin. A TEST channel with no domain accepts any origin; once a domain is set it is matched as on LIVE.
Customer token as Bearer <token>, returned by customers/login, customers/register or the OAuth callback. Expires after 7 days. It is a customer token, never an API key.
Version of the calling SDK (the Brainerce SDK sends it automatically). Informational: it is recorded on the channel and never changes the response.
curl -X POST "https://api.brainerce.com/api/vc/string/loyalty/enroll" \ -H "origin: string" \ -H "authorization: string" \ -H "X-SDK-Version: string"{
"enrolled": true,
"pointsBalance": 120,
"pendingPoints": 0,
"pendingPointsConfirmAt": "2019-08-24T14:15:22Z",
"lifetimeEarned": 340,
"program": {
"pointsName": "string",
"currencyRatio": 100,
"pendingDays": 14,
"status": "DRAFT"
},
"tier": {
"id": "string",
"name": "Gold",
"level": 2,
"pointsMultiplier": 1.5
},
"nextTier": {
"id": "string",
"name": "Gold",
"level": 2,
"pointsMultiplier": 1.5,
"qualificationType": "SPEND",
"qualificationThreshold": 500
},
"progressToNextTier": 0.4,
"pointsToNextTier": 0,
"paidMembership": {
"status": "ACTIVE",
"cancelAtPeriodEnd": true,
"nextBillingAt": "2019-08-24T14:15:22Z",
"subscribedAt": "2019-08-24T14:15:22Z",
"plan": {
"id": "string",
"name": "string",
"perksDescription": "string",
"priceAmount": 9.9,
"billingIntervalDays": 30,
"pointsMultiplier": 2
}
},
"referralCode": "string",
"referralWelcomeCoupon": {
"code": "string",
"type": "PERCENTAGE",
"value": 10
},
"badges": [
{
"id": "string",
"name": "string",
"description": "string",
"iconUrl": "string",
"awardedAt": "2019-08-24T14:15:22Z"
}
]
}{
"statusCode": 400,
"code": "VALIDATION_FAILED",
"message": "name should not be empty, price must be a positive number",
"timestamp": "2026-08-23T10:15:00.000Z",
"path": "/api/vc/{connectionId}/loyalty/enroll"
}{
"statusCode": 401,
"code": "UNAUTHORIZED",
"message": "Invalid or expired credential",
"timestamp": "2026-08-23T10:15:00.000Z",
"path": "/api/vc/{connectionId}/loyalty/enroll"
}{
"statusCode": 403,
"code": "INSUFFICIENT_SCOPE",
"message": "API key does not have the required scope: products:write",
"timestamp": "2026-08-23T10:15:00.000Z",
"path": "/api/vc/{connectionId}/loyalty/enroll"
}{
"statusCode": 404,
"code": "RESOURCE_NOT_FOUND",
"message": "Resource not found",
"timestamp": "2026-08-23T10:15:00.000Z",
"path": "/api/vc/{connectionId}/loyalty/enroll"
}{
"statusCode": 429,
"code": "RATE_LIMITED",
"message": "Too many requests",
"details": {
"retryAfterSeconds": 12
},
"timestamp": "2026-08-23T10:15:00.000Z",
"path": "/api/vc/{connectionId}/loyalty/enroll"
}Rewards I can redeem
Lists the active rewards the signed-in customer is allowed to redeem (their tier is high enough), cheapest first. Empty when the program is not active. Requires customers:auth.
Path Parameters
Sales channel ID (vc_*), the canonical salesChannelId. connectionId is the deprecated name of the same value and is still the literal path segment.
Header Parameters
Origin of the storefront page making the call, for example https://shop.example.com. Required: a request with no Origin header is refused with 403. On a LIVE channel its host must equal the channel's registered domain (or one of its subdomains) or match an allowed origin. A TEST channel with no domain accepts any origin; once a domain is set it is matched as on LIVE.
Customer token as Bearer <token>, returned by customers/login, customers/register or the OAuth callback. Expires after 7 days. It is a customer token, never an API key.
Version of the calling SDK (the Brainerce SDK sends it automatically). Informational: it is recorded on the channel and never changes the response.
curl -X GET "https://api.brainerce.com/api/vc/string/loyalty/rewards/available" \ -H "origin: string" \ -H "authorization: string" \ -H "X-SDK-Version: string"[
{
"id": "string",
"name": "string",
"description": "string",
"pointsCost": 500,
"type": "FIXED_DISCOUNT",
"discountValue": 10,
"minOrderAmount": 0,
"maxUsesPerUser": 1,
"isActive": true,
"minTierLevel": 0,
"createdAt": "2019-08-24T14:15:22Z",
"updatedAt": "2019-08-24T14:15:22Z"
}
]{
"statusCode": 401,
"code": "UNAUTHORIZED",
"message": "Invalid or expired credential",
"timestamp": "2026-08-23T10:15:00.000Z",
"path": "/api/vc/{connectionId}/loyalty/rewards/available"
}{
"statusCode": 403,
"code": "INSUFFICIENT_SCOPE",
"message": "API key does not have the required scope: products:write",
"timestamp": "2026-08-23T10:15:00.000Z",
"path": "/api/vc/{connectionId}/loyalty/rewards/available"
}{
"statusCode": 404,
"code": "RESOURCE_NOT_FOUND",
"message": "Resource not found",
"timestamp": "2026-08-23T10:15:00.000Z",
"path": "/api/vc/{connectionId}/loyalty/rewards/available"
}{
"statusCode": 429,
"code": "RATE_LIMITED",
"message": "Too many requests",
"details": {
"retryAfterSeconds": 12
},
"timestamp": "2026-08-23T10:15:00.000Z",
"path": "/api/vc/{connectionId}/loyalty/rewards/available"
}AI-recommended reward for me, always from the real catalog (rate-limited: spends merchant AI credits)
Picks one reward from the redeemable catalog for the customer, with AI when there are several. It spends merchant AI credits, so it is limited to 5 requests per minute per IP. The reward always comes from the real catalog. Requires customers:auth.
Path Parameters
Sales channel ID (vc_*), the canonical salesChannelId. connectionId is the deprecated name of the same value and is still the literal path segment.
Header Parameters
Origin of the storefront page making the call, for example https://shop.example.com. Required: a request with no Origin header is refused with 403. On a LIVE channel its host must equal the channel's registered domain (or one of its subdomains) or match an allowed origin. A TEST channel with no domain accepts any origin; once a domain is set it is matched as on LIVE.
Customer token as Bearer <token>, returned by customers/login, customers/register or the OAuth callback. Expires after 7 days. It is a customer token, never an API key.
Version of the calling SDK (the Brainerce SDK sends it automatically). Informational: it is recorded on the channel and never changes the response.
curl -X GET "https://api.brainerce.com/api/vc/string/loyalty/rewards/recommended" \ -H "origin: string" \ -H "authorization: string" \ -H "X-SDK-Version: string"{
"reward": {
"id": "string",
"name": "string",
"description": "string",
"pointsCost": 500,
"type": "FIXED_DISCOUNT",
"discountValue": 10,
"minOrderAmount": 0,
"maxUsesPerUser": 1,
"isActive": true,
"minTierLevel": 0,
"createdAt": "2019-08-24T14:15:22Z",
"updatedAt": "2019-08-24T14:15:22Z"
},
"reason": "string",
"source": "ai"
}{
"statusCode": 401,
"code": "UNAUTHORIZED",
"message": "Invalid or expired credential",
"timestamp": "2026-08-23T10:15:00.000Z",
"path": "/api/vc/{connectionId}/loyalty/rewards/recommended"
}{
"statusCode": 403,
"code": "INSUFFICIENT_SCOPE",
"message": "API key does not have the required scope: products:write",
"timestamp": "2026-08-23T10:15:00.000Z",
"path": "/api/vc/{connectionId}/loyalty/rewards/recommended"
}{
"statusCode": 404,
"code": "RESOURCE_NOT_FOUND",
"message": "Resource not found",
"timestamp": "2026-08-23T10:15:00.000Z",
"path": "/api/vc/{connectionId}/loyalty/rewards/recommended"
}{
"statusCode": 429,
"code": "RATE_LIMITED",
"message": "Too many requests",
"details": {
"retryAfterSeconds": 12
},
"timestamp": "2026-08-23T10:15:00.000Z",
"path": "/api/vc/{connectionId}/loyalty/rewards/recommended"
}{
"statusCode": 503,
"code": "INTERNAL_SERVER_ERROR",
"message": "Internal server error",
"timestamp": "2026-08-23T10:15:00.000Z",
"path": "/api/vc/{connectionId}/loyalty/rewards/recommended"
}Redeem a reward → one-time coupon
Redeems a reward: deducts its points and mints a one-time coupon bound to the customer. Requires customers:auth.
Path Parameters
Sales channel ID (vc_*), the canonical salesChannelId. connectionId is the deprecated name of the same value and is still the literal path segment.
Header Parameters
Origin of the storefront page making the call, for example https://shop.example.com. Required: a request with no Origin header is refused with 403. On a LIVE channel its host must equal the channel's registered domain (or one of its subdomains) or match an allowed origin. A TEST channel with no domain accepts any origin; once a domain is set it is matched as on LIVE.
Customer token as Bearer <token>, returned by customers/login, customers/register or the OAuth callback. Expires after 7 days. It is a customer token, never an API key.
Version of the calling SDK (the Brainerce SDK sends it automatically). Informational: it is recorded on the channel and never changes the response.
Reward to redeem, an id from loyalty/rewards/available. The points cost is deducted and a one-time coupon is minted.
curl -X POST "https://api.brainerce.com/api/vc/string/loyalty/redeem" \ -H "origin: string" \ -H "authorization: string" \ -H "X-SDK-Version: string" \ -H "Content-Type: application/json" \ -d '{ "rewardId": "clrew_abc123" }'{
"couponCode": "LOYALTY-1A2B3C4D5E",
"discountType": "FIXED_DISCOUNT",
"discountValue": 10,
"pointsSpent": 500,
"pointsBalance": 120
}{
"statusCode": 400,
"code": "VALIDATION_FAILED",
"message": "name should not be empty, price must be a positive number",
"timestamp": "2026-08-23T10:15:00.000Z",
"path": "/api/vc/{connectionId}/loyalty/redeem"
}{
"statusCode": 401,
"code": "UNAUTHORIZED",
"message": "Invalid or expired credential",
"timestamp": "2026-08-23T10:15:00.000Z",
"path": "/api/vc/{connectionId}/loyalty/redeem"
}{
"statusCode": 403,
"code": "INSUFFICIENT_SCOPE",
"message": "API key does not have the required scope: products:write",
"timestamp": "2026-08-23T10:15:00.000Z",
"path": "/api/vc/{connectionId}/loyalty/redeem"
}{
"statusCode": 404,
"code": "RESOURCE_NOT_FOUND",
"message": "Resource not found",
"timestamp": "2026-08-23T10:15:00.000Z",
"path": "/api/vc/{connectionId}/loyalty/redeem"
}{
"statusCode": 429,
"code": "RATE_LIMITED",
"message": "Too many requests",
"details": {
"retryAfterSeconds": 12
},
"timestamp": "2026-08-23T10:15:00.000Z",
"path": "/api/vc/{connectionId}/loyalty/redeem"
}Report a social share and grant the SOCIAL_SHARE earning-rule bonus (self-reported, once per customer)
Reports a social share and grants the social-share bonus of the program, once per customer. The share is self-reported and not verified. Requires customers:auth.
Path Parameters
Sales channel ID (vc_*), the canonical salesChannelId. connectionId is the deprecated name of the same value and is still the literal path segment.
Header Parameters
Origin of the storefront page making the call, for example https://shop.example.com. Required: a request with no Origin header is refused with 403. On a LIVE channel its host must equal the channel's registered domain (or one of its subdomains) or match an allowed origin. A TEST channel with no domain accepts any origin; once a domain is set it is matched as on LIVE.
Customer token as Bearer <token>, returned by customers/login, customers/register or the OAuth callback. Expires after 7 days. It is a customer token, never an API key.
Version of the calling SDK (the Brainerce SDK sends it automatically). Informational: it is recorded on the channel and never changes the response.
Network the shopper shared on. Informational only: it is not stored and does not change the bonus.
length <= 40curl -X POST "https://api.brainerce.com/api/vc/string/loyalty/social-share" \ -H "origin: string" \ -H "authorization: string" \ -H "X-SDK-Version: string" \ -H "Content-Type: application/json" \ -d '{}'{
"awarded": true,
"points": 50
}{
"statusCode": 400,
"code": "VALIDATION_FAILED",
"message": "name should not be empty, price must be a positive number",
"timestamp": "2026-08-23T10:15:00.000Z",
"path": "/api/vc/{connectionId}/loyalty/social-share"
}{
"statusCode": 401,
"code": "UNAUTHORIZED",
"message": "Invalid or expired credential",
"timestamp": "2026-08-23T10:15:00.000Z",
"path": "/api/vc/{connectionId}/loyalty/social-share"
}{
"statusCode": 403,
"code": "INSUFFICIENT_SCOPE",
"message": "API key does not have the required scope: products:write",
"timestamp": "2026-08-23T10:15:00.000Z",
"path": "/api/vc/{connectionId}/loyalty/social-share"
}{
"statusCode": 404,
"code": "RESOURCE_NOT_FOUND",
"message": "Resource not found",
"timestamp": "2026-08-23T10:15:00.000Z",
"path": "/api/vc/{connectionId}/loyalty/social-share"
}{
"statusCode": 429,
"code": "RATE_LIMITED",
"message": "Too many requests",
"details": {
"retryAfterSeconds": 12
},
"timestamp": "2026-08-23T10:15:00.000Z",
"path": "/api/vc/{connectionId}/loyalty/social-share"
}Paid membership plans I can subscribe to
Lists the active paid membership plans, cheapest first. Empty when the program is not active. Requires customers:auth.
Path Parameters
Sales channel ID (vc_*), the canonical salesChannelId. connectionId is the deprecated name of the same value and is still the literal path segment.
Header Parameters
Origin of the storefront page making the call, for example https://shop.example.com. Required: a request with no Origin header is refused with 403. On a LIVE channel its host must equal the channel's registered domain (or one of its subdomains) or match an allowed origin. A TEST channel with no domain accepts any origin; once a domain is set it is matched as on LIVE.
Customer token as Bearer <token>, returned by customers/login, customers/register or the OAuth callback. Expires after 7 days. It is a customer token, never an API key.
Version of the calling SDK (the Brainerce SDK sends it automatically). Informational: it is recorded on the channel and never changes the response.
curl -X GET "https://api.brainerce.com/api/vc/string/loyalty/membership/plans" \ -H "origin: string" \ -H "authorization: string" \ -H "X-SDK-Version: string"[
{
"id": "string",
"name": "string",
"perksDescription": "string",
"priceAmount": 9.9,
"billingIntervalDays": 30,
"pointsMultiplier": 2
}
]{
"statusCode": 401,
"code": "UNAUTHORIZED",
"message": "Invalid or expired credential",
"timestamp": "2026-08-23T10:15:00.000Z",
"path": "/api/vc/{connectionId}/loyalty/membership/plans"
}{
"statusCode": 403,
"code": "INSUFFICIENT_SCOPE",
"message": "API key does not have the required scope: products:write",
"timestamp": "2026-08-23T10:15:00.000Z",
"path": "/api/vc/{connectionId}/loyalty/membership/plans"
}{
"statusCode": 404,
"code": "RESOURCE_NOT_FOUND",
"message": "Resource not found",
"timestamp": "2026-08-23T10:15:00.000Z",
"path": "/api/vc/{connectionId}/loyalty/membership/plans"
}{
"statusCode": 429,
"code": "RATE_LIMITED",
"message": "Too many requests",
"details": {
"retryAfterSeconds": 12
},
"timestamp": "2026-08-23T10:15:00.000Z",
"path": "/api/vc/{connectionId}/loyalty/membership/plans"
}My saved payment methods (display fields only) for the subscribe flow
Lists the active saved cards of the signed-in customer (display fields only) for the subscribe flow. Requires customers:auth.
Path Parameters
Sales channel ID (vc_*), the canonical salesChannelId. connectionId is the deprecated name of the same value and is still the literal path segment.
Header Parameters
Origin of the storefront page making the call, for example https://shop.example.com. Required: a request with no Origin header is refused with 403. On a LIVE channel its host must equal the channel's registered domain (or one of its subdomains) or match an allowed origin. A TEST channel with no domain accepts any origin; once a domain is set it is matched as on LIVE.
Customer token as Bearer <token>, returned by customers/login, customers/register or the OAuth callback. Expires after 7 days. It is a customer token, never an API key.
Version of the calling SDK (the Brainerce SDK sends it automatically). Informational: it is recorded on the channel and never changes the response.
curl -X GET "https://api.brainerce.com/api/vc/string/loyalty/membership/payment-methods" \ -H "origin: string" \ -H "authorization: string" \ -H "X-SDK-Version: string"[
{
"id": "string",
"paymentMethod": "credit_card",
"brand": "visa",
"last4": "4242",
"expMonth": 0,
"expYear": 0,
"isDefault": true
}
]{
"statusCode": 401,
"code": "UNAUTHORIZED",
"message": "Invalid or expired credential",
"timestamp": "2026-08-23T10:15:00.000Z",
"path": "/api/vc/{connectionId}/loyalty/membership/payment-methods"
}{
"statusCode": 403,
"code": "INSUFFICIENT_SCOPE",
"message": "API key does not have the required scope: products:write",
"timestamp": "2026-08-23T10:15:00.000Z",
"path": "/api/vc/{connectionId}/loyalty/membership/payment-methods"
}{
"statusCode": 404,
"code": "RESOURCE_NOT_FOUND",
"message": "Resource not found",
"timestamp": "2026-08-23T10:15:00.000Z",
"path": "/api/vc/{connectionId}/loyalty/membership/payment-methods"
}{
"statusCode": 429,
"code": "RATE_LIMITED",
"message": "Too many requests",
"details": {
"retryAfterSeconds": 12
},
"timestamp": "2026-08-23T10:15:00.000Z",
"path": "/api/vc/{connectionId}/loyalty/membership/payment-methods"
}Subscribe to a paid membership plan, charging the saved card immediately (409 with a code on decline/SCA)
Subscribes the customer to a paid membership plan and charges the chosen saved card immediately. A declined card or one that needs extra authentication answers 409 with a code. Limited to 5 requests per minute per IP. Requires customers:auth.
Path Parameters
Sales channel ID (vc_*), the canonical salesChannelId. connectionId is the deprecated name of the same value and is still the literal path segment.
Header Parameters
Origin of the storefront page making the call, for example https://shop.example.com. Required: a request with no Origin header is refused with 403. On a LIVE channel its host must equal the channel's registered domain (or one of its subdomains) or match an allowed origin. A TEST channel with no domain accepts any origin; once a domain is set it is matched as on LIVE.
Customer token as Bearer <token>, returned by customers/login, customers/register or the OAuth callback. Expires after 7 days. It is a customer token, never an API key.
Version of the calling SDK (the Brainerce SDK sends it automatically). Informational: it is recorded on the channel and never changes the response.
Paid membership plan to subscribe to, an id from loyalty/membership/plans.
Saved card to charge now and for every cycle, an id from loyalty/membership/payment-methods. It must belong to the calling customer.
curl -X POST "https://api.brainerce.com/api/vc/string/loyalty/membership/subscribe" \ -H "origin: string" \ -H "authorization: string" \ -H "X-SDK-Version: string" \ -H "Content-Type: application/json" \ -d '{ "planId": "clplan_abc123", "savedPaymentTokenId": "cltok_abc123" }'{
"status": "ACTIVE",
"cancelAtPeriodEnd": true,
"nextBillingAt": "2019-08-24T14:15:22Z",
"subscribedAt": "2019-08-24T14:15:22Z",
"plan": {
"id": "string",
"name": "string",
"perksDescription": "string",
"priceAmount": 9.9,
"billingIntervalDays": 30,
"pointsMultiplier": 2
}
}{
"statusCode": 400,
"code": "VALIDATION_FAILED",
"message": "name should not be empty, price must be a positive number",
"timestamp": "2026-08-23T10:15:00.000Z",
"path": "/api/vc/{connectionId}/loyalty/membership/subscribe"
}{
"statusCode": 401,
"code": "UNAUTHORIZED",
"message": "Invalid or expired credential",
"timestamp": "2026-08-23T10:15:00.000Z",
"path": "/api/vc/{connectionId}/loyalty/membership/subscribe"
}{
"statusCode": 403,
"code": "INSUFFICIENT_SCOPE",
"message": "API key does not have the required scope: products:write",
"timestamp": "2026-08-23T10:15:00.000Z",
"path": "/api/vc/{connectionId}/loyalty/membership/subscribe"
}{
"statusCode": 404,
"code": "RESOURCE_NOT_FOUND",
"message": "Resource not found",
"timestamp": "2026-08-23T10:15:00.000Z",
"path": "/api/vc/{connectionId}/loyalty/membership/subscribe"
}{
"statusCode": 409,
"code": "CONFLICT",
"message": "The request conflicts with the current state of the resource",
"timestamp": "2026-08-23T10:15:00.000Z",
"path": "/api/vc/{connectionId}/loyalty/membership/subscribe"
}{
"statusCode": 429,
"code": "RATE_LIMITED",
"message": "Too many requests",
"details": {
"retryAfterSeconds": 12
},
"timestamp": "2026-08-23T10:15:00.000Z",
"path": "/api/vc/{connectionId}/loyalty/membership/subscribe"
}{
"statusCode": 503,
"code": "INTERNAL_SERVER_ERROR",
"message": "Internal server error",
"timestamp": "2026-08-23T10:15:00.000Z",
"path": "/api/vc/{connectionId}/loyalty/membership/subscribe"
}Cancel my paid membership (keeps perks until the period ends)
Cancels the paid membership. Perks last until the end of the paid period, unless the membership is past due, which cancels it at once. Requires customers:auth.
Path Parameters
Sales channel ID (vc_*), the canonical salesChannelId. connectionId is the deprecated name of the same value and is still the literal path segment.
Header Parameters
Origin of the storefront page making the call, for example https://shop.example.com. Required: a request with no Origin header is refused with 403. On a LIVE channel its host must equal the channel's registered domain (or one of its subdomains) or match an allowed origin. A TEST channel with no domain accepts any origin; once a domain is set it is matched as on LIVE.
Customer token as Bearer <token>, returned by customers/login, customers/register or the OAuth callback. Expires after 7 days. It is a customer token, never an API key.
Version of the calling SDK (the Brainerce SDK sends it automatically). Informational: it is recorded on the channel and never changes the response.
curl -X POST "https://api.brainerce.com/api/vc/string/loyalty/membership/cancel" \ -H "origin: string" \ -H "authorization: string" \ -H "X-SDK-Version: string"{
"status": "ACTIVE",
"cancelAtPeriodEnd": true,
"nextBillingAt": "2019-08-24T14:15:22Z",
"subscribedAt": "2019-08-24T14:15:22Z",
"plan": {
"id": "string",
"name": "string",
"perksDescription": "string",
"priceAmount": 9.9,
"billingIntervalDays": 30,
"pointsMultiplier": 2
}
}{
"statusCode": 401,
"code": "UNAUTHORIZED",
"message": "Invalid or expired credential",
"timestamp": "2026-08-23T10:15:00.000Z",
"path": "/api/vc/{connectionId}/loyalty/membership/cancel"
}{
"statusCode": 403,
"code": "INSUFFICIENT_SCOPE",
"message": "API key does not have the required scope: products:write",
"timestamp": "2026-08-23T10:15:00.000Z",
"path": "/api/vc/{connectionId}/loyalty/membership/cancel"
}{
"statusCode": 404,
"code": "RESOURCE_NOT_FOUND",
"message": "Resource not found",
"timestamp": "2026-08-23T10:15:00.000Z",
"path": "/api/vc/{connectionId}/loyalty/membership/cancel"
}{
"statusCode": 429,
"code": "RATE_LIMITED",
"message": "Too many requests",
"details": {
"retryAfterSeconds": 12
},
"timestamp": "2026-08-23T10:15:00.000Z",
"path": "/api/vc/{connectionId}/loyalty/membership/cancel"
}Mint a short-lived widget session for the embeddable loyalty widget. Pass the returned sessionId as the iframe URL path segment, never the real customerToken
Mints a short-lived session for the embeddable loyalty widget. Put the returned sessionId in the iframe URL, never the real customer token. Requires customers:auth.
Path Parameters
Sales channel ID (vc_*), the canonical salesChannelId. connectionId is the deprecated name of the same value and is still the literal path segment.
Header Parameters
Origin of the storefront page making the call, for example https://shop.example.com. Required: a request with no Origin header is refused with 403. On a LIVE channel its host must equal the channel's registered domain (or one of its subdomains) or match an allowed origin. A TEST channel with no domain accepts any origin; once a domain is set it is matched as on LIVE.
Customer token as Bearer <token>, returned by customers/login, customers/register or the OAuth callback. Expires after 7 days. It is a customer token, never an API key.
Version of the calling SDK (the Brainerce SDK sends it automatically). Informational: it is recorded on the channel and never changes the response.
curl -X POST "https://api.brainerce.com/api/vc/string/loyalty/widget-session" \ -H "origin: string" \ -H "authorization: string" \ -H "X-SDK-Version: string"{
"sessionId": "string",
"expiresAt": "2019-08-24T14:15:22Z",
"storeId": "string"
}{
"statusCode": 401,
"code": "UNAUTHORIZED",
"message": "Invalid or expired credential",
"timestamp": "2026-08-23T10:15:00.000Z",
"path": "/api/vc/{connectionId}/loyalty/widget-session"
}{
"statusCode": 403,
"code": "INSUFFICIENT_SCOPE",
"message": "API key does not have the required scope: products:write",
"timestamp": "2026-08-23T10:15:00.000Z",
"path": "/api/vc/{connectionId}/loyalty/widget-session"
}{
"statusCode": 404,
"code": "RESOURCE_NOT_FOUND",
"message": "Resource not found",
"timestamp": "2026-08-23T10:15:00.000Z",
"path": "/api/vc/{connectionId}/loyalty/widget-session"
}{
"statusCode": 429,
"code": "RATE_LIMITED",
"message": "Too many requests",
"details": {
"retryAfterSeconds": 12
},
"timestamp": "2026-08-23T10:15:00.000Z",
"path": "/api/vc/{connectionId}/loyalty/widget-session"
}