How do I search for process instances within a specific process ID when I know the value of a variable? I can use bpmnProcessId filter at /process-instances/search, and find instances by variable value at /variables/search. How do I combine them in one search?
If you know the name of the variable, even if you filter only by its name you will probably have several instances, the next problem will be how to resolve the precise instance
However this endpoint solves the issue of getting an IP by the variable name:
Yes, I know both name (ssn) and value of the variable. There should only be zero or one instance of the combination: Process ID + variable ssn with specific value. I am actually only interested if there is a hit or not.
@Bjorn_S In Camunda 8, to search for process instances within a specific bpmnProcessId
where a variable has a specific value, you’re right that:
/process-instances/search
allows filtering bybpmnProcessId
,state
,startDate
, etc./variables/search
allows filtering by variable name/value but doesn’t directly exposebpmnProcessId
.
However, there’s no out-of-the-box API endpoint that directly supports combining bpmnProcessId
and variable-based filtering in a single query. So you need to combine both filters manually in a two-step approach.
Two-step search (most practical via REST)
-
Search variables via
/variables/search
:POST /variables/search { "filter": { "name": "yourVariableName", "value": "yourValue" } }
This returns a list of
processInstanceKey
s that have the desired variable. -
Search process instances via
/process-instances/search
using the keys:POST /process-instances/search { "filter": { "bpmnProcessId": "yourProcessId", "processInstanceKeys": [12345, 67890] // from step 1 } }
Notes:
- You may need to batch the second request if the list of keys is large.
- Both endpoints are part of Operate API, and these APIs are not public-facing by default in self-managed setups. You must expose the Operate REST API if not already done.
- You can add other filters like
state
,startDate
, etc., as needed.
@Bjorn_S You can try something like below:
Here’s a sample Java implementation (using RestTemplate
) that:
- Searches for variables with a specific value (
/variables/search
). - Filters process instances matching a given
bpmnProcessId
and the matchingprocessInstanceKeys
from step 1 (/process-instances/search
).
Prerequisites
Add spring-web
dependency (for RestTemplate
), or use your preferred HTTP client (like OkHttp or WebClient).
Java Code
import org.springframework.http.*;
import org.springframework.web.client.RestTemplate;
import java.util.*;
public class Camunda8Search {
private static final String BASE_URL = "http://<operate-host>:<port>/v1";
private static final RestTemplate restTemplate = new RestTemplate();
public static void main(String[] args) {
String variableName = "customerId";
String variableValue = "12345";
String bpmnProcessId = "invoiceProcess";
List<Long> processInstanceKeys = getProcessInstanceKeysByVariable(variableName, variableValue);
if (processInstanceKeys.isEmpty()) {
System.out.println("No process instances found with the given variable.");
return;
}
List<Map<String, Object>> result = getProcessInstancesByProcessIdAndKeys(bpmnProcessId, processInstanceKeys);
// Print results
result.forEach(System.out::println);
}
private static List<Long> getProcessInstanceKeysByVariable(String name, String value) {
String url = BASE_URL + "/variables/search";
Map<String, Object> filter = Map.of("name", name, "value", value);
Map<String, Object> request = Map.of("filter", filter);
HttpEntity<Map<String, Object>> entity = new HttpEntity<>(request, getHeaders());
ResponseEntity<List> response = restTemplate.exchange(url, HttpMethod.POST, entity, List.class);
List<Map<String, Object>> variables = response.getBody();
List<Long> keys = new ArrayList<>();
if (variables != null) {
for (Map<String, Object> var : variables) {
Object key = var.get("processInstanceKey");
if (key instanceof Number) {
keys.add(((Number) key).longValue());
}
}
}
return keys;
}
private static List<Map<String, Object>> getProcessInstancesByProcessIdAndKeys(String bpmnProcessId, List<Long> keys) {
String url = BASE_URL + "/process-instances/search";
Map<String, Object> filter = new HashMap<>();
filter.put("bpmnProcessId", bpmnProcessId);
filter.put("processInstanceKeys", keys);
Map<String, Object> request = Map.of("filter", filter);
HttpEntity<Map<String, Object>> entity = new HttpEntity<>(request, getHeaders());
ResponseEntity<List> response = restTemplate.exchange(url, HttpMethod.POST, entity, List.class);
List<Map<String, Object>> instances = response.getBody();
return instances != null ? instances : Collections.emptyList();
}
private static HttpHeaders getHeaders() {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
// Add basic auth or bearer token if required
return headers;
}
}
Optional: Auth Support
If your Operate API is protected:
headers.setBasicAuth("username", "password");
// OR
headers.setBearerAuth("token");
Output
It will print matching process instances with:
- Matching variable (
customerId = 12345
) - Belonging to BPMN process (
invoiceProcess
)