Process Document
Last updated: September 29, 2026
Updated by: VNPT eContract's team
Purpose
Processes a single-file document according to its workflow, covering 4 types of actions: Approve, Sign Draw, E-Sign, and SmartCA Digital Signature. The API can also process adjacent workflow steps together with the root process.
See also: Batch Document Process API
- Request URL:
/api/documents/process - HTTP method:
POST - HTTP content-type:
application/json - Authorize:
Bearer token
This function requires the processId (which is the waitingProcess.id/id of the processing step) obtained from the send document process API or the login by process code API. This function only works after one of the two APIs above has already been called and returned process (process) data in the response body.
Adjacent process parameters
The following optional parameters can be added to the request of any processing action below:
| Key | Type | Required | Description |
|---|---|---|---|
processAllAdjacentProcesses | boolean | No | Process all adjacent workflow steps using their configured setup values. |
adjacentProcesses | Array[object] | No | Explicit list of adjacent workflow steps to process together with the root process. |
Each item in adjacentProcesses supports:
| Key | Type | Required | Description |
|---|---|---|---|
processId | string | Yes | ID of the adjacent process. |
signingPage | int | No | Signing page. If omitted, the configured process value is used. |
signingPosition | string | No | Signing coordinates. If omitted, the configured process value is used. |
signatureDisplayMode | int | No | Signature display mode for Sign Draw/E-Sign: 1 text only, 2 text and image, 3 image only. |
reason | string | No | Processing/signing reason for the adjacent process. |
signatureImage | string | No | Signature image as Base64/Data URI for Sign Draw/E-Sign. |
signatureText | string | No | Displayed signature text for Sign Draw/E-Sign. |
fontSize | int | No | Signature text font size for Sign Draw/E-Sign. |
| Configuration | Behavior |
|---|---|
processAllAdjacentProcesses: false, without adjacentProcesses | Process only the root process identified by processId. |
processAllAdjacentProcesses: false, with adjacentProcesses | Process the root process and only the explicitly listed adjacent processes. |
processAllAdjacentProcesses: true, without adjacentProcesses | Process the root process and all adjacent processes using configured setup values. |
Do not send processAllAdjacentProcesses: true together with adjacentProcesses unless this combination has been confirmed for the deployed version. The precedence between these two options is not defined in the source specification.
Sample request with adjacent processes
{
"processId": "a5af6828-6470-4282-8e42-08df1d03012f",
"reason": "Agree",
"reject": false,
"signatureDisplayMode": 2,
"signatureImage": "data:image/png;base64,...",
"signingPage": 1,
"signingPosition": "10,100,200,150",
"signatureText": "Confirm document content",
"fontSize": 12,
"processAllAdjacentProcesses": false,
"adjacentProcesses": [
{
"processId": "d70fdf67-3fc2-4ca0-8e41-08df1d03012f",
"reason": "Agree",
"signatureDisplayMode": 2,
"signatureImage": "data:image/png;base64,...",
"signingPage": 2,
"signingPosition": "10,100,200,150",
"signatureText": "Confirm document content",
"fontSize": 12
}
]
}
1. Approve
Applies to a processing step with accessPermission = 3 (Approve). The workflow consists of 2 API calls: step 1 sends a request for the system to send a confirmation OTP, step 2 sends the request again along with the OTP to confirm approval.
Parameters
| Key | Type | Description |
|---|---|---|
processId | string | [Required] ID of the pending processing step (from waitingProcess.id/process.id) |
reason | string | [Required] Reason for approval / rejection |
reject | boolean | [Required] Reject approval true: reject |
otp | string | [Required] OTP confirmation code // First call: pass null // Second call: pass the OTP received via Email/SMS |
Sample Request — Call 1
{
"processId": "08f2f33f-1abc-4567-1a30-08def6b00923",
"reason": "Agree",
"reject": false,
"otp": null
}
Sample Response — Call 1 (System sends confirmation OTP)
{
"data": {
"isBatchProcess": false,
"isSingleProcess": false,
"isProcessedByWorkerService": false,
"processId": "08f2f33f-1abc-4567-1a30-08def6b00923",
"documentId": "b0e5b86c-f4fb-42b4-9b7d-e679ce37e17a",
"documentIds": [],
"accessPermission": 3,
"signMethod": 2,
"signatureDisplayMode": 2,
"batchProcessStatus": 0,
"signingPage": 0,
"reason": "Agree",
"confirmReason": "Agree",
"showReason": false,
"fontSize": 0,
"receiveOtpMethod": 1,
"receiveOtpEmail": "example@gmail.com",
"requireOtpConfirmation": true,
"generateOtp": false,
"vnptCaPluginAdvancedSign": false
},
"success": true,
"code": 100,
"messages": [
"Send confirmation otp success"
]
}
code: 100 with the message "Send confirmation otp success" indicates the system has sent an OTP to the user's Email/SMS. You must call the API a second time, keeping the same parameters and adding the otp value, to complete the approval.
Sample Request — Call 2 (After receiving the OTP via Email/SMS)
{
"processId": "08f2f33f-1abc-4567-1a30-08def6b00923",
"reason": "Agree",
"reject": false,
"otp": "932230"
}
Sample Response — Call 2 (Approval successful)
Responses below have been shortened.
{
"data": {
"id": "b0e5b86c-f4fb-42b4-9b7d-e679ce37e17a",
"createdDate": "2026-08-12T17:15:26.2252705",
"lastModifiedDate": "2026-08-19T10:47:02.1618765+07:00",
"completedDate": "2026-08-19T10:47:02.161878+07:00",
"no": "26.CKDS.HR.EL49",
"subject": "Document 26.CKDS.HR.EL49",
"hasVerified": false,
"hasVerify": false,
"status": {
"value": 4,
"description": "Completed"
},
"contractStatus": {
"value": 0,
"description": "Undefined"
},
"createdByUserId": 2,
"processRecipientCount": 1,
"type": {
"id": 1,
"code": "CKDS",
"name": "Sales discount",
"description": "Sales discount document",
"documentCount": 1,
"children": []
},
"processes": [
{
"id": "08f2f33f-1abc-4567-1a30-08def6b00923",
"createdDate": "2026-08-12T17:15:38.1856745",
"comId": 1,
"isOrder": true,
"orderNo": 1,
"reason": "Agree",
"displayType": {
"value": 0,
"description": "0"
},
"accessPermission": {
"value": 3,
"description": "Approve"
},
"status": {
"value": 4,
"description": "Approved"
},
"processedDate": "2026-08-19T10:47:02.1608829+07:00",
"processedByUserId": 2,
"documentId": "b0e5b86c-f4fb-42b4-9b7d-e679ce37e17a",
"fillingItems": [],
"fileInfoId": "c551a762-b4e8-4907-40ef-08def6b0091b",
"attachments": []
}
],
"downloadUrl": "{{HOST}}/Api/Download?token=...",
"downloadOriginalUrl": "{{HOST}}/Api/Download?token=...",
"downloadWatermarkMetadataUrl": "{{HOST}}/Api/Download?token=...",
"fixedPosition": false
},
"success": true,
"code": 0,
"messages": [
"Approve document success"
]
}
2. Sign Draw
Applies to a processing step with accessPermission = 2 (Sign draw). The workflow consists of 2 API calls, similar to Approve, but with additional signature-related parameters (image, position, signature content, etc.).
Parameters
| Key | Type | Description |
|---|---|---|
processId | string | [Required] ID of the pending processing step (from waitingProcess.id/process.id) |
reason | string | [Required] Reason for signing / rejecting the signature |
reject | boolean | [Required] Reject signing the document true: reject signing the document |
otp | string | [Required] OTP confirmation code // First call: pass null // Second call: pass the OTP confirming the sign/reject action received via Email/SMS |
signatureDisplayMode | int | [Required] Signature display mode 1: Text only 2: Text and image 3: Image only |
signatureImage | string | [Required] Signature image // base64 string of the signature image |
signingPage | int | [Required] Signing page number |
signingPosition | string | [Required] Signing position / coordinates Rectangle = llx, lly, urx, ury - llx, lly = bottom-left coordinates of the signature - urx = llx + width - ury = lly + height The coordinate origin is the bottom-left corner of the document |
signatureText | string | [Required] Signature content |
fontSize | int | [Required] Font size |
showReason | boolean | [Required] Show reason false: do not show the signing reason true: show the signing reason |
confirmTermsConditions | boolean | [Required] Confirm legal terms and conditions before processing the document false: not agreed true: agreed |
Sample Request — Call 1
{
"processId": "e3516f41-dc3f-4e04-ba61-6a658ffa1b52",
"reason": "Agree with the content submitted for signing",
"reject": false,
"otp": null,
"signatureDisplayMode": 3,
"signatureImage": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAD…",
"signingPage": 1,
"signingPosition": "10,110,202,200",
"signatureText": "Signature Text",
"fontSize": 12,
"showReason": false,
"confirmTermsConditions": true
}
Sample Response — Call 1 (System sends confirmation OTP)
{
"data": {
"isBatchProcess": false,
"isSingleProcess": false,
"documentId": "b3db2a04-01fc-4cde-b27a-b24e26c77f86",
"accessPermission": 2,
"signMethod": 2,
"signatureDisplayMode": 0,
"batchProcessStatus": 0,
"signingPage": 0,
"signatureText": "Signature Text",
"signatureImage": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAD…",
"reason": "Agree with the content submitted for signing",
"confirmReason": "Agree",
"showReason": false,
"fontSize": 0,
"receiveOtpMethod": 1,
"receiveOtpPhone": "0919XXXXXX",
"receiveOtpEmail": "email_address",
"requireOtpConfirmation": true,
"vnptCaPluginAdvancedSign": false
},
"success": true,
"code": 100,
"messages": [
"Send confirmation otp success"
]
}
Sample Request — Call 2 (After receiving the OTP via Email/SMS)
{
"processId": "e3516f41-dc3f-4e04-ba61-6a658ffa1b52",
"reason": "Agree with the content submitted for signing",
"reject": false,
"otp": "089278",
"signatureDisplayMode": 3,
"signatureImage": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUg…",
"signingPage": 1,
"signingPosition": "10,110,202,200",
"signatureText": "Signature Text",
"fontSize": 12,
"showReason": false,
"confirmTermsConditions": true
}
Sample Response — Call 2 (Signing successful)
The response structure is the same as the Call 2 response for the Approve section above (full document details after processing), except for the messages returned:
Responses below have been shortened.
{
"data": {
"id": "b3db2a04-01fc-4cde-b27a-b24e26c77f86",
"createdDate": "2026-08-12T08:42:57.0910118",
"lastModifiedDate": "2026-08-19T09:59:47.2167854+07:00",
"completedDate": "2026-08-19T09:59:47.2169471+07:00",
"no": "26.CKDS.HR.EL49",
"subject": "Document 26.CKDS.HR.EL49",
"hasVerified": false,
"hasVerify": false,
"status": {
"value": 4,
"description": "Completed"
},
"contractStatus": {
"value": 0,
"description": "Undefined"
},
"createdByUserId": 1,
"processRecipientCount": 1,
"waitingProcesses": [],
"type": {
"id": 1,
"code": "CKDS",
"name": "Sales discount",
"description": "Sales discount document",
"documentCount": 1,
"children": []
},
"processes": [
{
"id": "df641313-b0d4-4020-1a2e-08def6b00923",
"createdDate": "2026-08-12T08:42:57.1493998",
"comId": 1,
"isOrder": true,
"orderNo": 1,
"signatureText": "Confirm document content",
"reason": "Agree",
"pageSign": 4,
"position": "345,190,485,250",
"fontSize": 12,
"displayType": {
"value": 2,
"description": "Text and image"
},
"signedMethod": {
"value": 2,
"description": "VNPT SmartCA"
},
"accessPermission": {
"value": 2,
"description": "Sign draw"
},
"status": {
"value": 3,
"description": "Signed"
},
"processedDate": "2026-08-19T09:59:47.1071048+07:00",
"processedByUserId": 2,
"documentId": "b3db2a04-01fc-4cde-b27a-b24e26c77f86"
}
],
"downloadUrl": "{{HOST}}/Api/Download?token=...",
"downloadOriginalUrl": "{{HOST}}/Api/Download?token=...",
"downloadWatermarkMetadataUrl": "{{HOST}}/Api/Download?token=...",
"fixedPosition": false
},
"success": true,
"code": 0,
"messages": [
"Sign document success"
]
}
3. E-Sign
Applies to a processing step with accessPermission = 7 (E-Sign). The submitted parameters, number of API calls (2 calls, with OTP), and response structure are entirely the same as the Sign Draw section above.
Parameters
Same parameters as 2. Sign Draw: processId, reason, reject, otp, signatureDisplayMode, signatureImage, signingPage, signingPosition, signatureText, fontSize, showReason, confirmTermsConditions.
Sample Request — Call 1 and Call 2
Same as the Sign Draw section: on the first call, pass otp: null so the system sends an OTP; on the second call, resend the request with the otp value received via Email/SMS.
Sample Response
- Call 1:
code: 100,messages: ["Send confirmation otp success"]— thedatastructure is the same as the Sign Draw section. - Call 2 (success):
code: 0,messages: ["Sign document success"]— thedatastructure is the full document detail after processing (same as the Call 2 response for the Approve section).
4. SmartCA Digital Signature
Applies to a processing step whose accessPermission is linked to the signing method signMethod = 2 (VNPT Smart CA). Unlike the 3 processing types above, SmartCA Digital Signature only requires a single API call and does not use the Email/SMS OTP mechanism — the system forwards the signing request to the SmartCA application/service and waits for the user to confirm the signature on the SmartCA side before returning the result.
Parameters
| Key | Type | Description |
|---|---|---|
processId | string | [Required] ID of the pending processing step (from waitingProcess.id/process.id) |
reason | string | [Required] Reason for signing / rejecting the signature |
reject | boolean | [Required] Reject signing the document true: reject signing the document |
signatureDisplayMode | int | [Required] Signature display mode 1: Text only 2: Text and image 3: Image only |
signatureImage | string | [Required] Signature image // base64 string of the signature image |
signingPage | int | [Required] Signing page number |
signingPosition | string | [Required] Signing position / coordinates Rectangle = llx, lly, urx, ury (see the coordinate rules in 2. Sign Draw) |
signatureText | string | [Required] Signature content |
fontSize | int | [Required] Font size |
showReason | boolean | [Required] Show reason false: do not show the signing reason true: show the signing reason |
SmartCaCertId | int | [Required] ID of the user's SmartCA digital certificate used for signing (from userCertificates[].id/defaultSmartCa.id) |
isBusinessSmartCaAccount | boolean | [Required] Whether the SmartCA account is a business or personal account true: Business false: Personal |
Sample Request
{
"processId": "f17fafe8-2480-4131-b6dd-08defd9fcac4",
"reason": "Agree with the content submitted for signing",
"reject": false,
"signatureDisplayMode": 2,
"signatureImage": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAD…",
"signingPage": 1,
"signingPosition": "334,614,474,674",
"signatureText": "Signature Text",
"fontSize": 12,
"showReason": false,
"SmartCaCertId": 3,
"isBusinessSmartCaAccount": false
}
Sample Response (Signing successful)
After the user confirms the signature on the SmartCA application, the API returns a result whose data structure is the full document detail after processing — the same as the Call 2 response for Approve/Sign Draw, for example:
Responses below have been shortened.
{
"data": {
"id": "e3516f41-dc3f-4e04-ba61-6a658ffa1b52",
"createdDate": "2026-08-12T08:42:57.0910118",
"lastModifiedDate": "2026-08-19T10:37:47.8944885+07:00",
"completedDate": "2026-08-19T10:37:47.8944888+07:00",
"no": "26.CKDS.HR.EL49",
"subject": "Document 26.CKDS.HR.EL49",
"hasVerified": false,
"hasVerify": false,
"status": {
"value": 4,
"description": "Completed"
},
"contractStatus": {
"value": 0,
"description": "Undefined"
},
"createdByUserId": 1,
"processRecipientCount": 2,
"waitingProcesses": [],
"type": {
"id": 1,
"code": "CKDS",
"name": "Sales discount",
"description": "Sales discount document",
"documentCount": 1,
"children": []
},
"processes": [
{
"id": "df641313-b0d4-4020-1a2e-08def6b00923",
"createdDate": "2026-08-12T08:42:57.1493998",
"comId": 1,
"isOrder": true,
"orderNo": 1,
"signatureText": "Signature Text",
"reason": "Agree with the content submitted for signing",
"pageSign": 1,
"position": "334,614,474,674",
"fontSize": 12,
"displayType": {
"value": 2,
"description": "Text and image"
},
"signedMethod": {
"value": 2,
"description": "VNPT SmartCA"
},
"accessPermission": {
"value": 7,
"description": "E-Sign"
},
"status": {
"value": 3,
"description": "Signed"
},
"processedDate": "2026-08-19T10:11:07.1403968",
"processedByUserId": 2,
"documentId": "e3516f41-dc3f-4e04-ba61-6a658ffa1b52"
}
],
"fixedPosition": false
},
"success": true,
"code": 0,
"messages": [
"Sign document success"
]
}
Sample Response Description (Call 2)
| Key | Type | Description |
|---|---|---|
success | boolean | Request processing status (true: Success, false: Failed) |
code | int | Response code from the system |
messages | array | List of messages or errors returned by the system |
data | object | Object containing the detailed information of the successfully processed document (see details) |
Common Errors
| Message | Description |
|---|---|
Document process not found | processId does not exist. Check the process step ID of the document again. |