Skip to main content

API early May 2026 improvements (1.6.4)

Sam Critchley
Co-Founder

Additional API features, improvements and fixes that shipped to production in early May 2026, on top of the earlier mid April 2026 release.

  • Added stateless JWT-based shopper authentication, allowing chains to configure trusted JWT issuers via jwt_jwks_url, jwt_issuer, and optional jwt_audience fields on alter-chain and get-chain. Shopper JWTs are validated using JWKS with automatic key-rotation support, and alter-user enforces an explicit customer_profile.write scope when called with JWT authentication.
  • Added a fixed_value calculation method to composable campaign reward methods, alongside the existing basket-value and items-value methods.
  • Added a context field to composable campaigns, with context-based filtering of available restrictions and reward methods.
  • Changed composable campaign budget and usage-limit configuration to be set at the reward-method level rather than the campaign level.
  • Changed admin and user permission payloads so that the legacy empty businesses block is no longer included in auth/login, auth/session, auth/get-user-permissions, and get-user responses for API version 1.6.4 and above. Older versions still return businesses: null for compatibility.
  • Improved phone-number verification so that re-submitting the same phone number on alter-user or add-user preserves the VERIFIED status instead of resetting to VALIDATED, avoiding unnecessary OTP re-verification.
  • Improved phone-number validation so that invalid phone numbers submitted via legacy API versions (below 1.6.1) are now stored with INVALID status instead of UNCHECKED, giving better data visibility.
  • Improved Stripe subscription handling to fix cancellation webhooks silently failing when a subscription's annual expiry had passed, and to prevent duplicate Stripe subscriptions being created by failed renewal retries.
  • Fixed composable campaign segment-restriction evaluation returning an incorrect type when the segment response was empty, which could cause campaigns with segment restrictions to behave unexpectedly.