Outcome
Issue any missing completion artifact for a completed envelope: the flattened PDF and the audit certificate bound to its source and completed hashes. Idempotent; existing artifacts are never regenerated.
Before you start
- Verify the environment, authenticated identity and specifically approved organization context.
- The published application permission is workspace:write. Resolve and bind the exact canonical Sign workspace. A supplied id or organization membership alone grants no workspace access.
- Session callers require read_write or admin workspace access. API-key resource binding is verified by Auth; never treat a caller-supplied header as an independent grant.
- Approve the documented mutation and actual recipient/document targets before CLI --confirm or MCP confirm:true. A synthetic fixture authorizes no live agreement, notification or data deletion.
Discover the target
topolo whoami --json
topolo actions get app_topolo_sign.envelopes.finalize --detail --json
topolo resources topolo-sign --json
topolo workspaces list topolo-sign --json
- Set SIGN_WORKSPACE_ID to the exact granted workspace returned by discovery.
- Resolve envelopeId through envelopes.list/get or retain the exact creation response.
Request
POST /api/envelopes/{envelopeId}/finalize
Inspect and test this action. Save the reviewed input as payload.json. Supply resource context separately.
Input fields
| Field | Required | Meaning | Constraints |
|---|---|---|---|
envelopeId | Required | Exact envelope.id returned by creation or envelopes.list/get in this workspace. | {"minLength":1} |
Read the complete input schema.
Effects
- Issues any completion artifact a completed envelope is still missing: the flattened completed PDF, then the audit certificate (JSON and PDF) bound to the source and completed hashes.
- Idempotent: an artifact that already exists is reused, never regenerated, so an attested hash never changes.
- Runs automatically when the last signer completes and from the scheduled sweep; call it only to recover an envelope that is still missing artifacts.
Interpret the response
completedSha256 and certificateSha256 are artifact hashes. Retain the input envelopeId; no new envelope id is returned.
Expect 200 with completedSha256 and certificateSha256. Call envelopes.audit_certificate.get and confirm $.certificateSha256 matches.
Inspect the success schema. CLI/MCP add their transport envelope; --detail requests the full CLI result. HTTP 204 contains no JSON payload.
Worked examples
Captured from the exported Sign Worker with the existing SQLite-backed D1 harness applying all core, envelope and audit migrations to one local database, in-memory R2 and synthetic Auth/workspace/archive/Notify transports. These examples prove local validation, persistence and artifact production. They do not prove separate deployed D1 topology, real recipient consent, provider delivery or a live signed agreement. All identities, signing links and documents are synthetic; replace identifiers through authorized discovery and never execute a fixture against a live organization. Binary download examples use the released SDK binary projection; tests Base64-decode and compare original bytes, lengths and server SHA-256 headers.
Supported request · Reuse completion artifacts for the synthetically completed envelope
Input · payload.json:
{
"envelopeId": "b0db0353-6d5a-4a9b-b3f4-85f439ec4953"
}
CLI:
topolo actions validate app_topolo_sign.envelopes.finalize --data @payload.json --json
topolo actions plan app_topolo_sign.envelopes.finalize --resource-type workspace --resource-id "$SIGN_WORKSPACE_ID" --data @payload.json --json
topolo actions call app_topolo_sign.envelopes.finalize --resource-type workspace --resource-id "$SIGN_WORKSPACE_ID" --data @payload.json --confirm --detail --json
MCP tool and arguments:
{
"tool": "topolo_call_action",
"arguments": {
"actionId": "app_topolo_sign.envelopes.finalize",
"input": {
"envelopeId": "b0db0353-6d5a-4a9b-b3f4-85f439ec4953"
},
"resourceType": "workspace",
"resourceId": "<exact granted id from discovery>",
"confirm": true,
"detail": true
}
}
Captured exported Worker response · HTTP 200:
{
"ok": true,
"completedSha256": "adb1ade0d475aa2cec7ff848d72e4af3c575f795ef9e4fe2575c2a3f9822e363",
"certificateSha256": "e29d63dd80fb18c5d411302046233fec15cfdd5383ac62179dcdfdbc631ecc6c"
}
HTTP 200. Expect 200 with completedSha256 and certificateSha256. Call envelopes.audit_certificate.get and confirm $.certificateSha256 matches.
Refused request · HTTP 401
Input · payload.json:
{
"envelopeId": "ed22fca5-d5f0-4392-8e71-96e247bf3875"
}
CLI:
topolo actions validate app_topolo_sign.envelopes.finalize --data @payload.json --json
topolo actions plan app_topolo_sign.envelopes.finalize --resource-type workspace --resource-id "$SIGN_WORKSPACE_ID" --data @payload.json --json
Captured exported Worker response · HTTP 401:
{
"error": "Token validation failed"
}
HTTP 401. Resolve the exact refusal before retrying. This request is not a successful workflow.
Refused request · HTTP 403
Input · payload.json:
{
"envelopeId": "ed22fca5-d5f0-4392-8e71-96e247bf3875"
}
CLI:
topolo actions validate app_topolo_sign.envelopes.finalize --data @payload.json --json
topolo actions plan app_topolo_sign.envelopes.finalize --resource-type workspace --resource-id "$SIGN_WORKSPACE_ID" --data @payload.json --json
Captured exported Worker response · HTTP 403:
{
"error": "This workspace requires read_write access",
"code": "workspace_access_insufficient"
}
HTTP 403. Resolve the exact refusal before retrying. This request is not a successful workflow.
Verify the result
- Expect 200 with completedSha256 and certificateSha256.
- Call envelopes.audit_certificate.get and confirm $.certificateSha256 matches.
Errors and recovery
envelope_not_found(HTTP 404): No envelope in this workspace carries that id. Call envelopes.list and use an id from the response.envelope_not_completed(HTTP 409): Only a completed envelope has artifacts. Wait until every recipient has signed.envelope_source_missing(HTTP 409): The envelope completed before immutable sources existed, so there is no bound document to flatten. Its legacy certificate is still readable with envelopes.audit_certificate.get.source_asset_missing(HTTP 409): The frozen source document could not be read from storage. Retry later; if it persists, raise an incident — do not re-upload, the hash is fixed.auth_error(HTTP 401): Reauthenticate in the same approved context before retrying.workspace_access_insufficient(HTTP 403): Discover the actual workspace grant and obtain the documented required access; do not retry with a guessed workspace or broader organization.
Some existing refusals return a human message as error rather than a stable code; preserve the actual response, status and request id. Platform validation, authentication and resource checks can refuse before the handler.
Recovery boundary
Nothing to undo: finalization only adds missing immutable artifacts.
Related actions
- Get Sign audit certificate: Get the immutable audit certificate issued when an envelope completed: signer identities, capacities, consent and evidence hashes, the source and completed document SHA-256 and a hash chain over the audit trail, plus the certificate's own hash.
Evidence
Captured from the exported Sign Worker with the existing SQLite-backed D1 harness applying all core, envelope and audit migrations to one local database, in-memory R2 and synthetic Auth/workspace/archive/Notify transports. These examples prove local validation, persistence and artifact production. They do not prove separate deployed D1 topology, real recipient consent, provider delivery or a live signed agreement. All identities, signing links and documents are synthetic; replace identifiers through authorized discovery and never execute a fixture against a live organization. Binary download examples use the released SDK binary projection; tests Base64-decode and compare original bytes, lengths and server SHA-256 headers.