Contract Creation Guide

APISign supports two distinct workflows for creating contracts, each suited for different use cases. This guide explains both approaches and when to use each one.

Overview

Two Contract Creation Flows

  1. Blank Contract (One-off) - Start from scratch with custom content and fields
  2. Template-based Contract - Use a pre-defined template with variable substitution

Important Validation Rules

Template-Based Contracts:

  • Must provide template_id to identify the template
  • Must provide variables object with values for all creator-completed fields from the template
  • Must NOT provide content (content comes from the template)
  • Must NOT provide fields (field definitions come from the template)

Non-Template (Blank) Contracts:

  • Must provide content with the full contract markdown
  • Must provide fields array defining all field types and assignments
  • Must NOT provide template_id
  • Must NOT provide variables (use fields directly in the content)

Flow 1: Blank Contract Creation

When to Use

  • One-time contracts with unique terms
  • Quick agreements without needing reusability
  • Custom contracts that don't fit existing templates
  • Situations where field types and assignments are known upfront

How It Works

  1. Provide the complete contract content in markdown format
  2. Define field types and assignments directly in the creation request
  3. Send immediately to signers

API Endpoint

POST /api/contract/create

Request Format

{
  "name": "Service Agreement - John Smith",
  "content": "# Service Agreement\n\nThis agreement is between {{COMPANY_NAME}} and {{CLIENT_NAME}}.\n\n**Service Type:** {{SERVICE_CATEGORY}}\n**Project:** {{PROJECT_DESCRIPTION}}\n\nSigned on {{DATE_SIGNED}}\n\n{{CLIENT_SIGNATURE}}\n{{CLIENT_INITIALS}}",
  "fields": [
    {
      "name": "COMPANY_NAME",
      "type": "text",
      "completedBy": "creator"
    },
    {
      "name": "CLIENT_NAME", 
      "type": "text",
      "completedBy": "creator"
    },
    {
      "name": "SERVICE_CATEGORY",
      "type": "label",
      "completedBy": "creator"
    },
    {
      "name": "PROJECT_DESCRIPTION",
      "type": "text",
      "completedBy": "creator"
    },
    {
      "name": "DATE_SIGNED",
      "type": "date",
      "completedBy": "signer"
    },
    {
      "name": "CLIENT_SIGNATURE",
      "type": "signature",
      "completedBy": "signer"
    },
    {
      "name": "CLIENT_INITIALS",
      "type": "initials",
      "completedBy": "signer"
    }
  ],
  "signers": [
    {
      "name": "John Smith",
      "email": "john@example.com",
      "signing_order": 1
    }
  ],
}

Field Types

  • text - Plain text input for general data entry
  • email - Email address input with validation
  • phone - Phone number input with formatting
  • date - Date picker for selecting dates
  • label - Display-only text label (non-editable, useful for categories/descriptions)
  • signature - Signature drawing canvas for legal signatures
  • initials - Initials drawing canvas for acknowledgments
  • timestamp - Auto-filled with signing timestamp
  • signer_name - Auto-filled with signer's name

Field Assignment

  • creator - Filled when creating the contract
  • signer - Filled by the signer during signing process

Flow 2: Template-based Contract Creation

When to Use

  • Recurring contracts with standard terms
  • Contracts that follow organizational templates
  • High-volume contract generation
  • Situations requiring consistency across multiple contracts

How It Works

  1. Create a reusable template with variables
  2. Create contracts from the template
  3. Provide values for creator variables
  4. System handles field types and signer assignments from template

Step 1: Create Template

POST /api/template/create
{
  "name": "Service Agreement Template",
  "content": "# Service Agreement\n\nThis agreement is between {{COMPANY_NAME}} and {{CLIENT_NAME}}...\n\nService starts: {{START_DATE}}\nService ends: {{END_DATE}}\n\nRate: {{HOURLY_RATE}}/hour\n\nSigned on {{DATE_SIGNED}}\n\n{{CLIENT_SIGNATURE}}\n{{CLIENT_INITIALS}}",
  "fields": [
    {
      "name": "COMPANY_NAME",
      "type": "text",
      "completedBy": "creator"
    },
    {
      "name": "CLIENT_NAME",
      "type": "text",
      "completedBy": "creator"
    },
    {
      "name": "START_DATE",
      "type": "date",
      "completedBy": "creator"
    },
    {
      "name": "END_DATE",
      "type": "date",
      "completedBy": "creator"
    },
    {
      "name": "HOURLY_RATE",
      "type": "text",
      "completedBy": "creator"
    },
    {
      "name": "DATE_SIGNED",
      "type": "date",
      "completedBy": "signer"
    },
    {
      "name": "CLIENT_SIGNATURE",
      "type": "signature",
      "completedBy": "signer"
    },
    {
      "name": "CLIENT_INITIALS",
      "type": "initials",
      "completedBy": "signer"
    }
  ]
}

Step 2: Create Contract from Template

POST /api/contract/create
{
  "name": "Service Agreement - John Smith",
  "template_id": "cm4abc123...",
  "signers": [
    {
      "name": "John Smith",
      "email": "john@example.com",
      "signing_order": 1
    }
  ],
  "variables": {
    "COMPANY_NAME": "Acme Corp",
    "CLIENT_NAME": "John Smith",
    "START_DATE": "2024-01-01",
    "END_DATE": "2024-12-31",
    "HOURLY_RATE": "$150"
  },
}

Key Differences

AspectBlank ContractTemplate-based
Content SourceProvided in request (required)From template (must not provide)
Field DefinitionsProvided in request (required)Inherited from template (must not provide)
VariablesNot used (must not provide)Required for creator fields
ReusabilityOne-time useReusable template
Setup TimeQuick for one-offInitial template setup required
ConsistencyManual consistencyEnforced by template
Best ForUnique agreementsStandardized contracts
Variable SubstitutionAt signing timeCreator values at creation, signer values at signing

Variable Processing

Creator Variables (Template Contracts Only)

  • Substituted when the contract is created
  • Values provided in variables object
  • Permanently replaced in the contract content
  • Not visible to signers
  • All creator-completed fields from the template must have values provided

Signer Variables

  • Remain as placeholders until signing
  • Each signer only sees and fills their assigned fields
  • Different signers can have different field assignments
  • Auto-filled fields (timestamp, signer_name) populate automatically

Multi-signer Support

Both flows support multiple signers with ordered signing:

{
  "signers": [
    {
      "name": "First Signer",
      "email": "first@example.com",
      "signing_order": 1
    },
    {
      "name": "Second Signer",
      "email": "second@example.com",
      "signing_order": 2
    }
  ],
  "fields": {
    "signers": [
      {
        "signing_order": 1,
        "signerFields": ["FIELD1", "SIGNATURE1"]
      },
      {
        "signing_order": 2,
        "signerFields": ["FIELD2", "SIGNATURE2"]
      }
    ]
  }
}

Response Format

Both flows return the same response structure:

{
  "contract": {
    "id": "cm4xyz789...",
    "name": "Service Agreement - John Smith",
    "status": "sent",
    "created_at": "2024-01-15T10:00:00Z",
    "sent_at": "2024-01-15T10:00:01Z"
  },
  "signers": [
    {
      "id": "cm4signer1...",
      "name": "John Smith",
      "email": "john@example.com",
      "status": "pending",
      "signing_order": 1,
      "signing_url": "https://app.apisign.io/sign?contract=cm4xyz789&signer=cm4signer1"
    }
  ]
}

Error Handling

Common errors and their meanings:

  • 400 Bad Request - Invalid field definitions or missing required data
  • 404 Not Found - Template not found (for template-based creation)
  • 422 Unprocessable Entity - Variable mismatch or invalid field assignments

Best Practices

For Blank Contracts

  1. Define all fields upfront to ensure proper rendering
  2. Test the markdown formatting before sending
  3. Validate email addresses before creation
  4. Use descriptive field names

For Template-based Contracts

  1. Create templates for frequently used contract types
  2. Use consistent variable naming conventions
  3. Document required creator_values for each template
  4. Version templates when making significant changes
  5. Test templates thoroughly before production use

Examples

Example 1: Simple NDA (Blank Contract)

{
    "name": "NDA - Quick Agreement",
    "content": "# Non-Disclosure Agreement\n\nEffective {{DATE}}\n\nParties agree to maintain confidentiality...\n\n{{SIGNATURE}}",
    "fields": [
        {
            "name": "DATE",
            "type": "date",
            "completedBy": "signer"
        },
        {
            "name": "SIGNATURE",
            "type": "signature",
            "completedBy": "signer"
        }
    ],
    "signers": [
        {
            "name": "Jane Doe",
            "email": "jane@example.com",
            "signing_order": 1
        }
    ]
}

Example 2: Employment Contract (Template-based)

First create the template, then create contracts from it with different employee details:

{
  "template_id": "cm4empl001...",
  "name": "Employment Contract - Sarah Johnson",
  "signers": [
    {
      "name": "Sarah Johnson",
      "email": "sarah@example.com",
      "signing_order": 1
    }
  ],
  "creator_values": {
    "EMPLOYEE_NAME": "Sarah Johnson",
    "POSITION": "Senior Developer",
    "SALARY": "$120,000",
    "START_DATE": "2024-02-01",
    "DEPARTMENT": "Engineering"
  },
}