Goal

Subscribe to or unsubscribe from changelog release announcements with a single API call. The Astro Subscribe button on /<locale>/changelog uses these endpoints under the hood; the same flow is available to any cookie-authenticated client.

Both endpoints require cookie authentication (app_token). API keys are not accepted (this is a per-user setting, not a machine-to-machine surface).

Prerequisites

  • An active user session (valid app_token cookie) — log in via /login first.
  • The app_csrf cookie is set by the same login flow and is read client-side for the X-CSRF-Token header.

Steps

1. Read your current subscription status

curl -s -X GET 'https://api.example.com/v1/users/me/changelog/subscribe-status' \
  -H 'Cookie: app_token=<your-token>'

Response (200):

{
  "data": {
    "type": "changelog_subscription_status",
    "id": "<user_id>",
    "attributes": {
      "subscribed": true,
      "channels": {
        "in_app": true,
        "email": true
      }
    }
  }
}

subscribed is true only when both channels are enabled. The two-channel coupling is intentional — the Subscribe button is a coarse all-or-nothing control. If you need per-channel control (e.g. in-app only, no email), use the granular notification preferences API instead.

2. Toggle the subscription

curl -s -X POST 'https://api.example.com/v1/users/me/changelog/subscribe' \
  -H 'Cookie: app_token=<your-token>; app_csrf=<your-csrf>' \
  -H 'X-CSRF-Token: <your-csrf>' \
  -H 'Content-Type: application/json' \
  -d '{"enabled": true}'
  • enabled: true enables BOTH changelog.release_published.in_app AND changelog.digest_monthly.email preferences.
  • enabled: false disables BOTH.
  • The response shape matches the subscribe-status endpoint, with subscribed reflecting the new state.

The toggle is idempotent — calling with the same value as the current state is a no-op (no audit event is emitted when nothing changes).

Errors

StatusCodeCause
401unauthorizedMissing or invalid cookie.
401csrf_missing / csrf_mismatchPOST without a valid X-CSRF-Token header.
422invalid_enabledBody missing enabled, or value is not a boolean.