External Approvers
External Approvers
Section titled “External Approvers”External approvers are people outside your organisation — vendors, clients, contractors, counter-parties — who need to act on a workflow step but do not have an Aptiwise account.
They receive a one-time email link and can approve, reject, acknowledge, or sign directly from that link. No login, no account registration.
How It Works
Section titled “How It Works”The encrypted token in the email link encodes {instance_id, step_id, approver_email}. No session or login is required — the token is the sole auth mechanism.
Defining an External Approver Step
Section titled “Defining an External Approver Step”Set employee_type: external on the approver block to mark the step as public-facing:
workflow: vendor_review: type: decision approval_type: needs_to_approve # or needs_to_sign, needs_to_acknowledge approver: email: "vendor@example.com" employee_type: external on_approve: end_workflow: true on_reject: end_workflow: trueAll four approval types work for external approvers:
| approval_type | Effect |
|-----------------|--------|
| needs_to_approve | External party approves or rejects |
| needs_to_sign | External party draws and submits a signature |
| needs_to_acknowledge | Non-blocking — external party acknowledges; workflow continues immediately |
| receives_a_copy | Non-blocking — external party is notified; no action required |
Dynamic Email from a Form Field
Section titled “Dynamic Email from a Form Field”If the approver's email is not known at design time, collect it in the form and reference it with ${form.<field_name>}:
form: fields: - name: vendor_name type: text label: Vendor Contact Name required: true
- name: vendor_email type: email label: Vendor Email Address required: true help_text: "This person will receive a link to review and sign — no account needed"
workflow: internal_approval: type: decision approval_type: needs_to_approve approver: role: "${requestor.manager}" on_approve: continue_to: vendor_sign on_reject: end_workflow: true
vendor_sign: type: decision approval_type: needs_to_sign approver: email: "${form.vendor_email}" name: "${form.vendor_name}" employee_type: external on_approve: end_workflow: true on_reject: end_workflow: trueThe ${form.vendor_email} expression is resolved at step-creation time from the instance's form data.
See docs/examples/external-approver-dynamic-email.yaml for a complete annotated example.
Employee Record Resolution
Section titled “Employee Record Resolution”Every approver action — including public ones — is tied to an employees row for audit purposes. When an external approver opens their link, the system resolves their record in this order:
| State | What happens |
|-------|-------------|
| Active employee with that email exists in the company | Record reused — no duplicate created |
| Inactive employee with that email exists in the company | Record reused — avoids a UNIQUE (email, company_id) constraint error |
| No record exists | A minimal employee_type = external record is auto-created |
This resolution is applied for all action types (approve, sign, acknowledge). You can safely use ${form.vendor_email} even if the vendor was previously registered or their account was deactivated.
Public API Endpoints
Section titled “Public API Endpoints”Action endpoint
Section titled “Action endpoint”POST /services/v1/approvals/public/{token}/actionBody:
{ "action": "approve", "comments": "Reviewed and approved."}Works for all approval types. The token identifies the instance, step, and approver email.
Signature endpoints
Section titled “Signature endpoints”External approvers who need to sign can draw their signature before or after acting:
GET /services/v1/signatures/public/{token} → check if a saved signature existsPOST /services/v1/signatures/public/{token} → save a drawn signature (base64 PNG)See Signatures for the full signature canvas and field reference.
External Employee Records
Section titled “External Employee Records”Auto-created records are minimal:
| Field | Value |
|-------|-------|
| name | Derived from email (alice.smith@example.com → Alice Smith) |
| employee_type | external |
| is_active | true |
| user_id | null — no system account |
Formally inviting the person later via the admin panel upgrades their record (adds user_id, full profile) without losing their approval history or saved signature.
See also:
- Decision Steps — step configuration reference
- Acknowledgement Steps — non-blocking external acknowledgement
- Signatures — signature canvas,
needs_to_sign, andsignature_field - Approval Types — full
approval_typereference