{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-products/fincore/sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":[]},"type":"markdown"},"seo":{"title":"2026-03-11","siteUrl":"https://docs.monato.com","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":"2026-03-11","__idx":0},"children":["2026-03-11"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"summary","__idx":1},"children":["Summary"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This release updates the public Idempotency guide to better explain deterministic ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Idempotency-Key"]}," generation. The guide now clarifies that the request body must be canonicalized before hashing, and it includes clearer reference samples for Python and Node.js."]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"fixed","__idx":2},"children":["Fixed"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"idempotency-canonical-json-hashing-clarification--docs","__idx":3},"children":["Idempotency canonical JSON hashing clarification — ",{"$$mdtype":"Tag","name":"em","attributes":{},"children":["Fixed"]}," [Docs]"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Impact:"]}," The Idempotency guide now explains more precisely how to compute ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["body_hash"]},": the request body must be canonicalized before hashing, with object keys sorted alphabetically at every level and serialized consistently.",{"$$mdtype":"Tag","name":"br","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Action required:"]}," Review your implementation if you generate deterministic ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Idempotency-Key"]}," values client-side, especially in non-Python implementations.",{"$$mdtype":"Tag","name":"br","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["References:"]}," ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/products/fincore/guides/idempotency"]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"python-deterministic-key-generation-sample--docs","__idx":4},"children":["Python deterministic key generation sample — ",{"$$mdtype":"Tag","name":"em","attributes":{},"children":["Fixed"]}," [Docs]"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Impact:"]}," The Python sample now includes clearer inline comments and step-by-step guidance for generating a deterministic ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Idempotency-Key"]},". No backend behavior changed.",{"$$mdtype":"Tag","name":"br","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Action required:"]}," None, unless you want to align your implementation with the updated reference example.",{"$$mdtype":"Tag","name":"br","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["References:"]}," ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/products/fincore/guides/idempotency"]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"nodejs-deterministic-key-generation-sample--docs","__idx":5},"children":["Node.js deterministic key generation sample — ",{"$$mdtype":"Tag","name":"em","attributes":{},"children":["Fixed"]}," [Docs]"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Impact:"]}," The Node.js sample was updated to make the normalization logic clearer and align the example with canonical JSON hashing expectations described in the guide.",{"$$mdtype":"Tag","name":"br","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Action required:"]}," If you implemented the previous sample directly, verify that your body hashing logic produces the same deterministic output for semantically identical payloads, including nested objects.",{"$$mdtype":"Tag","name":"br","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["References:"]}," ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/products/fincore/guides/idempotency"]}]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"migration-notes","__idx":6},"children":["Migration notes"]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Canonicalize the request body before hashing"]}]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Sort object keys consistently before computing the SHA-256 hash."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Ensure semantically identical payloads generate the same ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["body_hash"]},"."]}]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Keep UUID v5 generation unchanged"]}]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Continue using:",{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["name = client_id + method + body_hash"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Idempotency-Key = UUIDv5(namespace, name)"]}]}]}]}]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Validate client-side implementations"]}]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["If you copied a previous example into production code, confirm it matches the canonicalization rules described in the updated guide."]}]}]}]}]},"headings":[{"value":"2026-03-11","id":"2026-03-11","depth":1},{"value":"Summary","id":"summary","depth":2},{"value":"Fixed","id":"fixed","depth":2},{"value":"Idempotency canonical JSON hashing clarification — [Docs]","id":"idempotency-canonical-json-hashing-clarification--docs","depth":3},{"value":"Python deterministic key generation sample — [Docs]","id":"python-deterministic-key-generation-sample--docs","depth":3},{"value":"Node.js deterministic key generation sample — [Docs]","id":"nodejs-deterministic-key-generation-sample--docs","depth":3},{"value":"Migration notes","id":"migration-notes","depth":2}],"frontmatter":{"title":"2026-03-11","description":"Idempotency documentation update: canonical JSON hashing clarification and improved deterministic key generation samples.","sidebar":"../sidebars.yaml","seo":{"title":"2026-03-11"}},"lastModified":"2026-03-12T00:22:00.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/products/fincore/changelog/2026-03-11","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}