Driftwatch

APIs / Vercel

Vercel API changes

Breaking changes, deprecations and new fields in the Vercel API, as they ship.

Vercel1 breaking
  • Breakingdirection flip: their tools call this safe

    cmdId is no longer accepted

    No error is raised. The value is ignored and your results change silently, which is the hardest class of break to notice.

    POST /v2/sandboxes/sessions/{sessionId}/cmd · cmdId
    Code that breaks
    await client.post("/v2/sandboxes/sessions/{sessionId}/cmd", {
      // cmdId is now ignored, not rejected
      cmdId: value,
    });
Vercel1 breaking1 additive
  • Breakingdirection flip: their tools call this safe

    name can now return "connect-cancel-mcp-event-subscription", "connect-create-mcp-event-subscription", "organization-name-update"

    Producer-side tools call this additive. It breaks exhaustive switches, strict parsers and generated client enums.

    can now return "connect-cancel-mcp-event-subscription", "connect-create-mcp-event-subscription", "organization-name-update"

    3 places: ListEventType.name, ListEventType.replacedBy[], UserEvent.type
    Code that breaks
    switch (response.name) {
      // existing branches …
      // no branch for "connect-cancel-mcp-event-subscription"
      // no branch for "connect-create-mcp-event-subscription"
      // no branch for "organization-name-update"
      default:
        throw new Error("unexpected name");
    }
  • Additive

    Request property name added

    No action needed unless it is required.

    PATCH /v1/organizations/{organizationId} · name
Vercel2 breaking4 additive
  • Breakingdirection flip: their tools call this safe

    permissions can now return "read-write:access-group"

    Producer-side tools call this additive. It breaks exhaustive switches, strict parsers and generated client enums.

    can now return "read-write:access-group"

    4 places: UserEvent.payload.permissions[], UserEvent.payload.nextPermissions[], UserEvent.payload.after.permissions[], UserEvent.payload.before.permissions[]
    Code that breaks
    switch (response.payload.permissions[0]) {
      // existing branches …
      // no branch for "read-write:access-group"
      default:
        throw new Error("unexpected permissions");
    }
  • Breakingdirection flip: their tools call this safe

    Response field author is no longer guaranteed

    Producer-side tools call this non-breaking. For a consumer it is a null dereference on an unknown future date.

    UserEvent.payload.author · reachable from 1 operation
    Code that breaks
    // response.payload.author may now be absent or null
    const author = response.payload.author ?? fallback;
  • Additive

    /v1/organizations added

    No action needed.

    /v1/organizations
  • Additive

    /v1/organizations/{organizationId} added

    No action needed.

    /v1/organizations/{organizationId}
  • Additive

    /v1/organizations/{organizationId}/teams added

    No action needed.

    /v1/organizations/{organizationId}/teams
  • Additive

    /v1/organizations/{organizationId}/teams/{targetTeamId} added

    No action needed.

    /v1/organizations/{organizationId}/teams/{targetTeamId}
Vercel3 breaking2 behavioral9 additive
  • Breakingdirection flip: their tools call this safe

    nodeVersion can now return "26.x"

    Producer-side tools call this additive. It breaks exhaustive switches, strict parsers and generated client enums.

    can now return "26.x"

    16 places: POST /v1/projects/{idOrName}/avatar · nodeVersion, GET /v1/microfrontends/groups/{groupId}/projects · projects[].nodeVersion, DELETE /v1/projects/{idOrName}/avatar · nodeVersion, PATCH /v1/projects/{projectId}/microfrontends · nodeVersion, GET /v10/projects · nodeVersion, GET /v10/projects · projects[].nodeVersion +10 more
    Code that breaks
    switch (response.nodeVersion) {
      // existing branches …
      // no branch for "26.x"
      default:
        throw new Error("unexpected nodeVersion");
    }
  • Breaking

    Response field result removed

    Reads of this field return undefined, and the failure surfaces wherever that value is used rather than at the call.

    GET /v1/security/firewall/bypass/rules · result · 3 call sites
    Code that breaks
    // response.result is now undefined
    const result = response.result;
  • Breaking

    Response field pagination removed

    GET /v1/security/firewall/bypass/rules · pagination
    Code that breaks
    // response.pagination is now undefined
    const pagination = response.pagination;
  • Behavioral

    204 is now documented on /v1/security/firewall/bypass/rules

    An unhandled branch in your error handling.

    DELETE /v1/security/firewall/bypass/rules
  • Behavioral

    Status code no longer documented

    Dead branch, or an undocumented response you still receive.

    DELETE /v1/security/firewall/bypass/rules
9 new response fields
  • conditionGroup
  • createdAt
  • condition
  • domain
  • id
  • note
  • projectId
  • updatedAt
  • rules
Vercel4 additive
4 new response fields
  • ConnectConnector.appTokens.isStaticCredential
  • ConnectConnector.userTokens.isStaticCredential
  • ConnectConnectorCreateResult.appTokens.isStaticCredential
  • ConnectConnectorCreateResult.userTokens.isStaticCredential
Vercel1 breaking2 additive
  • Breakingdirection flip: their tools call this safe

    name can now return "firewall-conditional-bypass-created", "firewall-conditional-bypass-deleted"

    Producer-side tools call this additive. It breaks exhaustive switches, strict parsers and generated client enums.

    can now return "firewall-conditional-bypass-created", "firewall-conditional-bypass-deleted"

    3 places: ListEventType.name, ListEventType.replacedBy[], UserEvent.type
    Code that breaks
    switch (response.name) {
      // existing branches …
      // no branch for "firewall-conditional-bypass-created"
      // no branch for "firewall-conditional-bypass-deleted"
      default:
        throw new Error("unexpected name");
    }
  • Additive

    /v1/security/firewall/bypass/rules added

    No action needed.

    /v1/security/firewall/bypass/rules
  • Additive

    Response field nonSensitive added

    No action needed unless you validate responses against a closed schema.

    POST /v1/storage/stores/integration/direct · store.secrets[].nonSensitive
Vercel2 breaking2 additive
  • Breakingdirection flip: their tools call this safe

    type can now return "response_code"

    Producer-side tools call this additive. It breaks exhaustive switches, strict parsers and generated client enums.

    can now return "response_code"

    18 places: GET /v1/security/firewall/config · active.conditions[].conditionGroup[].conditions[].type, GET /v1/security/firewall/config · active.rules[].conditionGroup[].conditions[].type, GET /v1/security/firewall/config · active.rulesets[].conditionGroup[].conditions[].type, GET /v1/security/firewall/config · draft.conditions[].conditionGroup[].conditions[].type, GET /v1/security/firewall/config · draft.rules[].conditionGroup[].conditions[].type, GET /v1/security/firewall/config · draft.rulesets[].conditionGroup[].conditions[].type +12 more
    Code that breaks
    switch (response.active.conditions[0].conditionGroup[0].conditions[0].type) {
      // existing branches …
      // no branch for "response_code"
      default:
        throw new Error("unexpected type");
    }
  • Breakingdirection flip: their tools call this safe

    nextPermissions can now return "read-write:project-members", "read:audit-log", "read:project-members"

    Producer-side tools call this additive. It breaks exhaustive switches, strict parsers and generated client enums.

    can now return "read-write:project-members", "read:audit-log", "read:project-members"

    4 places: UserEvent.payload.nextPermissions[], UserEvent.payload.permissions[], UserEvent.payload.after.permissions[], UserEvent.payload.before.permissions[]
    Code that breaks
    switch (response.payload.nextPermissions[0]) {
      // existing branches …
      // no branch for "read-write:project-members"
      // no branch for "read:audit-log"
      // no branch for "read:project-members"
      default:
        throw new Error("unexpected nextPermissions");
    }
2 new response fields
  • security.firewallRoutes[].response_has
  • projects[].security.firewallRoutes[].response_has
Vercel1 breaking
  • Breakingdirection flip: their tools call this safe

    permissions can now return "read-write:ai-gateway-budgets", "read:ai-gateway-budgets"

    Producer-side tools call this additive. It breaks exhaustive switches, strict parsers and generated client enums.

    can now return "read-write:ai-gateway-budgets", "read:ai-gateway-budgets"

    4 places: UserEvent.payload.permissions[], UserEvent.payload.nextPermissions[], UserEvent.payload.after.permissions[], UserEvent.payload.before.permissions[]
    Code that breaks
    switch (response.payload.permissions[0]) {
      // existing branches …
      // no branch for "read-write:ai-gateway-budgets"
      // no branch for "read:ai-gateway-budgets"
      default:
        throw new Error("unexpected permissions");
    }
Vercel1 breaking1 behavioral9 additive
5 new response fields
  • services[].builder.config.daemon.instances
  • services[].builder.config.daemon.terminationGracePeriodSeconds
  • AiGatewayBudgetList.defaultCoveredCounts
  • AiGatewayBudgetList.nextCursor
  • AiGatewayRuleList.nextCursor
Vercel2 additive
2 new response fields
  • Flag.seenInProduction
  • seenInProduction
Vercel1 breaking
  • Breakingdirection flip: their tools call this safe

    protectionMode is no longer accepted

    Usually ignored rather than rejected, so the call succeeds and does something subtly different.

    PATCH /v9/projects/{idOrName} · trustedIps.protectionMode
    Code that breaks
    await client.post("/v9/projects/{idOrName}", {
      // protectionMode is now ignored, not rejected
      protectionMode: value,
    });
Vercel3 behavioral6 additive
6 new response fields
  • Team.membership.isOrgBackingTeamMembership
  • TeamLimited.membership.isOrgBackingTeamMembership
  • UserEvent.payload.projectId
  • UserEvent.payload.createdByParentTeamId
  • UserEvent.payload.source
  • UserEvent.payload.scope
Vercel1 breaking3 additive
Vercel2 additive
2 new response fields
  • passwordProtection.deploymentType
  • projects[].passwordProtection.deploymentType
Vercel1 breaking
  • Breakingdirection flip: their tools call this safe

    name can now return "organization-dsync-sync-start"

    Producer-side tools call this additive. It breaks exhaustive switches, strict parsers and generated client enums.

    can now return "organization-dsync-sync-start"

    3 places: ListEventType.name, ListEventType.replacedBy[], UserEvent.type
    Code that breaks
    switch (response.name) {
      // existing branches …
      // no branch for "organization-dsync-sync-start"
      default:
        throw new Error("unexpected name");
    }
Vercel2 breaking1 behavioral5 additive
Vercel1 breaking1 additive
  • Breakingdirection flip: their tools call this safe

    name can now return "sandbox-drive-snapshot-created", "sandbox-drive-snapshot-deleted"

    Producer-side tools call this additive. It breaks exhaustive switches, strict parsers and generated client enums.

    can now return "sandbox-drive-snapshot-created", "sandbox-drive-snapshot-deleted"

    3 places: ListEventType.name, ListEventType.replacedBy[], UserEvent.type
    Code that breaks
    switch (response.name) {
      // existing branches …
      // no branch for "sandbox-drive-snapshot-created"
      // no branch for "sandbox-drive-snapshot-deleted"
      default:
        throw new Error("unexpected name");
    }
  • Additive

    Response field snapshot added

    No action needed unless you validate responses against a closed schema.

    NamedSandbox.mounts[key].snapshot · reachable from 10 operations
Vercel1 breaking24 additive
  • Breakingdirection flip: their tools call this safe

    name can now return "organization-dsync-delete"

    Producer-side tools call this additive. It breaks exhaustive switches, strict parsers and generated client enums.

    can now return "organization-dsync-delete"

    3 places: ListEventType.name, ListEventType.replacedBy[], UserEvent.type
    Code that breaks
    switch (response.name) {
      // existing branches …
      // no branch for "organization-dsync-delete"
      default:
        throw new Error("unexpected name");
    }
  • Additive

    DELETE /v1/projects/{idOrName}/avatar added

    No action needed.

    DELETE /v1/projects/{idOrName}/avatar
23 new response fields
  • partnerCalls
  • projectName
  • createdAt
  • transferredStoreIds
  • createdBy
  • description
  • environments
  • id
  • kind
  • maintainerIds
  • ownerId
  • projectId
  • revision
  • slug
  • state
  • permanent
  • resourceTransferErrors
  • tags
  • typeName
  • updatedAt
  • seed
  • updatedBy
  • variants
Vercel6 additive
6 new response fields
  • resourceConfig.elasticBuildMachine
  • projects[].resourceConfig.elasticBuildMachine
  • AuthUser.resourceConfig.security.teamLevelConditions
  • AuthUser.resourceConfig.security.teamLevelRules
  • AuthUser.resourceConfig.security.teamLevelRulesets
  • AuthUser.resourceConfig.security.securityLists
Vercel1 breaking1 behavioral7 additive
  • Breakingdirection flip: their tools call this safe

    name can now return "messageboard-private-space-updated", "messageboard-space-updated", "v0-migration-subscription-completed"

    Producer-side tools call this additive. It breaks exhaustive switches, strict parsers and generated client enums.

    can now return "messageboard-private-space-updated", "messageboard-space-updated", "v0-migration-subscription-completed"

    3 places: ListEventType.name, UserEvent.type, ListEventType.replacedBy[]
    Code that breaks
    switch (response.name) {
      // existing branches …
      // no branch for "messageboard-private-space-updated"
      // no branch for "messageboard-space-updated"
      // no branch for "v0-migration-subscription-completed"
      default:
        throw new Error("unexpected name");
    }
  • Behavioral

    Status code no longer documented

    Dead branch, or an undocumented response you still receive.

    GET /v5/user/tokens/{tokenId} · 7 call sites
  • Additive

    /v2/sandboxes/drives/{name}/fork added

    No action needed.

    /v2/sandboxes/drives/{name}/fork
6 new response fields
  • startedAt
  • defaultResourceConfig.elasticBuildMachine
  • runs[].startedAt
  • Team.membership.organizationId
  • projects[].defaultResourceConfig.elasticBuildMachine
  • TeamLimited.membership.organizationId
Vercel1 breaking4 additive
  • Breakingdirection flip: their tools call this safe

    name can now return "messageboard-schema-registered", "messageboard-visibility-updated"

    Producer-side tools call this additive. It breaks exhaustive switches, strict parsers and generated client enums.

    can now return "messageboard-schema-registered", "messageboard-visibility-updated"

    3 places: ListEventType.name, ListEventType.replacedBy[], UserEvent.type
    Code that breaks
    switch (response.name) {
      // existing branches …
      // no branch for "messageboard-schema-registered"
      // no branch for "messageboard-visibility-updated"
      default:
        throw new Error("unexpected name");
    }
  • Additive

    /v2/sandboxes/drives/{nameOrId} added

    No action needed.

    /v2/sandboxes/drives/{nameOrId}
3 new response fields
  • services[].builder.config.daemon
  • Drive.rootDriveId
  • Drive.parentDriveId
Vercel1 breaking5 additive
  • Breaking

    Response field minSampleSize removed

    Reads of this field return undefined, and the failure surfaces wherever that value is used rather than at the call.

    9 places: GET /v1/microfrontends/groups/{groupId}/projects · projects[].rollingRelease.gate.checks[].minSampleSize, POST /v11/projects · rollingRelease.gate.checks[].minSampleSize, GET /v9/projects/{idOrName} · rollingRelease.gate.checks[].minSampleSize, POST /v1/projects/{idOrName}/avatar · rollingRelease.gate.checks[].minSampleSize, GET /v1/projects/{idOrName}/rolling-release/config · rollingRelease.gate.checks[].minSampleSize, PATCH /v1/projects/{projectId}/microfrontends · rollingRelease.gate.checks[].minSampleSize +3 more
    Code that breaks
    // response.projects[0].rollingRelease.gate.checks[0].minSampleSize is now undefined
    const minSampleSize = response.projects[0].rollingRelease.gate.checks[0].minSampleSize;
  • Additive

    since is now optional

    No action needed.

    GET /v10/projects · since
  • Additive

    until is now optional

    GET /v10/projects · until
3 new response fields
  • rollingRelease.gate.checks[].significanceLevel
  • Team.limited
  • projects[].rollingRelease.gate.checks[].significanceLevel
Vercel1 breaking
  • Breakingdirection flip: their tools call this safe

    name can now return "project-avatar-dark-mode-update"

    Producer-side tools call this additive. It breaks exhaustive switches, strict parsers and generated client enums.

    can now return "project-avatar-dark-mode-update"

    3 places: ListEventType.name, ListEventType.replacedBy[], UserEvent.type
    Code that breaks
    switch (response.name) {
      // existing branches …
      // no branch for "project-avatar-dark-mode-update"
      default:
        throw new Error("unexpected name");
    }
Vercel2 additive
2 new response fields
  • taskSummary
  • runs[].taskSummary
Vercel2 breaking1 behavioral16 additive
  • Breakingdirection flip: their tools call this safe

    name can now return "v0-migration-payment-confirmed"

    Producer-side tools call this additive. It breaks exhaustive switches, strict parsers and generated client enums.

    can now return "v0-migration-payment-confirmed"

    3 places: ListEventType.name, ListEventType.replacedBy[], UserEvent.type
    Code that breaks
    switch (response.name) {
      // existing branches …
      // no branch for "v0-migration-payment-confirmed"
      default:
        throw new Error("unexpected name");
    }
  • Breakingdirection flip: their tools call this safe

    triggerData is no longer accepted

    Usually ignored rather than rejected, so the call succeeds and does something subtly different.

    2 places: ConnectCreateConnectorRequest.triggerData, ConnectUpdateConnectorRequest.triggerData
    Code that breaks
    await client.post("/…", {
      // triggerData is now ignored, not rejected
      triggerData: value,
    });
  • Behavioral

    500 is now documented on /v2/connect/connectors/{connector}

    An unhandled branch in your error handling.

    PATCH /v2/connect/connectors/{connector}
  • Additive

    /v1/connect/connectors/{connector}/managed/eject added

    No action needed.

    /v1/connect/connectors/{connector}/managed/eject
8 new response fields
  • ConnectConnector.supportsManagedEjection
  • avatarDarkMode
  • projects[].avatarDarkMode
  • ConnectConnectorCreateResult.supportsManagedEjection
  • taskDefinitions[].packageDirectory
  • taskRuns[].deploymentBinding
  • jobs[].tasks[].definition.packageDirectory
  • jobs[].tasks[].run.deploymentBinding
7 new request properties
  • ConnectUpdateConnectorRequest.triggerVerificationInput
  • ConnectCreateConnectorRequest.triggerVerificationInput
  • ConnectCreateConnectorRequest.triggerRegistrationInput
  • ConnectUpdateConnectorRequest.triggerRegistrationInput
  • source.integrationId
  • source.resourceId
  • source.integrationConfigurationId
Vercel1 breaking2 additive
  • Breaking

    Response field abuse removed

    Reads of this field return undefined, and the failure surfaces wherever that value is used rather than at the call.

    8 places: GET /v1/microfrontends/groups/{groupId}/projects · projects[].abuse, POST /v1/projects/{idOrName}/avatar · abuse, PATCH /v1/projects/{projectId}/microfrontends · abuse, GET /v10/projects · projects[].abuse, GET /v10/projects · abuse, POST /v11/projects · abuse +2 more
    Code that breaks
    // response.projects[0].abuse is now undefined
    const abuse = response.projects[0].abuse;
2 new request properties
  • ConnectConnectorCreateData.defaultResource
  • ConnectConnectorUpdateData.defaultResource
Vercel2 breaking2 behavioral1 additive
  • Breakingdirection flip: their tools call this safe

    meterReason can now return "retention_opt_out"

    Producer-side tools call this additive. It breaks exhaustive switches, strict parsers and generated client enums.

    Team.deploymentStorageRollout.meterReason · reachable from 3 operations
    Code that breaks
    switch (response.deploymentStorageRollout.meterReason) {
      // existing branches …
      // no branch for "retention_opt_out"
      default:
        throw new Error("unexpected meterReason");
    }
  • Breakingdirection flip: their tools call this safe

    cohort can now return "already_metered", "extreme", "medium_plus", "metered_opt_in"

    Producer-side tools call this additive. It breaks exhaustive switches, strict parsers and generated client enums.

    Team.deploymentStorageRollout.cohort · reachable from 3 operations
    Code that breaks
    switch (response.deploymentStorageRollout.cohort) {
      // existing branches …
      // no branch for "already_metered"
      // no branch for "extreme"
      // no branch for "medium_plus"
      // no branch for "metered_opt_in"
      default:
        throw new Error("unexpected cohort");
    }
  • Behavioral

    409 is now documented on /v1/connect/authorize/{connector}

    An unhandled branch in your error handling.

    POST /v1/connect/authorize/{connector} · 6 call sites
  • Behavioral

    504 is now documented on /v1/connect/connectors/{connector}

    An unhandled branch in your error handling.

    GET /v1/connect/connectors/{connector} · 5 call sites
  • Additive

    Response field defaultContinuousUsageKind added

    No action needed unless you validate responses against a closed schema.

    Team.defaultContinuousUsageKind · reachable from 3 operations
Vercel1 breaking5 additive
  • Breaking

    Response field schema removed

    Reads of this field return undefined, and the failure surfaces wherever that value is used rather than at the call.

    18 places: GET /v1/global-config · schema, POST /v1/global-config · syncedToDynamoAt, POST /v1/global-config · transfer, GET /v1/global-config/{edgeConfigId} · schema, GET /v1/global-config · purpose, GET /v1/global-config · transfer +12 more
    Code that breaks
    // response.schema is now undefined
    const schema = response.schema;
5 new response fields
  • expectationRef
  • expectationRevision
  • runs[].expectationRef
  • runs[].expectationRevision
  • createdBy
Vercel1 breaking
  • Breaking

    Response field email removed

    Reads of this field return undefined, and the failure surfaces wherever that value is used rather than at the call.

    76 places: UserEvent.payload.newOwner.email, UserEvent.payload.newOwner.emailDomains, UserEvent.payload.newOwner.emailNotifications, UserEvent.payload.newOwner.enablePreviewFeedback, UserEvent.payload.newOwner.importFlowGitNamespaceId, UserEvent.payload.newOwner.acceptanceState +70 more
    Code that breaks
    // response.payload.newOwner.email is now undefined
    const email = response.payload.newOwner.email;
Vercel3 breaking19 additive
  • Breakingdirection flip: their tools call this safe

    permissions can now return "read-write:project-trusted-sources", "read:project-trusted-sources"

    Producer-side tools call this additive. It breaks exhaustive switches, strict parsers and generated client enums.

    can now return "read-write:project-trusted-sources", "read:project-trusted-sources"

    4 places: UserEvent.payload.before.permissions[], UserEvent.payload.permissions[], UserEvent.payload.nextPermissions[], UserEvent.payload.after.permissions[]
    Code that breaks
    switch (response.payload.before.permissions[0]) {
      // existing branches …
      // no branch for "read-write:project-trusted-sources"
      // no branch for "read:project-trusted-sources"
      default:
        throw new Error("unexpected permissions");
    }
  • Breaking

    Response field default removed

    Reads of this field return undefined, and the failure surfaces wherever that value is used rather than at the call.

    UserEvent.payload.next.default · reachable from 1 operation
    Code that breaks
    // response.payload.next.default is now undefined
    const default = response.payload.next.default;
  • Breaking

    Response field roles removed

    UserEvent.payload.next.roles · reachable from 1 operation
    Code that breaks
    // response.payload.next.roles is now undefined
    const roles = response.payload.next.roles;
  • Additive

    action is now optional

    No action needed.

    GET /v1/security/firewall/events · action
  • Additive

    ruleKind is now optional

    GET /v1/security/firewall/events · ruleKind
  • Additive

    sort is now optional

    GET /v1/security/firewall/events · sort
  • Additive

    actionType is now optional

    GET /v1/security/firewall/events · actionType
  • Additive

    cursor is now optional

    GET /v1/security/firewall/events · cursor
  • Additive

    ip is now optional

    GET /v1/security/firewall/events · ip
  • Additive

    isActive is now optional

    GET /v1/security/firewall/events · isActive
  • Additive

    limit is now optional

    GET /v1/security/firewall/events · limit
  • Additive

    ruleId is now optional

    GET /v1/security/firewall/events · ruleId
  • Additive

    /v1/security/firewall/events/summary added

    No action needed.

    /v1/security/firewall/events/summary
9 new response fields
  • abuse.blockHistory[].abuseAgentRunId
  • projects[].abuse.blockHistory[].abuseAgentRunId
  • abuse.block.abuseAgentRunId
  • projects[].abuse.block.abuseAgentRunId
  • UserEvent.payload.next.teams
  • UserEvent.payload.newOwner.abuse.blockHistory[].abuseAgentRunId
  • UserEvent.payload.next.organizationPermissions
  • UserEvent.payload.next.teamRoles
  • pagination
Vercel3 breaking1 behavioral4 additive
  • Breaking

    Response field createdAt removed

    Reads of this field return undefined, and the failure surfaces wherever that value is used rather than at the call.

    14 places: GET /v1/global-config · createdAt, GET /v1/global-config · createdBy, GET /v1/global-config · deletedAt, GET /v1/global-config · digest, GET /v1/global-config · id, GET /v1/global-config · itemCount +8 more
    Code that breaks
    // response.createdAt is now undefined
    const createdAt = response.createdAt;
  • Breakingdirection flip: their tools call this safe

    name can now return "flags-connection-created", "flags-connection-deleted"

    Producer-side tools call this additive. It breaks exhaustive switches, strict parsers and generated client enums.

    can now return "flags-connection-created", "flags-connection-deleted"

    3 places: ListEventType.name, ListEventType.replacedBy[], UserEvent.type
    Code that breaks
    switch (response.name) {
      // existing branches …
      // no branch for "flags-connection-created"
      // no branch for "flags-connection-deleted"
      default:
        throw new Error("unexpected name");
    }
  • Breaking

    value changed type

    Parse failure, or silent coercion depending on your client.

    GET /v1/global-config
    Code that breaks
    // payload
    // was: object
    // now: array
  • Behavioral

    204 is now documented on /v1/global-config/{edgeConfigId}/item/{edgeConfigItemKey}

    An unhandled branch in your error handling.

    GET /v1/global-config/{edgeConfigId}/item/{edgeConfigItemKey}
4 new response fields
  • Session.v0
  • NamedSandbox.v0
  • Snapshot.v0
  • Drive.v0
Vercel2 breaking6 additive