403 with
code: FEATURE_LOCKED and details.requiredPlan. Reads, deletes and CSV
exports are never gated.
Unique coupons
Turn a discount into a unique-per-recipient discount:code becomes the prefix of each one-time code and no longer works by itself.
In emails,
{{unique_coupon:<discountId>}} issues one code per recipient at
send time and {{unique_coupon_url:<discountId>}} links to checkout with it.
At checkout
GET /discounts/apply/{code}/{productId}?email= (public) resolves a one-time
code only for its email:
Creating a checkout reserves the code (and a personal offer) for that
checkout for 30 minutes, so two checkouts opened at once can’t both be paid
at the discounted price. The payment consumes it; a declined or abandoned
checkout gives it back.
Personal deadlines
offer.type is percentage, fixed or price; fallback.type is
full_price, percentage or fixed; trigger.type is audience_joined,
lead_magnet (with productId) or automation_entered (with
automationId).
The personal link (?pf_sid=…) identifies the person on your store. It is
the same encrypted visitor token that browse abandonment uses, so one link
serves both. Without the server’s signing key, links are plain product links
(personalized: false) and personal offers don’t apply. The
offer itself is enforced from their server-side clock: after it ends, or once
they bought at the offer price, checkout charges the fallback price whatever
token they bring.
SDK and MCP
The MCP server exposeslist_unique_codes, generate_unique_codes,
list_personal_deadlines, create_personal_deadline, get_personal_deadline,
update_personal_deadline, delete_personal_deadline,
list_personal_deadline_entries, start_personal_deadline and
get_personal_deadline_link. The Node.js SDK gains the same operations in its
next release.