{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":[]},"type":"markdown"},"seo":{"title":"PERS API Changelog","llmstxt":{"hide":false,"sections":[{"title":"Table of contents","includeFiles":["**/*"],"excludeFiles":[]}],"excludeFiles":[]}},"dynamicMarkdocComponents":[],"compilationErrors":[],"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"pers-api-changelog","__idx":0},"children":["PERS API Changelog"]},{"$$mdtype":"Tag","name":"blockquote","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Public changelog for the PERS Platform API."," ","Tracking started April 2026."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Current Version:"]}," 2.0.17"]}]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"v2017---2026-06-03","__idx":1},"children":["v2.0.17 - 2026-06-03"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"-improvements","__idx":2},"children":["🔧 Improvements"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Enhanced Platform Detection"]},": Added automatic User-Agent parsing as fallback when SDK doesn't provide platform information (OS, browser, device type)"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Data Quality Tracking"]},": Platform data now includes quality indicator (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["platformSource: 'sdk' | 'auto'"]},") to distinguish authoritative vs auto-detected information"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Mobile Browser Tracking"]},": Mobile browsers (Chrome, Safari on phones/tablets) now correctly tracked as ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["channel: 'web'"]}," - check ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["platform.deviceType"]}," to distinguish mobile vs desktop web users"]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"-security","__idx":3},"children":["🔒 Security"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Added database-level unique email constraint per tenant to prevent duplicate registrations and race conditions"]}]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"v2017---2026-05-30","__idx":4},"children":["v2.0.17 - 2026-05-30"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"-new-features","__idx":5},"children":["✨ New Features"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Attribution Tracking"]},": New attribution tracking for analytics across all entities (users, claims, redemptions, bookings)"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["DataSource Headers"]},": SDK can send ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["x-source-channel"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["x-source"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["x-source-medium"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["x-source-campaign"]}," headers for campaign tracking"]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"-improvements-1","__idx":6},"children":["🔧 Improvements"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Auto-detects channel/source from User-Agent and Referer headers when SDK headers not provided"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Standalone serverless function for booking operations"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Users now have ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["registrationSource"]}," field for analytics"]}]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"v2015---2026-05-09","__idx":7},"children":["v2.0.15 - 2026-05-09"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"-new-features-1","__idx":8},"children":["✨ New Features"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Business Ownership"]},": Added ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["ownerBusinessId"]}," field to campaigns, redemptions, and token metadata for tracking which business owns/promotes the entity"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Owner Business Loading"]},": Added ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["?include=ownerBusiness"]}," query parameter to load owner business entity details"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Owner Business Filtering"]},": Added ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["?ownerBusinessId"]}," filter parameter to campaigns, redemptions, and token metadata endpoints"]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"️-breaking-changes","__idx":9},"children":["⚠️ Breaking Changes"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Deprecated CampaignBusinessEngagement"]},": Use ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["TriggerSource.businessId"]}," for business participation tracking instead"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Business Loading"]},": ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["?include=businesses"]}," now extracts business IDs from TriggerSources instead of deprecated CampaignBusinessEngagement"]}]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"v2014---2026-05-18","__idx":10},"children":["v2.0.14 - 2026-05-18"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"-new-features-2","__idx":11},"children":["✨ New Features"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Booking Terminology"]},": Renamed \"reservation\" to \"booking\" throughout the API for clarity"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Simplified Booking Types"]},": Booking requirement values now: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["'active'"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["'future'"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["'past'"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["'active_future'"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["'any'"]},", or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["null"]}," (removed ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["'none'"]},")"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Enhanced Redemption Includes"]},": Redemptions now support ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["?include=userInfo,booking"]}," to load user field validation and booking eligibility data"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Booking Query Filters"]},": ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["GET /bookings"]}," endpoint now supports ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["?userId"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["?businessId"]}," query parameters"]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"️-breaking-changes-1","__idx":12},"children":["⚠️ Breaking Changes"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Terminology Change"]},": All \"reservation\" references changed to \"booking\" (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["reservationRequirement"]}," → ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["bookingRequirement"]},")"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Removed Endpoint"]},": ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["GET /users/:id/bookings"]}," removed - use ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["GET /bookings?userId=:id"]}," instead"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Type Change"]},": ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["BookingRequirementType"]}," value ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["'none'"]}," removed - use ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["null"]}," instead"]}]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"v2013---2026-04-29","__idx":13},"children":["v2.0.13 - 2026-04-29"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"-new-features-3","__idx":14},"children":["✨ New Features"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Transaction Metadata URIs"]},": Added ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["metadataUri"]}," field to transactions for tracking IPFS/storage URLs of NFT metadata"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Structured Auth Errors"]},": Token refresh failures now return specific error codes (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["REFRESH_TOKEN_EXPIRED"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["REFRESH_TOKEN_REVOKED"]},") for programmatic detection"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Redemption Type Management"]},": Added ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PUT /redemptions/types/:id"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["DELETE /redemptions/types/:id"]}," endpoints for admin management"]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"-improvements-2","__idx":15},"children":["🔧 Improvements"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["DPoP Clock Tolerance"]},": Increased tolerance for corporate environments with clock drift (10 min past, 5 min future)"]}]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"v2012---2026-04-26","__idx":16},"children":["v2.0.12 - 2026-04-26"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"-new-features-4","__idx":17},"children":["✨ New Features"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Date Range Filtering"]},": Added ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["dateFrom"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["dateTo"]}," query parameters to campaign claims and redemption redeems endpoints"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Multi-Tag Filtering"]},": Added ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["tags"]}," parameter (OR match) on campaigns, redemptions, and businesses for flexible tag-based queries"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Business Search"]},": Added ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["search"]}," parameter to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["GET /businesses"]}," endpoint for name-based searching"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Immediate Activation"]},": Added ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["isActive"]}," option to activate redemptions and token metadata immediately upon creation"]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"-bug-fixes","__idx":18},"children":["🐛 Bug Fixes"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["User Endpoints"]},": Fixed ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PUT /users/me"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["POST /users/info"]},", and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PUT /users/:identifier"]}," to return virtual wallets in response"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Date Validation"]},": Invalid date formats now return proper ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["400 Bad Request"]}," errors instead of silently failing"]}]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"v2011---2026-04-25","__idx":19},"children":["v2.0.11 - 2026-04-25"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"-new-features-5","__idx":20},"children":["✨ New Features"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Custom Field Definitions"]},": Added support for custom user information fields with validation rules"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["User Info Validation"]},": New ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["POST /users/info"]}," endpoint for submitting and validating custom field data"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Geocoding v2"]},": Enhanced geocoding with support for address components, place IDs, and improved accuracy"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Analytics Enhancements"]},": Added ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["totalClaims"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["totalRedemptions"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["totalBurns"]}," metrics to user analytics"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Owner Business Filtering"]},": Analytics endpoints now support ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["ownerBusinessId"]}," filter for business-specific reporting"]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"-improvements-3","__idx":21},"children":["🔧 Improvements"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Auto-Enrichment"]},": Analytics results now automatically include campaign/redemption names and owner business IDs"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Transaction Status Filtering"]},": Analytics now filters to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["SUCCEEDED"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["BROADCASTED"]}," transactions by default"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["SQL Query Performance"]},": Fixed PostgreSQL column quoting and JOIN syntax for analytics queries"]}]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"v2010---2026-04-01","__idx":22},"children":["v2.0.10 - 2026-04-01"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"-new-features-6","__idx":23},"children":["✨ New Features"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["OIDC Discovery"]},": Added ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/.well-known/openid-configuration"]}," endpoint for enterprise SSO integration"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Webhook Metadata"]},": Webhook trigger endpoint now returns structured response with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["executionId"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["statusCode"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["durationMs"]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"-improvements-4","__idx":24},"children":["🔧 Improvements"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Improved platform stability for high-traffic multi-tenant scenarios"]}]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]}]},"headings":[{"value":"PERS API Changelog","id":"pers-api-changelog","depth":1},{"value":"v2.0.17 - 2026-06-03","id":"v2017---2026-06-03","depth":2},{"value":"🔧 Improvements","id":"-improvements","depth":3},{"value":"🔒 Security","id":"-security","depth":3},{"value":"v2.0.17 - 2026-05-30","id":"v2017---2026-05-30","depth":2},{"value":"✨ New Features","id":"-new-features","depth":3},{"value":"🔧 Improvements","id":"-improvements-1","depth":3},{"value":"v2.0.15 - 2026-05-09","id":"v2015---2026-05-09","depth":2},{"value":"✨ New Features","id":"-new-features-1","depth":3},{"value":"⚠️ Breaking Changes","id":"️-breaking-changes","depth":3},{"value":"v2.0.14 - 2026-05-18","id":"v2014---2026-05-18","depth":2},{"value":"✨ New Features","id":"-new-features-2","depth":3},{"value":"⚠️ Breaking Changes","id":"️-breaking-changes-1","depth":3},{"value":"v2.0.13 - 2026-04-29","id":"v2013---2026-04-29","depth":2},{"value":"✨ New Features","id":"-new-features-3","depth":3},{"value":"🔧 Improvements","id":"-improvements-2","depth":3},{"value":"v2.0.12 - 2026-04-26","id":"v2012---2026-04-26","depth":2},{"value":"✨ New Features","id":"-new-features-4","depth":3},{"value":"🐛 Bug Fixes","id":"-bug-fixes","depth":3},{"value":"v2.0.11 - 2026-04-25","id":"v2011---2026-04-25","depth":2},{"value":"✨ New Features","id":"-new-features-5","depth":3},{"value":"🔧 Improvements","id":"-improvements-3","depth":3},{"value":"v2.0.10 - 2026-04-01","id":"v2010---2026-04-01","depth":2},{"value":"✨ New Features","id":"-new-features-6","depth":3},{"value":"🔧 Improvements","id":"-improvements-4","depth":3}],"frontmatter":{"seo":{"title":"PERS API Changelog"}},"lastModified":"2026-06-03T06:51:55.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/8.changelog","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}