API Versioning Changelog

This page records changes to Hubbl's two customer-facing API surfaces, the REST API at api.hubbl.com and the MCP server at mcp.hubbl.com, per the API Versioning Policy.

Entries are reverse-chronological. Each entry carries a surface (API or MCP), an optional version, and a tag:

  • breaking requires a new major version per the policy.
  • additive adds new behavior in place, so existing integrations are unaffected.
  • description-update is MCP only. A tool's description changed, so LLM behavior may shift even though the contract is unchanged.
  • deprecated marks a version that entered its deprecation window. Includes the planned sunset date.

Customers with active integrations should subscribe at minimum to breaking and deprecated entries.

No endpoint or tool queries Salesforce directly. Everything reads Hubbl's own data, and org-scoped resources reflect the org's most recent scan.

July 30, 2026

API + MCP

  • Custom Code endpointsadditive

    Read access to the code-quality and metadata-inventory data captured in an org's Hubbl scan: per-file line counts, Apex class-type classifications, PMD violations against Apex, ESLint findings against LWC and Aura JavaScript, and the scanned metadata items themselves.

    • API: GET /v1/orgs/{orgId}/{codeCounts,classTypes,esLints,pmds,items}, each with a single-record companion except classTypes.
    • MCP: list_org_code_counts / get_org_code_count, list_org_class_types, list_org_es_lints / get_org_es_lint, list_org_pmd_violations / get_org_pmd_violation, and list_org_items / get_org_item.
  • Org Limits endpointsadditive

    Read access to each Salesforce and Hubbl limit recorded for an org, with its cap, remaining headroom, and derived percent used (DailyApiRequests, PermissionSets, DailyBulkApiBatches, and the rest). This is one row per limit, so the list returns every limit in a single page.

    • API: GET /v1/orgs/{orgId}/orgLimits and GET /v1/orgs/{orgId}/orgLimits/{name}. The by-name record is identical in shape to the list record.
    • MCP: list_org_limits and get_org_limit.
  • Cloud Usage and object usage endpointsadditive

    Read access to the adoption data behind the dashboard's Cloud tab: a per-cloud adoption breakdown with an overall usage summary, plus per-object metrics covering record counts, active users, automations, field counts, and last-used dates.

    • API: GET /v1/orgs/{orgId}/cloudUsage (a singleton, so no filter, sort, or pagination) and GET /v1/orgs/{orgId}/objectUsages.
    • MCP: get_org_cloud_usage and list_org_object_usages.
  • Connected App Assignments endpointadditive

    Read access to the junction rows that link a connected app to the profile or permission set it is granted through, completing the picture alongside the existing Connected Apps and Profiles and Permission Sets resources. Each row targets exactly one of the two: profileId or permissionSetId is set, and the other is null.

    • API: GET /v1/orgs/{orgId}/connectedAppAssignments.
    • MCP: list_org_connected_app_assignments.
  • Stable error codes for filter and server failuresadditive

    Server errors are no longer reported as malformed filters. Previously a 500 came back with the "poorly formatted RQL filter" message, which sent agents into retry loops against a failing backend.

    • MCP: every list and get tool now returns a stable code in structuredContent.error, one of bad_filter, rate_limited, not_found, access_denied, or server_error. Genuine 400s keep the filter elicitation and its resource:// links.
    • API: filter failures now split three ways. A parse error returns 400 with the reason, a value that is only rejected later in processing returns 400 with a safe classification hint (previously a 500), and everything else returns 500.

MCP

  • Stricter validation on the sign-in flowadditive

    Sign-in requests are validated more strictly, and errors are now returned directly to the caller instead of being redirected. Supported clients (Claude Desktop, Cursor, and the rest) need no changes.

    • An /authorize request that omits PKCE, or sends a code_challenge_method other than S256, now returns 400 with invalid_request in the response body. Previously the error was delivered to the client's redirect_uri. Custom integrations that read OAuth errors off their redirect URI need to read the response body instead.
    • A /callback request that does not correspond to a sign-in Hubbl started returns 400.
    • Sign-in flows already in progress when this ships fail once with a 400; retrying completes normally.
  • Server version 1.0.0additive

    The initialization handshake now reports serverInfo.version as 1.0.0. This is Hubbl's server software version, not the API contract version — the contract stays v1, addressed by the endpoint path. No client action is needed.

  • GET /v1/mcp returns 405additive

    The MCP endpoint now answers unsupported methods with 405 Method Not Allowed and an Allow: POST, DELETE header, where it previously fell through to a generic 404. Hubbl's server offers no SSE stream on GET, which the MCP specification requires be signalled this way. POST and DELETE are unchanged.

  • Retryable flag on server errorsadditive

    Server-error responses now carry retryable: true in structuredContent, so a caller can tell a transient backend failure from a permanent one without reading the message. The stable error codes are unchanged.

    • Messages for not_found, access_denied, and server_error now name a next step: which list_* tool verifies an id, when to re-authenticate, and that a retry is safe after a short wait. Message text is not part of the versioned contract, so clients matching on structuredContent.error are unaffected.
  • RQL reference link in list_* filter descriptionsdescription-update

    The filter parameter description on all 22 list_* tools now links to the public RQL reference at https://docs.hubbl.com/rql. The filter contract itself is unchanged.

  • get_org_issues removedbreaking

    The deprecated get_org_issues alias has been removed at the end of its closed-beta deprecation window. Use list_org_issues, which takes the same parameters and returns the same response shape.

  • OAuth and transport security hardeningadditive

    The OAuth client behind MCP sign-in now rejects any authorization-code request that arrives without a PKCE code_challenge and code_challenge_method=S256, returning invalid_request. The MCP specification already requires PKCE of all clients, so supported clients (Claude Desktop, Cursor, and the rest) need no changes. Custom OAuth integrations that skipped PKCE have to add it.

    • API keys are unaffected, as are refresh-token exchanges and token-exchange flows.
    • The MCP endpoint's TLS policy now enforces TLS 1.2 or higher using FIPS-validated ciphers. Clients still negotiating TLS 1.0 or 1.1 can no longer connect.
    • v1 is unchanged — this is an enforcement change, not a contract change.

July 23, 2026

API + MCP

  • Orgs listadditive

    List and search the Salesforce orgs you can access, the first endpoint in the public surface that is not scoped to a single org. It returns a compact record per org (salesforceId, name, edition, instance URL, sandbox flag, last scan date and status, scan count, and Hubbl score); fetch the single org for the full record. You see only the orgs you already have access to in the dashboard.

    • API: GET /v1/orgs.
    • MCP: list_orgs, the entry point for resolving an orgId before calling any per-org tool.
  • License Usage endpointsadditive

    Read access to the license usage captured in an org's Hubbl scan: total, used, and remaining counts per license, with type, status, and expiration date.

    • API: GET /v1/orgs/{orgId}/licenseUsages and GET /v1/orgs/{orgId}/licenseUsages/{apiName}.
    • MCP: list_org_license_usages and get_org_license_usage.
  • Profiles and Permission Sets endpointsadditive

    Read access to the Salesforce profiles and permission sets captured in an org's Hubbl scan, including the risky-permission flags surfaced on the dashboard's Profiles and Permission Sets tab (modifyAllData, viewAllData, manageUsers, dataExport, authorApex, and the rest).

    • API: GET /v1/orgs/{orgId}/sfProfiles and /sfProfiles/{sfProfileId}, plus GET /v1/orgs/{orgId}/permissionSets and /permissionSets/{permissionSetId}.
    • MCP: list_org_sf_profiles / get_org_sf_profile and list_org_permission_sets / get_org_permission_set.
  • Login Activity endpointsadditive

    Read access to Salesforce login activity for an org: a per-user table carrying 30, 90, and 365 day login counts, plus an adoption rollup of licensed users, how many logged in, how many did not, and login adoption percentage over the same trailing windows.

    • API: GET /v1/orgs/{orgId}/loginActivity and GET /v1/orgs/{orgId}/loginActivity/overview. The overview is a singleton with no pagination, and takes an optional repeatable license parameter that scopes every count in the response to the selected Salesforce license types.
    • MCP: list_org_login_activity and get_org_login_activity_overview.

July 17, 2026

API

  • Public list page size capped at 200, default 50breaking

    Every public list endpoint now caps limit at 200 (was 1000) and lowers the default page size to 50 where it was higher. Requests above 200 are clamped to 200, not rejected (no new 400s). This keeps a single response from overwhelming a consumer's context window and reduces token/inference cost for agent callers.

    • Max lowered 1000 → 200 on GET /v1/orgs and GET /v1/orgs/{orgId}/{connectedApps,fields,objects,objects/{objectId}/fields,installedPackages,issues,flows,triggers,workflows}.
    • Default lowered on GET /v1/orgs (100 → 50), /v1/orgs/{orgId}/fields (200 → 50), /v1/orgs/{orgId}/objects/{objectId}/fields (200 → 50), and /v1/orgs/{orgId}/issues (100 → 50). Callers relying on the old default now get fewer items per page; paginate for more.
    • GET /v1/orgs/{orgId}/issues now defaults to sort -priority,effort when none is supplied, and drops the never-populated updatedAt property from the response schema.

MCP

  • list_org_* tools capped at 200, default 50breaking

    Every list_org_* tool now caps limit at 200 (was 1000) in its input schema and defaults to 50. Unlike REST (which clamps), MCP rejects a limit above 200, matching the tool's stated schema.

  • List-tool descriptions reconciled with the APIdescription-update

    A consistency pass aligned every list_org_* tool's advertised fields, filter/sort fields, and enum values with what the API actually accepts and returns, so tool descriptions no longer over-promise fields or reference renamed tools. LLM behavior may shift slightly even though the underlying contract is unchanged.

July 9, 2026

API + MCP

  • Triggers endpointsadditive

    Read access to the Apex triggers captured in an org's Hubbl scan, completing the automation trio alongside Workflows and Flows.

    • API: list and filter triggers, or fetch a single trigger's full record.
    • MCP: list_org_triggers and get_org_trigger.

MCP

  • Ready-made promptsadditive

    The MCP server now offers five one-click prompts for common tasks: top priority fixes, security risk audit, legacy automation cleanup, connected app review, and unused field cleanup.

  • Tool annotationsadditive

    Every MCP tool now carries standard annotations (read-only, destructive, idempotent, and open-world hints) and a display title, so clients no longer treat read-only tools as potential writes. Annotations are hints, not security guarantees.

  • One-click connect for remote clientsadditive

    OAuth-based remote MCP clients can now connect in one click, with no API key or manual client setup.

  • Filter validation fixesadditive

    list_org_fields now accepts all the documented filter field names it previously rejected. No contract change; behavior now matches the docs.

June 25, 2026

API + MCP

  • Workflows and Flows endpointsadditive

    Read access to the workflow rules and flows captured in an org's Hubbl scan, the first two of the automation trio.

    • API: list/filter and single-record fetch for each.
    • MCP: list_org_workflows / get_org_workflow and list_org_flows / get_org_flow.

API

  • Rate limits and quota endpointadditive

    Per-account rate limiting is now enforced, with daily and monthly windows. API-key and OAuth usage share one account quota, and requests over the limit receive a standard rate-limit response.

    • New GET /v1/orgs/{orgId}/quota returns your current usage against the daily and monthly limits so you can pace your requests.

MCP

  • Resource links on filter errorsadditive

    When a filter value is rejected, the error now points to the resource:// lookup of valid values for that field, so agents can self-correct without a separate docs lookup.

June 12, 2026

API + MCP

  • OAuth2 sign-inadditive

    Any user, not just admins, can now connect to the REST API or MCP server by signing in with a Hubbl account, with no API key required. You see only the orgs and scans you already have access to, and existing API keys keep working unchanged.

  • Fields and Objects endpointsadditive

    Programmatic read access to the field-level and object-level data captured in an org's Hubbl scan.

    • Fields: list and filter scanned fields, or fetch a single field's full record.
    • Objects: list an org's objects, fetch a single object, or list the fields on a given object.
  • Cleaner response payloadsadditive

    MCP responses now carry the full payload in structuredContent, with content[0].text reduced to a pointer, removing duplicated JSON. Redundant scan timestamps were dropped from connectedApps, installedPackages, and fields responses.

MCP

  • get_org_issues renamed to list_org_issuesadditivedeprecated

    Renamed to match the list_* / get_* convention. The old get_org_issues name still works as an alias and emits a deprecation notice when called; it will be removed at the end of the closed-beta window.

June 11, 2026

API

  • Unversioned URLs removedbreaking

    The pre-versioning REST endpoints at api.hubbl.com/orgs/... (and adjacent paths) are no longer reachable. All customer-facing REST traffic is now served from api.hubbl.com/v1/....

    • Beta-program customers were notified directly ahead of the cutover and migrated to the versioned URLs.
    • This is a one-time cutover; future version retirements will follow the standard 3-month deprecation process described in the policy.
  • v1 launchedadditive

    Initial release of the versioned public REST API at api.hubbl.com/v1/. Customer-facing endpoints under /v1/orgs/ are reachable on the new public gateway.

    • Discovery endpoint at GET https://api.hubbl.com/ (unauthenticated) returns the list of supported versions and their status.
    • Version header on every versioned response: X-Hubbl-API-Version: 1. The Deprecation and Sunset headers will appear here when a future major version retires v1.

MCP

  • v1 launchedadditive

    Initial release of the versioned MCP server at mcp.hubbl.com/v1/mcp (Streamable HTTP transport).

    • In-protocol discovery via the server_info tool — callable from any MCP session, returns the list of supported MCP versions and their status.
    • HTTP discovery at GET https://mcp.hubbl.com/ (unauthenticated) returns the same payload, intended for operators and monitoring tools that want to check version state without running an MCP handshake.
  • Unversioned endpoint deprecateddeprecated

    The unversioned endpoint at mcp.hubbl.com/mcp is deprecated and will be removed on 2026-06-25. Update your MCP client configuration (Claude Desktop, Cursor, etc.) to point at mcp.hubbl.com/v1/mcp.

    • During the transition window, the unversioned endpoint serves the same responses as /v1/mcp so existing clients continue to work.
    • Responses on the unversioned path carry Deprecation: true and Sunset HTTP headers per RFC 9745 and RFC 8594. These are visible to operators monitoring HTTP traffic; end-user MCP clients generally don't surface them, so direct config updates are still required.
    • Unlike REST (which was hard-cut at the same launch), MCP retains this 3-month transition because client config updates require manual user action, which adds lag risk.