Browse by type
SDK API docs. Orchestration Cluster API Client full API docs.
This is the official Camunda 8 JavaScript SDK. It is written in TypeScript and runs on Node.js. See why this SDK does not run in a web browser.
If you need to run an application in the web browser, then look at using the @camunda8/orchestration-cluster-api package directly.
See the Getting Started Example in the Camunda Docs for a quick start.
This SDK provides API clients for various versions of Camunda 8. If you are doing a greenfield project on Camunda 8.8 or later, then you should consider directly using the @camunda8/orchestration-cluster-api package. That package provides a client for the Camunda 8 Orchestration Cluster API, a REST API with full functionality.
This SDK includes that client, but relying on this SDK package pulls in other API clients, which - if you are not using them - exposes you to several factors:
How to choose?
Use the @camunda8/sdk package if:
Use the @camunda8/orchestration-cluster-api package directly if:
The SDK provides clients for several Camunda 8 APIs.
If you are doing a greenfield project on Camunda 8.8.0 or later, then you should use the Camunda Orchestration Cluster API with getOrchestrationClusterApiClient. This is a REST API that provides complete cluster functionality in one API surface. This client is strongly typed and provides strong types for request and response fields (eg: ProcessInstanceKey, ProcessDefinitionId, etc).
To progressively adopt this client in existing projects alongside previous clients, you can call getOrchestrationClusterApiClientLoose to get a client that does not strongly type the request and response fields (they remain primitive scalar string type).
This is the official supported-by-Camunda Nodejs SDK for Camunda Platform 8.
The Node.js SDK will not always support all features of Camunda Platform 8 immediately upon their release. Complete API coverage for a platform release will lag behind the platform release.
Prioritisation of implementing features is influenced by customer demand.
The SDK package tracks Camunda Platform 8 minor versioning. Feature releases to support current Platform minor version features result in a patch release of the SDK.
Install the SDK as a dependency:
npm i @camunda8/sdk
The functionality of Camunda 8 is exposed via dedicated clients for the component APIs. The recommended API client for Camunda 8.8 is the Orchestration Cluster API, using the CamundaClient returned by getOrchestrationClusterApiClient().
import { Camunda8 } from '@camunda8/sdk'
const c8 = new Camunda8()
// Camunda 8 Orchestration Cluster API (STRICT client) - recommended from 8.8.0
// Provides strongly typed request & response IDs (e.g. ProcessInstanceKey, ProcessDefinitionId)
const orchestration = c8.getOrchestrationClusterApiClient()
// Camunda 8 Orchestration Cluster API (LOOSE client) - progressive adoption variant
// Same methods, but all IDs are plain string. Start here in existing codebases, then
// migrate to the strict client when convenient.
const orchestrationLoose = c8.getOrchestrationClusterApiClientLoose()
The configuration for the SDK can be done by any combination of environment variables and explicit configuration passed to the Camunda8 constructor.
The recommended method of configuration is using the zero-conf constructor, which hydrates the configuration completely from the environment:
const camunda = new Camunda8()
This allows you to cleanly separate the concern of configuration from your code and locate it purely in environment variable management.
The complete documentation of all configuration parameters (environment variables) can be found here.
Any configuration passed in to the Camunda8 constructor is merged over any configuration in the environment. The configuration object fields and the environment variables have exactly the same names.
From Camunda 8.8 onwards the unified Orchestration Cluster API is the preferred interface. This SDK exposes it via two factory methods to enable smooth, incremental migration:
| Factory | Purpose | ID / Key Types | Recommended Use |
|---|---|---|---|
getOrchestrationClusterApiClient() |
Strict (strongly typed) client | Branded TypeScript types (e.g. ProcessInstanceKey, ProcessDefinitionId) |
Greenfield projects or code already prepared for branded types |
getOrchestrationClusterApiClientLoose() |
Loose client | Plain string |
Progressive adoption in existing code expecting raw string IDs |
Branded (nominal) types significantly reduce accidental mixing of unrelated IDs (for example passing a decision definition id where a process instance key is expected). However, adopting them in an existing codebase can require refactors across many modules. The loose client lets you start calling the new endpoints immediately without touching those modules. You can then migrate incrementally to the strict client as you update code.
const ocaLoose = c8.getOrchestrationClusterApiClientLoose().getOrchestrationClusterApiClient() and address TypeScript compile errors by adopting the branded ID types (usually by propagating the type instead of string).Set ZEEBE_REST_ADDRESS without the version suffix; the SDK will append /v2 exactly once:
export ZEEBE_REST_ADDRESS='http://localhost:8888'
Results in effective base URL: http://localhost:8888/v2.
If you include /v2 already:
export ZEEBE_REST_ADDRESS='http://localhost:8888/v2'
It is preserved (not duplicated). Trailing slashes are stripped before normalization (http://localhost:8888/ -> http://localhost:8888/v2).
Use the strict client for new code, libraries, or examples where type safety improves clarity. Use the loose client when: - You need a rapid drop-in replacement without changing existing function signatures. - You are migrating many modules gradually. - You want to defer adoption of branded ID types until later.
Both clients expose identical method names and behaviors; only the TypeScript surface differs. Runtime semantics and responses are otherwise equivalent.
import { Camunda8 } from '@camunda8/sdk'
const c8 = new Camunda8()
// Strict client (preferred once migrated)
const oca = c8.getOrchestrationClusterApiClient()
const proc = await oca.createProcessInstance({
processDefinitionId: ProcessDefinitionId.assumeExists('order-process'),
variables: { orderId: 'A123' },
})
// proc.processInstanceKey is a branded type (not a plain string)
// Loose client (progressive adoption)
const ocaLoose = c8.getOrchestrationClusterApiClientLoose()
const procLoose = await ocaLoose.createProcessInstance({
processDefinitionId: 'order-process',
variables: { orderId: 'B456' },
})
// procLoose.processInstanceKey is a plain string
When converting code from loose to strict, remove unnecessary casts like (key as string) and allow the compiler to guide corrections where branded types surface.
To migrate existing code that uses plain strings for identifiers without immediately switching every module to the strict client, you can "lift" those strings into branded key types incrementally.
All branded key lifter namespaces are grouped under OrchestrationLifters so the root SDK export surface stays tidy:
import { OrchestrationLifters } from '@camunda8/sdk'
// Suppose you previously passed raw strings:
const rawProcessInstanceKey = '2251799813685249'
// Lift it to the branded type (runtime value is still a string, but type safety now applies):
const processInstanceKey = OrchestrationLifters.ProcessInstanceKey.assumeExists(rawProcessInstanceKey)
// Use with strict client
const c8 = new Camunda8()
const oca = c8.getOrchestrationClusterApiClient()
await oca.cancelProcessInstance({ processInstanceKey })
Common helper: assumeExists(value: string) turns a known-valid legacy identifier into its branded equivalent. Use this when you are certain the ID refers to an existing entity (the lifter does not perform a network validation; it is purely nominal typing).
Suggested incremental approach:
1. Start by replacing output values first (e.g. responses from createProcessInstance) where the strict client already returns branded types.
2. Introduce lifters at the boundaries where you still receive legacy strings (configuration, environment, persistence layer, legacy SDK modules).
3. Remove lifters once those boundaries natively produce branded types.
All available lifters (examples): ProcessInstanceKey, ProcessDefinitionId, JobKey, ElementInstanceKey, DecisionDefinitionKey, FormKey, UserTaskKey, VariableKey, etc. See OrchestrationLifters export for the complete list.
Entity keys in Camunda 8.6 and earlier are stored and represented as int64 numbers. The range of int64 extends to numbers that cannot be represented by the JavaScript number type. To deal with this, int64 keys are serialised by the SDK to the JavaScript string type. See this issue for more details.
For int64 values whose type is not known ahead of time, such as job variables, you can pass an annotated data transfer object (DTO) to decode them reliably. See the section on Process Variable Typing. If no DTO is specified, the default behavior of the SDK is to serialise all numbers to JavaScript number, and to throw an exception if a number value is detected at a runtime that cannot be accurately represented as the JavaScript number type (that is, a value greater than 2^53-1).
Calls to APIs can be authorized using a number of strategies. The most common is OAuth - a token that is obtained via a client id/secret pair exchange.
OAUTH strategy and provide configuration only. The token exchange and its lifecycle are managed by the SDK in this strategy. This passes the token in the authorization header of requests.BASIC strategy. This adds the login credentials as the authorization header on requests.COOKIE strategy. This manages a session cookie obtained from a login endpoint, and adds it as a cookie header to requests.BEARER strategy. This is a strategy that allows you to dynamically provide the Bearer token directly. The currently set token is added as the authorization header on requests.NONE strategy.For more details on each of these scenarios, see the relevant section below.
To disable Auth, set the environment variable CAMUNDA_AUTH_STRATEGY=NONE. You can use this when running against a minimal Zeebe broker in a development environment, for example. You can also use this when your authentication is being done using an x509 mTLS certificate (see the section on mTLS).
If your platform is secured with OAuth token exchange (Camunda SaaS or Self-Managed with Identity), provide the following configuration fields at a minimum, either via the Camunda8 constructor or in environment variables:
CAMUNDA_AUTH_STRATEGY=OAUTH
ZEEBE_GRPC_ADDRESS=...
ZEEBE_REST_ADDRESS=...
ZEEBE_CLIENT_ID=...
ZEEBE_CLIENT_SECRET=...
CAMUNDA_OAUTH_URL=...
To get a token for
$ claude mcp add camunda-8-js-sdk \
-- python -m otcore.mcp_server <graph>