{"slug": "additive-vercel-2-new-response-fields", "title": "[Additive] Vercel: 2 new response fields", "summary": "Vercel shipped two additive response fields to its API, permissions.schedulePreview and projects[].permissions.schedulePreview, alongside a set of new enum values that strict parsers and generated clients must handle. The new values include event names such as \"ai-security-review\", \"firewall-conditional-bypass-updated\", \"integration-secret-rotated\" and \"vercel-agent-security-finding-created\", plus \"aws-oidc\" for type, \"org-admin-sync\" for membership.joinedFrom.origin, \"14cpu-28gb\" for buildMachineType, and the permissions \"read-write:ai-gateway-byok-credentials\" and \"read:ai-gateway-byok-credentials\". Vercel labels the changes additive and says no action is needed, but notes they break exhaustive switches, strict parsers and generated client enums, and that fields such as transferRequest, v0 and elasticBuildMachine.memory now return undefined.", "body_md": "[Vercel](https://driftwatch.et/apis/vercel)2 additive\n\n## 2 new response fields\n\n- permissions.schedulePreview\n- projects[].permissions.schedulePreview\n\n[APIs](https://driftwatch.et/providers) / Vercel\n\nBreaking changes, deprecations and new fields in the Vercel API, as they ship.\n\nProducer-side tools call this additive. It breaks exhaustive switches, strict parsers and generated client enums.\n\ncan now return \"organization-team-dsync-update\"\n\n```\nswitch (response.name) {\n  // existing branches …\n  // no branch for \"organization-team-dsync-update\"\n  default:\n    throw new Error(\"unexpected name\");\n}\n```\n\ncan now return \"aws-oidc\"\n\n```\nswitch (response.type) {\n  // existing branches …\n  // no branch for \"aws-oidc\"\n  default:\n    throw new Error(\"unexpected type\");\n}\n```\n\nAn unhandled branch in your error handling.\n\ncan now return \"ai-security-review\", \"firewall-conditional-bypass-updated\", \"integration-previous-secret-revoked\", \"integration-secret-rotated\", \"team-runtime-cache-updated\", \"vercel-agent-security-finding-created\"\n\n```\nswitch (response.name) {\n  // existing branches …\n  // no branch for \"ai-security-review\"\n  // no branch for \"firewall-conditional-bypass-updated\"\n  // no branch for \"integration-previous-secret-revoked\"\n  // no branch for \"integration-secret-rotated\"\n  // no branch for \"team-runtime-cache-updated\"\n  // no branch for \"vercel-agent-security-finding-created\"\n  default:\n    throw new Error(\"unexpected name\");\n}\nswitch (response.source) {\n  // existing branches …\n  // no branch for \"project-overview-recommended-integrations\"\n  default:\n    throw new Error(\"unexpected source\");\n}\n```\n\nReads of this field return undefined, and the failure surfaces wherever that value is used rather than at the call.\n\n``` js\n// response.transferRequest is now undefined\nconst transferRequest = response.transferRequest;\n```\n\nNo action needed.\n\ncan now return \"org-admin-sync\"\n\n```\nswitch (response.membership.joinedFrom.origin) {\n  // existing branches …\n  // no branch for \"org-admin-sync\"\n  default:\n    throw new Error(\"unexpected origin\");\n}\n```\n\ncan now return \"team-data-cache-user-disabled-updated\"\n\n```\nswitch (response.replacedBy[0]) {\n  // existing branches …\n  // no branch for \"team-data-cache-user-disabled-updated\"\n  default:\n    throw new Error(\"unexpected replacedBy\");\n}\n```\n\ncan now return \"connect-branding-updated\"\n\n```\nswitch (response.name) {\n  // existing branches …\n  // no branch for \"connect-branding-updated\"\n  default:\n    throw new Error(\"unexpected name\");\n}\n```\n\ncan now return \"14cpu-28gb\"\n\n```\nswitch (response.resourceConfig.buildMachineType) {\n  // existing branches …\n  // no branch for \"14cpu-28gb\"\n  default:\n    throw new Error(\"unexpected buildMachineType\");\n}\n```\n\ncan now return \"read-write:ai-gateway-byok-credentials\", \"read:ai-gateway-byok-credentials\"\n\n```\nswitch (response.payload.permissions[0]) {\n  // existing branches …\n  // no branch for \"read-write:ai-gateway-byok-credentials\"\n  // no branch for \"read:ai-gateway-byok-credentials\"\n  default:\n    throw new Error(\"unexpected permissions\");\n}\n```\n\nNo action needed unless it is required.\n\n```\n// response.projects[0].resourceConfig.elasticBuildMachine.memory is now undefined\nconst memory = response.projects[0].resourceConfig.elasticBuildMachine.memory;\n// response.defaultResourceConfig.elasticBuildMachine.label is now undefined\nconst label = response.defaultResourceConfig.elasticBuildMachine.label;\n// response.projects[0].defaultResourceConfig.elasticBuildMachine.cores is now undefined\nconst cores = response.projects[0].defaultResourceConfig.elasticBuildMachine.cores;\n```\n\nDead branch, or an undocumented response you still receive.\n\n``` js\n// response.v0 is now undefined\nconst v0 = response.v0;\n```\n\ncan now return \"project-git-credential-attestation-created\", \"project-git-credential-attestation-deleted\", \"project-git-credential-grant-attestation-revoked\", \"project-git-credential-grant-attested\"\n\n```\nswitch (response.name) {\n  // existing branches …\n  // no branch for \"project-git-credential-attestation-created\"\n  // no branch for \"project-git-credential-attestation-deleted\"\n  // no branch for \"project-git-credential-grant-attestation-revoked\"\n  // no branch for \"project-git-credential-grant-attested\"\n  default:\n    throw new Error(\"unexpected name\");\n}\n```\n\ncan now return \"project\"\n\n```\nswitch (response.creator.type) {\n  // existing branches …\n  // no branch for \"project\"\n  default:\n    throw new Error(\"unexpected type\");\n}\n```\n\ncan now return \"messageboard-project-channel-created\", \"messageboard-project-private-channel-created\"\n\n```\nswitch (response.name) {\n  // existing branches …\n  // no branch for \"messageboard-project-channel-created\"\n  // no branch for \"messageboard-project-private-channel-created\"\n  default:\n    throw new Error(\"unexpected name\");\n}\n```\n\ncan now return \"messageboard-private-project-granted\", \"messageboard-private-project-revoked\", \"messageboard-project-granted\", \"messageboard-project-revoked\"\n\n```\nswitch (response.name) {\n  // existing branches …\n  // no branch for \"messageboard-private-project-granted\"\n  // no branch for \"messageboard-private-project-revoked\"\n  // no branch for \"messageboard-project-granted\"\n  // no branch for \"messageboard-project-revoked\"\n  default:\n    throw new Error(\"unexpected name\");\n}\n```\n\ncan now return \"startup-terms-accepted\"\n\n```\nswitch (response.replacedBy[0]) {\n  // existing branches …\n  // no branch for \"startup-terms-accepted\"\n  default:\n    throw new Error(\"unexpected replacedBy\");\n}\n```\n\nA relaxation. Existing payloads are unaffected.\n\ncan now return \"organization-sso-deleted\"\n\n```\nswitch (response.name) {\n  // existing branches …\n  // no branch for \"organization-sso-deleted\"\n  default:\n    throw new Error(\"unexpected name\");\n}\njs\n// response.resourceConfig.buildMachine.cores is now undefined\nconst cores = response.resourceConfig.buildMachine.cores;\nswitch (response.config.resourceConfig.buildMachine.purchaseType) {\n  // existing branches …\n  // no branch for \"14cpu-28gb\"\n  default:\n    throw new Error(\"unexpected purchaseType\");\n}\n```\n\ncan now return \"read-write:webhooks\"\n\n```\nswitch (response.payload.permissions[0]) {\n  // existing branches …\n  // no branch for \"read-write:webhooks\"\n  default:\n    throw new Error(\"unexpected permissions\");\n}\njs\n// response.daemons[0].config.replicas is now undefined\nconst replicas = response.daemons[0].config.replicas;\njs\n// response.daemons[0].config.configuredReplicas is now undefined\nconst configuredReplicas = response.daemons[0].config.configuredReplicas;\njs\n// response.projects[0].permissions.messageboardSpace is now undefined\nconst messageboardSpace = response.projects[0].permissions.messageboardSpace;\n```\n\ncan now return \"product\"\n\n```\nswitch (response.payload.budget.budgetItem.scope) {\n  // existing branches …\n  // no branch for \"product\"\n  default:\n    throw new Error(\"unexpected scope\");\n}\n```\n\ncan now return \"messageboard-channel-created\", \"messageboard-channel-updated\", \"messageboard-private-channel-created\", \"messageboard-private-channel-updated\"\n\n```\nswitch (response.replacedBy[0]) {\n  // existing branches …\n  // no branch for \"messageboard-channel-created\"\n  // no branch for \"messageboard-channel-updated\"\n  // no branch for \"messageboard-private-channel-created\"\n  // no branch for \"messageboard-private-channel-updated\"\n  default:\n    throw new Error(\"unexpected replacedBy\");\n}\njs\n// response.ownerId is now undefined\nconst ownerId = response.ownerId;\njs\n// response.payload.spaceId is now undefined\nconst spaceId = response.payload.spaceId;\n```\n\ncan now return \"xaa-updated\"\n\n```\nswitch (response.name) {\n  // existing branches …\n  // no branch for \"xaa-updated\"\n  default:\n    throw new Error(\"unexpected name\");\n}\njs\n// response.daemons[0].config.image.vhs is now undefined\nconst vhs = response.daemons[0].config.image.vhs;\njs\n// response.daemons[0].replicas.items[0].iroh is now undefined\nconst iroh = response.daemons[0].replicas.items[0].iroh;\n```\n\ncan now return \"use:github\"\n\n```\nswitch (response.payload.permissions[0]) {\n  // existing branches …\n  // no branch for \"use:github\"\n  default:\n    throw new Error(\"unexpected permissions\");\n}\njs\n// response.payload.data.reason is now undefined\nconst reason = response.payload.data.reason;\njs\n// response.payload.data.planSlug is now undefined\nconst planSlug = response.payload.data.planSlug;\n```\n\nNo error is raised. The value is ignored and your results change silently, which is the hardest class of break to notice.\n\n```\nawait client.post(\"/v2/sandboxes/sessions/{sessionId}/cmd\", {\n  // cmdId is now ignored, not rejected\n  cmdId: value,\n});\n```\n\ncan now return \"connect-cancel-mcp-event-subscription\", \"connect-create-mcp-event-subscription\", \"organization-name-update\"\n\n```\nswitch (response.type) {\n  // existing branches …\n  // no branch for \"connect-cancel-mcp-event-subscription\"\n  // no branch for \"connect-create-mcp-event-subscription\"\n  // no branch for \"organization-name-update\"\n  default:\n    throw new Error(\"unexpected type\");\n}\n```\n\ncan now return \"read-write:access-group\"\n\n```\nswitch (response.payload.nextPermissions[0]) {\n  // existing branches …\n  // no branch for \"read-write:access-group\"\n  default:\n    throw new Error(\"unexpected nextPermissions\");\n}\n```\n\nProducer-side tools call this non-breaking. For a consumer it is a null dereference on an unknown future date.\n\n``` js\n// response.payload.author may now be absent or null\nconst author = response.payload.author ?? fallback;\n```\n\ncan now return \"26.x\"\n\n```\nswitch (response.projects[0].nodeVersion) {\n  // existing branches …\n  // no branch for \"26.x\"\n  default:\n    throw new Error(\"unexpected nodeVersion\");\n}\njs\n// response.result is now undefined\nconst result = response.result;\njs\n// response.pagination is now undefined\nconst pagination = response.pagination;\n```\n\ncan now return \"firewall-conditional-bypass-created\", \"firewall-conditional-bypass-deleted\"\n\n```\nswitch (response.name) {\n  // existing branches …\n  // no branch for \"firewall-conditional-bypass-created\"\n  // no branch for \"firewall-conditional-bypass-deleted\"\n  default:\n    throw new Error(\"unexpected name\");\n}\n```\n\nNo action needed unless you validate responses against a closed schema.\n\ncan now return \"response_code\"\n\n```\nswitch (response.active.rulesets[0].conditionGroup[0].conditions[0].type) {\n  // existing branches …\n  // no branch for \"response_code\"\n  default:\n    throw new Error(\"unexpected type\");\n}\n```\n\ncan now return \"read-write:project-members\", \"read:audit-log\", \"read:project-members\"\n\n```\nswitch (response.payload.permissions[0]) {\n  // existing branches …\n  // no branch for \"read-write:project-members\"\n  // no branch for \"read:audit-log\"\n  // no branch for \"read:project-members\"\n  default:\n    throw new Error(\"unexpected permissions\");\n}\n```\n\ncan now return \"read-write:ai-gateway-budgets\", \"read:ai-gateway-budgets\"\n\n```\nswitch (response.payload.after.permissions[0]) {\n  // existing branches …\n  // no branch for \"read-write:ai-gateway-budgets\"\n  // no branch for \"read:ai-gateway-budgets\"\n  default:\n    throw new Error(\"unexpected permissions\");\n}\n// response.services[0].builder.config.daemon.replicas may now be absent or null\nconst replicas = response.services[0].builder.config.daemon.replicas ?? fallback;\n```\n\nUsually ignored rather than rejected, so the call succeeds and does something subtly different.\n\n```\nawait client.post(\"/v9/projects/{idOrName}\", {\n  // protectionMode is now ignored, not rejected\n  protectionMode: value,\n});\n```\n\ncan now return \"admin-saml-sp-signing-key-created\", \"admin-saml-sp-signing-key-updated\"\n\n```\nswitch (response.name) {\n  // existing branches …\n  // no branch for \"admin-saml-sp-signing-key-created\"\n  // no branch for \"admin-saml-sp-signing-key-updated\"\n  default:\n    throw new Error(\"unexpected name\");\n}\n```\n\ncan now return \"organization-dsync-sync-start\"\n\n```\nswitch (response.name) {\n  // existing branches …\n  // no branch for \"organization-dsync-sync-start\"\n  default:\n    throw new Error(\"unexpected name\");\n}\n```\n\ncan now return \"admin-saml-idp-material-deleted\", \"admin-saml-idp-material-set\", \"vercel-ci-repository-settings-updated\"\n\n```\nswitch (response.name) {\n  // existing branches …\n  // no branch for \"admin-saml-idp-material-deleted\"\n  // no branch for \"admin-saml-idp-material-set\"\n  // no branch for \"vercel-ci-repository-settings-updated\"\n  default:\n    throw new Error(\"unexpected name\");\n}\n```\n\ncan now return \"stripe-api-key\"\n\n```\nswitch (response.type) {\n  // existing branches …\n  // no branch for \"stripe-api-key\"\n  default:\n    throw new Error(\"unexpected type\");\n}\n```\n\ncan now return \"sandbox-drive-snapshot-created\", \"sandbox-drive-snapshot-deleted\"\n\n```\nswitch (response.name) {\n  // existing branches …\n  // no branch for \"sandbox-drive-snapshot-created\"\n  // no branch for \"sandbox-drive-snapshot-deleted\"\n  default:\n    throw new Error(\"unexpected name\");\n}\n```\n\ncan now return \"organization-dsync-delete\"\n\n```\nswitch (response.type) {\n  // existing branches …\n  // no branch for \"organization-dsync-delete\"\n  default:\n    throw new Error(\"unexpected type\");\n}\n```\n\n", "url": "https://wpnews.pro/news/additive-vercel-2-new-response-fields", "canonical_source": "https://driftwatch.et/apis/vercel#cmvyuv46c00010djmxc63qae9-fields", "published_at": "2026-11-02 05:25:39+00:00", "updated_at": "2026-11-02 06:22:09.722907+00:00", "lang": "en", "topics": ["developer-tools", "ai-infrastructure"], "entities": ["Vercel"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/additive-vercel-2-new-response-fields", "markdown": "https://wpnews.pro/news/additive-vercel-2-new-response-fields.md", "text": "https://wpnews.pro/news/additive-vercel-2-new-response-fields.txt", "jsonld": "https://wpnews.pro/news/additive-vercel-2-new-response-fields.jsonld"}}