Skip to content

Guest Signing

The recipient-side experience for someone signing a document without a vScrawl account — reached via /sign/:code (the emailed link's landing page), which exchanges the code at /wait?docCode=... and lands the recipient straight in the signing editor. On completion they land on a /thanks page (with a "Create Account" call to action); an expired or already-used link goes to /link-expired instead.

This is the same mechanism every recipient goes through in a normal Sending & Signing flow and every child workflow inside a Power Survey.

End-to-end sequence

sequenceDiagram
    participant API
    participant Email
    participant Recipient

    Note over API: Workflow sent
    API-->>API: Mint encrypted code (recipientId + workflowId)
    API->>Email: Commence email with link containing code
    Email->>Recipient: Recipient opens link (/sign/:code)

    Recipient->>API: GET /auth/v1/getGuestToken/{code}
    API->>Recipient: GuestTokenResponse (access + refresh token)

    Recipient->>API: GET /workflow/v1/{workflowId} (Bearer guest token)
    API-->>Recipient: Workflow + document + field state

    opt Identity verification required for this recipient
        Recipient->>API: POST /workflow/v1/{workflowId}/identity/send-otp
        API->>Email: 6-digit code (10 min expiry)
        Recipient->>API: POST /workflow/v1/{workflowId}/identity/verify-otp {code}
    end

    opt Consent required
        Recipient->>API: POST /workflow/v1/{workflowId}/consent
    end

    Recipient->>API: POST /workflow/v1/{documentId}/fields/save (per field)
    Recipient->>API: POST /workflow/v1/{workflowId}/sign
    Note over Recipient: Lands on /thanks

Whenever a workflow is dispatched to a recipient — the initial send, the next recipient in an ordered sequence, or a delegated hand-off — the API builds an encrypted code from the recipient and workflow ids, with an expiry.

recipientId here is the specific recipient row, not just the person's user id — the same person can hold two different recipient rows on one workflow (a real signer plus a separate hidden delegate/assistant row), and the link always resolves to the exact row it was generated for.

2. Redeeming the code

GET /auth/v1/getGuestToken/{code}

{code} is the opaque value embedded in the emailed link — never constructed by a client. See Authentication → Guest JWT for the token shape. If the code is malformed or expired, this call fails and the recipient lands on /link-expired.

3. Recipient resolution on every subsequent call

Every call the recipient makes afterward carries their guest JWT, with a recipientId claim that's authoritative for "which recipient is acting" — this is what keeps a person with multiple recipient rows on one workflow correctly routed.

4. Step-up identity verification (optional, per recipient)

Some recipients are flagged to require identity verification when added (see Sending & Signing → Recipients). For these, holding a valid guest token is necessary but not sufficient:

POST /workflow/v1/{workflowId}/identity/send-otp

Sends a 6-digit code (10-minute expiry, 30-second resend throttle, 5 attempts max).

POST /workflow/v1/{workflowId}/identity/verify-otp
Content-Type: application/json

{ "code": "482913" }

Any sign/approve action is rejected until this is completed for a recipient flagged this way.

POST /workflow/v1/{workflowId}/consent
Content-Type: application/json

{
  "consentTextHash": "sha256:...",
  "consentText": "I agree to use electronic records and signatures...",
  "consentSource": "WEB"
}

consentSource is WEB, MOBILE, or UNKNOWN. Stored alongside the capturing IP address, user-agent, and timestamp — this is the evidentiary trail referenced in the workflow's evidence report.

6. Signing

Once identity/consent gates (if any) are satisfied, the recipient proceeds exactly as described in Sending & Signing → Recipient views and signs. Nothing about the signing calls differs for a guest vs. a logged-in user — only the token's scope is narrower.

Token lifecycle notes

  • The guest token pair is used directly as a bearer token for the signing session — it doesn't become a normal browser session.
  • It's scoped to the one workflow (and, via the recipientId claim, the one recipient row) it was minted for — not a general-purpose account credential.