Breaking changes - API
Moov reserves the right to make changes to our API at any time. Breaking changes disrupt existing integrations and require immediate updates to mitigate errors. Non-breaking changes enhance or extend the API without affecting current operations. Certain changes may straddle the line, making it essential to consider the context and usage patterns. This page covers various API change scenarios, identifying which changes are breaking and non-breaking.
Moov will communicate all breaking changes directly, in an appropriate time frame for customers to update their integrations accordingly. Breaking changes will also be announced in our changelog (subscribe for notifications).
Breaking changes
The following list has been established as breaking changes and will require action to remedy.
1. Removing an existing field
Example: Removing the lastName
field from the user profile API.
Outcome: Integrations that depend on this field will encounter errors or incomplete data.
2. Changing the data type of a field
Example: Changing the id
field from a string to an integer.
Outcome: Integrations expecting a string may fail to parse the new integer value.
3. Changing the structure of the response
Example: Modifying the response structure from a flat JSON to a nested JSON.
Outcome: Integrations that parse the response based on the old structure must adapt to the new structure.
4. Removing an endpoint
Example: Removing the GET /users/{userID}/profile
endpoint.
Outcome: Integrations that rely on this endpoint will no longer be able to retrieve user profiles.
5. Changing endpoint URLs
Example: Changing the endpoint URL from /user
to /profile/user
.
Outcome: Integrations will break if they have not been updated with a call to the new URL.
6. Modifying required fields in requests
Example: Making the email
field required in a request where it was previously optional, or adding a new required field.
Outcome: Requests will fail if the modified field is not provided.
7. Changing HTTP methods
Example: Changing the HTTP method from POST
to PUT
for creating a new resource.
Outcome: Request methods must be updated accordingly.
8. Changing default values
Example: Changing the default value of a sortOrder
field from ASC
to DESC
.
Outcome: The change alters the default behavior of the sort. If the integration relied on the previous default sorting behavior, it will need to accommodate this change, otherwise it can be ignored.
9. Changing date formats
Example: Changing date format from MM-DD-YYYY
to YYYY-MM-DD
.
Outcome: Date parsing must adapt to the new format.
10. Adding authentication requirements
Example: Requiring an API key for an endpoint that previously did not need authentication.
Outcome: New authentication mechanisms must be implemented.
11. Changing field names
Example: Renaming username
to user_name
.
Outcome: References must update to the new field.
12. Changing pagination logic
Example: Switching from page-based to cursor-based pagination.
Outcome: Changes are required for handling new pagination logic.
13. Changing a field’s valid values
Example: Removing a previously valid enum value.
Outcome: Changes are required to use a different value.
14. Adding new fields to responses that require interaction
Example: Adding a disabledOn
timestamp to the user profile response.
Outcome: Generally considered non-breaking, however in this case it could be considered breaking as it states this model is disabled and non-interactable.
15. Adding a new enum value to field set - Moov set, integration read
Example: Adding a DISABLED
status to an existing status
enum.
Outcome: Integrations aren’t set up to handle new values. A new enum value will fall through a catch all error.
16. Bug fixes resulting in different status codes
Example: Changing an HTTP response code from 404 Not Found
to 409 Conflict
.
Outcome: Integration expects a 404
for the specific error case but is getting back a 409
. Integration must update to handle this new response code.
Non-breaking changes
The following list has been established as non-breaking changes for integrations that adhere to industry standards.
1. Adding a new optional field to a response
Example: Adding an optional middleName
field to the user profile response that the integration may or may not return.
Outcome: Integrations should not be affected by this change. However, this action may result in a breaking change if response fields are strictly validated.
2. Adding a new informational field to a response
Example: Adding a createdAt
or updatedOn
timestamp to the user profile response that will always be returned.
Outcome: Integrations should not be affected by this change. However, this action may result in a breaking change if response fields are strictly validated.
3. Adding new endpoints
Example: Adding a new endpoint GET /users/{userID}/friends
.
Outcome: Integrations are not affected by new endpoints.
4. Deprecating an endpoint (with adequate notice)
Example: Marking GET /users/{userID}/profile
as deprecated but still functional.
Outcome: As long as the endpoint continues to function and integrations have time to update, this is a non-breaking change.
5. Enhancing performance or fixing non-behavioral bugs
Example: Improving response time or fixing a typo in the documentation.
Outcome: These changes do not affect the API’s interface or expected behavior.
6. Adding new response headers
Example: Including a new header X-Request-ID
in responses.
Outcome: As long as existing headers remain unchanged, this is a non-breaking change.
7. New enum value to field set - client set, Moov read
Example: Adding a NEW_FEATURE
status to an existing action
enum.
Outcome: Fields set and requested by the integration owner should not break since its return is expected.
8. Bug fixes resulting in different status codes - generic to specific
Example: Changing an HTTP response code from 409 Conflict
to 500 Internal Server Error
.
Outcome: Moov considers this non-breaking if a generic error status code of 500
or 400
is changed to a status code that’s already defined by the API.
9. Consistent array ordering without explicit ordering specified
Example: Returning an array of ['b', 'a']
without specifying it must be alphabetical via a query argument.
Outcome: An item in an array doesn’t care about order.
10. Consistent map ordering
Example: Returning an map of {"b": true, "a": true}
.
Outcome: All lookups of the value are via the key.