Skip to main content
Formalingo

End-to-End Signing Flow

A complete walkthrough of the document signing workflow via the API.

End-to-End Signing Flow

This guide walks through the complete workflow from uploading a document to getting a signed PDF.

Signature evidence

Completed signing workflows keep a signer and document evidence package alongside the PDF:

  • Explicit e-sign consent before submission
  • Viewed, consent, field completion, submission, and PDF-generated audit events
  • Signer timestamps, IP address, and user agent where available
  • Completed PDF hash for later byte-for-byte comparison
  • Cryptographic verification seal over the signer, audit, and document evidence
  • Public verification certificate at /verify/{submissionId}

Formalingo is designed to support ESIGN/UETA-style electronic signature workflows in the US. Internationally, it supports standard electronic signature evidence trails. It is not a qualified trust service provider and does not create eIDAS qualified electronic signatures (QES), which require qualified certificates and qualified trust-service workflows.

Step 1: Upload the document

curl -X POST https://app.formalingo.com/api/v1/documents \
-H "Authorization: Bearer af_live_YOUR_KEY" \
-F "file=@contract.pdf" \
-F "title=Service Agreement"
# → { "data": { "id": "DOC_ID", ... } }

Step 2: Create signer roles

curl -X POST https://app.formalingo.com/api/v1/documents/DOC_ID/signer-roles \
-H "Authorization: Bearer af_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{ "label": "Client" }'
# → { "data": { "role": "signer_1", ... } }

Step 3: Place fields on the document

curl -X POST https://app.formalingo.com/api/v1/documents/DOC_ID/fields \
-H "Authorization: Bearer af_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
  "label": "Client Signature",
  "type": "digital_signature",
  "pageNumber": 2,
  "x": 0.1, "y": 0.85,
  "width": 0.35, "height": 0.06,
  "assigneeRole": "signer_1",
  "isRequired": true
}'

Step 4: Create a submission

curl -X POST https://app.formalingo.com/api/v1/documents/DOC_ID/submissions \
-H "Authorization: Bearer af_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
  "signers": [{
    "role": "signer_1",
    "name": "Jane Smith",
    "email": "jane@client.com",
    "prefill": {
      "COMPANY_FIELD_ID": "Client Corp Ltd"
    }
  }]
}'
# → { "data": { "signers": [{ "link": "https://www.formalingo.com/d/TOKEN", ... }] } }

Send signers[0].link to your signer. They open it in their browser, review the document, and sign.

Step 6: Wait for completion

When all signers complete signing:

  • Submission statuscompleted
  • A signed PDF is generated and stored
  • A completed PDF hash and verification seal are recorded
  • A document_all_complete webhook event fires (if configured)

You can either poll the submissions endpoint or listen to the document_all_complete webhook.

Option A: Poll for completion

curl https://app.formalingo.com/api/v1/documents/DOC_ID/submissions \
-H "Authorization: Bearer af_live_YOUR_KEY"
# Look for status: "completed" in the response

Option B: Webhook

Configure a document_all_complete webhook — see Webhook Events for payload details.

Step 7: Verify the evidence

After completion, use the verification certificate to review the signing evidence before or after downloading the signed PDF.

  • Public certificate: https://www.formalingo.com/verify/{submissionId}
  • Public API: GET /api/verify/document/{submissionId}
  • Creator API: GET /api/documents/{id}/verify?submissionId={submissionId}

Verification checks whether the current PDF bytes match the recorded hash and whether the stored evidence payload matches the cryptographic seal. Older submissions generated before sealing may need PDF regeneration before hash and seal verification are available.

Step 8: Download the signed PDF

Once the submission is completed, download the signed PDF:

GET/api/v1/documents/{id}/submissions/{sid}/pdf
Required permissions:submissions:download_pdf

Returns a short-lived presigned download URL (5-minute expiry). Use the URL to download the file directly.

# Get the download URL
curl https://app.formalingo.com/api/v1/documents/DOC_ID/submissions/SUB_ID/pdf \
-H "Authorization: Bearer af_live_YOUR_KEY"

# Response: { "data": { "downloadUrl": "https://...", "expiresIn": 300 } }

# Download the PDF
curl -o signed-contract.pdf "DOWNLOAD_URL_FROM_RESPONSE"
Response200
{
  "success": true,
  "data": {
    "submissionId": "submission-uuid",
    "completedAt": "2026-03-11T14:30:00.000Z",
    "downloadUrl": "https://storage.supabase.co/...signed.pdf?token=...",
    "expiresIn": 300
  }
}

The downloadUrl expires after 5 minutes. Request a new URL by calling the endpoint again.