Migrate from Camunda 7
This guide walks you through migrating an existing Camunda Platform 7 application to Priostack. Most migrations can be completed in a day for small projects, or a week for large enterprise deployments.
https://priostack.com/api/v1, HTTPS and JSON, API key in X-API-Key). Job logic can stay; there is no /engine-rest, no gRPC and no Zeebe client support, so URLs alone do not carry over.
Section 1: What's Compatible
Priostack runs BPMN 2.0, so your existing process diagrams transfer with changes limited to extensions. What runs on the hosted service:
- Tasks, gateways (exclusive, parallel, inclusive, event-based), embedded sub-processes, and event sub-processes with a timer start event (the other start events deploy but have no hosted trigger)
- Call activities that name, in the standard
calledElementattribute, a process deployed before the caller (otherwise the call is offered to workers as a job of typecallActivity:<name>) - Sequence flow conditions using FEEL expressions
- Timer intermediate and boundary events with an ISO 8601 duration or date. A
timeCycleis refused at deploy, and a timer start event does not schedule anything: instances start through the API - Compensation handlers, run in reverse order when the model throws compensation explicitly
- Multi-instance tasks (parallel and sequential)
- DMN 1.3 decision tables, evaluated inline by a business rule task
What is accepted at deploy but has no hosted trigger today: message and signal catch events and receive tasks wait as ordinary worker jobs (there is no message or signal API, see the table below), and error and escalation boundary events do not fire from worker code, because the REST API has no call for a worker to throw a BPMN error.
Section 2: What's Different
| Camunda 7 | Priostack |
|---|---|
Java Delegates (camunda:class) |
External service tasks with job workers. No Java required. |
| Embedded Spring/CDI injection | Workers are standalone services that poll the API. Any language. |
| Groovy scripts in Script Tasks | Not run inline. A script task becomes a worker job of type script:<name or id>; move the logic into a worker. |
Java API (RuntimeService, TaskService) |
REST API over HTTPS and JSON. Job workers use Zeebe-style REST calls (POST /api/v1/jobs/activate, /complete, /fail), not the Zeebe gRPC protocol. |
camunda:formKey for user tasks |
No form support. A user task is a job of type userTask; render the form in your own UI or the Tasklist and complete it with POST /api/v1/tasks/{id}/complete. |
| Cockpit UI for monitoring | Priostack Console at priostack.com/console |
REST Engine API (/engine-rest/) |
Priostack REST API (/api/v1/). Different paths and bodies: see the feature mapping below. |
| History tables in relational DB | Process history via REST API and Console |
| Self-hosted (on your infrastructure) | Hosted service at priostack.com. There is no self-hosted edition. |
Section 3: Migration Steps
Step 1: Export Your BPMN Files
From Camunda Modeler or Cockpit, export all your BPMN files as .bpmn XML files. Keep DMN files too.
Step 2: Remove Camunda-Specific Extensions
Open each BPMN file and replace Camunda 7 extension elements. The Priostack snippets are fragments: paste them inside a <definitions> element that declares xmlns:zeebe="http://camunda.org/schema/zeebe/1.0".
<serviceTask id="validateOrder"
camunda:class="com.example.ValidateOrderDelegate"
camunda:asyncBefore="true" />
<serviceTask id="validateOrder"
name="Validate Order">
<extensionElements>
<zeebe:taskDefinition
type="validate-order"
retries="3" />
</extensionElements>
</serviceTask>
<userTask id="review"
camunda:assignee="${reviewer}"
camunda:candidateGroups="managers" />
<userTask id="review" name="Review Order" />
<!-- Assignment is not read from the model.
Assign or claim through the API:
POST /api/v1/tasks/{id}/assign
POST /api/v1/tasks/{id}/claim -->
Step 3: Rewrite Java Delegates as Workers
For each Java Delegate class, create an equivalent external worker in Go, Python, or JavaScript. See the Workers Guide.
@Component
public class ValidateOrderDelegate
implements JavaDelegate {
@Autowired
private OrderService orderService;
@Override
public void execute(DelegateExecution exec) {
String orderId = (String) exec
.getVariable("orderId");
boolean valid = orderService.validate(orderId);
exec.setVariable("orderValid", valid);
}
}
func processJob(job Job) (map[string]interface{}, error) {
orderId, _ := job.Variables["orderId"].(string)
// Call your existing service
valid, err := orderService.Validate(orderId)
if err != nil {
return nil, err
}
return map[string]interface{}{
"orderValid": valid,
}, nil
}
Step 4: Update API Calls
POST /engine-rest/process-definition
/key/order-processing/start
{
"variables": {
"orderId": { "value": "123", "type": "String" }
}
}
POST /api/v1/process-instances
X-API-Key: your_key
{
"bpmnProcessId": "order-processing",
"variables": {
"orderId": "123"
}
}
Step 5: Deploy and Test
# Deploy your updated BPMN (free on this route; 200 with a deployments array)
curl -X POST "https://priostack.com/api/v1/process-definitions?resourceName=order-processing.bpmn" \
-H "X-API-Key: your_key" \
-H "Content-Type: application/xml" \
--data-binary @order-processing.bpmn
# Start your workers
export PRIOSTACK_API_KEY=your_key
go run worker.go
# Start a test instance (201, costs 1 credit)
curl -X POST https://priostack.com/api/v1/process-instances \
-H "X-API-Key: your_key" \
-H "Content-Type: application/json" \
-d '{"bpmnProcessId":"order-processing","variables":{"orderId":"TEST-001"}}'
Section 4: Feature Mapping
| Camunda 7 Feature | Priostack Equivalent | Notes |
|---|---|---|
| RuntimeService.startProcessInstanceByKey() | POST /api/v1/process-instances | Direct REST equivalent |
| TaskService.complete() | POST /api/v1/tasks/{id}/complete, or completeTask on POST /api/v1/graphql | The REST route costs 1 credit; the GraphQL mutation is free |
| ExternalTaskService | POST /api/v1/jobs/activate + /complete | Zeebe-style polling |
| DecisionService.evaluateDecision() | POST /api/v1/decisions/{decisionId}/evaluate, or a BusinessRuleTask in BPMN | Deploy the DMN first with POST /api/v1/models |
| HistoryService.createProcessInstanceQuery() | GET /api/v1/process-instances | REST API |
| ManagementService (incidents) | GET /api/v1/incidents | REST API |
| Cockpit web app | priostack.com/console | Hosted monitoring UI |
| Tasklist web app | priostack.com/tasklist | Hosted human task UI |
| camunda:formKey | Not supported | Build the form in your own UI |
| Message correlation (correlate()) | Not available on the hosted API | There is no message route today. A message wait is a worker job (message:<name> or event:message:<elementId>) that a worker can complete, with no correlation-key matching |