📦 Generated API ​
One file per BPMN process, containing type-safe constants for all extracted elements.
Structure ​
The generated Process API is an object (Kotlin) or class (Java) with nested sections:
| Section | Contents |
|---|---|
PROCESS_ID | The process identifier from the BPMN model |
Elements | All flow node IDs (tasks, events, gateways, subprocesses) |
CallActivities | Called process IDs for call activity elements |
Messages | Message names from message events and receive tasks |
TaskTypes | Worker types / topics / delegate expressions from service tasks |
Timers | Timer configurations with type and value |
Errors | Error definitions with name and code |
Signals | Signal names from signal events |
Variables | All extracted process variables |
Sections are only included when the BPMN model contains matching elements.
Full Example ​
Given a newsletter subscription BPMN process, bpmn-to-code generates:
// Generated by bpmn-to-code
@file:Suppress("unused")
package de.emaarco.example
object NewsletterSubscriptionProcessApiV1 {
const val PROCESS_ID: String = "newsletterSubscription"
object Elements {
const val TIMER_EVERY_DAY: String = "Timer_EveryDay"
const val TIMER_AFTER_3_DAYS: String = "Timer_After3Days"
const val ERROR_EVENT_INVALID_MAIL: String = "ErrorEvent_InvalidMail"
const val ACTIVITY_CONFIRM_REGISTRATION: String = "Activity_ConfirmRegistration"
const val SUB_PROCESS_CONFIRMATION: String = "SubProcess_Confirmation"
const val END_EVENT_REGISTRATION_ABORTED: String = "EndEvent_RegistrationAborted"
const val END_EVENT_SUBSCRIPTION_CONFIRMED: String = "EndEvent_SubscriptionConfirmed"
const val END_EVENT_REGISTRATION_COMPLETED: String = "EndEvent_RegistrationCompleted"
const val END_EVENT_REGISTRATION_NOT_POSSIBLE: String = "EndEvent_RegistrationNotPossible"
const val ACTIVITY_ABORT_REGISTRATION: String = "Activity_AbortRegistration"
const val ACTIVITY_SEND_WELCOME_MAIL: String = "Activity_SendWelcomeMail"
const val ACTIVITY_SEND_CONFIRMATION_MAIL: String = "Activity_SendConfirmationMail"
const val START_EVENT_SUBMIT_REGISTRATION_FORM: String = "StartEvent_SubmitRegistrationForm"
const val START_EVENT_REQUEST_RECEIVED: String = "StartEvent_RequestReceived"
}
object Messages {
const val MESSAGE_FORM_SUBMITTED: String = "Message_FormSubmitted"
const val MESSAGE_SUBSCRIPTION_CONFIRMED: String = "Message_SubscriptionConfirmed"
}
object TaskTypes {
const val NEWSLETTER_REGISTRATION_COMPLETED: String = "newsletter.registrationCompleted"
const val NEWSLETTER_ABORT_REGISTRATION: String = "newsletter.abortRegistration"
const val NEWSLETTER_SEND_WELCOME_MAIL: String = "newsletter.sendWelcomeMail"
const val NEWSLETTER_SEND_CONFIRMATION_MAIL: String = "newsletter.sendConfirmationMail"
}
object Timers {
val TIMER_EVERY_DAY: BpmnTimer = BpmnTimer("Duration", "PT1M")
val TIMER_AFTER_3_DAYS: BpmnTimer = BpmnTimer("Duration", "PT2M30S")
data class BpmnTimer(
val type: String,
val timerValue: String,
)
}
object Errors {
val ERROR_INVALID_MAIL: BpmnError = BpmnError("Error_InvalidMail", "500")
data class BpmnError(
val name: String,
val code: String,
)
}
object Signals {
const val SIGNAL_REGISTRATION_NOT_POSSIBLE: String = "Signal_RegistrationNotPossible"
}
object Variables {
const val SUBSCRIPTION_ID: String = "subscriptionId"
}
}// Generated by bpmn-to-code
package de.emaarco.example;
public class NewsletterSubscriptionProcessApiV1 {
public static final String PROCESS_ID = "newsletterSubscription";
public static class Elements {
public static final String TIMER_EVERY_DAY = "Timer_EveryDay";
public static final String ACTIVITY_CONFIRM_REGISTRATION = "Activity_ConfirmRegistration";
// ... same constants as Kotlin, with Java syntax
}
public static class Messages {
public static final String MESSAGE_FORM_SUBMITTED = "Message_FormSubmitted";
public static final String MESSAGE_SUBSCRIPTION_CONFIRMED = "Message_SubscriptionConfirmed";
}
// ... same structure for TaskTypes, Timers, Errors, Signals, Variables
}Variable Extraction ​
Variables are extracted from different sources depending on the engine. See the engine-specific pages for details:
- Zeebe — variables from
zeebe:ioMappingandzeebe:loopCharacteristics - Camunda 7 — variables from
camunda:inputOutput,camunda:in/camunda:out,camunda:properties, and multi-instance attributes - Operaton — same patterns as Camunda 7, using the
operaton:namespace
INFO
bpmn-to-code only extracts variables from explicit I/O mappings, not from expressions in sequence flows, gateways, or script tasks. This is by design — the BPMN model should be the single source of truth for its variable contract.
Model Merging ​
When multiple BPMN files share the same processId, bpmn-to-code merges them into a single API. The generated API contains the superset of all elements across all files.
This is useful for process variants (e.g. dev vs prod configurations) that share the same process identifier.