{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":[]},"type":"markdown"},"seo":{"title":"Versioning and compatibility","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":"versioning-and-compatibility","__idx":0},"children":["Versioning and compatibility"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This page is the stability contract for the Rho API. It states what may change in a released"," ","version, what may not, and the notice you can expect before anything is deprecated."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"versioning-model","__idx":1},"children":["Versioning model"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The Rho API is versioned per release; today that's the URL path ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/api/v1"]},". The current version is ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["v1"]},"."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["v1"]}," is stable and additive-only"]},". A request that works today keeps working. Changes that would"," ","break existing code require a ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["new API version"]},"; we do not ship them into ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/api/v1"]},"."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Any ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["v1"]}," deprecation or sunset comes with ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["at least 15 days' notice"]}," before the change takes effect."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"what-can-change-without-a-new-version","__idx":2},"children":["What can change without a new version"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The following are ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["non-breaking"]}," and can ship into ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["v1"]}," at any time. Build your app so these"," ","never break it:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["A new enum value."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["A new nullable response field."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["A new optional query parameter."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"what-requires-a-new-version","__idx":3},"children":["What requires a new version"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The following are ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["breaking"]},". They will not ship into ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["v1"]},"; they require a new API version:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Removing or renaming an enum value."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Removing a response field."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Changing a field's type."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Making an optional field required."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"client-obligations","__idx":4},"children":["Client obligations"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Because the additive changes above ship without a version bump, write your code to tolerate them:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Handle unknown enum values gracefully."]}," A value set grows as Rho adds new products and rails, so"," ","a field such as ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["transaction_type"]}," can return a value your code has not seen before. Give any"," ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["switch"]}," on it a default case so a new value shows up as unknown rather than an error."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Handle new response fields gracefully."]}," Ignore fields you do not recognize rather than failing to"," ","parse the response, so a field added later never breaks deserialization."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Treat IDs as opaque strings."]}," Do not parse structure out of an ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["id"]}," or assume a fixed format; use"," ","it only as a whole value to look records up and reference them."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Store IDs as-is."]}," Persist the full string exactly as returned, without assuming a fixed length or"," ","layout."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"mcp-parity","__idx":5},"children":["MCP parity"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The MCP server is 1:1 with the REST API, so the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/mcp/v1"]}," tool schemas follow the same policy as the"," ","REST contracts above: additive-only, with breaking changes requiring a new version. One policy covers"," ","both surfaces."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Tool ",{"$$mdtype":"Tag","name":"em","attributes":{},"children":["names"]}," derive from the frozen ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["v1"]}," operationIds, so ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["tool names will never change"]},". You can"," ","reference them explicitly in workflows, agent skills, and saved automations without them breaking."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Tool ",{"$$mdtype":"Tag","name":"em","attributes":{},"children":["descriptions"]}," are not part of the contract - they may be improved at any time to help agents use"," ","the tools well, and such changes are never treated as breaking."]}]},"headings":[{"value":"Versioning and compatibility","id":"versioning-and-compatibility","depth":1},{"value":"Versioning model","id":"versioning-model","depth":2},{"value":"What can change without a new version","id":"what-can-change-without-a-new-version","depth":2},{"value":"What requires a new version","id":"what-requires-a-new-version","depth":2},{"value":"Client obligations","id":"client-obligations","depth":2},{"value":"MCP parity","id":"mcp-parity","depth":2}],"frontmatter":{"seo":{"title":"Versioning and compatibility"}},"lastModified":"2026-07-29T13:58:14.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/docs/v1/versioning","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}