Skip to main content
Version: 8.9 (unreleased)

Camunda 8.9 APIs & Tools migration guide

Migrate your API integrations, SDKs, and generated clients to Camunda 8.9.

About this guide

This guide details the API and SDK changes introduced in Camunda 8.9 that require customer action.

Details are provided for each integration type, including what changed, why, and what action you must take.

Integration typeDescription
Official SDK usersJava client, TypeScript SDK, Python SDK, C# SDK.
Generated-client usersClients generated from the Camunda OpenAPI specification.
Custom integrationsCustom code that calls the Camunda REST API directly.
info

For a full list of changes, see the 8.9 release announcements and release notes.

Upgrade steps

Complete the following steps in this guide:

  1. Upgrade to the latest official Camunda SDK versions.
  2. If you generate clients from OpenAPI, regenerate them from the 8.9 specification.
  3. Re-run compilation/type checks and address any errors.
  4. Review and apply fixes for the breaking changes, deprecations, and supported environment changes below.

API and SDK changes to migrate before Camunda 8.10

If you did not already migrate to the following APIs and SDKs during your 8.8 upgrade, Camunda recommends you perform these migrations before you upgrade to 8.9, as this must be performed before 8.10.

If you already performed these migrations during your 8.8 upgrade, proceed to Camunda 8.9 breaking changes, deprecations, and supported environment changes.

8.9 statusComponent/UseMigrate toMigrate by
DeprecatedV1 component APIsOrchestration Cluster APIBefore Camunda 8.10
DeprecatedZeebeClientCamunda Java ClientBefore Camunda 8.10
DeprecatedSpring Zeebe SDKCamunda Spring Boot StarterBefore Camunda 8.10
DeprecatedZeebe Process Test (ZPT)Camunda Process Test (CPT)Before Camunda 8.10
DeprecatedJob-based user tasksCamunda user tasksBefore Camunda 8.10
tip

Camunda 8.9 breaking changes, deprecations, and supported environment changes

Review the actions required for the following 8.9 changes:

TypeChange
Breaking changeBug fix: FormResult.schema type corrected from object to string
Breaking changeDocument API response schemas now have explicit required and nullable annotations
Breaking changeMCP Client and MCP Remote Client connectors
Breaking changeOpenAPI enum extensions
Breaking changeOpenAPI type-safety enhancements
Breaking changeResource deletion endpoint now returns a response body
Breaking changeSearch filter validation errors now return structured error collections
Breaking changeSpring Boot 4.0 default for Camunda Spring Boot Starter
Breaking changeType-safe pagination model in the Camunda Java client
Breaking changeversionTag returns null instead of empty string when absent
DeprecatedDeprecated: enum literals in Orchestration Cluster API v2

Breaking changes

Review actions required for the following breaking changes:

Bug fix: FormResult.schema type corrected from object to string

Change

The schema property in FormResult was incorrectly specified as type: object in the OpenAPI contract. The server has always returned it as a JSON string. The specification is now corrected.

Why

This is a bug fix. The original specification was inaccurate and caused incorrect typing in generated clients.

Impact

This impacts the Java client as io.camunda.client.api.search.response.Form::getSchema() now returns String instead of Object.

Action

Update to the latest SDK version. If you are a Java client user, update any calls to Form::getSchema() that cast or process the return value as Object — it is now String.

Document API response schemas now have explicit required and nullable annotations

Change

The OpenAPI specification now uses distinct schemas for document request and response payloads, and adds explicit required / nullable annotations to document response types.

Why

A shared DocumentMetadata schema was used for both creating and reading documents. Because response fields like customProperties are always populated by the server but optional in requests, a single schema could not accurately express both contracts. This caused incorrect required/optional behavior in generated clients.

Affected schemas

SchemaChange
DocumentMetadataNow request-only. Removed required: [customProperties]customProperties is now optional in requests.
DocumentMetadataResponse (new)Response schema with required fields: fileName, expiresAt, size, contentType, customProperties, processDefinitionId, processInstanceKey. expiresAt, processDefinitionId, and processInstanceKey are nullable.
DocumentReferencemetadata now references DocumentMetadataResponse. Added required: camunda.document.type, storeId, documentId, contentHash, metadata. contentHash is now nullable.
DocumentLinkurl and expiresAt are now explicitly required.
UserTaskResult.candidateGroupsNow marked as required in the response schema.
UserTaskProperties.candidateGroupsNow marked as required in the response schema.

Impact

The Java client is impacted as DocumentMetadataImpl (both io.camunda.client and the deprecated io.camunda.zeebe.client) now uses DocumentMetadataResponse instead of DocumentMetadata internally.

Action

Update to the latest SDK version. The updated response models are included automatically. Re-compile your application to verify.

MCP Client and MCP Remote Client connectors

Change

Breaking changes were introduced in alpha 2 to the element templates and runtime configuration of the MCP Client.

Why

This improves the stability and configuration model of the MCP connectors.

Action

Update both the MCP Client and MCP Remote Client connectors to use element template version 1. See the MCP documentation for details.

OpenAPI enum extensions

Change

New enum literals were added to support expanded 8.9 functionality.

Why

These additions enable new features such as decision instance deletion and user task authorization.

Enum members added

EnumNew value
BatchOperationTypeEnum / BatchOperationTypeFilterPropertyDELETE_DECISION_INSTANCE
ResourceTypeEnumUSER_TASK
PermissionTypeEnumCOMPLETE

Action

Update to the latest SDK version for full enum support. Re-compile your application — the compiler will signal any exhaustive match issues.

OpenAPI type-safety enhancements

Change

Several request properties in the OpenAPI contract now use stronger domain types instead of plain string, and one schema type was renamed. This completes the type-safety work that began in 8.8.

Why

This increases compile-time safety and helps prevent semantic substitution errors — for example, accidentally passing a tenantId where a documentId is expected. Compilers can now reason about semantic correctness in addition to structural correctness for these fields.

Affected fields and types

FieldOld typeNew type
CreateDeploymentData.body.tenantIdstringTenantId
CreateDocumentData.query.documentIdstringDocumentId
SearchCorrelatedMessageSubscriptionsData.body.filter.processDefinitionKey.$eqstringProcessDefinitionKey
CorrelatedMessageSubscriptionFilter.processDefinitionKeystringProcessDefinitionKeyFilterProperty | undefined
CorrelatedMessageSubscriptionSearchQuery.filter.processDefinitionKey.$eqstringProcessDefinitionKey

Schema rename

Old nameNew name
ProcessInstanceIncidentSearchQueryIncidentSearchQuery

Example — message subscription filter payload:

Before
{
"processDefinitionKey": "2251799813685251"
}
After (for example, using $eq)
{
"processDefinitionKey": { "$eq": "2251799813685251" }
}

Action

Update to the latest SDK version. The wire-type of these fields does not change, so most SDK users will not need code changes. Re-compile your application to verify.

Resource deletion endpoint now returns a response body

Change

The resource deletion endpoint POST /resources/{resourceKey}/deletion now returns a response body instead of an empty response.

Why

This provides explicit deletion feedback, making client-side confirmation, auditing, and follow-up workflow logic more reliable.

Action

Update to the latest SDK version. The updated response model is included automatically.

Spring Boot 4.0 default for Camunda Spring Boot Starter

Change

Starting with 8.9.0, the default Camunda Spring Boot Starter (camunda-spring-boot-starter) is bundled with and requires Spring Boot 4.0.x. A dedicated camunda-spring-boot-3-starter module is available for applications that are not yet ready to upgrade.

Action

  • Migrate your application to Spring Boot 4.0.x and continue using camunda-spring-boot-starter.
  • If you cannot migrate yet, switch your dependency to camunda-spring-boot-3-starter, which is bundled with Spring Boot 3.5.x. Note that OSS support for Spring Boot 3.5.x ends in June 2026, so plan your migration accordingly.
  • See the Spring Boot support timeline for details.
  • See the dedicated Spring Boot 3 and 4 modules documentation for more information.

versionTag returns null instead of empty string when absent

Change

API response fields for versionTag now return null instead of an empty string "" when no version tag is set.

Why

This properly signals absence instead of leaking an internal empty-string default. It aligns versionTag with how other optional fields like businessId are handled, simplifying absence-detection logic.

Action

Update to the latest SDK version. Review any code that checks for an empty string ("") to detect a missing version tag, and update it to check for null.

Search filter validation errors now return structured error collections

Change

REST API search endpoints now collect all filter validation errors and return them together in a single 400 Bad Request response. Previously, only the first conversion error was returned.

Why

This is a bug fix that improves error handling consistency across the REST API. Collecting all validation errors in a single response makes debugging easier.

Impact

Search filter validation error responses now contain a list of all validation issues instead of stopping at the first error. The error detail format has changed:

AspectBeforeAfterBreaking?
HTTP status code400400No
ProblemDetail title"Bad Request""INVALID_ARGUMENT"Yes
ProblemDetail detail"Failed to parse date-time: [invalid]""The provided evaluationDate 'invalid' cannot be parsed as a date according to RFC 3339, section 5.6."Yes
Error collectionFails on first errorCollects all validation errorsYes (response may contain more errors)

Affected search endpoints include all endpoints that accept advanced search filters with key fields (such as processInstanceKey, processDefinitionKey, scopeKey) or date fields (such as startDate, endDate, creationDate).

Who is affected?

  • Customers parsing error response bodies (specifically title or detail fields) for validation errors → affected.
  • Customers only checking HTTP status codes → not affected.
  • Customers sending valid requests → not affected (happy path is unchanged).

Action

If your code parses error response bodies from search endpoints for specific validation error messages, update it to handle:

  • The title field value changed from "Bad Request" to "INVALID_ARGUMENT".
  • The detail field now contains more descriptive, structured messages.
  • A collection of validation errors in the response body (instead of a single error message).

Type-safe pagination model in the Camunda Java client

Change

The Camunda Java client now uses type-safe pagination interfaces (AnyPage, OffsetPage, CursorForwardPage, CursorBackwardPage) instead of the previous SearchRequestPage class. Each search or statistics endpoint exposes only the pagination methods it actually supports.

Direction methods on AnyPage now return style-specific interfaces: from() returns OffsetPage, after() returns CursorForwardPage, and before() returns CursorBackwardPage. This prevents mixing incompatible pagination styles at compile time.

Why

The previous API allowed mixing incompatible pagination styles (for example, .page(p -> p.from(10).after("cursor"))), which always resulted in a 400 Bad Request at runtime. This change surfaces that restriction at compile time. The pattern mirrors the existing sort polymorphism design (TypedSortableRequest).

Impact

This change is not binary-compatible. Code compiled against the previous API will fail at runtime without recompilation, because the method signature changed from page(Consumer<SearchRequestPage>) to page(Consumer<AnyPage>). All users must recompile their applications.

Additionally, TypedSearchRequest now has 4 generic type parameters (previously 3) and TypedPageableRequest now has 2 (previously 1), which is a source-breaking change for custom implementations of these interfaces.

Migration reference

Before (8.8)After (8.9)
import ...search.request.SearchRequestPageimport ...search.page.AnyPage
import ...search.request.SearchRequestOffsetPageimport ...search.page.OffsetPage
Consumer<SearchRequestPage>Consumer<AnyPage>
Consumer<SearchRequestOffsetPage>Consumer<OffsetPage>
SearchRequestBuilders.searchRequestPage(fn)SearchRequestBuilders.anyPage(fn) (old method deprecated)
implements TypedSearchRequest<F, S, Self>implements TypedSearchRequest<F, S, AnyPage, Self>
implements TypedPageableRequest<Self>implements TypedPageableRequest<AnyPage, Self>
SearchRequestPage r = p.from(10)OffsetPage r = p.from(10)
SearchRequestPage r = p.after("c")CursorForwardPage r = p.after("c")

Action

Update to the latest Java client version and recompile your application. If you use inline lambdas with valid pagination patterns (for example, .page(p -> p.from(5).limit(10))), your source code does not require changes — but recompilation is mandatory.

If you have explicit references to SearchRequestPage, replace them with AnyPage. If you store the return value of direction methods (for example, SearchRequestPage r = p.from(10)), update the variable type to OffsetPage, CursorForwardPage, or CursorBackwardPage as appropriate.

note

This change is specific to the Camunda Java client. Generated clients and custom REST API integrations are not affected.

Deprecations

Review the actions required for the following deprecations:

Deprecated: enum literals in Orchestration Cluster API v2

The following enum literals are now marked as deprecated:

  • UNSPECIFIED in DecisionDefinitionTypeEnum
  • UNKNOWN in DecisionInstanceStateFilterProperty
  • UNKNOWN in DecisionInstanceStateEnum

These values were reintroduced to preserve backward compatibility but are planned for removal in a future release. Removal will be signaled as a breaking change at that time.

Action

Avoid using these values in new integrations. If your code references them, plan to remove these references before the 8.10 release.

Next steps

Once you have completed the upgrade steps in this guide, you should:

  1. Re-compile and run your test suite against the 8.9 API.
  2. Review 8.9 release announcements for additional context on each change.