Build a Workflow from Scratch (Builder API)
While creating a Workflow from a Blueprint is ideal for repeatable processes, SignStack also provides a powerful "Builder API" giving you complete control to define and launch unique, one-off workflows entirely through code.
This approach is perfect when your application needs to dynamically generate the workflow structure itself, perhaps based on user input or complex internal logic. Think of it like building a custom house brick-by-brick instead of using a pre-designed floor plan.
💡 Using the UI: You can also build custom workflows visually using the SignStack dashboard.
The Workflow Object: Key Components
Creating a workflow programmatically involves defining a JSON object that describes the entire process. Before diving into the API calls, let's understand the key sections of this object:
-
displayName(Optionalstring): A human-readable name for this specific workflow instance (e.g., "Custom Enterprise Deal - Q4"). -
documents(Requiredarray): Defines the specific documents involved. Each entry specifies:-
key: A unique key for this document instance within the workflow (e.g.,mainAgreement). -
fileId(Optional): The ID of the base PDF file. Optional iftemplateKeyis specified. -
templateKey(Optional): The key of aTemplateto inherit field definitions and metadata from. If bothfileIdand atemplateKeyare provided, thefileIdhere overrides the template's default file. -
entityMapping: An object mapping the template's requiredentitySlotkeys to theentitykeys defined in this workflow request (e.g.,{ "customer": "clientInfo", "deal": "dealInfo" }).
-
-
participants(Requiredarray): Defines the actual people (name, email) involved in this specific workflow instance, each identified by a uniquekeyfor referencing within this request (e.g.,primarySigner). -
entities(Requiredarray): Provides the initial data state for the workflow. Each entry specifies thekeyfor this instance (e.g.,clientInfo), theschemaKeydefining its structure, and the actualdataobject. -
steps(Requiredarray) &rootStepKey(Requiredstring): This defines the core process logic using SignStack's recursiveStepmodel. You'll defineContainersteps (withexecutionMode,completionRule,children) andTasksteps (likeparticipantTaskwhich links aparticipantKeyto specificroleLinkson documents). TherootStepIdpoints to the entry point of this step tree. -
status(Optionalstring): Determines the initial state. Set toDraftif building incrementally, orInProgressif creating and sending in one go. Defaults toDraft.
Building Incrementally with the API (Recommended for Dev/Debug)
While you can send the entire object in one POST request (see "Alternative" below), building it incrementally using PATCH is often easier during development as it allows for validation at each stage.
Step 1: Create a Draft Workflow
Start by creating an empty container.
-
Endpoint:
POST /v1/organizations/{organizationId}/workflows -
Request Body:
{ "displayName": "Custom Deal - Project Phoenix" } -
Response:
201 Createdwith the newWorkflowobject (status: "Draft"). Store the returnedid.
Step 2: Add Components (documents, participants, entities)
Use PATCH requests to add the core components to the draft. Send only the sections you want to add or update.
-
Endpoint:
PATCH /v1/organizations/{organizationId}/workflows/{workflowId} -
Request Body (Example):
{ "documents": [ { "key": "mainAgreement", "fileId": "file_abc...", "templateKey": "standardContractV3", "entityMapping": { "customer": "clientInfo", "deal": "dealInfo" } } ], "participants": [ { "key": "signerA", "firstName": "Jane", "lastName": "Doe", "email": "..." } ], "entities": [ { "key": "clientInfo", "schemaKey": "customerSchemaV1", "data": { ... } } ] } -
Response:
200 OKwith the updatedWorkflowobject (still inDraft).
Step 3: Define the Workflow Steps
Add the process logic by sending the steps array and rootStepId.
-
Endpoint:
PATCH /v1/organizations/{organizationId}/workflows/{workflowId} -
Request Body:
{ "rootStepKey": "root", "steps": [ { "key": "root", "type": "CONTAINER", "executionMode": "SEQUENTIAL", "completionRule": "ALL", "children": ["buyerSignStep"] }, { "key": "buyerSignStep", "type": "PARTICIPANT_TASK", "participantTask": { "participantKey": "signerA", "roleLinks": [ { "documentKey": "mainAgreement", "templateRoleKey": "primaryBuyer" } ] } } ] } -
Response:
200 OKwith the fully definedWorkflowobject (stillDraft).
Step 4: Send the Workflow
Once fully defined and valid, trigger execution.
-
Endpoint:
POST /v1/organizations/{organizationId}/workflows/{workflowId}/send -
Request Body: (Can be empty)
-
Backend Logic: Validates, sets
statustoInProgress, generates signing tokens, starts the root step, and enqueues notifications. -
Response:
200 OKwith the updatedWorkflowobject (status: "InProgress").
Alternative: Single API Call
The POST /v1/organizations/{orgId}/workflows endpoint also supports creating and sending a workflow in a single call. To do this, provide the complete Workflow object (including documents, participants, entities, steps, rootStepId) and set the initial status to InProgress in the request body.
This single-cal method is often more efficient for production integrations but can be harder to debug if the initial payload is invalid.
The Builder API provides ultimate flexibility, allowing you to programmatically construct any workflow imaginable directly from your application code.
➡️ Next: Guides: Monitor Workflow Status