Loyalty when AI agents shop
More and more orders are placed by an AI agent on the shopper’s behalf: ChatGPT, Gemini, Copilot or the Shop app finds the product, fills the cart and checks out. Nobody sees your theme, the Charm widget or a discount field. This page explains what still works, what does not, and how agents can read a member’s loyalty status through the Universal Commerce Protocol (UCP).
What members keep automatically
Section titled “What members keep automatically”Charm’s tier and membership perks run as an automatic Shopify discount (a Discount Function) tied to the customer, not to a code. Whenever the checkout knows who the buyer is, they apply, whether a person or an agent is at the keyboard:
| Perk | In an AI-agent checkout |
|---|---|
| Tier or membership percentage or fixed discount | Applies when the buyer is identified |
| Member pricing on products or collections | Applies when the buyer is identified |
| Free shipping for a tier or membership | Applies when the buyer is identified |
| Points for the order, tier progress, cashback | Awarded after the order, as always |
| Store credit | Spent by Shopify for a signed-in buyer |
Fixed amounts and minimum order values are converted to the currency the agent checks out in, so a 10 EUR tier discount is worth the same in a CZK or USD checkout.
Identified means the checkout carries the Shopify customer: the shopper signed in, or the agent platform linked their Shopify identity (Shopify’s buyer-linked checkout does this and applies automatic discounts). A guest checkout with only an email address gets no member perks, exactly as on your own storefront.
What needs the shopper
Section titled “What needs the shopper”- Discount codes from points redemptions, birthdays, milestones and tier gifts are bound to the customer but must still be entered. An agent can apply a code the shopper gives it; it cannot discover one on its own.
- Members-only products are hidden by your theme. An agent does not see the theme, so the product is not blocked in an agent checkout.
- Referral and affiliate links attribute through the storefront. In an agent checkout, the friend’s or affiliate’s code attributes the order instead.
The UCP loyalty extension
Section titled “The UCP loyalty extension”The Universal Commerce Protocol (Google and Shopify) is how
AI agents talk to stores about catalog, cart and checkout. Its loyalty
extension, dev.ucp.common.loyalty, lets a store tell the agent which
membership and tier the buyer holds, what the benefits are and how many
points the cart will earn, so the agent can say “you’re Gold, this order earns
240 points” before the buyer commits.
Charm returns exactly that object:
curl -X POST "https://charm.appfleece.app/api/v1/customers/7712345/ucp-loyalty" \ -H "Authorization: Bearer chrm_live_..." \ -H "Content-Type: application/json" \ -d '{ "line_items": [{ "product_id": "8123456789", "price": 60, "quantity": 2 }] }'{ "loyalty": { "com.myshopify.your-store.loyalty": { "id": "mbr_3f9a61c0d2e4b7a8", "name": "Rewards Club", "display_id": "****2345", "tiers": [ { "id": "gold", "name": "Gold", "benefits": [ { "id": "points_multiplier", "description": "2× points on every order" }, { "id": "benefit_free_shipping", "description": "Free shipping" } ] } ], "rewards": [ { "currency": { "name": "points", "code": "PTS", "decimal_places": 0 }, "earning_forecast": { "amount": 240, "breakdown": [ { "id": "base", "amount": 120, "description": "1 points per EUR spent" }, { "id": "tier_multiplier", "amount": 120, "description": "Gold bonus (2× points)", "benefit_id": "points_multiplier" } ] } } ], "provisional": false } }, "messages": [ { "type": "info", "code": "membership_benefit_eligible", "path": "$.loyalty['com.myshopify.your-store.loyalty']", "content": "Gold: 2× points apply to this order." } ]}| UCP field | What Charm puts there |
|---|---|
| map key | com.myshopify.<your-handle>.loyalty, the claim id an agent sends in context.eligibility |
id | An opaque member id, stable per customer, never the Shopify id |
display_id | The last four digits of the customer id, masked |
tiers | The tier the member holds, with its benefits as display text |
rewards[].currency | Your points name |
rewards[].earning_forecast | Points the cart would earn; the breakdown rows add up to the total |
provisional | false: Charm answers only for a customer the caller identified |
The balance is deliberately absent: UCP models spendable value as a payment method or a future redemption capability, not as loyalty data.
A buyer who is not a member gets an empty loyalty map and an
eligibility_invalid message, as the specification asks.
Endpoints
Section titled “Endpoints”GET /customers/{customer_id}/ucp-loyalty: membership and tierPOST /customers/{customer_id}/ucp-loyalty: the same, with the earning forecast for a cartPOST /estimates: the plain points estimate for a cart, without the UCP wrapping
All three accept a customer session token, so a shopper-facing app can call them for its own customer. None of them calls Shopify, and nothing is written.
Who serves it to agents
Section titled “Who serves it to agents”Shopify answers UCP requests for stores on its agentic channels. Today Shopify does not yet offer apps a documented way to contribute the loyalty extension; we are working with Shopify on it, and the object above is ready to pass through the day it opens. If you run your own UCP server (headless or custom commerce), return this object unchanged in your catalog, cart and checkout responses.