Newsletter
Subscribe
POST /access/api/v1/newsletter
Rate limited: 5 requests per IP per shop per hour.
Request body:
{
"email": "customer@example.com",
"_hp": ""
}
_hp is a honeypot field for bot protection. It must be present in the form but visually hidden, and must be submitted empty. Bots that auto-fill forms will fill it in, and those submissions are silently rejected.
<!-- Visually hide, do NOT use display:none (bots detect that) -->
<input
name="_hp"
tabindex="-1"
autocomplete="off"
style="opacity:0;position:absolute;height:0;width:0;"
/>
Response:
The API returns one of three messages depending on the subscriber's state:
{ "status": "success", "message": "Subscribed" }
{ "status": "success", "message": "Email not verified, new link sent" }
{ "status": "success", "message": "Subscription renewed" }
Show a generic "Check your inbox to confirm your subscription" message for all three — the distinction is internal.
Possible errors:
| Code | Meaning |
|---|---|
EMAIL_ALREADY_SUBSCRIBED | Email is already subscribed and verified |
NEWSLETTER_LIMIT_EXCEEDED | Shop's newsletter subscription limit reached |
NEWSLETTER_RATE_LIMITED | Too many attempts from this IP |
Verify subscription
PATCH /access/api/v1/newsletter/:id
Called when the customer clicks the confirmation link in the welcome email. Your /newsletter/verify page receives these query params from the API-generated email link:
/newsletter/verify?subscription=<id>&integrity=<integrityId>&email=<email>
Extract them and call this endpoint with :id = subscription:
Request body:
{
"email": "customer@example.com",
"integrityId": "69e8a7d9ab1adef7b2fb13b3"
}
Response:
{ "status": "success", "message": "Verified" }
Possible errors: SUBSCRIPTION_NOT_FOUND, SUBSCRIPTION_NOT_VALID
Unsubscribe
DELETE /access/api/v1/newsletter/:id
Called when the customer clicks the unsubscribe link. Your /newsletter/unsubscribe page receives these query params from the API-generated email link:
/newsletter/unsubscribe?subscription=<id>&email=<email>
Extract them and call this endpoint with :id = subscription:
Request body:
{ "email": "customer@example.com" }
Response:
{ "status": "success", "message": "Unsubscribed" }
Possible errors: SUBSCRIPTION_NOT_FOUND