API Versioning Policy
Purpose
This policy defines how Hubbl evolves its customer-facing APIs over time so that:
- Customers can build integrations against Hubbl's APIs with confidence
- Hubbl can release improvements without breaking existing integrations
- When a breaking change is unavoidable, customers receive predictable, sufficient notice to migrate
Scope
This policy applies to Hubbl's customer-facing API surfaces:
- Public REST API (
api.hubbl.com) - MCP server
The REST API and MCP server share the same policy rules but maintain independent version numbers. For example, the REST API may be on v1 while MCP is on v2.
Versioning Scheme
Hubbl uses path-based major versioning. Every customer-facing API request includes the version as a leading path segment:
- REST:
api.hubbl.com/v1/orgs/{orgId} - MCP: each major version is served at its own connection endpoint (
mcp.hubbl.com/v1/mcpfor v1; future major versions at/v2/mcp, etc.). Tool and resource URIs within a major version do not carry version segments — they're addressed by their MCP-protocol names (e.g.,hubbl://issue-categories, toolget_org_info).
There is no minor or patch version in the URL. Within a major version, all additive (non-breaking) changes ship in place.
Hubbl explicitly does not use:
- Header-based versioning (e.g.,
Accept: application/vnd.hubbl.v1+json) - Date-based versioning (e.g.,
/2026-05-26/...) - Subdomain versioning (e.g.,
v1.api.hubbl.com) - Unversioned alias paths (e.g.,
/stable,/beta)
Preferring Additive Evolution
Major version bumps are expensive — for Hubbl to maintain two concurrent versions, and for customers to migrate. When a breaking change is on the table, the first option to consider is shipping the new behavior as a new additive endpoint or parameter rather than modifying the existing one. For example, if /v1/orgs/{orgId}/issues needs a different response shape, prefer adding a new endpoint that returns the new shape over breaking the original.
This approach does not apply to cross-cutting changes — auth model, error envelope, pagination conventions, or anything else that can't reasonably be carried by a single new endpoint. Those remain the legitimate cases for a major version bump.
Most mature public APIs remain on v2 or v3 throughout their lifetime; Hubbl expects to follow the same pattern. Major version bumps are reserved as a last resort, used only when no additive path exists.
Change Classification
Every change to the API is classified as additive or breaking.
Additive (non-breaking)
These ship in place on the current major version without a deprecation window:
- New endpoints
- New optional request parameters
- New response fields
- New enum values, but only when the enum is explicitly documented as extensible. Enums are non-extensible by default — adding a value to a non-extensible enum is breaking.
- New HTTP headers in responses
Breaking
These require a new major version and trigger the deprecation process for the prior version:
- Removed endpoints, parameters, response fields, or enum values
- Renamed fields
- Changed data types (e.g.,
number→string) - Changed request or response shapes, including the structure of error responses
- Required parameters added to existing endpoints
- Behavioral changes (e.g., default-value changes, validation-rule changes)
- Authentication or authorization requirement changes
Edge cases
- Bug fixes: if documented behavior changes to match documentation, this is non-breaking. If undocumented behavior that customers may rely on changes, Hubbl will document the change in the changelog and treat it as breaking when the impact is material. For example, a fix that changes the order of items in an unsorted list is not material; a fix that changes the value of a field from
nullto0for existing records is material. - Performance changes: non-breaking unless they materially change response times in ways that affect client timeouts.
- Security fixes: changes that tighten authentication or authorization to address a security issue may ship without a deprecation window. These will be documented in the changelog and, where possible, communicated to affected customers ahead of the change.
When classification is uncertain, Hubbl errs on the side of treating a change as breaking and bumps the major version.
Deprecation Process
Breaking changes require a minimum 3-month deprecation window before the old major version is sunset. The 3-month minimum reflects the API's current early-customer status. Longer windows (6–12 months for breaking changes is the industry norm) will apply as the customer base grows. Additive changes do not have a deprecation window — they ship in place on the current version.
Signals
When a major version enters deprecation, customers are notified through:
- Changelog entry at docs.hubbl.com/changelog tagged
deprecated - Email notification to API key owners
- Surface-specific runtime signals:
- REST: HTTP response headers on every request to the deprecated version —
Deprecation: true(per RFC 9745) andSunset: <RFC 7231 HTTP date>(per RFC 8594) — the planned sunset date. - MCP: the
server_infotool's response annotates the deprecated version with its status and plannedsunsetDate, and tool descriptions for renamed or removed tools include a deprecation notice (see MCP-Specific Rules). HTTP-layer headers are not used — MCP clients do not consume them, and the protocol-level mechanisms are the canonical channel.
- REST: HTTP response headers on every request to the deprecated version —
Sunset
On the sunset date, the deprecated major version is removed. Requests to it return 410 Gone.
Concurrent Support
Hubbl supports the current major version and the one immediately prior simultaneously. At any point in time there are at most two supported major versions.
When a new major version is released, the previous current version enters deprecation, and the version that was already deprecated reaches sunset. For example, if v1 is current and v2 ships:
v2becomes currentv1enters deprecation and is supported for the deprecation window- Any older version (e.g.,
v0, if it had still been alive in deprecation) reaches sunset
Version Identification
Response header (REST)
Every REST response includes:
X-Hubbl-API-Version: 1
The value is the major version number that handled the request.
MCP responses do not carry an equivalent HTTP header. The version is identifiable from the URL path the client connects to (e.g., mcp.hubbl.com/v1/mcp) and from the server_info tool.
Discovery endpoint
GET / is the one unversioned REST endpoint — it sits above the version paths so clients can discover what versions exist before choosing one. It returns the list of available versions and their status:
{
"versions": [{ "name": "v1", "status": "current" }]
}
Possible status values: current, deprecated.
When a deprecated version exists alongside the current one, the response includes the planned sunset date:
{
"versions": [
{ "name": "v1", "status": "deprecated", "sunsetDate": "2026-12-01" },
{ "name": "v2", "status": "current" }
]
}
MCP discovery
Version discovery. MCP clients identify the major API version (v1, v2, ...) from the connection endpoint URL path they were configured against. The MCP protocol's initialization handshake also exchanges a serverInfo.version field, but that reflects Hubbl's server software version (e.g., 0.1.0) — not the API contract version covered by this policy. Programmatic access to the current API version and its deprecation status is via the server_info tool described below.
Deprecation status. MCP exposes the same version-and-deprecation info via two channels, depending on how you're reaching the server:
server_infoMCP tool — callable from any MCP session.GET /onmcp.hubbl.com— for operators and monitoring tools that want to check version state over plain HTTP without running an MCP handshake.
Both return the same { versions: [...] } shape, listing every supported MCP version (current and deprecated), each annotated with its status and — when deprecated — the planned sunset date:
{
"versions": [{ "name": "v1", "status": "current" }]
}
When a deprecated version coexists with the current one, the response includes the planned sunset date so clients can plan their migration:
{
"versions": [
{ "name": "v1", "status": "deprecated", "sunsetDate": "2026-12-01" },
{ "name": "v2", "status": "current" }
]
}
Per-tool deprecation notices (for renamed or removed tools) continue to be carried in each tool's description, as covered above.
MCP-Specific Rules
MCP follows all the rules above, with two additional guardrails specific to AI tool usage.
Tool descriptions are versioned
Tool description text is part of the tool's contract — model behavior can shift meaningfully based on description wording. Description changes follow the same classification:
- Additive: clarifying wording, adding examples, expanding context. Ships in place.
- Breaking: changing the documented purpose, scope, or expected use of a tool. Requires a major version bump.
Because LLM behavior is sensitive to wording, even additive description changes can shift how models call a tool. All description updates are recorded in the changelog regardless of classification so customers can correlate behavioral changes to specific revisions.
Tool renames keep aliases
When a tool is renamed, the old name remains registered as an alias for the full deprecation window. Both names route to the same handler, and the old name's description includes a deprecation note pointing to the new name.
Enforcement
All proposed API changes are reviewed against this policy. Automated checks in Hubbl's CI pipeline detect breaking changes that are not accompanied by a major version bump and block them from merging.
Appendix: Examples
Example 1 — Adding an optional filter parameter
A new optional
filterquery parameter is added toGET /v1/orgs/{orgId}/issues.
Classification: Additive. Existing clients that don't pass the parameter see no change. Action: Ships on the current major version. No deprecation needed.
Example 2 — Renaming a response field
The response field
hubblScoreis renamed toscore.
Classification: Breaking. Clients reading hubblScore would break.
Action: Requires a new major version. The new field name ships in /v2/; /v1/ continues to return hubblScore until sunset.
Example 3 — Adding a new endpoint
A new endpoint
GET /v1/orgs/{orgId}/usersis added.
Classification: Additive. No existing client is affected. Action: Ships on the current major version.
Example 4 — Renaming an MCP tool
The tool
get_org_infois renamed tolookup_org.
Classification: Breaking. AI clients calling get_org_info by name would fail.
Action: lookup_org is added as the new name. get_org_info remains registered as an alias routing to the same handler for the full deprecation window. The old tool's description includes a deprecation note pointing to the new name.
Example 5 — Rewriting an MCP tool description
The description for
get_org_issuesis rewritten to emphasize thefieldsparameter for token efficiency.
Classification: Additive if it clarifies existing behavior; breaking if it changes the documented purpose of the tool. Action: If additive, ships on the current major version. If breaking, requires a major version bump.