Skip to content

Webhooks API

Webhooks enable real-time notifications when events occur in LexgoSign.

Overview

Subscribe to events and receive HTTP POST requests to your server when:

  • Envelopes change status
  • Files are uploaded via presigned URLs
  • Evidence sheets are generated
  • Recipients sign documents
  • Emails are delivered or opened
  • Validation codes are verified

Webhook Events

Envelope Events

Event Description
envelope.sending_failed Asynchronous send failed; inspect envelope state/errors
envelope.in_progress Envelope sent to recipients
envelope.success All recipients signed
envelope.voided Envelope cancelled
envelope.evidence_generated Evidence sheet PDF generated and available
envelope.file_uploaded File uploaded via presigned URL and ready

Recipient Events

Event Description
recipient.email_sent Invitation email sent
recipient.email_received Email delivered (via AWS SES)
recipient.email_opened Recipient opened email
recipient.email_clicked Recipient clicked link
recipient.email_bounced Email bounced
recipient.link_generated Unique access link created for recipient
recipient.in_progress Recipient can now sign
recipient.signed_all Recipient completed signing
recipient.rejected Recipient declined

Validation Events (2FA)

Event Description
recipient.validation_code_generated Verification code created
recipient.validation_code_sent Code email sent
recipient.validation_code_success Code verified successfully
recipient.validation_code_failed Invalid code submitted
recipient.validation_code_expired Code expired
recipient.validation_max_attempts Too many failed attempts

Create Webhook

Endpoint

POST /v1/webhooks

Request

curl -X POST https://api.lexgo.cl/v1/webhooks \
  -H "Authorization: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-app.com/webhooks/lexgo",
    "subscriptions": "envelope.success,envelope.evidence_generated,recipient.signed_all",
    "auth_type": "header",
    "auth": "Bearer your_webhook_secret"
  }'

Response

{
  "success": true,
  "webhook": {
    "id": "6f1c0e8a-3b52-4d7e-9a41-2c8d5e7b9f10",
    "url": "https://your-app.com/webhooks/lexgo",
    "auth_type": "HEADER",
    "subscriptions": "envelope.success,envelope.evidence_generated,recipient.signed_all",
    "created_at": "2025-11-01T10:00:00Z",
    "updated_at": "2025-11-01T10:00:00Z"
  },
  "request_id": "req_abc123"
}

Request fields:

Field Description
url Endpoint that receives the POST deliveries
subscriptions Comma-separated event names from the lists above. Unknown names are silently dropped
auth_type header (send auth as the Authorization header of each delivery) or no_auth (default). Returned uppercase (HEADER, NO_AUTH)
auth Header value used when auth_type is header; never returned in responses

Webhook Payload

When an event occurs, LexgoSign sends a POST request:

File Upload Event Example

When a presigned upload completes processing:

{
  "id": "event_abc123",
  "event_type": "envelope.file_uploaded",
  "data": {
    "envelope_id": "51f8ad72-0b51-4bf4-ab7f-6575e4f68ad5",
    "presigned_upload_id": "upload_xyz789",
    "file_id": "b66efe2d-a3c8-43d6-80d2-1f4e71fa0216",
    "order": 0,
    "file_name": "contract.pdf",
    "custom_key": "main_doc",
    "status": "COMPLETED",
    "uploaded_at": "2025-11-20T19:20:15-03:00",
    "processed_at": "2025-11-20T19:20:18-03:00"
  }
}

Use this event to know when uploads are ready. See Uploads API.

Recipient Event Example

{
  "id": "cbbda446-ac8a-4102-b992-b1032db17cf0",
  "event_type": "recipient.in_progress",
  "data": {
    "id": "45d6e9bf-61d6-423c-b8f0-68fdc71429ab",
    "custom_key": "0",
    "order": 0,
    "status": "IN_PROGRESS",
    "created_at": "2025-11-18T15:44:11.804-03:00",
    "updated_at": "2025-11-18T15:59:09.042-03:00",
    "name": "Jane Smith",
    "name_label": "Name:",
    "email": "recipient@company.com",
    "email_label": "Email:"
  }
}

Envelope Event Example

{
  "id": "d7bd4315-5838-4a9c-b5c1-e96942825078",
  "event_type": "envelope.evidence_generated",
  "data": {
    "id": "51f8ad72-0b51-4bf4-ab7f-6575e4f68ad5",
    "name": "employment_agreement_2025",
    "status": "SUCCESS",
    "errors": [],
    "warnings": [],
    "created_at": "2025-11-18T15:44:11.534-03:00",
    "updated_at": "2025-11-18T16:03:07.120-03:00",
    "evidence_document_url": "https://lexgo-secure.s3.us-east-2.amazonaws.com/evidence-sheets/2025-11-18-evidence.pdf",
    "evidence_generated_at": "2025-11-18T16:03:08.456-03:00",
    "documents": [
      {
        "id": "b66efe2d-a3c8-43d6-80d2-1f4e71fa0216",
        "custom_key": "0",
        "file_type": "SIGNABLE",
        "order": 0,
        "status": "SIGNED",
        "created_at": "2025-11-18T15:44:12.952-03:00",
        "updated_at": "2025-11-18T16:03:07.112-03:00",
        "file_name": "employment_agreement_2025.pdf",
        "content_type": "application/pdf",
        "file_size": 1023380,
        "page_count": 1,
        "url": "https://lexgo-secure.s3.us-east-2.amazonaws.com/pki/files/data/469/c50/d8-/original/document.pdf?X-Amz-Algorithm=..."
      }
    ],
    "recipients": [
      {
        "id": "45d6e9bf-61d6-423c-b8f0-68fdc71429ab",
        "custom_key": "0",
        "order": 0,
        "status": "SIGNED_ALL",
        "created_at": "2025-11-18T15:44:11.804-03:00",
        "updated_at": "2025-11-18T16:02:18.393-03:00",
        "name": "Jane Smith",
        "name_label": "Name:",
        "email": "jane.smith@company.com",
        "email_label": "Email:"
      },
      {
        "id": "e2616688-a514-455e-a0d1-92ad8b544825",
        "custom_key": "1",
        "order": 1,
        "status": "SIGNED_ALL",
        "created_at": "2025-11-18T15:44:11.833-03:00",
        "updated_at": "2025-11-18T16:03:07.044-03:00",
        "name": "Robert Johnson",
        "name_label": "Name:",
        "email": "robert.johnson@company.com",
        "email_label": "Email:"
      }
    ],
    "placements": [
      {
        "id": "a24bf7b1-d9b2-49d2-8231-68d899445a63",
        "custom_key": "4",
        "placement_type": "SIGNATURE",
        "created_at": "2025-11-18T15:44:11.944-03:00",
        "updated_at": "2025-11-18T15:44:11.944-03:00",
        "recipient_id": "45d6e9bf-61d6-423c-b8f0-68fdc71429ab",
        "recipient_key": "0",
        "document_id": "b66efe2d-a3c8-43d6-80d2-1f4e71fa0216",
        "document_key": "0",
        "order": 0,
        "coordinates": {
          "id": "Lexgo-Sign-0",
          "top": "1538.6666666667",
          "left": "2554.3333333333",
          "page": "0"
        },
        "token": null
      }
    ],
    "settings": {
      "emails": {
        "envelope_invitation": "FALSE",
        "envelope_voided": "FALSE",
        "envelope_rejected": "FALSE",
        "envelope_signed": "FALSE"
      },
      "documents": {
        "include_page_id": "TRUE",
        "custom_page_id": "CVE:",
        "signatures_per_page": 4,
        "signatures_per_row": 1
      },
      "signature_flow": {
        "language": "ES",
        "signature_order": "SEQUENTIAL",
        "signature_types": "DRAWN, UPLOADED",
        "signature_color": "#290088",
        "sender_name": "Company Name",
        "sender_enterprise": null
      },
      "signature": {
        "style": "SIMPLE",
        "type": "INTERNATIONAL",
        "image": "DEFAULT",
        "text": "DEFAULT",
        "bg_image": "https://example.com/signature-bg.png"
      },
      "validations": {
        "email": {
          "order": 0,
          "enabled": "FALSE"
        },
        "phone": {
          "order": 1,
          "enabled": "FALSE",
          "methods": "SMS"
        },
        "id_check": {
          "order": 2,
          "enabled": "FALSE"
        },
        "biometric": {
          "order": 3,
          "enabled": "FALSE"
        }
      }
    }
  }
}

Note: The envelope.evidence_generated event includes:

  • evidence_document_url: Direct link to download the evidence sheet PDF
  • evidence_generated_at: Timestamp when the evidence was generated

These fields are available at the top level of the data object. The payload also includes complete envelope information: documents, recipients, signature placements, and all configuration settings.

List Webhooks

curl https://api.lexgo.cl/v1/webhooks \
  -H "Authorization: YOUR_API_KEY"

The response is {"webhooks": [...], "request_id": "..."}, ordered by creation time. Each item has id, url, auth_type, subscriptions, created_at and updated_at.

Get Webhook

GET /v1/webhooks/{webhook_id} returns {"webhook": {...}, "request_id": "..."} with the same fields. An unknown ID returns 404 with {"error": "Webhook not found"}.

Update Webhook

curl -X PUT https://api.lexgo.cl/v1/webhooks/{webhook_id} \
  -H "Authorization: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "subscriptions": "envelope.success,envelope.voided"
  }'

All fields are optional. The response is {"success": true, "webhook": {...}, "request_id": "..."}; an unknown ID returns 404.

Delete Webhook

curl -X DELETE https://api.lexgo.cl/v1/webhooks/{webhook_id} \
  -H "Authorization: YOUR_API_KEY"

The response is {"success": true, "webhook": {...}, "request_id": "..."} with the deleted webhook; an unknown ID returns 404.

Delivery and Retries

Webhooks are best-effort asynchronous notifications. A failed or timed-out delivery has up to three scheduled retries after approximately 5, 10, and 20 seconds (four total attempts). Requests use a 5-second response timeout and a 2-second connection timeout.

The payload id identifies one queued delivery and remains stable across its retries. Store processed IDs to avoid repeating side effects. Separate events or subscriptions may have separate IDs, even for the same envelope. The payload contains the resource state at delivery time; it is not an immutable event snapshot.

Delivery is not exactly once and is not guaranteed. Notifications can be duplicated, delayed, or missed, and arrival order must not define your business state. Use GET /v1/envelopes/:id to reconcile stored envelope IDs, especially after timeouts, retry exhaustion, or missing expected events. See Webhook Integration.

Best Practices

  1. Authenticate: If configured, compare the Authorization header to your shared secret; the payload has no documented cryptographic signature (optionally also allowlist the webhook source IPs)
  2. Respond quickly: Return 200 status immediately
  3. Process async: Handle payload in background job
  4. Log events: Track all webhook deliveries
  5. Handle duplicates: Implement idempotency

Next Steps