API Documentation

WeGoSign API Documentation

Integrate document signing into your applications with our powerful REST API. Send documents for signature, track progress, and automate your workflows.

Getting Started

Everything you need to integrate WeGoSign into your application

Introduction

The WeGoSign API is organized around REST. Our API has predictable resource-oriented URLs, accepts JSON-encoded request bodies, returns JSON-encoded responses, and uses standard HTTP response codes, authentication, and verbs.

Secure

All API requests are made over HTTPS with SHA-256 hashed API keys

Fast

Average response time under 200ms for most operations

RESTful

Standard REST conventions with predictable resource URLs

Idempotent

Safe to retry requests without creating duplicates

Base URL

https://www.wegosign.com/api/v1

Machine-readable reference: https://www.wegosign.com/api/v1/openapi.json (OpenAPI 3.1, generated from the live route surface; legacy paths are flagged deprecated with their successor).

Quickstart

Send your first document for signature in just a few steps:

1

Get your API key

Navigate to your organization settings in the dashboard and create a new API key.

API keys start with wgs_live_ for production or wgs_test_ for testing.

2

Create a template

Upload a PDF and define signature fields via the dashboard or API.

curl -X POST https://www.wegosign.com/api/v1/templates \
  -H "Authorization: Bearer wgs_live_<YOUR_API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Employment Contract",
    "description": "Standard employment agreement",
    "document": {
      "data": "base64_encoded_pdf_content",
      "filename": "contract.pdf"
    }
  }'
3

Send for signature

Create an envelope with your template and specify the signers.

curl -X POST https://www.wegosign.com/api/v1/envelopes \
  -H "Authorization: Bearer wgs_live_<YOUR_API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{
    "templateId": "template_id_from_step_2",
    "title": "Employment Contract - John Doe",
    "message": "Please review and sign the attached contract.",
    "signers": [
      {
        "name": "John Doe",
        "email": "john@example.com",
        "role": "signer"
      }
    ]
  }'
4

Done!

The signer receives an email with a link to sign the document. You can track progress via the API or webhooks.

Authentication

The WeGoSign API uses API keys to authenticate requests. You can create and manage API keys from your organization settings in the dashboard.

API Key Format

wgs_live_*

Production keys for live transactions

wgs_test_*

Test keys for development and testing

Making Authenticated Requests

Include your API key in the Authorization header using the Bearer scheme:

Example Request
curl https://www.wegosign.com/api/v1/templates \
  -H "Authorization: Bearer wgs_live_<YOUR_API_KEY>"

Alternative: X-API-Key Header

If your platform strips Authorization headers (common with some serverless environments), you can use theX-API-Key header as a fallback:

X-API-Key: wgs_live_<YOUR_API_KEY>

Keep your API keys secure

Never expose API keys in client-side code or public repositories. Store them securely in environment variables.

API Reference

Complete reference for all API endpoints

Templates

Templates are reusable document definitions with pre-configured signature fields. Upload a PDF, define where signatures should go, and reuse it for multiple envelopes.

GET
/api/v1/templates

List Templates

Retrieves all templates for your organization.

Query Parameters

include_archived
boolean(default: false)

Include archived templates in the response

Response

Response
{
  "data": [
    {
      "id": "tpl_abc123",
      "name": "Employment Contract",
      "description": "Standard employment agreement",
      "pageCount": 3,
      "fieldCount": 5,
      "roles": ["employee", "employer"],
      "isArchived": false,
      "createdAt": 1704543600000,
      "updatedAt": 1704543600000
    }
  ]
}
POST
/api/v1/templates

Create Template

Creates a new template by uploading a PDF document. Optionally include fields with conditional logic.

Request Body

Template creation payload with base64-encoded PDF and optional fields

Request
{
  "name": "Employment Contract",
  "description": "Standard employment agreement",
  "document": {
    "data": "base64_encoded_pdf_content",
    "filename": "contract.pdf"
  },
  "fields": [
    {
      "id": "field_1",
      "type": "signature",
      "role": "employee",
      "page": 1,
      "x": 100,
      "y": 500,
      "width": 200,
      "height": 50,
      "required": true,
      "label": "Employee Signature"
    },
    {
      "id": "field_2",
      "type": "dropdown",
      "role": "employee",
      "page": 1,
      "x": 100,
      "y": 300,
      "width": 150,
      "height": 30,
      "required": true,
      "label": "Department",
      "options": [
        { "label": "Engineering", "value": "eng" },
        { "label": "Sales", "value": "sales" }
      ]
    }
  ]
}

Response

Returns the created template with field count and roles.

Response
{
  "data": {
    "id": "tpl_abc123",
    "name": "Employment Contract",
    "description": "Standard employment agreement",
    "documentName": "contract.pdf",
    "fieldCount": 2,
    "roles": ["employee"],
    "createdAt": 1704543600000
  }
}
GET
/api/v1/templates/:id

Get Template

Retrieves a template with fields, roles, placeholder keys, archive status, and document URL.

Path Parameters

id
required
string

Template ID

Response

Response
{
  "data": {
    "id": "tpl_abc123",
    "name": "Employment Contract",
    "description": "Standard employment agreement",
    "pageCount": 3,
    "fields": [],
    "roles": ["employee"],
    "placeholderKeys": [],
    "isArchived": false,
    "documentUrl": "https://...",
    "createdAt": 1704543600000,
    "updatedAt": 1704543600000
  }
}
PUT
/api/v1/templates/:id

Update Template

Updates template metadata.

Path Parameters

id
required
string

Template ID

Request Body

Template metadata fields

Request
{
  "name": "Employment Contract v2",
  "description": "Updated employment agreement"
}

Response

Response
{
  "data": {
    "id": "tpl_abc123",
    "name": "Employment Contract v2",
    "description": "Updated employment agreement",
    "updatedAt": 1704543600000
  }
}
DELETE
/api/v1/templates/:id

Archive Template

Archives a template so it no longer appears in default template lists.

Path Parameters

id
required
string

Template ID

Response

Response
{
  "data": {
    "id": "tpl_abc123",
    "archived": true
  }
}
PATCH
/api/v1/templates/:id/fields

Update Template Fields

Updates all fields for a template. Supports all field types and conditional logic.

Request Body

Array of fields with positions, types, and optional conditions

Request
{
  "fields": [
    {
      "id": "field_1",
      "type": "dropdown",
      "role": "signer",
      "page": 1,
      "x": 100,
      "y": 200,
      "width": 150,
      "height": 30,
      "required": true,
      "label": "Select Option",
      "options": [
        { "label": "Option A", "value": "a" },
        { "label": "Option B", "value": "b" }
      ]
    },
    {
      "id": "field_2",
      "type": "text",
      "role": "signer",
      "page": 1,
      "x": 100,
      "y": 250,
      "width": 200,
      "height": 30,
      "required": false,
      "label": "Additional Details",
      "conditions": [
        {
          "sourceFieldId": "field_1",
          "operator": "equals",
          "value": "b"
        }
      ],
      "conditionAction": "show",
      "conditionLogic": "all"
    }
  ]
}

Response

Returns the updated field count and roles.

Response
{
  "data": {
    "id": "tpl_abc123",
    "fieldCount": 2,
    "roles": ["signer"],
    "updatedAt": 1704543600000
  }
}
GET
/api/v1/templates/:id/fields

Get Template Fields

Retrieves all fields for a template including their conditions.

Response

Returns all fields, roles, and placeholder keys for the template.

Response
{
  "data": {
    "templateId": "tpl_abc123",
    "fields": [
      {
        "id": "field_1",
        "type": "dropdown",
        "role": "signer",
        "page": 1,
        "x": 100,
        "y": 200,
        "width": 150,
        "height": 30,
        "required": true,
        "label": "Select Option",
        "options": [
          { "label": "Option A", "value": "a" },
          { "label": "Option B", "value": "b" }
        ]
      }
    ],
    "roles": ["signer"],
    "placeholderKeys": []
  }
}

Packages

Packages bundle multiple templates into a single multi-document signing workflow. Create packages, map package-level roles to template roles, and send them through the envelopes API.

GET
/api/v1/packages

List Packages

Retrieves all template packages for your organization.

Query Parameters

include_archived
boolean(default: false)

Include archived packages in the response

Response

Response
{
  "data": [
    {
      "id": "pkg_abc123",
      "name": "New Hire Package",
      "description": "All onboarding documents",
      "status": "active",
      "templates": [
        {
          "templateId": "tpl_contract",
          "order": 0,
          "name": "Employment Contract",
          "pageCount": 3,
          "fieldCount": 8,
          "roles": ["employee", "employer"]
        }
      ],
      "roleMappings": [],
      "stats": {
        "documentCount": 2,
        "totalFields": 14,
        "totalPages": 7,
        "roleCount": 2
      },
      "createdAt": 1704543600000,
      "updatedAt": 1704543600000
    }
  ]
}
POST
/api/v1/packages

Create Package

Creates a package from one or more templates. Role mappings are auto-generated when omitted.

Request Body

Package creation payload

Request
{
  "name": "New Hire Package",
  "description": "All onboarding documents",
  "templateIds": ["tpl_contract", "tpl_w4"],
  "roleMappings": [
    {
      "packageRoleId": "role_1",
      "packageRoleName": "Employee",
      "color": "#3b82f6",
      "templateRoles": [
        { "templateId": "tpl_contract", "roleId": "employee" },
        { "templateId": "tpl_w4", "roleId": "employee" }
      ]
    }
  ]
}

Response

Returns the created package with template details and aggregate stats.

Response
{
  "data": {
    "id": "pkg_abc123",
    "name": "New Hire Package",
    "description": "All onboarding documents",
    "status": "active",
    "templates": [
      {
        "templateId": "tpl_contract",
        "order": 0,
        "name": "Employment Contract",
        "pageCount": 3,
        "fieldCount": 8,
        "roles": ["employee", "employer"]
      }
    ],
    "roleMappings": [],
    "stats": {
      "documentCount": 2,
      "totalFields": 14,
      "totalPages": 7,
      "roleCount": 2
    },
    "createdAt": 1704543600000,
    "updatedAt": 1704543600000
  }
}
GET
/api/v1/packages/:id

Get Package

Retrieves a specific package by ID.

Path Parameters

id
required
string

The package ID

Response

Returns package metadata, template details, role mappings, and stats.

Response
{
  "data": {
    "id": "pkg_abc123",
    "name": "New Hire Package",
    "description": "All onboarding documents",
    "status": "active",
    "templates": [],
    "roleMappings": [],
    "stats": {
      "documentCount": 2,
      "totalFields": 14,
      "totalPages": 7,
      "roleCount": 2
    },
    "createdAt": 1704543600000,
    "updatedAt": 1704543600000
  }
}
PUT
/api/v1/packages/:id

Update Package

Updates package metadata, template order, or role mappings.

Path Parameters

id
required
string

The package ID

Request Body

Fields to update

Request
{
  "name": "Updated New Hire Package",
  "templateIds": ["tpl_contract", "tpl_w4", "tpl_handbook"]
}

Response

Response
{
  "data": {
    "id": "pkg_abc123",
    "name": "Updated New Hire Package",
    "status": "active",
    "templates": [],
    "roleMappings": [],
    "stats": {
      "documentCount": 3,
      "totalFields": 20,
      "totalPages": 12,
      "roleCount": 2
    },
    "createdAt": 1704543600000,
    "updatedAt": 1704550000000
  }
}
DELETE
/api/v1/packages/:id

Archive Package

Archives a package so it no longer appears in default package lists.

Path Parameters

id
required
string

The package ID

Response

Response
{
  "data": {
    "id": "pkg_abc123",
    "archived": true
  }
}

Envelopes

Envelopes represent documents sent for signature. Create an envelope from a template or package, specify one or more signers, and track the signing progress.

Envelope Status Lifecycle

draft
sent
viewed
completed

Multiple Signers & Signing Order

Sequential Signing

Signers sign one after another. Use different signingOrder values (1, 2, 3...). Signer 2 can only sign after Signer 1 completes.

Parallel Signing

All signers can sign simultaneously. Use the same signingOrder value for all signers (e.g., all set to 1).

GET
/api/v1/envelopes

List Envelopes

Retrieves all envelopes for your organization with optional filtering.

Query Parameters

status
string

Filter by status: draft, sent, viewed, signed, completed, declined, cancelled, expired

limit
number(default: 50)

Number of results per page

Response

Response
{
  "data": [
    {
      "id": "env_xyz789",
      "title": "Employment Contract - John Doe",
      "status": "sent",
      "templateName": "Employment Contract",
      "signers": [
        {
          "id": "sgn_abc123",
          "name": "John Doe",
          "email": "john@example.com",
          "role": "employee",
          "status": "pending"
        }
      ],
      "createdAt": 1704543600000,
      "completedAt": null,
      "expiresAt": 1705148400000
    }
  ]
}
POST
/api/v1/envelopes

Create & Send Envelope

Creates a new envelope from a template or package with one or more signers. Supports sequential or parallel signing.

Query Parameters

templateId
string

Template ID to send. Provide exactly one of templateId or packageId.

packageId
string

Package ID for a multi-document signing workflow. Provide exactly one of templateId or packageId.

signers
required
array

Array of signers. Each signer needs name, email. Optional: role, signingOrder (for sequential signing), redirectUrl.

signers[].signingOrder
number(default: 1)

Order in which signers sign. Same number = parallel signing. Different numbers = sequential (1 signs first, then 2, etc.).

scheduledAt
string (ISO 8601)

Schedule envelope to be sent at a future time. Must be 5 min to 30 days in the future. Omit to send immediately.

Request Body

Envelope creation payload with multiple signers

Request
{
  "templateId": "tpl_abc123",
  "title": "Employment Contract - John Doe",
  "message": "Please review and sign the attached contract.",
  "expiresInHours": 168,
  "scheduledAt": "2026-01-15T09:00:00Z",
  "signers": [
    {
      "name": "John Doe",
      "email": "john@example.com",
      "role": "employee",
      "signingOrder": 1,
      "redirectUrl": "https://yourapp.com/signed"
    },
    {
      "name": "Jane Smith",
      "email": "jane@company.com",
      "role": "employer",
      "signingOrder": 2
    },
    {
      "name": "Legal Team",
      "email": "legal@company.com",
      "role": "approver",
      "signingOrder": 3
    }
  ]
}

Response

Returns envelope ID and unique signing URLs for each signer. Status is 'scheduled' if scheduledAt provided, otherwise 'sent'.

Response
{
  "data": {
    "id": "env_xyz789",
    "status": "scheduled",
    "scheduledAt": "2026-01-15T09:00:00.000Z",
    "signers": [
      {
        "id": "sgn_abc123",
        "email": "john@example.com",
        "signingUrl": "https://www.wegosign.com/sign/abc123..."
      },
      {
        "id": "sgn_def456",
        "email": "jane@company.com",
        "signingUrl": "https://www.wegosign.com/sign/def456..."
      },
      {
        "id": "sgn_ghi789",
        "email": "legal@company.com",
        "signingUrl": "https://www.wegosign.com/sign/ghi789..."
      }
    ]
  }
}
GET
/api/v1/envelopes/:id

Get Envelope

Retrieves detailed information about a specific envelope.

Path Parameters

id
required
string

The envelope ID

Response

Response
{
  "data": {
    "id": "env_xyz789",
    "title": "Employment Contract - John Doe",
    "status": "completed",
    "createdAt": 1704543600000,
    "sentAt": 1704543610000,
    "completedAt": 1704630000000,
    "expiresAt": 1705148400000
  }
}
DELETE
/api/v1/envelopes/:id

Cancel Envelope

Cancels an envelope. Only envelopes in 'sent' status can be cancelled.

Path Parameters

id
required
string

The envelope ID

Response

Response
{
  "data": {
    "id": "env_xyz789",
    "status": "cancelled"
  }
}
POST
/api/v1/envelopes/:id/remind

Send Reminder

Sends a reminder email to signers who haven't completed signing.

Path Parameters

id
required
string

The envelope ID

Request Body

Optional parameters for the reminder

Request
{
  "signerId": "sgn_abc123",
  "message": "Friendly reminder to sign the document."
}

Response

Response
{
  "data": {
    "success": true,
    "remindedCount": 1
  }
}
GET
/api/v1/envelopes/:id/audit-log

Get Audit Log

Retrieves the complete audit trail for an envelope showing all actions.

Query Parameters

limit
number(default: 100)

Number of records to return

Path Parameters

id
required
string

The envelope ID

Response

Response
{
  "data": [
    {
      "id": "log_1",
      "action": "envelope_created",
      "actionDescription": "Envelope created",
      "actorType": "api",
      "actorEmail": "admin@company.com",
      "ipAddress": "192.168.1.1",
      "timestamp": 1704543600000
    },
    {
      "id": "log_2",
      "action": "document_viewed",
      "actionDescription": "Document viewed by signer",
      "actorType": "signer",
      "actorEmail": "john@example.com",
      "ipAddress": "203.0.113.50",
      "timestamp": 1704550000000
    }
  ]
}
GET
/api/v1/envelopes/:id/download

Download Signed Document

Retrieves download URLs for the signed PDF document and certificate. Only available for completed envelopes.

Query Parameters

type
string(default: all)

What to download: 'document', 'certificate', or 'all'

Path Parameters

id
required
string

The envelope ID

Response

Download URLs expire after 1 hour. Request new URLs if they have expired.

Response
{
  "data": {
    "id": "env_xyz789",
    "title": "Employment Contract - John Doe",
    "status": "completed",
    "completedAt": 1704630000000,
    "documentUrl": "https://storage.convex.cloud/...",
    "certificateUrl": "https://storage.convex.cloud/...",
    "expiresIn": "1 hour"
  }
}

Signers

Signers are the recipients of an envelope who need to sign the document. Track individual signer progress and status.

GET
/api/v1/envelopes/:id/signers

Get Envelope Signers

Retrieves all signers for an envelope with their current status.

Path Parameters

id
required
string

The envelope ID

Response

Response
{
  "data": [
    {
      "id": "sgn_abc123",
      "email": "john@example.com",
      "name": "John Doe",
      "role": "employee",
      "signingOrder": 1,
      "status": "signed",
      "viewedAt": 1704550000000,
      "signedAt": 1704560000000,
      "declinedAt": null,
      "declineReason": null,
      "reminderSentAt": null
    }
  ]
}

Bulk Sends

Send documents to multiple recipients at once. Perfect for onboarding, mass communications, or any scenario requiring the same document sent to many people. Supports column mapping for placeholders and prefilled fields, scheduled sends, and error reporting.

Growth Plan & Above
POST
/api/v1/bulk-sends

Create Bulk Send

Creates and initiates a bulk send operation for multiple recipients. Supports column mappings for document placeholders and prefilled signer fields, as well as scheduled sends.

Request Body

Bulk send creation payload

Request
{
  "templateId": "tpl_abc123",
  "titlePrefix": "Onboarding Document",
  "message": "Welcome! Please sign your onboarding documents.",
  "expiresInHours": 168,
  "recipients": [
    {
      "email": "john@example.com",
      "name": "John Doe",
      "role": "employee",
      "additionalData": {
        "company": "Acme Inc",
        "start_date": "2024-02-01",
        "employee_id": "EMP-001"
      }
    },
    {
      "email": "jane@example.com",
      "name": "Jane Smith",
      "role": "employee",
      "additionalData": {
        "company": "Acme Inc",
        "start_date": "2024-02-15",
        "employee_id": "EMP-002"
      }
    }
  ],
  "columnMappings": {
    "placeholders": {
      "company": "company_name",
      "start_date": "employment_start_date"
    },
    "signerFields": {
      "employee_id": "field_employee_id"
    }
  },
  "scheduledAt": 1704600000000
}

Response

Bulk sends are processed asynchronously. If scheduledAt is provided, status will be 'scheduled' and processing will begin at that time. Column mappings allow mapping recipient additionalData to document placeholders or prefillable signer fields.

Response
{
  "data": {
    "id": "bulk_abc123",
    "totalRecipients": 2,
    "status": "scheduled",
    "scheduledAt": 1704600000000,
    "message": "Bulk send scheduled for 2024-01-07T08:00:00.000Z"
  }
}
GET
/api/v1/bulk-sends/:id

Get Bulk Send Status

Retrieves the status and results of a bulk send operation, including all created envelopes.

Path Parameters

id
required
string

The bulk send ID

Response

Response
{
  "data": {
    "id": "bulk_abc123",
    "templateId": "tpl_abc123",
    "templateName": "Employment Contract",
    "status": "completed",
    "totalRecipients": 2,
    "processedCount": 2,
    "successCount": 2,
    "failureCount": 0,
    "errors": [],
    "columnMappings": {
      "placeholders": { "company": "company_name" },
      "signerFields": { "employee_id": "field_employee_id" }
    },
    "scheduledAt": null,
    "createdAt": 1704543600000,
    "completedAt": 1704543700000,
    "envelopes": [
      {
        "id": "env_xyz789",
        "title": "Onboarding Document - John Doe",
        "status": "sent",
        "placeholderValues": [
          { "key": "company_name", "value": "Acme Inc" }
        ],
        "signers": [
          {
            "email": "john@example.com",
            "status": "sent",
            "prefilledFields": { "field_employee_id": "EMP-001" }
          }
        ]
      }
    ]
  }
}
GET
/api/v1/bulk-sends/:id/errors

Get Error Report

Retrieves a detailed error report for a bulk send. Useful for identifying which recipients failed and why. Supports JSON and CSV formats.

Path Parameters

id
required
string

The bulk send ID

format
string

Response format: 'json' (default) or 'csv'

Response

Use ?format=csv to download errors as a CSV file for easy analysis in spreadsheets.

Response
{
  "data": {
    "bulkSendId": "bulk_abc123",
    "templateId": "tpl_abc123",
    "titlePrefix": "Onboarding Document",
    "status": "completed",
    "summary": {
      "totalRecipients": 10,
      "successCount": 8,
      "failureCount": 2
    },
    "createdAt": 1704543600000,
    "completedAt": 1704543700000,
    "errors": [
      {
        "row": 5,
        "email": "invalid@example",
        "errorType": "invalid_data",
        "errorMessage": "Invalid email format"
      },
      {
        "row": 8,
        "email": "quota@example.com",
        "errorType": "quota_exceeded",
        "errorMessage": "Monthly envelope limit reached"
      }
    ]
  }
}
DELETE
/api/v1/bulk-sends/:id

Cancel Bulk Send

Cancels a bulk send operation and all its associated pending envelopes. Scheduled bulk sends can also be cancelled before they start processing.

Path Parameters

id
required
string

The bulk send ID

Response

Returns the number of envelopes that were cancelled. Completed bulk sends cannot be cancelled.

Response
{
  "data": {
    "id": "bulk_abc123",
    "cancelled": true,
    "cancelledEnvelopes": 5
  }
}

Bulk Send Webhook Events

Subscribe to these webhook events to track bulk send progress:

  • bulk_send.started - Fired when bulk send processing begins
  • bulk_send.completed - Fired when all envelopes have been processed
  • bulk_send.failed - Fired when bulk send fails (all recipients failed)

Invoices

Create, send, and manage client invoices programmatically. Track payments, record partial payments, and receive webhook notifications for the full invoice lifecycle.

Pro Plan & Above

Invoice Lifecycle

draftsentviewedpaid

Invoices can also transition to overdue (past due date), partially_paid (partial payment recorded), or void (cancelled).

GET
/api/v1/invoices

List Invoices

Retrieves all invoices for your organization, optionally filtered by status.

Query Parameters

status
string

Filter by status: draft, sent, viewed, overdue, paid, partially_paid, void

limit
number

Maximum results to return (default: 50, max: 100)

Response

Response
{
  "data": [
    {
      "id": "inv_abc123",
      "invoiceNumber": "INV-0001",
      "clientName": "John Smith",
      "clientEmail": "john@example.com",
      "clientCompany": "Acme Corp",
      "title": "Consulting Services - March 2026",
      "currency": "NGN",
      "totalKobo": 5000000,
      "status": "sent",
      "invoiceDate": 1711929600000,
      "dueDate": 1714521600000,
      "sentAt": 1711929600000,
      "viewCount": 3,
      "createdAt": 1711929600000
    }
  ]
}
POST
/api/v1/invoices

Create Invoice

Creates a new draft invoice. The invoice must be sent separately using the Send endpoint.

Request Body

Invoice details. All amounts are in kobo (smallest currency unit).

Request
{
  "clientName": "John Smith",
  "clientEmail": "john@example.com",
  "clientCompany": "Acme Corp",
  "title": "Consulting Services - March 2026",
  "currency": "NGN",
  "lineItems": [
    {
      "description": "Strategy consulting (10 hours)",
      "quantity": 10,
      "unitPriceKobo": 500000,
      "totalKobo": 5000000
    },
    {
      "description": "Document review",
      "quantity": 1,
      "unitPriceKobo": 200000,
      "totalKobo": 200000
    }
  ],
  "subtotalKobo": 5200000,
  "taxRate": 7.5,
  "taxAmountKobo": 390000,
  "totalKobo": 5590000,
  "invoiceDate": 1711929600000,
  "dueDate": 1714521600000,
  "notes": "Payment due within 30 days."
}

Response

Response
{
  "data": {
    "id": "inv_abc123",
    "invoiceNumber": "INV-0001",
    "status": "draft",
    "totalKobo": 5590000,
    "viewToken": "a1b2c3d4...",
    "createdAt": 1711929600000
  }
}
GET
/api/v1/invoices/:id

Get Invoice

Retrieves a specific invoice with full details including payment history.

Path Parameters

id
required
string

The invoice ID

Response

Response
{
  "data": {
    "id": "inv_abc123",
    "invoiceNumber": "INV-0001",
    "clientName": "John Smith",
    "clientEmail": "john@example.com",
    "title": "Consulting Services",
    "currency": "NGN",
    "lineItems": [...],
    "subtotalKobo": 5200000,
    "taxRate": 7.5,
    "taxAmountKobo": 390000,
    "totalKobo": 5590000,
    "paidAmountKobo": 2000000,
    "status": "partially_paid",
    "payments": [
      {
        "amountKobo": 2000000,
        "paymentDate": 1712534400000,
        "paymentMethod": "bank_transfer",
        "reference": "TXN-12345"
      }
    ],
    "viewCount": 5,
    "lastViewedAt": 1712620800000,
    "sentAt": 1711929600000,
    "dueDate": 1714521600000
  }
}
PATCH
/api/v1/invoices/:id

Update Invoice

Updates a draft invoice. Only invoices in draft status can be modified.

Path Parameters

id
required
string

The invoice ID

Request Body

Fields to update (all optional)

Request
{
  "title": "Updated Title",
  "dueDate": 1714521600000,
  "notes": "Updated payment terms."
}

Response

Response
{
  "data": {
    "id": "inv_abc123",
    "status": "draft",
    "title": "Updated Title",
    "updatedAt": 1712534400000
  }
}
POST
/api/v1/invoices/:id/send

Send Invoice

Sends a draft invoice to the client via email. The invoice status changes to 'sent' and a public view link is generated.

Path Parameters

id
required
string

The invoice ID

Response

Triggers invoice.sent webhook. The client receives an email with a link to view and download the invoice.

Response
{
  "data": {
    "success": true
  }
}
POST
/api/v1/invoices/:id/payments

Record Payment

Records a payment against an invoice. Supports partial payments — the invoice status automatically updates to 'partially_paid' or 'paid' based on the total amount received.

Path Parameters

id
required
string

The invoice ID

Request Body

Payment details

Request
{
  "amountKobo": 2000000,
  "paymentDate": "2026-04-10T00:00:00.000Z",
  "paymentMethod": "bank_transfer",
  "reference": "TXN-12345",
  "note": "First installment"
}

Response

Triggers invoice.payment_recorded webhook on every payment. When fully paid, also triggers invoice.paid webhook and sends a receipt email to the client.

Response
{
  "data": {
    "success": true,
    "status": "partially_paid"
  }
}
POST
/api/v1/invoices/:id/void

Void Invoice

Voids an invoice, making it permanently inactive. Cannot void invoices that are already paid or voided.

Path Parameters

id
required
string

The invoice ID

Response

Triggers invoice.voided webhook.

Response
{
  "data": {
    "success": true
  }
}

Generic Business Apps

Use one API surface for available business apps that share the generic record engine, including Business Intake, Hiring Packets, and Renewals & Compliance.

Apps Platform
GET
/api/v1/apps/:appSlug/records

List App Records

Lists records for an available generic business app.

Query Parameters

status
string

Optional record status filter

limit
number

Maximum records to return

Path Parameters

appSlug
required
string

Available app slug, such as business-intake, hiring-packets, or renewals-compliance

Response

Response
{
  "data": [
    {
      "record": {
        "id": "rec_abc123",
        "appSlug": "business-intake",
        "recordType": "vendor_onboarding",
        "title": "Acme Catering",
        "status": "pending_review"
      }
    }
  ]
}
POST
/api/v1/apps/:appSlug/records

Create App Record

Creates a generic app record using the app's default record type unless recordType is provided. Use fields for declared typed values from the schema endpoint and relatedParty for contact details.

Path Parameters

appSlug
required
string

Available app slug

Request Body

Generic app record fields

Request
{
  "title": "Acme Catering",
  "recordType": "vendor_onboarding",
  "status": "pending_review",
  "metadata": {
    "contactEmail": "sam@example.com"
  }
}

Response

Response
{
  "data": {
    "id": "rec_abc123"
  }
}
GET
/api/v1/apps/:appSlug/records/:id

Get App Record

Returns one generic app record by ID.

Path Parameters

appSlug
required
string

Available app slug

id
required
string

Generic app record ID

Response

Response
{
  "data": {
    "record": {
      "id": "rec_abc123",
      "appSlug": "business-intake",
      "recordType": "vendor_onboarding",
      "title": "Acme Catering",
      "status": "pending_review"
    }
  }
}
PATCH
/api/v1/apps/:appSlug/records/:id

Update App Record

Atomically updates status, title, description, dates, amounts, contact or typed fields. Discover fields with the schema endpoint. fields merges declared keys; null clears optional fields. Legacy metadata replaces metadata; do not send both.

Path Parameters

appSlug
required
string

Available app slug

id
required
string

Generic app record ID

Request Body

Partial record update

Request
{
  "status": "approved",
  "title": "Reviewed onboarding"
}

Response

Response
{
  "data": {
    "id": "record_abc123",
    "title": "Reviewed onboarding",
    "status": "approved"
  }
}
GET
/api/v1/apps/:appSlug/records/:id/documents

List App Record Documents

Lists documents attached to a generic app record. The API resolves the record and uses its actual record type.

Path Parameters

appSlug
required
string

Available app slug

id
required
string

Generic app record ID

Response

Response
{
  "data": [
    {
      "id": "doc_abc123",
      "entityType": "vendor_onboarding",
      "fileName": "acme-w9.pdf",
      "status": "pending_review"
    }
  ]
}
POST
/api/v1/apps/:appSlug/records/:id/documents

Attach App Record Document

Uploads a base64-encoded document to a generic app record.

Path Parameters

appSlug
required
string

Available app slug

id
required
string

Generic app record ID

Request Body

Document upload payload

Request
{
  "requirementKey": "tax_form",
  "label": "Signed W-9",
  "document": {
    "filename": "acme-w9.pdf",
    "contentType": "application/pdf",
    "data": "base64..."
  }
}

Response

Response
{
  "data": {
    "id": "doc_abc123"
  }
}
GET
/api/v1/apps/:appSlug/records/:id/approvals

List App Record Approvals

Lists approval requests for a generic app record.

Path Parameters

appSlug
required
string

Available app slug

id
required
string

Generic app record ID

Response

Response
{
  "data": [
    {
      "id": "appr_abc123",
      "entityType": "vendor_onboarding",
      "status": "pending"
    }
  ]
}
POST
/api/v1/apps/:appSlug/records/:id/approvals

Request App Record Approval

Creates an internal approval request for a generic app record.

Path Parameters

appSlug
required
string

Available app slug

id
required
string

Generic app record ID

Request Body

Approval request payload

Request
{
  "title": "Finance approval",
  "mode": "sequential",
  "approvers": [
    { "approverEmail": "finance@example.com", "stepNumber": 1 }
  ]
}

Response

Response
{
  "data": {
    "id": "appr_abc123"
  }
}
GET
/api/v1/apps/:appSlug/records/:id/portal-links

List App Record Portal Links

Lists public intake portal links for a generic app record.

Path Parameters

appSlug
required
string

Available app slug

id
required
string

Generic app record ID

Response

Response
{
  "data": [
    {
      "id": "portal_abc123",
      "status": "active",
      "recipientEmail": "sam@example.com"
    }
  ]
}
POST
/api/v1/apps/:appSlug/records/:id/portal-links

Create App Record Portal Link

Creates a public intake portal link for a generic app record.

Path Parameters

appSlug
required
string

Available app slug

id
required
string

Generic app record ID

Request Body

Portal link payload

Request
{
  "recipientName": "Sam Lee",
  "recipientEmail": "sam@example.com",
  "notificationChannels": ["email"]
}

Response

Response
{
  "data": {
    "id": "portal_abc123",
    "url": "https://www.wegosign.com/intake/token"
  }
}
DELETE
/api/v1/apps/:appSlug/records/:id/portal-links/:portalLinkId

Revoke App Record Portal Link

Revokes a public intake portal link for a generic app record.

Path Parameters

appSlug
required
string

Available app slug

id
required
string

Generic app record ID

portalLinkId
required
string

Portal link ID

Response

Response
{
  "data": {
    "status": "revoked"
  }
}
GET
/api/v1/apps/:appSlug/records/:id/ledger

List a Record's Ledger

Money movements against a record, newest first, with totals in, out, net, and by kind. Grant Tracker reads the ledger as disbursements and spend against the award; Asset Checkout as deposits held, refunded, applied, and damage charges. Amounts are integer minor units (kobo).

Path Parameters

appSlug
required
string

Available app slug

id
required
string

Generic app record ID

Response

Response
{
  "data": [
    {
      "id": "ledger_abc123",
      "kind": "disbursement",
      "direction": "in",
      "amountKobo": 2500000,
      "currency": "NGN",
      "entryDate": 1757328000000,
      "description": "Tranche 1",
      "reference": "FF-2026-01",
      "createdAt": 1757328000000
    }
  ],
  "totals": {
    "inKobo": 2500000,
    "outKobo": 0,
    "netKobo": 2500000,
    "byKind": { "disbursement": 2500000, "expense": 0 },
    "currency": "NGN",
    "mixedCurrency": false
  }
}
POST
/api/v1/apps/:appSlug/records/:id/ledger

Add a Ledger Entry

Records one money movement on a record. kind is one of disbursement, expense, deposit_held, deposit_applied, deposit_refund, damage_charge, payment, other; direction (in or out) defaults from the kind; amountKobo is a whole non-negative amount in minor units; currency defaults to NGN; entryDate accepts a millisecond timestamp or an ISO date and defaults to now. Emits app.record.updated.

Path Parameters

appSlug
required
string

Available app slug

id
required
string

Generic app record ID

Request Body

kind, amountKobo, and description are required; direction, currency, entryDate, reference, and invoiceId are optional

Request
{
  "kind": "expense",
  "amountKobo": 120000,
  "currency": "NGN",
  "entryDate": "2026-09-01",
  "description": "Field visit",
  "reference": "EXP-9"
}

Response

Response
{
  "data": {
    "id": "ledger_abc124",
    "recordId": "record_abc123",
    "kind": "expense",
    "direction": "out",
    "amountKobo": 120000,
    "currency": "NGN",
    "entryDate": 1756684800000,
    "description": "Field visit",
    "reference": "EXP-9"
  }
}
GET
/api/v1/apps/:appSlug/records/export

Export App Records as CSV

Downloads the app's records (newest first, up to 2000 rows) as a CSV with one column per typed field. Accepts the same filters as the list route.

Query Parameters

status
string

Filter by status

includeArchived
boolean

Include archived records (default: false)

Path Parameters

appSlug
required
string

Available app slug

Response

Response
id,title,status,recordType,owner,createdAt,updatedAt,dueDate,amount,currency,partyName,partyEmail,partyCompany,partyPhone,funder,programName
rec_abc123,Community health award,active,grant,Ada Lovelace,2026-09-08T10:00:00.000Z,2026-09-08T10:00:00.000Z,2026-12-15T00:00:00.000Z,50000.00,NGN,Program Officer,officer@funder.org,Ford Foundation,,Ford Foundation,Health
GET
/api/v1/apps/:appSlug/records/calendar.ics

Subscribe to App Record Dates as an iCalendar Feed

An iCalendar (ICS) feed with one all-day event per record that has a due date (up to 2000 rows). Each event's UID is the record ID, so calendar apps update events in place, and the URL opens the record in the dashboard. Accepts the same filters as the list route.

Query Parameters

status
string

Filter by status

includeArchived
boolean

Include archived records (default: false)

Path Parameters

appSlug
required
string

Available app slug

Response

Response
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//WeGoSign//renewals-compliance//EN
BEGIN:VEVENT
UID:rec_abc123@wegosign
DTSTART;VALUE=DATE:20261215
DTEND;VALUE=DATE:20261216
SUMMARY:Liability policy — Expiring Soon
URL:https://www.wegosign.com/acme/apps/renewals-compliance/rec_abc123
END:VEVENT
END:VCALENDAR
GET
/api/v1/apps/:appSlug/records/:id/links

List Linked Envelopes and Invoices

Envelopes and client invoices linked to a record, with the linked document's current title and status.

Path Parameters

appSlug
required
string

Available app slug

id
required
string

Generic app record ID

Response

Response
{
  "data": [
    {
      "id": "link_abc123",
      "linkType": "agreement_envelope",
      "targetId": "env_abc123",
      "createdAt": 1757328000000,
      "target": { "kind": "envelope", "id": "env_abc123", "title": "Grant agreement", "status": "completed" }
    }
  ]
}
POST
/api/v1/apps/:appSlug/records/:id/links

Link an Envelope or Invoice to a Record

Attaches a signed envelope or a client invoice to any generic app record. For Agreements & Revenue the engagement status also follows the linked document (contract sent or signed, invoice ready, sent, partially paid, paid).

Path Parameters

appSlug
required
string

Available app slug

id
required
string

Generic app record ID

Request Body

Exactly one of envelopeId or invoiceId

Request
{
  "envelopeId": "env_abc123"
}

Response

Response
{
  "data": {
    "id": "record_abc123",
    "linkId": "link_abc123",
    "status": "contract_sent",
    "linked": { "envelopeId": "env_abc123" }
  }
}

Asset Checkout Register

The register behind Asset Checkout: the physical assets (laptops, cameras, vehicles) that loan records borrow. Loan records themselves use the generic app record routes with appSlug=asset-checkout; these routes manage the assets and move one asset onto or off a loan. Money is in integer minor units (kobo).

Apps Platform
GET
/api/v1/apps/asset-checkout/assets

List Assets

The asset register sorted by tag, each with its current holder (the loan record, holder name, and due date) when checked out. Retired assets are hidden unless status=retired or includeRetired=true.

Query Parameters

status
string

available, checked_out, maintenance, or retired

includeRetired
boolean

Include retired assets (default: false)

Response

Response
{
  "data": [
    {
      "id": "asset_abc123",
      "assetTag": "MBP-001",
      "name": "MacBook Pro 16",
      "category": "Laptop",
      "serialNumber": "C02XYZ",
      "valueKobo": 250000000,
      "currency": "NGN",
      "condition": "good",
      "status": "checked_out",
      "currentRecordId": "record_abc123",
      "holder": {
        "recordId": "record_abc123",
        "recordTitle": "Laptop for Ada",
        "recordStatus": "checked_out",
        "holderName": "Ada Lovelace",
        "dueDate": 1760313600000
      },
      "createdAt": 1757328000000,
      "updatedAt": 1757328000000
    }
  ]
}
POST
/api/v1/apps/asset-checkout/assets

Create an Asset

Adds an asset to the register. assetTag must be unique within the organization (a duplicate is a 400); condition defaults to good and status to available. purchaseDate is a calendar date (YYYY-MM-DD); valueKobo is a whole non-negative amount in minor units.

Request Body

assetTag, name, and category are required; serialNumber, purchaseDate, valueKobo, currency, condition (new, good, fair, damaged, lost, retired), and notes are optional

Request
{
  "assetTag": "MBP-001",
  "name": "MacBook Pro 16",
  "category": "Laptop",
  "serialNumber": "C02XYZ",
  "purchaseDate": "2026-01-15",
  "valueKobo": 250000000,
  "currency": "NGN",
  "condition": "new"
}

Response

Response
{
  "data": {
    "id": "asset_abc123",
    "assetTag": "MBP-001",
    "name": "MacBook Pro 16",
    "category": "Laptop",
    "condition": "new",
    "status": "available",
    "holder": null,
    "createdAt": 1757328000000,
    "updatedAt": 1757328000000
  }
}
GET
/api/v1/apps/asset-checkout/assets/:assetId

Get an Asset

One asset with its current holder. An asset that does not exist or belongs to another organization is a 404.

Path Parameters

assetId
required
string

Asset ID

Response

Response
{
  "data": {
    "id": "asset_abc123",
    "assetTag": "MBP-001",
    "name": "MacBook Pro 16",
    "category": "Laptop",
    "condition": "good",
    "status": "available",
    "holder": null,
    "createdAt": 1757328000000,
    "updatedAt": 1757328000000
  }
}
PATCH
/api/v1/apps/asset-checkout/assets/:assetId

Update or Retire an Asset

Updates register fields (assetTag, name, category, serialNumber, purchaseDate, valueKobo, currency, condition, notes). Setting condition to new, good, or fair on an asset in maintenance returns it to available. Send { "status": "retired" } (optionally with notes) to retire the asset; retiring is refused while it is checked out, and any other status is a 400 because loans move through the check-out and check-in routes.

Path Parameters

assetId
required
string

Asset ID

Request Body

Any register field, or status: retired on its own

Request
{
  "condition": "fair",
  "notes": "Scuffed lid, works fine"
}

Response

Response
{
  "data": {
    "id": "asset_abc123",
    "assetTag": "MBP-001",
    "condition": "fair",
    "status": "available",
    "notes": "Scuffed lid, works fine",
    "holder": null,
    "updatedAt": 1757414400000
  }
}
POST
/api/v1/apps/asset-checkout/assets/:assetId/check-out

Check an Asset Out

Binds an available asset to an Asset Checkout loan record: the record gets assetId, assetTag, assetDescription, and checkoutDate (today unless already set) and emits app.record.updated. An asset that is not available, or a record from another app, is a 400; a missing asset or record is a 404.

Path Parameters

assetId
required
string

Asset ID

Request Body

recordId of the Asset Checkout record receiving the asset

Request
{
  "recordId": "record_abc123"
}

Response

Response
{
  "data": {
    "id": "asset_abc123",
    "assetTag": "MBP-001",
    "status": "checked_out",
    "currentRecordId": "record_abc123",
    "holder": { "recordId": "record_abc123", "recordTitle": "Laptop for Ada", "holderName": "Ada Lovelace" }
  },
  "recordId": "record_abc123"
}
POST
/api/v1/apps/asset-checkout/assets/:assetId/check-in

Check an Asset In

Releases the asset from its loan with the condition it came back in. The record gets returnedDate (today), condition, and optional conditionNotes and emits app.record.updated; the asset returns to available, or waits in maintenance when damaged or lost. An asset that is not checked out is a 400.

Path Parameters

assetId
required
string

Asset ID

Request Body

condition is one of new, good, fair, damaged, lost; conditionNotes is optional

Request
{
  "condition": "damaged",
  "conditionNotes": "Cracked screen"
}

Response

Response
{
  "data": {
    "id": "asset_abc123",
    "assetTag": "MBP-001",
    "condition": "damaged",
    "status": "maintenance",
    "holder": null
  },
  "recordId": "record_abc123"
}

Business Intake

Create intake records for clients, vendors, partners, suppliers, consultants, agencies, contractors, and other business relationships with type-specific documents, approvals, tasks, team assignments, portal links, and encrypted vault fields.

Apps Platform
GET
/api/v1/business-intake

List Business Intakes

Lists Business Intake records with checklist readiness, task counts, approval count, team count, portal count, and vault summary counts.

Query Parameters

status
string

Filter by status, for example pending_review or approved

limit
number

Maximum records to return (max: 200)

Response

Response
{
  "data": [
    {
      "record": {
        "id": "rec_abc123",
        "title": "Acme Catering",
        "status": "pending_review",
        "metadata": { "intakeType": "vendor" },
        "relatedParty": {
          "name": "Sam Lee",
          "email": "sam@example.com",
          "company": "Acme Catering"
        }
      },
      "checklistSummary": {
        "requiredCount": 4,
        "approvedRequired": 3,
        "missingRequired": 1,
        "completionPercent": 75
      },
      "pendingApprovalCount": 1,
      "vaultItemCount": 2
    }
  ]
}
POST
/api/v1/business-intake

Create Business Intake

Creates a Business Intake record. Set intakeType to client, vendor, partner, supplier, consultant, agency, contractor, or other.

Request Body

Business intake fields

Request
{
  "title": "Acme Catering",
  "intakeType": "vendor",
  "contactName": "Sam Lee",
  "contactEmail": "sam@example.com",
  "companyName": "Acme Catering",
  "serviceCategory": "Catering",
  "taxClassification": "LLC",
  "paymentTerms": "Net 30",
  "riskLevel": "standard",
  "targetStartDate": "2026-05-15"
}

Response

Response
{
  "data": {
    "id": "rec_abc123"
  }
}
GET
/api/v1/business-intake/:intakeId

Get Business Intake

Returns the intake record, required document checklist, documents, tasks, approvals, team members, portal links, vault summaries, action register entries, and audit activity.

Path Parameters

intakeId
required
string

Business Intake record ID

Response

Response
{
  "data": {
    "record": { "id": "rec_abc123", "title": "Acme Catering", "status": "pending_review" },
    "checklistSummary": { "completionPercent": 75 },
    "checklist": [...],
    "documents": [...],
    "actions": [...],
    "approvals": [...],
    "members": [...],
    "vaultItems": [
      { "fieldKey": "bank_account", "label": "Bank account", "redactedPreview": "****1234" }
    ]
  }
}
POST
/api/v1/business-intake/:intakeId/documents

Attach Business Intake Document

Uploads a base64-encoded document to an intake checklist item.

Path Parameters

intakeId
required
string

Business Intake record ID

Request Body

Document upload payload

Request
{
  "requirementKey": "tax_form",
  "status": "pending_review",
  "accessLevel": "finance",
  "isSensitive": true,
  "document": {
    "filename": "acme-w9.pdf",
    "contentType": "application/pdf",
    "data": "base64..."
  }
}

Response

Response
{
  "data": {
    "id": "doc_abc123"
  }
}
POST
/api/v1/business-intake/:intakeId/tasks

Create Business Intake Task

Creates an intake follow-up, onboarding, review, or setup task.

Request Body

Task payload

Request
{
  "title": "Verify payment details",
  "description": "Confirm remittance details with finance",
  "dueDate": 1778803200000
}

Response

Response
{
  "data": {
    "id": "appr_abc123"
  }
}
POST
/api/v1/business-intake/:intakeId/approvals

Request Business Intake Approval

Creates an internal approval request for intake review.

Request Body

Approval request

Request
{
  "title": "Finance approval",
  "mode": "sequential",
  "approvers": [
    { "approverEmail": "finance@example.com", "stepNumber": 1 }
  ]
}

Response

Response
{
  "data": {
    "id": "appr_abc123"
  }
}
POST
/api/v1/business-intake/:intakeId/team

Assign Business Intake Team Member

Assigns an existing workspace member to the intake record.

Request Body

Team assignment

Request
{
  "userId": "user_abc123",
  "role": "contributor"
}

Response

Response
{
  "data": {
    "id": "member_abc123"
  }
}
POST
/api/v1/business-intake/:intakeId/portal-links

Create Business Intake Portal Link

Creates a public intake link for document collection and optional email/SMS notification.

Request Body

Portal link payload

Request
{
  "recipientName": "Sam Lee",
  "recipientEmail": "sam@example.com",
  "recipientPhone": "+15551234567",
  "notificationChannels": ["email", "sms"]
}

Response

Response
{
  "data": {
    "id": "portal_abc123"
  }
}
POST
/api/v1/business-intake/:intakeId/vault

Set Business Intake Vault Field

Creates or updates an encrypted intake vault field. The API returns the vault item ID, not the plaintext value.

Request Body

Encrypted field payload

Request
{
  "fieldKey": "bank_account",
  "label": "Bank account",
  "value": "1234567890",
  "accessLevel": "finance"
}

Response

Response
{
  "data": {
    "id": "vault_abc123"
  }
}

Hiring Packets

Create hiring packet records, collect offer letters and agreements, track policy acknowledgments, manage onboarding tasks, assign team members, create external portal links, request approvals, and store restricted values in the encrypted vault.

Apps Platform
GET
/api/v1/hiring-packets

List Hiring Packets

Lists Hiring Packet records with checklist readiness, approval count, open task count, team count, and vault summary counts.

Query Parameters

status
string

Filter by status, for example offer_sent or cleared_to_start

limit
number

Maximum records to return (max: 200)

Response

Response
{
  "data": [
    {
      "packet": { "id": "rec_abc123", "title": "Avery Johnson", "status": "offer_sent" },
      "checklistSummary": { "requiredCount": 3, "approvedRequired": 1, "completionPercent": 33 },
      "openTaskCount": 2,
      "teamMemberCount": 1,
      "vaultItemCount": 0
    }
  ]
}
POST
/api/v1/hiring-packets

Create Hiring Packet

Creates a Hiring Packet record with candidate, role, worker type, start date, manager, and compensation metadata.

Request Body

Hiring packet fields

Request
{
  "candidateName": "Avery Johnson",
  "candidateEmail": "avery@example.com",
  "candidatePhone": "+2348012345678",
  "smsAlerts": true,
  "roleTitle": "Operations Manager",
  "department": "Operations",
  "workerType": "employee",
  "startDate": "2026-05-15"
}

Response

Response
{
  "data": {
    "id": "rec_abc123"
  }
}
POST
/api/v1/hiring-packets/:packetId/tasks

Create Hiring Packet Task

Creates an onboarding task and emits generic app action events plus Hiring Packet task events.

Request Body

Task fields

Request
{
  "title": "Provision laptop",
  "dueDate": 1770000000000
}

Response

Response
{
  "data": {
    "id": "action_abc123"
  }
}
POST
/api/v1/hiring-packets/:packetId/portal-links

Create Hiring Packet Portal Link

Creates a public intake link for the candidate or contractor to submit details and checklist documents.

Request Body

Portal link fields

Request
{
  "recipientName": "Avery Johnson",
  "recipientEmail": "avery@example.com",
  "notificationChannels": ["sms"],
  "label": "Candidate document collection"
}

Response

Response
{
  "data": {
    "id": "link_abc123",
    "url": "https://www.wegosign.com/intake/token"
  }
}

Renewals & Compliance

Track contracts, permits, insurance certificates, training credentials, policy acknowledgments, regulatory filings, custom compliance items, required evidence, approvals, tasks, teams, portal submissions, and encrypted vault fields.

Apps Platform
GET
/api/v1/renewals-compliance

List Compliance Items

Lists Renewals & Compliance records with checklist readiness, approval count, open task count, team count, and vault summary counts.

Query Parameters

status
string

Filter by status, for example pending_documents, compliant, expiring_soon, or expired

limit
number

Maximum records to return (max: 200)

Response

Response
{
  "data": [
    {
      "item": { "id": "rec_abc123", "title": "General Liability COI", "status": "expiring_soon" },
      "checklistSummary": { "requiredCount": 3, "approvedRequired": 2, "completionPercent": 67 },
      "openTaskCount": 1,
      "teamMemberCount": 1,
      "vaultItemCount": 0
    }
  ]
}
POST
/api/v1/renewals-compliance

Create Compliance Item

Creates a configurable renewal or compliance item. The tracking type determines the default document and evidence checklist.

Request Body

Compliance item fields

Request
{
  "title": "General Liability COI",
  "trackingType": "insurance_coi",
  "relatedPartyName": "Northstar Logistics",
  "issuingAuthority": "Carrier Mutual",
  "expirationDate": "2026-08-01",
  "renewalDueDate": "2026-07-15",
  "policyNumber": "COI-2026-1001"
}

Response

Response
{
  "data": {
    "id": "rec_abc123"
  }
}
POST
/api/v1/renewals-compliance/:itemId/documents

Attach Compliance Evidence

Attaches a base64-encoded required document or supporting evidence file to a compliance item.

Request Body

Document upload fields

Request
{
  "requirementKey": "certificate_of_insurance",
  "label": "Current COI",
  "document": {
    "filename": "coi.pdf",
    "contentType": "application/pdf",
    "data": "base64..."
  }
}

Response

Response
{
  "data": {
    "id": "doc_abc123"
  }
}
POST
/api/v1/renewals-compliance/:itemId/tasks

Create Compliance Task

Creates a renewal reminder, follow-up, filing, inspection, or review task.

Request Body

Task fields

Request
{
  "title": "Request renewed COI",
  "dueDate": 1784073600000
}

Response

Response
{
  "data": {
    "id": "action_abc123"
  }
}

Webhooks

Receive real-time notifications when events occur in your account. Configure webhook endpoints to automate workflows and keep your systems in sync.

Growth Plan & Above
POST
/api/v1/webhooks

Create Webhook

Creates a new webhook endpoint to receive event notifications.

Request Body

Webhook configuration

Request
{
  "url": "https://yourapp.com/webhooks/wegosign",
  "events": [
    "envelope.created",
    "envelope.sent",
    "envelope.completed",
    "signer.viewed",
    "signer.signed",
    "signer.declined",
    "document.downloaded"
  ],
  "description": "Main production webhook"
}

Response

The webhook secret is only shown once on creation. Store it securely for signature verification.

Response
{
  "data": {
    "id": "whk_abc123",
    "url": "https://yourapp.com/webhooks/wegosign",
    "events": ["envelope.created", "envelope.completed", "signer.signed"],
    "description": "Main production webhook",
    "secret": "whsec_abc123xyz789...",
    "isActive": true,
    "createdAt": 1704543600000
  }
}
GET
/api/v1/webhooks

List Webhooks

Retrieves all webhooks configured for your organization.

Response

Response
{
  "data": [
    {
      "id": "whk_abc123",
      "url": "https://yourapp.com/webhooks/wegosign",
      "events": ["envelope.completed", "signer.signed"],
      "description": "Main production webhook",
      "isActive": true,
      "failureCount": 0,
      "lastDeliveredAt": 1704550000000,
      "createdAt": 1704543600000
    }
  ]
}
GET
/api/v1/webhooks/:id

Get Webhook

Retrieves a specific webhook by its ID.

Path Parameters

id
required
string

The webhook ID

Response

Response
{
  "data": {
    "id": "whk_abc123",
    "url": "https://yourapp.com/webhooks/wegosign",
    "events": ["envelope.completed", "signer.signed"],
    "description": "Main production webhook",
    "isActive": true,
    "failureCount": 0,
    "lastDeliveredAt": 1704550000000,
    "createdAt": 1704543600000
  }
}
DELETE
/api/v1/webhooks/:id

Delete Webhook

Permanently deletes a webhook endpoint.

Path Parameters

id
required
string

The webhook ID

Response

Response
{
  "data": {
    "id": "whk_abc123",
    "deleted": true
  }
}

Record workflows

GET
/api/v1/apps

Discover apps

Available apps and schema discovery paths.

Response

Response
{
  "data": []
}
GET
/api/v1/organization/members

List active organization members

Use returned user IDs for assignment; paginate with limit and cursor.

Response

Response
{
  "data": {
    "items": [],
    "nextCursor": null
  }
}
GET
/api/v1/apps/:appSlug/schema

Discover app schema

Typed fields, statuses, document requirements and signing policies. Optional recordId resolves record overrides; subtype selects a record subtype.

Path Parameters

appSlug
required
string

ID or app slug returned by WeGoSign

Response

Response
{
  "data": {
    "appSlug": "hiring-packets",
    "recordType": "hiring_packet",
    "fields": [],
    "requirements": [],
    "allowedTransitions": []
  }
}
GET
/api/v1/apps/:appSlug/records/:id/obligations

List obligations

Includes a proposed Grant Tracker reporting schedule; this read does not create obligations.

Path Parameters

appSlug
required
string

ID or app slug returned by WeGoSign

id
required
string

ID or app slug returned by WeGoSign

Response

Response
{
  "data": {
    "items": [],
    "proposedSchedule": []
  }
}
POST
/api/v1/apps/:appSlug/records/:id/obligations

Add obligations

Atomic batch of at most 60 items; matching titles and dates are skipped.

Path Parameters

appSlug
required
string

ID or app slug returned by WeGoSign

id
required
string

ID or app slug returned by WeGoSign

Request Body

Request fields

Request
{
  "items": [
    {
      "title": "Quarterly report",
      "kind": "report",
      "dueDate": 1803859200000
    }
  ]
}

Response

Response
{
  "data": {
    "ids": [
      "obligation_id"
    ],
    "created": 1
  }
}
PATCH
/api/v1/apps/:appSlug/records/:id/obligations/:obligationId

Update obligation

Edit title, kind, dueDate, notes or status (open, submitted, waived).

Path Parameters

appSlug
required
string

ID or app slug returned by WeGoSign

id
required
string

ID or app slug returned by WeGoSign

obligationId
required
string

ID or app slug returned by WeGoSign

Request Body

Request fields

Request
{
  "status": "waived"
}

Response

Response
{
  "data": {
    "id": "resource_id"
  }
}
DELETE
/api/v1/apps/:appSlug/records/:id/obligations/:obligationId

Delete obligation

Deletes this record obligation.

Path Parameters

appSlug
required
string

ID or app slug returned by WeGoSign

id
required
string

ID or app slug returned by WeGoSign

obligationId
required
string

ID or app slug returned by WeGoSign

Response

Response
POST
/api/v1/apps/:appSlug/records/:id/obligations/:obligationId/complete

Submit obligation

Optional documentId must belong to the same record; notes are optional.

Path Parameters

appSlug
required
string

ID or app slug returned by WeGoSign

id
required
string

ID or app slug returned by WeGoSign

obligationId
required
string

ID or app slug returned by WeGoSign

Request Body

Request fields

Request
{
  "notes": "Report submitted"
}

Response

Response
{
  "data": {
    "id": "resource_id"
  }
}
GET
/api/v1/apps/:appSlug/records/:id/presets

List record presets

Built-in and organization bundles with suggested and applied state.

Path Parameters

appSlug
required
string

ID or app slug returned by WeGoSign

id
required
string

ID or app slug returned by WeGoSign

Response

Response
{
  "data": {
    "presets": [],
    "appliedKeys": []
  }
}
POST
/api/v1/apps/:appSlug/records/:id/presets

Apply record preset

Applies a discovered presetKey without duplicating existing tasks or requirements.

Path Parameters

appSlug
required
string

ID or app slug returned by WeGoSign

id
required
string

ID or app slug returned by WeGoSign

Request Body

Request fields

Request
{
  "presetKey": "key_from_list"
}

Response

Response
{
  "data": {
    "tasksCreated": 1,
    "requirementsAdded": 1,
    "presetName": "Selected preset"
  }
}
GET
/api/v1/apps/:appSlug/records/:id/signing

Get record signing options

Discover signable requirements, derived placeholders and previous sends.

Path Parameters

appSlug
required
string

ID or app slug returned by WeGoSign

id
required
string

ID or app slug returned by WeGoSign

Response

Response
{
  "data": {
    "signable": [],
    "party": {},
    "placeholderValues": [],
    "linked": []
  }
}
POST
/api/v1/apps/:appSlug/records/:id/signing

Send record requirement for signature

Choose exactly one templateId or packageId and a declared requirementKey. Supply all countersigners. requestKey is required: identical retries replay the original envelope; different arguments with the same key return 409. Completion attaches the signed PDF and applies the declared transition.

Path Parameters

appSlug
required
string

ID or app slug returned by WeGoSign

id
required
string

ID or app slug returned by WeGoSign

Request Body

Request fields

Request
{
  "requestKey": "offer_send_001",
  "requirementKey": "key_from_options",
  "templateId": "template_id",
  "signerName": "Ada",
  "signerEmail": "ada@example.com"
}

Response

Response
{
  "data": {
    "envelopeId": "envelope_id",
    "status": "offer_sent",
    "replayed": false
  }
}
GET
/api/v1/apps/:appSlug/records/:id/tasks

List record tasks

The record action register.

Path Parameters

appSlug
required
string

ID or app slug returned by WeGoSign

id
required
string

ID or app slug returned by WeGoSign

Response

Response
{
  "data": []
}
POST
/api/v1/apps/:appSlug/records/:id/tasks

Create record task

Optional description, dueDate and ownerUserId; owner must be an active organization member.

Path Parameters

appSlug
required
string

ID or app slug returned by WeGoSign

id
required
string

ID or app slug returned by WeGoSign

Request Body

Request fields

Request
{
  "title": "Review documents"
}

Response

Response
{
  "data": {
    "id": "resource_id"
  }
}
PATCH
/api/v1/apps/:appSlug/records/:id/tasks/:taskId

Update record task

Edit task fields or status: open, in_progress, completed, cancelled.

Path Parameters

appSlug
required
string

ID or app slug returned by WeGoSign

id
required
string

ID or app slug returned by WeGoSign

taskId
required
string

ID or app slug returned by WeGoSign

Request Body

Request fields

Request
{
  "status": "completed"
}

Response

Response
{
  "data": {
    "id": "resource_id"
  }
}
POST
/api/v1/apps/:appSlug/records/:id/team

Assign record team member

Assign an active organization member as owner, contributor, approver or viewer.

Path Parameters

appSlug
required
string

ID or app slug returned by WeGoSign

id
required
string

ID or app slug returned by WeGoSign

Request Body

Request fields

Request
{
  "userId": "user_id",
  "role": "contributor"
}

Response

Response
{
  "data": {
    "id": "resource_id"
  }
}
POST
/api/v1/apps/:appSlug/records/:id/documents/:documentId/review

Review record document

Document readiness review; individual approval decisions remain session-authenticated. Status: approved, rejected, needs_revision, expired; optional rejectionReason.

Path Parameters

appSlug
required
string

ID or app slug returned by WeGoSign

id
required
string

ID or app slug returned by WeGoSign

documentId
required
string

ID or app slug returned by WeGoSign

Request Body

Request fields

Request
{
  "status": "approved"
}

Response

Response
{
  "data": {
    "id": "document_id",
    "status": "approved"
  }
}
Model Context Protocol (MCP)

Connect WeGoSign to AI assistants and agent clients through the hosted MCP endpoint or local stdio server

Overview

WeGoSign exposes the same REST API workflows through MCP tools, resources, and prompts. Hosted MCP clients can connect to /api/mcp with a WeGoSign API key or the advertised OAuth 2.1 authorization-code flow, and local clients can run the standalone MCP server package.

Signing Workflows

Send template or package envelopes, track signers, remind, cancel, and download

Template Packages

List, create, update, archive, and send multi-document packages

Business Automation

Manage webhooks, invoices, bulk sends, and SSO status from agent clients

Hosted MCP server info
{
  "endpoint": "https://www.wegosign.com/api/mcp",
  "transport": "Streamable HTTP",
  "authentication": "OAuth 2.1 (S256 PKCE) or Bearer API key"
}

MCP Tools

MCP tools map to authenticated /api/v1 operations. The send-envelope tool accepts exactly one oftemplateId or packageId.

CategoryTools
Envelopeslist-envelopes, get-envelope, send-envelope, cancel-envelope, send-reminder, download-envelope, get-envelope-audit-log, get-envelope-signers
Templateslist-templates, get-template, get-template-fields, create-template, update-template, archive-template, update-template-fields
Template Packageslist-packages, get-package, create-package, update-package, archive-package
Bulk Sendscreate-bulk-send, get-bulk-send, get-bulk-send-errors
Invoiceslist-invoices, create-invoice, get-invoice, send-invoice, record-payment, void-invoice
Event Ledgerlist-event-ledger-events, get-event-ledger-event, create-event-ledger-event, update-event-ledger-event, create-event-ledger-sponsor, create-event-ledger-expense, import-meetumo-event-ledger
Generic Business Appslist-business-records, get-business-record, create-business-record, update-business-record-status, list-business-record-documents, attach-business-record-document, list-business-record-approvals, request-business-record-approval, create-business-record-portal-link
Agreements & Revenuelink-agreement-revenue-record (plus the generic business record tools)
Asset Checkoutlist-assets, create-asset, check-out-asset, check-in-asset (plus the generic business record tools for loan records)
Business Intakelist-business-intakes, get-business-intake, create-business-intake, update-business-intake-status, attach-business-intake-document, review-business-intake-document, create-business-intake-task, update-business-intake-task, request-business-intake-approval, assign-business-intake-team-member, create-business-intake-portal-link, set-business-intake-vault-field
Hiring Packetslist-hiring-packets, get-hiring-packet, create-hiring-packet, update-hiring-packet-status, attach-hiring-packet-document, review-hiring-packet-document, create-hiring-packet-task, update-hiring-packet-task, request-hiring-packet-approval, assign-hiring-packet-team-member, create-hiring-packet-portal-link, set-hiring-packet-vault-field
Renewals & Compliancelist-renewal-compliance-items, get-renewal-compliance-item, create-renewal-compliance-item, update-renewal-compliance-status, attach-renewal-compliance-document, review-renewal-compliance-document, create-renewal-compliance-task, update-renewal-compliance-task, request-renewal-compliance-approval, assign-renewal-compliance-team-member, create-renewal-compliance-portal-link, set-renewal-compliance-vault-field
Webhooks & SSOlist-webhooks, get-webhook, create-webhook, delete-webhook, get-sso-config

Record workflows

Discover typed fields with get-app-schema before editing. Record sends require a requestKey: reuse the key and arguments on retry; different arguments return 409. Individual approval decisions require the signed-in approver. Writes are never automatically retried.

list-organization-members, list-apps, get-app-schema, update-business-record, list-business-record-ledger, add-business-record-ledger-entry, list-business-record-links, link-business-record, list-business-record-portal-links, revoke-business-record-portal-link, export-business-records, get-business-record-calendar, list-business-record-obligations, add-business-record-obligations, update-business-record-obligation, complete-business-record-obligation, delete-business-record-obligation, list-business-record-presets, apply-business-record-preset, get-business-record-signing-options, send-business-record-for-signature, list-business-record-tasks, create-business-record-task, update-business-record-task, assign-business-record-team-member, review-business-record-document, get-asset, update-asset, retire-asset

Resources: wegosign://apps, wegosign://apps/{appSlug}/schema, wegosign://apps/{appSlug}/records/{recordId}. Prompts: manage-app-record, prepare-grant-reporting. Organization stats is a latest-envelope sample.

Connect from Claude or ChatGPT

Claude.ai, Claude Desktop, and ChatGPT connect to the hosted endpoint as a remote MCP server. Each registers itself through OAuth 2.1 (dynamic client registration, PKCE), opens the WeGoSign authorize page in your browser, and asks for a WeGoSign API key. The key is exchanged for an opaque access token; the assistant never stores the key itself. Use the URL exactly as shown, including the www host.

Remote MCP server URL
https://www.wegosign.com/api/mcp

Claude.ai and Claude Desktop

  1. Open Settings, then Connectors, and choose Add custom connector.
  2. Enter WeGoSign as the name and the server URL above, then click Add.
  3. Click Connect. On the WeGoSign authorize page, paste an API key from Settings, Developer.
  4. Enable the WeGoSign tools in a chat. Team and Enterprise workspaces may need an admin to allow custom connectors.

ChatGPT (Developer mode)

  1. Turn on Developer mode under Settings, Apps, Advanced settings (Pro, Team, Enterprise, and Edu plans).
  2. Create a connector with the server URL above and OAuth authentication.
  3. Complete the WeGoSign authorize page with an API key, then enable the connector in a chat.
  4. Developer mode is required: outside it ChatGPT only accepts servers that expose search and fetch tools, which WeGoSign does not provide.

Tokens carry the scopes of the API key used to authorize; revoking that key disconnects the assistant.

Local stdio server

For clients that launch a command instead of connecting to a URL, the @accelerated-capacity/wegosign-mcp package runs the same tool set over stdio on your machine. It needs Node.js 18 or newer and a WeGoSign API key; the key never leaves your computer.

Claude Desktop / Cursor configuration
{
  "mcpServers": {
    "wegosign": {
      "command": "npx",
      "args": ["-y", "@accelerated-capacity/wegosign-mcp"],
      "env": {
        "WEGOSIGN_API_KEY": "wgs_live_your_key"
      }
    }
  }
}

Resources & Prompts

Resources

wegosign://organization/stats, wegosign://templates,wegosign://packages, wegosign://webhooks,wegosign://sso/config, wegosign://envelopes/{envelopeId}/audit,wegosign://invoices, wegosign://event-ledger,wegosign://business-intake,wegosign://hiring-packets, and wegosign://renewals-compliance.

Prompts

send-for-signature, send-package-for-signature,check-pending, and weekly-report.

Guides

Best practices and implementation guides

Document Signing Flow

Understanding the complete lifecycle of a document from creation to completion.

1

Create Template

Upload a PDF and define signature fields via the dashboard or API. Templates are reusable and can be used for multiple envelopes.

2

Create & Send Envelope

Create an envelope from a template and specify signers. Each signer receives a unique, secure signing link via email.

3

Signer Views Document

When a signer clicks their link, they can view the document and see where they need to sign. This triggers the 'signer.viewed' webhook.

4

Signer Completes Signing

The signer fills in required fields and signs. They can draw, type, or upload a signature. This triggers 'signer.signed'.

5

Document Completed

When all signers complete, the envelope status changes to 'completed'. Download the signed PDF with embedded audit trail.

Basic Field Types

signature

Full signature - draw, type, or upload

initials

Quick initials field

sender_signature

Sender pre-signs before sending

date

Auto-filled date field

text

Free-form text input

checkbox

Checkbox for acknowledgments

Advanced Field Types

email

Email address with validation

phone

Phone number with country code

number

Numeric input with min/max validation

dropdown

Single-select dropdown menu

radio_group

Radio buttons - select one option

multi_select

Checkboxes - select multiple options

date_picker

Calendar date picker for custom dates

Conditional Field Logic

Show, hide, or require fields based on other field values. Configure conditions in the template editor.

Supported Operators:

• equals - Value matches exactly
• not_equals - Value does not match
• contains - Value contains text
• not_contains - Value does not contain text
• is_empty - Field is empty
• is_not_empty - Field has a value
• greater_than / less_than - Numeric comparison

Actions:

• Show - Display field when conditions are met
• Hide - Hide field when conditions are met
• Require - Make field required when conditions are met

Sequential Signing

Control the order in which signers must sign documents. Sequential signing ensures that signers can only access and sign the document when it's their turn.

How It Works

1. Assign a signingOrder number to each signer (1 = first)

2. Signers with lower numbers must complete before higher numbers can access the document

3. Signers attempting to access out of order receive a "not your turn" message

API Example

Sequential signing request
{
  "templateId": "template_abc123",
  "signers": [
    { "name": "Manager", "email": "manager@company.com", "signingOrder": 1 },
    { "name": "Director", "email": "director@company.com", "signingOrder": 2 },
    { "name": "CEO", "email": "ceo@company.com", "signingOrder": 3 }
  ]
}

Parallel Signing

For parallel signing where all signers can sign simultaneously, assign the samesigningOrder to all signers or omit it entirely.

Template Packages

Template packages allow you to bundle multiple templates together for complex multi-document signing workflows. Signers receive all documents in a single signing session.

Key Features

Multi-Document Bundles

Combine multiple templates into a single package

Unified Role Mapping

Map package roles to template-specific roles

Single Signing Session

Signers complete all documents in one session

Consistent Experience

Same signer sees their fields across all docs

Dashboard and API

Template packages can be managed in the dashboard or through the/api/v1/packages endpoints. MCP clients can use list-packages,create-package, andsend-envelope withpackageId to send a multi-document package.

Scheduled Sends

Schedule envelopes to be sent at a future date and time. Perfect for time-sensitive documents or coordinating across time zones.

API Example

Scheduled envelope request
{
  "templateId": "template_abc123",
  "signers": [
    { "name": "John Doe", "email": "john@example.com" }
  ],
  "scheduledAt": "2024-12-15T09:00:00Z"
}

Constraints

• Minimum: Must be at least 5 minutes in the future

• Maximum: Cannot be more than 30 days in the future

• Format: ISO 8601 timestamp (e.g., 2024-12-15T09:00:00Z)

Bulk Send Scheduling

Bulk sends also support scheduling. Include scheduledAtin your bulk send request to schedule mass document delivery.

CC Recipients

Add CC (carbon copy) recipients to receive copies of the envelope without needing to sign. They're notified when the envelope is sent and completed.

API Example

Envelope with CC recipients
{
  "templateId": "template_abc123",
  "signers": [
    { "name": "John Doe", "email": "john@example.com" }
  ],
  "ccRecipients": [
    { "name": "Legal Team", "email": "legal@company.com" },
    { "name": "HR Manager", "email": "hr@company.com" }
  ]
}

CC vs Signers

FeatureSignersCC Recipients
Can sign document✓—
Notified when sent✓✓
Notified when completed✓✓
Receives signed document✓✓

Password Protection

Add an extra layer of security by requiring signers to enter a password before viewing and signing documents. Available on all plans.

Key Features

Per-Signer Passwords

Each signer has their own unique password

Auto-Generated

8-character alphanumeric passwords by default

Multi-Channel Delivery

Deliver via Email, SMS, or WhatsApp

Lockout Protection

Account locked after 5 failed attempts

Security Flow

1. Sender enables password protection for a signer

2. Password is auto-generated (or custom-set) and delivered via chosen channel

3. Signer must enter correct password before viewing the document

4. After 5 failed attempts, access is locked until sender resends password

Dashboard Only

Password protection is currently configured through the dashboard when creating envelopes. API support for password-protected envelopes is planned for a future release.

Invoicing Guide

WeGoSign's invoicing API lets you create, send, and track client invoices programmatically. This guide walks through common invoicing workflows.

1. Create and Send an Invoice

Invoices are created in draft status. You must explicitly send them to deliver the email to the client.

// Step 1: Create a draft invoice
const invoice = await fetch("https://www.wegosign.com/api/v1/invoices", {
  method: "POST",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    clientName: "John Smith",
    clientEmail: "john@example.com",
    title: "Consulting Services - April 2026",
    currency: "NGN",
    lineItems: [
      { description: "Strategy session (2hrs)", quantity: 2, unitPriceKobo: 500000, totalKobo: 1000000 }
    ],
    subtotalKobo: 1000000,
    totalKobo: 1000000,
    invoiceDate: Date.now(),
    dueDate: Date.now() + 30 * 24 * 60 * 60 * 1000
  })
});
const { data } = await invoice.json();

// Step 2: Send it
await fetch(`https://www.wegosign.com/api/v1/invoices/${data.id}/send`, {
  method: "POST",
  headers: { "Authorization": "Bearer YOUR_API_KEY" }
});

2. Record Payments

Record partial or full payments. The invoice status updates automatically: partial payments set it to partially_paid, and when the total is reached it becomes paid.

// Record a partial payment
const result = await fetch(`https://www.wegosign.com/api/v1/invoices/${invoiceId}/payments`, {
  method: "POST",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    amountKobo: 500000,
    paymentMethod: "bank_transfer",
    reference: "TXN-12345"
  })
});
// { "data": { "success": true, "status": "partially_paid" } }

// Record remaining payment
await fetch(`https://www.wegosign.com/api/v1/invoices/${invoiceId}/payments`, {
  method: "POST",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    amountKobo: 500000,
    paymentMethod: "bank_transfer",
    reference: "TXN-12346"
  })
});
// { "data": { "success": true, "status": "paid" } }
// Client receives a receipt email automatically

3. Listen for Invoice Events

Subscribe to invoice webhook events to automate your billing workflow. The invoice.viewed event fires every time the client opens the invoice page — useful for tracking engagement.

// Create a webhook for invoice events
await fetch("https://www.wegosign.com/api/v1/webhooks", {
  method: "POST",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    url: "https://yourapp.com/webhooks/invoices",
    events: [
      "invoice.sent",
      "invoice.viewed",
      "invoice.payment_recorded",
      "invoice.paid",
      "invoice.overdue",
      "invoice.reminder_sent"
    ],
    description: "Invoice lifecycle tracking"
  })
});

// Example webhook payload for invoice.payment_recorded:
// {
//   "type": "invoice.payment_recorded",
//   "data": {
//     "invoice_id": "inv_abc123",
//     "invoice_number": "INV-0001",
//     "client_email": "john@example.com",
//     "amount_kobo": 500000,
//     "total_paid_kobo": 500000,
//     "total_kobo": 1000000,
//     "currency": "NGN",
//     "payment_method": "bank_transfer",
//     "status": "partially_paid"
//   }
// }

Invoice Webhook Events Reference

EventWhenFrequency
invoice.createdInvoice created as draftOnce
invoice.sentInvoice email sent to clientOnce
invoice.viewedClient opens the invoice pageEvery view
invoice.payment_recordedA payment is recordedEvery payment
invoice.paidInvoice fully paidOnce
invoice.overdueInvoice passes due dateOnce
invoice.reminder_sentOverdue reminder email sentEach reminder
invoice.voidedInvoice voided/cancelledOnce

Webhook Events

WeGoSign sends webhook notifications for the following events:

Envelope Events

envelope.created

An envelope has been created

envelope.sent

An envelope has been sent to signers

envelope.viewed

Any signer has viewed the document

envelope.signed

Any signer has completed their signature

envelope.completed

All signers have completed signing

envelope.declined

Any signer has declined to sign

envelope.cancelled

An envelope has been cancelled

envelope.expired

An envelope has expired without completion

Signer Events

signer.viewed

A specific signer has viewed the document

signer.signed

A specific signer has completed signing

signer.declined

A specific signer has declined to sign

Reminder Events

reminder.sent

A reminder email was sent to a signer (automatic or manual)

Document Events

document.downloaded

A signed document has been downloaded

Invoice Events

invoice.created

A new client invoice has been created

invoice.sent

An invoice has been sent to the client via email

invoice.viewed

The client opened the invoice page (fires on every view)

invoice.payment_recorded

A payment was recorded (including partial payments)

invoice.paid

An invoice has been fully paid

invoice.overdue

An invoice has passed its due date

invoice.reminder_sent

An overdue reminder email was sent to the client

invoice.voided

An invoice has been voided

Generic App Events

app.record.created

A business app record has been created

app.record.status_changed

A business app record status has changed

app.document.attached

A document was attached to a business app record

app.document.reviewed

A business app document was approved, rejected, expired, or sent for revision

app.approval.completed

A business app approval request was approved

app.approval.step_decided

A business app approval step was approved or rejected

app.portal.link_created

An external intake portal link was created for a business app record

app.portal.submitted

An external recipient submitted fields or documents through the intake portal

app.action.created

A business app action or task was created

app.action.completed

A business app action or task was completed

app.record.due_soon

A record's date is approaching (30, 7, and 1 days before)

app.record.overdue

A record's date has passed and it is still open

app.document.expiring

An approved document is about to expire

app.document.expired

An approved document has expired

app.action.due_soon

An open task is due within 7 days

app.action.overdue

An open task is past its due date

app.portal.link_expiring

An active portal link is about to expire

app.portal.reminder

The outside party was chased for an unanswered portal request (3, 7, and 14 days after issue)

app.obligation.due_soon

An open report, milestone, or return on a record is due within 30 days

app.obligation.overdue

An open report, milestone, or return on a record is past its due date

Business Intake Events

business_intake.record.created

A business intake record has been created

business_intake.record.status_changed

A business intake status has changed

business_intake.document.attached

A required intake document or evidence file was attached

business_intake.document.reviewed

A business intake document was approved, rejected, expired, or sent for revision

business_intake.task.completed

A business intake task was completed

business_intake.approval.completed

A business intake approval request was approved

business_intake.payment_details.updated

Encrypted payment details changed

business_intake.team.assigned

A team member was assigned to a business intake record

business_intake.vault.updated

An encrypted business intake vault field changed

business_intake.portal.submitted

A recipient submitted details or documents through an intake portal link

Hiring Packets Events

hiring_packets.packet.created

A hiring packet has been created

hiring_packets.packet.status_changed

A hiring packet status has changed

hiring_packets.document.attached

An offer letter, contractor agreement, policy acknowledgment, or onboarding file was attached

hiring_packets.task.created

An onboarding task was created for a hiring packet

hiring_packets.task.completed

An onboarding task was completed for a hiring packet

hiring_packets.team.assigned

A team member was assigned to a hiring packet

hiring_packets.approval.completed

A hiring packet approval request was approved

hiring_packets.vault.updated

An encrypted hiring packet vault field changed

hiring_packets.portal.submitted

A candidate or contractor submitted details or documents through an intake portal link

Renewals & Compliance Events

renewals_compliance.item.created

A renewal or compliance item has been created

renewals_compliance.item.status_changed

A compliance item status has changed

renewals_compliance.document.attached

A required compliance document or evidence file was attached

renewals_compliance.document.reviewed

A compliance document was approved, rejected, expired, or sent for revision

renewals_compliance.task.completed

A compliance task or renewal reminder was completed

renewals_compliance.approval.completed

A compliance approval request was approved

renewals_compliance.vault.updated

An encrypted compliance vault field changed

renewals_compliance.portal.submitted

An external party submitted details or evidence through an intake portal link

Bulk Send Events

bulk_send.started

A bulk send job has started processing

bulk_send.completed

A bulk send job has finished successfully

bulk_send.failed

A bulk send job has failed

Webhook Payload Structure

Example Webhook Payload (signer.signed event)
{
  "id": "evt_abc123xyz",
  "type": "signer.signed",
  "created": 1704543600000,
  "data": {
    "envelope": {
      "id": "env_xyz789",
      "title": "Employment Contract - John Doe",
      "status": "signed",
      "createdAt": 1704543600000,
      "completedAt": null
    },
    "signer": {
      "id": "sgn_abc123",
      "email": "john@example.com",
      "name": "John Doe",
      "role": "employee",
      "status": "signed",
      "viewedAt": 1704543500000,
      "signedAt": 1704543600000,
      "declinedAt": null,
      "declineReason": null,
      "completedFields": [
        {
          "fieldId": "field_signature_1",
          "value": "data:image/png;base64,iVBORw0KGgoAAA...",
          "completedAt": 1704543590000
        },
        {
          "fieldId": "field_email_1",
          "value": "john.doe@example.com",
          "completedAt": 1704543580000
        },
        {
          "fieldId": "field_dropdown_1",
          "value": "Full-Time",
          "completedAt": 1704543570000
        }
      ]
    },
    "timestamp": 1704543600000
  }
}

Verifying Webhook Signatures

Verify that webhooks are actually from WeGoSign by checking the signature header:

Signature Verification (Node.js)
1import crypto from 'crypto';
2
3function verifyWebhookSignature(payload, signature, timestamp, secret) {
4 // Signature format is "sha256=<hex>"
5 const signatureHex = signature.replace('sha256=', '');
6
7 // Create message: timestamp.payload
8 const message = `${timestamp}.${payload}`;
9
10 const expectedSignature = crypto
11 .createHmac('sha256', secret)
12 .update(message)
13 .digest('hex');
14
15 return crypto.timingSafeEqual(
16 Buffer.from(signatureHex),
17 Buffer.from(expectedSignature)
18 );
19}
20
21// In your webhook handler
22app.post('/webhooks/wegosign', (req, res) => {
23 const signature = req.headers['x-webhook-signature'];
24 const timestamp = req.headers['x-webhook-timestamp'];
25 const eventType = req.headers['x-webhook-event'];
26
27 const isValid = verifyWebhookSignature(
28 JSON.stringify(req.body),
29 signature,
30 timestamp,
31 process.env.WEBHOOK_SECRET
32 );
33
34 if (!isValid) {
35 return res.status(401).send('Invalid signature');
36 }
37
38 // Access payload fields: id, type, created, data
39 const { id, type, created, data } = req.body;
40 console.log('Processing event:', type, 'Event ID:', id);
41
42 // Process the webhook based on event type...
43 res.status(200).send('OK');
44});

Error Handling

The API uses standard HTTP status codes and returns error details in a consistent format.

Error Response Format

Error Response
{
  "error": "validation_error",
  "message": "Invalid email format for signer",
  "details": {
    "field": "signers[0].email",
    "value": "invalid-email"
  }
}

HTTP Status Codes

200

Success - Request completed successfully

201

Created - Resource created successfully

400

Bad Request - Invalid request parameters

401

Unauthorized - Invalid or missing API key

403

Forbidden - Insufficient permissions

404

Not Found - Resource doesn't exist

429

Too Many Requests - Rate limit exceeded

500

Server Error - Something went wrong on our end

Rate Limits

API rate limits vary by plan and operation type. Rate limit information is included in response headers.

Rate Limit Headers

X-RateLimit-Limit

Maximum requests allowed in the window

X-RateLimit-Remaining

Requests remaining in current window

X-RateLimit-Reset

Unix timestamp when the limit resets

Retry-After

Seconds to wait before retrying (429 responses only)

Limits by Plan

Ready to get started?

Create your free account and get API keys to start integrating document signing today.