eContract Developers

Core Concepts

Core concepts of the eContract API, from workspaces and roles to the contract lifecycle, async document processing, signers, signing order and templates.

Understanding these core concepts will help you build effective integrations with the eContract API.

Workspaces

Workspaces are the top-level organizational unit in eContract. Each workspace is an isolated tenant with its own contracts, users, templates, and API keys.

  • A user can belong to multiple workspaces
  • API keys are scoped to a single workspace
  • All API requests operate within the context of one workspace

Workspace Roles

RoleDescription
owner, adminFull workspace management: users, API keys, webhooks, settings
contract_managerCreate, send, and manage contracts
memberWork with contracts as the workspace allows
viewerRead-only access to contracts

API keys and OAuth tokens act with their user's role capped at contract_manager; see Machine role.

Contract Lifecycle

Contracts follow a defined lifecycle from creation to completion:

┌───────┐     ┌─────────┐     ┌────────────┐     ┌───────────┐
│ DRAFT │────→│ PENDING │────→│ IN_SIGNING │────→│ COMPLETED │
└───────┘     └─────────┘     └────────────┘     └───────────┘
    │              │                │
    │              │                │
    ▼              ▼                ▼
┌────────┐    ┌────────┐      ┌─────────┐
│ VOIDED │    │ VOIDED │      │ EXPIRED │
└────────┘    └────────┘      └─────────┘

Contract Statuses

StatusDescription
draftContract created, can add files and edit details
pendingReady but not yet submitted for signing
in_signingSent to signers, awaiting signatures
completedAll signers have signed
voidedCancelled by the creator
expiredSigning deadline passed (default: 90 days)

Key Rules

  • Only draft contracts can be edited, have files added, or be deleted
  • Contracts in draft or pending status can be submitted for signing
  • Contracts can be voided unless they are completed or already voided
  • A contract moves to completed automatically when all signers finish

Creating a Contract

curl -X POST https://api.econtract.online/api/v1/contracts \
  -H "Authorization: Bearer cl_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "NDA Agreement",
    "description": "Mutual non-disclosure agreement",
    "signingOrderType": "parallel",
    "expiresInDays": 30
  }'
const contract = await fetch(
  "https://api.econtract.online/api/v1/contracts",
  {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.ECONTRACT_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      title: "NDA Agreement",
      description: "Mutual non-disclosure agreement",
      signingOrderType: "parallel",
      expiresInDays: 30,
    }),
  }
).then((r) => r.json());
contract = requests.post(
    "https://api.econtract.online/api/v1/contracts",
    headers={"Authorization": f"Bearer {os.environ['ECONTRACT_API_KEY']}"},
    json={
        "title": "NDA Agreement",
        "description": "Mutual non-disclosure agreement",
        "signingOrderType": "parallel",
        "expiresInDays": 30,
    },
).json()

Async Contract Processing

The POST /contracts/send endpoint creates and sends a contract in a single API call. Because this involves file processing, signer validation, and contract submission, it runs asynchronously.

How It Works

  1. Request — You call POST /contracts/send with files/template, signers, and contract details
  2. Immediate response — The API returns 202 Accepted with the contract in processing state
  3. Background processing — A worker adds signers, submits the contract, and transitions it to in_signing
  4. Completion — processingStatus changes to ready (success) or failed (error)

Processing Status

StatusDescription
processingBackground worker is processing the contract
readyProcessing complete — contract is now in_signing
failedAn error occurred — check processingError for details

Monitoring Processing

Option 1: Polling

# Poll GET /contracts/:id until processingStatus changes
curl https://api.econtract.online/api/v1/contracts/{contractId} \
  -H "Authorization: Bearer cl_live_your_key"

Option 2: Webhooks (recommended)

Register a webhook for these events:

EventDescription
contract.processing.completedProcessing succeeded, contract is in_signing
contract.processing.failedProcessing failed with error

See Webhooks for setup instructions.

Failure Handling

Processing is retried automatically (up to 3 attempts). When it still fails:

  • processingStatus is set to failed
  • processingError contains the error message
  • The contract is kept, so polling clients see the failure instead of a 404
  • A contract.processing.failed webhook is sent

Fix the input and make a new POST /contracts/send request (with a new Idempotency-Key).

Documents & Files

Each contract can have one or more attached files. Supported formats:

FormatNotes
PDFNative support, no conversion needed
DOCXAutomatically converted to PDF after upload

Uploading Files

Upload files to a draft contract:

curl -X POST \
  "https://api.econtract.online/api/v1/contracts/{contractId}/files" \
  -H "Authorization: Bearer cl_live_your_key" \
  -F "[email protected]"

DOCX Conversion

When you upload a DOCX file, eContract converts it to PDF automatically. The file object includes a conversionStatus field:

StatusDescription
pendingConversion queued
completedPDF ready
failedConversion error — retry with POST /contracts/{id}/files/{fileId}/retry-conversion

File Size Limits

  • Direct upload: 50 MB per file
  • Multipart upload: Use the multipart API for larger files

Signers & Signing Flow

Signers are the people who need to sign a contract. eContract supports both internal users (workspace members) and external signers (anyone with an email address).

Adding Signers to a Draft

POST /contracts/send adds the signers for you. For a draft created with POST /contracts, add them one by one:

curl -X POST "https://api.econtract.online/api/v1/contracts/$CONTRACT_ID/signers" \
  -H "Authorization: Bearer cl_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "signerType": "external",
    "email": "[email protected]",
    "name": "Jane Smith",
    "signOrder": 1
  }'
await fetch(`https://api.econtract.online/api/v1/contracts/${contractId}/signers`, {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.ECONTRACT_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    signerType: "external",
    email: "[email protected]",
    name: "Jane Smith",
    signOrder: 1,
  }),
});
requests.post(
    f"https://api.econtract.online/api/v1/contracts/{contract_id}/signers",
    headers={"Authorization": f"Bearer {os.environ['ECONTRACT_API_KEY']}"},
    json={
        "signerType": "external",
        "email": "[email protected]",
        "name": "Jane Smith",
        "signOrder": 1,
    },
)

/external-signers is the workspace address book of external signers, not the list of a contract's signers.

Signer Statuses

StatusDescription
pendingAdded to contract, not yet notified
notifiedSigning invitation email sent
viewedSigner opened the signing page
signedSigner completed their signature
rejectedSigner declined to sign
expiredSigning period expired

Signing Order

eContract supports two signing order types:

  • sequential — Signers are notified one at a time in signOrder. Signer 2 is notified only after Signer 1 completes.
  • parallel — All signers are notified immediately and can sign in any order.

Signing Flow

When a contract is submitted:

  1. Notification — Signers receive an email with a secure signing link
  2. View — Signer opens the link and reviews the document
  3. OTP verification — Signer verifies their identity via email OTP
  4. Sign or decline — Signer draws/uploads their signature or declines
  5. Completion — When all signers finish, the contract moves to completed

Resending Notifications

If a signer hasn't responded, resend the signing request:

curl -X POST \
  "https://api.econtract.online/api/v1/contracts/{contractId}/resend-signing-request" \
  -H "Authorization: Bearer cl_live_your_key"

Templates

Templates let you create reusable contract structures with variable placeholders.

Creating a Template

curl -X POST https://api.econtract.online/api/v1/contract-templates \
  -H "Authorization: Bearer cl_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Standard NDA",
    "description": "Mutual non-disclosure agreement template",
    "category": "legal"
  }'

Template Variables

Extract variables from a template document:

curl -X POST \
  "https://api.econtract.online/api/v1/contract-templates/{templateId}/extract-variables" \
  -H "Authorization: Bearer cl_live_your_key"

Generating a Contract from a Template

curl -X POST \
  "https://api.econtract.online/api/v1/contract-templates/{templateId}/generate" \
  -H "Authorization: Bearer cl_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "variables": {
      "companyName": "Acme Corp",
      "effectiveDate": "2026-04-01"
    }
  }'

This creates a new contract in draft status with the template variables filled in.

On this page