How versioning works in the Sally API
The version of the Sally API is the first path segment: /v1.0. There is deliberately no sliding /v1, so a path you wrote down keeps meaning what it meant. This page explains what freezing a version means and which changes get a new version.
It also shows how to keep the version in a single constant, so that moving to a later version is a one-line change in your code.
Quick navigation
- The current version
- What freezing means
- What does not get a new version
- The exception: the health check
- Keep the base URL in one place
1. The current version
| Version | Status | Path |
|---|---|---|
1.0 | Current, under active development, not frozen yet | /v1.0 |
Version 1.0 can still change in ways that break a client, so treat it as a moving target for now. Every change is listed in the release notes. We will announce when the version is frozen.
2. What freezing means
Once a version is frozen, it keeps answering exactly as it did at that moment and is never changed again. Work continues on the next version (/v1.1), and a client that wants the old behavior simply stays on its path. A redesign too large to carry that way becomes a new major version (/v2).
3. What does not get a new version
A new version is only created for a change that could break a client. A purely additive change does not get one: a new endpoint, a new field or a new enum value appears in the version you are already using.
| Change | New version? | Where it appears |
|---|---|---|
| New endpoint | No | In the version you already use |
| New field in a response | No | In the version you already use |
| New enum value | No | In the version you already use |
| Change that could break a client | Yes | In the next version, for example /v1.1 |
| Redesign too large for that | Yes, a new major version | /v2 |
Your client therefore has to tolerate two things: fields it does not know and enum values it has never seen. A parser that rejects either of them breaks on a change that was designed to be harmless.
As long as 1.0 is not frozen, this table describes the rule for frozen versions. Until then, check the release notes before you update your integration.
4. The exception: the health check
GET /health deliberately carries no version. A liveness probe says nothing about the contract, and a monitor should not have to follow a version change. It also needs no token.
5. Keep the base URL in one place
Put the version into a single constant and build every path from it. When a later version comes, you change one line and nothing else:
- cURL
- JavaScript
- Python
SALLY_API="https://api.sally.io/v1.0"
curl "$SALLY_API/me" -H "Authorization: Bearer $SALLY_TOKEN"
curl "$SALLY_API/directories/$DIRECTORY_ID/recordings" -H "Authorization: Bearer $SALLY_TOKEN"
# The health check has no version
curl "https://api.sally.io/health"
const SALLY_API = 'https://api.sally.io/v1.0';
async function sally(path) {
const response = await fetch(`${SALLY_API}${path}`, {
headers: {Authorization: `Bearer ${process.env.SALLY_TOKEN}`},
});
return response.json();
}
const me = await sally('/me');
const recordings = await sally(`/directories/${directoryId}/recordings`);
import os
import requests
SALLY_API = "https://api.sally.io/v1.0"
def sally(path):
response = requests.get(
f"{SALLY_API}{path}",
headers={"Authorization": f"Bearer {os.environ['SALLY_TOKEN']}"},
)
return response.json()
me = sally("/me")
recordings = sally(f"/directories/{directory_id}/recordings")
Read responses into objects that ignore unknown fields, and give every enum a fallback branch for values you do not know yet. Then new fields and enum values in the same version cannot break your integration.