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.
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.
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.
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.
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.
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.
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.
Changing HTTP methods
- Example: Changing the HTTP method from
POST
toPUT
for creating a new resource. - Outcome: Request methods must be updated accordingly.
Changing default values
- Example: Changing the default value of a
sortOrder
field fromASC
toDESC
. - 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.
Changing date formats
- Example: Changing date format from
MM-DD-YYYY
toYYYY-MM-DD
. - Outcome: Date parsing must adapt to the new format.
Adding authentication requirements
- Example: Requiring an API key for an endpoint that previously did not need authentication.
- Outcome: New authentication mechanisms must be implemented.
Changing field names
- Example: Renaming
username
touser_name
. - Outcome: References must update to the new field.
Changing pagination logic
- Example: Switching from page-based to cursor-based pagination.
- Outcome: Changes are required for handling new pagination logic.
Changing a field’s valid values
- Example: Removing a previously valid enum value.
- Outcome: Changes are required to use a different value.
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.
Adding a new enum value to field set - Moov set, integration read
- Example: Adding a
DISABLED
status to an existingstatus
enum. - Outcome: Integrations aren’t set up to handle new values. A new enum value will fall through a catch all error.
Bug fixes resulting in different status codes
- Example: Changing an HTTP response code from
404 Not Found
to409 Conflict
. - Outcome: Integration expects a
404
for the specific error case but is getting back a409
. 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.
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.
Adding a new informational field to a response
- Example: Adding a
createdAt
orupdatedOn
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.
Adding new endpoints
- Example: Adding a new endpoint
GET /users/{userID}/friends
. - Outcome: Integrations are not affected by new endpoints.
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.
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.
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.
New enum value to field set - client set, Moov read
- Example: Adding a
NEW_FEATURE
status to an existingaction
enum. - Outcome: Fields set and requested by the integration owner should not break since its return is expected.
Bug fixes resulting in different status codes - generic to specific
- Example: Changing an HTTP response code from
409 Conflict
to500 Internal Server Error
. - Outcome: Moov considers this non-breaking if a generic error status code of
500
or400
is changed to a status code that’s already defined by the API.
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.
Consistent map ordering
- Example: Returning an map of
{"b": true, "a": true}
- Outcome: All lookups of the value are via the key.