# API Sign Documentation > Complete documentation for API Sign - digital contract management and e-signature platform. > URL: https://apisign.io > API Base URL: https://apisign.io/api --- # Table of Contents 1. Getting Started - Documentation Overview - Quick Start 2. Templates - Templates Overview - Creating Templates - Template Variables - Writing Guide 3. Contracts - Contracts Overview - Creating Contracts - Signing Process 4. API Reference - API Overview - Authentication - Contracts API - Templates API - Webhooks - MCP Server --- # GETTING STARTED ## Documentation Overview Complete guide to using API Sign for digital contract management. ### Quick Links Common Tasks: - Create your first template: /docs/quick-start#step-1-create-your-first-template - Send a contract for signature: /docs/quick-start#step-4-send-for-signature - Generate an API key: /docs/api/auth#generate-api-keys - Set up webhook notifications: /docs/api/webhooks#setting-up-webhooks Popular Guides: - Working with template variables: /docs/app/templates/variables - How the signing process works: /docs/app/contracts/signing - Automate contract sending via API: /docs/api/contracts#send-contract --- ## Quick Start Create your first template and send a contract for signature in minutes. ### Prerequisites Before you begin, make sure you have: - An API Sign account - Access to the dashboard - Basic understanding of digital contracts ### Step 1: Create Your First Template Templates are reusable document structures that you can use to generate contracts. Let's create a simple service agreement template. 1. Navigate to the **Templates** section in your dashboard 2. Click **"New Template"** 3. Choose a template name (e.g., "Service Agreement") 4. Add your document content with placeholders for dynamic data #### Adding Template Variables Template variables allow you to customize documents for each contract. Use the `{{variable_name}}` syntax: ``` This Service Agreement is between {{client_name}} and {{service_provider}}. The services will be provided from {{start_date}} to {{end_date}}. Total compensation: {{total_amount}} ``` #### Adding Signature Fields Add signature fields where parties need to sign: 1. Click **"Add Field"** in the template editor 2. Select **"Signature Field"** 3. Position it where the signature should appear 4. Assign it to a signer role (e.g., "Client", "Service Provider") ### Step 2: Create a Contract from Your Template Once your template is ready: 1. Go to **Contracts** → **"New Contract"** 2. Select your template 3. Fill in the template variables: - Client Name: "Acme Corporation" - Service Provider: "Your Company" - Start Date: "2024-01-01" - End Date: "2024-12-31" - Total Amount: "$10,000" ### Step 3: Add Signers Specify who needs to sign the contract: 1. Click **"Add Signer"** 2. Enter the signer's details: - Name - Email address - Role (must match your template's signature field assignments) ### Step 4: Send for Signature 1. Review your contract in the preview 2. Click **"Send for Signature"** 3. Signers will receive an email with a link to sign the document ### Step 5: Track Progress Monitor your contract's status in real-time: - **Draft**: Contract is being prepared - **Sent**: Waiting for signatures - **Partially Signed**: Some parties have signed - **Completed**: All parties have signed - **Expired**: Signing deadline has passed ### Common Issues #### Contract Not Sending - Verify all signers have valid email addresses - Check that all required fields are completed - Ensure template has at least one signature field #### Signers Can't Access Contract - Check spam/junk folders - Verify the signing link hasn't expired - Confirm the email address is correct --- # TEMPLATES ## Templates Overview Templates are the foundation of API Sign's contract management system. They allow you to create reusable document structures that can be customized for each contract while maintaining consistency and compliance. ### What Are Templates? Templates are reusable document blueprints that define the content, structure, and fields of a contract. They include: - **Static content**: Text that remains the same across all contracts - **Template variables**: Placeholders for dynamic content (e.g., names, dates, amounts, signatures, timestamps) - **Formatting**: Styling and layout that ensures professional appearance - **Branding elements**: Logos, colors, and fonts that reflect your organization's identity --- ## Creating Templates Templates are reusable document structures written in Markdown with dynamic variables. Create a template once, then generate unlimited contracts from it. ### Create a New Template 1. Go to **Templates** in your dashboard 2. Click **New Template** 3. Enter a name and optional description 4. Write your template content in the editor ### Writing Template Content The template editor shows your Markdown on the left with a live preview on the right. Templates use Markdown for formatting: ```markdown # Service Agreement This agreement is between **{{client_name}}** and **{{provider_name}}**. ## Scope of Work {{scope_description}} ## Payment Terms - Total amount: {{total_amount}} - Due date: {{due_date}} --- **Client Signature:** {{client_signature}} **Provider Signature:** {{provider_signature}} ``` ### Supported Markdown - **Headings**: `#`, `##`, `###` - **Bold**: `**text**` - **Italic**: `*text*` - **Lists**: `-` or `1.` - **Horizontal rules**: `---` - **Tables**: Standard Markdown tables ### Adding Variables Variables are placeholders that get replaced when creating a contract. Use double curly braces: ``` {{variable_name}} ``` Common variable examples: ``` {{client_name}} {{client_email}} {{contract_date}} {{total_amount}} {{project_description}} ``` **Note:** Use snake_case for variable names (lowercase with underscores). Avoid spaces and special characters. ### Adding Signature Fields Signature fields are special variables that create interactive signature areas: ``` {{client_signature}} {{provider_signature}} ``` When a signer views the contract, these become clickable signature fields. ### Importing Word Documents Already have contracts in Word format? Upload them directly: 1. Click **Import** when creating a template 2. Select your `.docx` file 3. The content is automatically converted to Markdown 4. Edit as needed and add variables ### Preview and Test Before using a template: 1. Click **Preview** to see how it renders 2. Create a test contract with sample data 3. Verify all variables display correctly 4. Test the signature flow **Important:** Always test your template with a sample contract before sending to real clients. --- ## Template Variables Variables are placeholders in your template that get replaced with actual values. They use double curly braces: ``` {{variable_name}} ``` ### Variable Syntax Use snake_case for variable names: ``` {{client_name}} {{contract_date}} {{project_description}} {{client_signature}} ``` **Naming rules:** - Lowercase letters and underscores only - Start with a letter, not a number - No spaces or special characters ### Configuring Variables After adding variables to your template, click the **Variables** tab to configure how each variable behaves. #### Completed By Each variable is completed by either the **Creator** (when creating the contract) or the **Signer** (when signing). | Completed By | When it's filled | Example variables | |--------------|------------------|-------------------| | Creator | During contract creation | `{{client_name}}`, `{{contract_date}}`, `{{total_amount}}` | | Signer | During signing | `{{client_signature}}`, `{{signer_name}}`, `{{initials}}` | #### Field Types The available field types depend on who completes the variable. **Creator field types:** - **Text** - General text input - **Email** - Email address - **Phone** - Phone number - **Date** - Date picker **Signer field types:** - **Signature** - Signature capture field - **Initials** - Initials field - **Signer Name** - Auto-filled with signer's name - **Timestamp** - Auto-filled with signing date/time ### Common Variable Patterns #### Contract details (Creator) ``` {{client_name}} {{client_email}} {{contract_date}} {{project_description}} {{total_amount}} ``` #### Signature fields (Signer) ``` {{client_signature}} {{provider_signature}} {{client_initials}} {{witness_signature}} ``` ### Example Template ```markdown # Service Agreement **Client:** {{client_name}} **Email:** {{client_email}} **Date:** {{contract_date}} ## Services {{project_description}} ## Payment Total: {{total_amount}} --- **Client Signature:** {{client_signature}} **Provider Signature:** {{provider_signature}} ``` **Note:** API Sign automatically suggests field types based on variable names. Variables containing "signature" become signature fields, "email" becomes email fields, etc. --- ## Writing Guide A comprehensive guide to crafting professional documents and templates in API Sign using Markdown syntax. ### Markdown Basics API Sign templates use Markdown, a lightweight formatting syntax that's easy to learn and produces clean, professional documents. #### Headings Use `#` symbols to create headings. More `#` symbols mean smaller headings: ```markdown # Main Title (H1) ## Section Heading (H2) ### Subsection (H3) #### Minor Heading (H4) ``` #### Text Formatting ```markdown **Bold text** for emphasis *Italic text* for subtle emphasis ***Bold and italic*** for strong emphasis ~~Strikethrough~~ for deleted content ``` #### Lists **Unordered lists** use `-`, `*`, or `+`: ```markdown - First item - Second item - Nested item - Another nested item - Third item ``` **Ordered lists** use numbers: ```markdown 1. First step 2. Second step 3. Third step ``` #### Links ```markdown [Link text](https://example.com) ``` #### Horizontal Rules Use three or more dashes, asterisks, or underscores to create a horizontal line: ```markdown --- ``` ### Template Variables Variables are placeholders that get replaced with actual values when creating a contract from your template. #### Basic Syntax Wrap variable names in double curly braces: ```markdown {{variable_name}} ``` #### Naming Conventions Use descriptive, lowercase names with underscores: - `{{client_name}}` - The client's full name - `{{contract_date}}` - Date of the contract - `{{total_amount}}` - Total payment amount - `{{company_address}}` - Company street address #### Common Variables | Variable | Description | Example Value | |----------|-------------|---------------| | `{{client_name}}` | Client's full name | John Smith | | `{{client_email}}` | Client's email address | john@example.com | | `{{company_name}}` | Your company name | Acme Corp | | `{{contract_date}}` | Date of the agreement | January 15, 2025 | | `{{effective_date}}` | When the contract takes effect | February 1, 2025 | | `{{expiration_date}}` | When the contract expires | January 31, 2026 | | `{{total_amount}}` | Total contract value | $10,000.00 | | `{{payment_terms}}` | Payment schedule | Net 30 | #### Variable Types When configuring your template, you can specify how each variable should be completed: **Creator-filled variables** - Values you provide when creating a contract: - Client names and contact information - Dates and deadlines - Amounts and quantities - Custom terms **Signer-filled variables** - Values the signer provides when signing: - Signatures - Initials - Date signed - Additional information they need to provide ### Document Structure #### Contract Header Start with clear identification: ```markdown # Service Agreement **Agreement Number:** {{agreement_number}} **Date:** {{contract_date}} --- ``` #### Parties Section Clearly identify all parties involved: ```markdown ## Parties This Agreement is entered into between: **Service Provider:** {{provider_name}} {{provider_address}} {{provider_email}} **Client:** {{client_name}} {{client_address}} {{client_email}} ``` #### Terms and Conditions Use numbered sections for legal clarity: ```markdown ## Terms and Conditions ### 1. Services The Service Provider agrees to provide the following services: {{service_description}} ### 2. Compensation The Client agrees to pay {{total_amount}} according to the following schedule: {{payment_schedule}} ### 3. Term This Agreement shall commence on {{effective_date}} and continue until {{expiration_date}}. ``` #### Signature Block End with a clear signature section: ```markdown --- ## Signatures By signing below, both parties agree to the terms and conditions outlined in this Agreement. **Service Provider:** Signature: {{provider_signature}} Name: {{provider_name}} Date: {{provider_sign_date}} **Client:** Signature: {{client_signature}} Name: {{client_name}} Date: {{client_sign_date}} ``` ### Field Types #### Signature Fields For electronic signatures, use descriptive variable names: ```markdown {{signature}} {{client_signature}} {{provider_signature}} ``` Configure these as **Signature** type in the Variables tab. #### Initials Fields For initials on specific clauses: ```markdown Initials: {{client_initials}} ``` Configure as **Initials** type. #### Text Fields For signer-provided text information: ```markdown Title: {{signer_title}} Company: {{signer_company}} ``` #### Date Fields For dates the signer provides: ```markdown Date Signed: {{date_signed}} ``` ### Best Practices #### Keep It Clear - Use plain language when possible - Define technical terms - Break long paragraphs into shorter ones - Use headings to organize content #### Be Consistent - Use the same formatting throughout - Keep variable naming conventions consistent - Maintain consistent spacing and structure #### Test Your Template 1. Create a test contract from your template 2. Fill in all variables with sample data 3. Preview the rendered document 4. Check that all formatting looks correct 5. Verify signature fields are properly placed #### Legal Considerations - Include all necessary legal disclaimers - Clearly state governing law and jurisdiction - Define dispute resolution procedures - Include severability clauses ### Example Templates #### Simple Service Agreement ```markdown # Service Agreement This Service Agreement ("Agreement") is entered into as of {{contract_date}}. ## Parties **Provider:** {{provider_name}} **Client:** {{client_name}} ## Services Provider agrees to perform the following services: {{service_description}} ## Compensation Client agrees to pay Provider {{total_amount}} for the services described above. ## Term This Agreement begins on {{start_date}} and ends on {{end_date}}. ## Signatures **Provider:** {{provider_signature}} Date: {{provider_sign_date}} **Client:** {{client_signature}} Date: {{client_sign_date}} ``` #### Non-Disclosure Agreement (NDA) ```markdown # Non-Disclosure Agreement This Non-Disclosure Agreement is entered into by and between: **Disclosing Party:** {{disclosing_party}} **Receiving Party:** {{receiving_party}} **Effective Date:** {{effective_date}} ## 1. Definition of Confidential Information "Confidential Information" means any information disclosed by the Disclosing Party that is marked as confidential or that reasonably should be understood to be confidential. ## 2. Obligations The Receiving Party agrees to: - Hold all Confidential Information in strict confidence - Not disclose Confidential Information to any third parties - Use Confidential Information only for {{permitted_purpose}} ## 3. Term This Agreement shall remain in effect for {{term_length}} from the Effective Date. ## 4. Signatures **Disclosing Party:** {{disclosing_signature}} Name: {{disclosing_name}} Date: {{disclosing_sign_date}} **Receiving Party:** {{receiving_signature}} Name: {{receiving_name}} Date: {{receiving_sign_date}} ``` --- # CONTRACTS ## Contracts Overview Contracts are documents generated from templates, filled with real data, and sent to signers. Once all parties sign, the contract is complete and legally binding. ### Contract Lifecycle Every contract moves through these stages: | Status | Description | |--------|-------------| | **Draft** | Contract is being created or edited | | **Pending** | Sent to signers, awaiting signatures | | **Completed** | All parties have signed | | **Expired** | Deadline passed without completion | ### Creating a Contract 1. Select a template from your library 2. Fill in the variable values (client name, dates, amounts, etc.) 3. Add signers with their email addresses 4. Send for signature ### Signing Workflow Contracts support different signing orders: - **Sequential** - Signers complete in order (Client signs first, then Provider) - **Parallel** - All signers receive the contract simultaneously ### What Signers See When a signer receives a contract: 1. They get an email with a secure signing link 2. They review the document in their browser 3. They complete any required fields (signature, initials, dates) 4. They submit and receive a confirmation ### After Completion When all parties have signed: - A final PDF is generated with all signatures - All parties receive a copy via email - The contract is stored in your dashboard - An audit trail documents the entire process --- ## Creating Contracts Create contracts by selecting a template and filling in the details. The contract is generated instantly and ready to send for signatures. ### Create a Contract 1. Go to **Contracts** in your dashboard 2. Click **New Contract** 3. Select a template 4. Fill in the variable values 5. Add signers 6. Send for signature ### Fill in Variables Variables from your template appear as form fields. Fill in each one: ``` Client Name: Acme Corporation Client Email: john@acme.com Contract Date: January 15, 2025 Project Description: Website redesign Total Amount: $5,000 ``` The contract preview updates in real-time as you fill in values. ### Add Signers For each signer, provide: - **Name** - Full legal name - **Email** - Where they'll receive the signing link - **Role** - Label like "Client" or "Provider" Example setup: | Name | Email | Role | |------|-------|------| | John Smith | john@acme.com | Client | | Jane Doe | jane@yourcompany.com | Provider | ### Signing Order Choose how signers receive the contract: **Sequential** - One at a time in order ``` 1. Client signs first 2. Provider signs after client completes ``` **Parallel** - Everyone at once ``` All signers receive the contract simultaneously ``` ### Review and Send Before sending: 1. **Preview** - Check how the contract looks 2. **Verify variables** - Make sure all values are correct 3. **Check signers** - Confirm email addresses 4. **Send** - Contract is emailed to the first signer (or all signers if parallel) **Tip:** Create a test contract and send it to yourself to verify everything works before sending to real clients. ### After Sending Once sent, you can: - Track signing progress in real-time - Send reminders to signers who haven't completed - Download the contract at any time - Cancel if needed (before completion) --- ## Signing Process When you send a contract, signers receive an email with a secure link. They review the document, complete their fields, and sign electronically. ### What Signers Receive Signers get an email like this: ``` Subject: Please sign: Service Agreement You've been requested to sign a contract from [Your Company]. Document: Service Agreement From: Jane Doe [Review & Sign] ``` Clicking the button opens the contract in their browser. ### Signing Steps 1. **Open the link** - Secure access, no account required 2. **Review the document** - Read through the entire contract 3. **Complete fields** - Fill in any required information 4. **Sign** - Draw, type, or upload a signature 5. **Submit** - Confirm and complete ### Signature Options Signers can create their signature by: - **Drawing** - Use mouse or finger to draw - **Typing** - Type name, rendered in signature font - **Upload** - Upload an image of their signature All methods are legally valid electronic signatures. ### Field Types Signers May See | Field | Description | |-------|-------------| | **Signature** | Full signature capture | | **Initials** | Short initials field | | **Date** | Date picker or auto-filled | | **Text** | Free text input | | **Checkbox** | Confirmation checkboxes | ### Mobile Signing The signing interface works on phones and tablets. Signers can complete contracts from anywhere without installing an app. ### After Signing When a signer completes their signature: - They see a confirmation screen - They receive an email confirmation - The next signer is notified (if sequential) - You're notified of the progress ### When All Parties Sign Once everyone has signed: 1. The contract status changes to **Completed** 2. A final PDF is generated with all signatures 3. All parties receive a copy via email 4. The audit trail is finalized **Audit Trail:** Every action is logged: when the contract was viewed, when fields were completed, IP addresses, and timestamps. This provides legal proof of the signing process. ### Reminders If a signer hasn't completed: - Automatic reminders can be configured - You can manually send reminders from the dashboard - Signers can request the link be resent ### Troubleshooting **Signer didn't receive email?** - Check spam/junk folder - Verify email address is correct - Resend from the contract details page **Can't complete signature?** - Try a different browser - Clear browser cache - Use the mobile device instead --- # API REFERENCE ## API Overview Programmatically create, send, and manage contracts for e-signatures. **Base URL:** https://apisign.io/api ### Quick Start #### 1. Get Your API Key Generate an API key from your dashboard settings at /dashboard/account/api-keys #### 2. Make Your First Request ```bash curl -X GET https://apisign.io/api/contract/find \ -H "x-api-key: your_api_key_here" \ -H "Content-Type: application/json" ``` #### 3. Create a Contract ```bash curl -X POST https://apisign.io/api/contract/create \ -H "x-api-key: your_api_key_here" \ -H "Content-Type: application/json" \ -d '{ "name": "Service Agreement", "content": "# Agreement\n\nThis agreement is between...\n\n**Signature:** {{signature}}", "signers": [ { "email": "john@example.com", "name": "John Smith", "signing_order": 1 } ] }' ``` ### Error Responses All endpoints return errors in a consistent format: ```json { "error": "Error message describing what went wrong", "details": [ { "field": "email", "message": "Invalid email format" } ] } ``` ### HTTP Status Codes | Status | Description | |--------|-------------| | `200` | Success | | `400` | Bad Request - Invalid parameters | | `401` | Unauthorized - Missing or invalid API key | | `403` | Forbidden - Insufficient permissions | | `404` | Not Found - Resource doesn't exist | | `500` | Internal Server Error | --- ## Authentication API Sign uses API keys for authentication. All API requests must include a valid API key in the request headers. ### API Key Management #### Getting Your API Key 1. Log in to your API Sign dashboard 2. Navigate to **Account** → **API Keys** 3. Click **Create API Key** 4. Copy and securely store your API key **Important:** API keys are only shown once during creation. Store them securely and never share them publicly. #### API Key Types **Production Keys** - Used for live contracts and real signatures - Full access to all API endpoints **Test Keys** - Used for development and testing - Limited to test mode operations - No charges for API usage - Contracts created are not legally binding ### Authentication Method Include your API key in the `x-api-key` header: ```http x-api-key: your_api_key_here ``` ### Example Requests #### cURL Example ```bash curl -X GET https://apisign.io/api/contract/find \ -H "x-api-key: your_api_key_here" \ -H "Content-Type: application/json" ``` #### JavaScript Example ```javascript const response = await fetch('https://apisign.io/api/contract/find', { method: 'GET', headers: { 'x-api-key': 'your_api_key_here', 'Content-Type': 'application/json' } }); const contracts = await response.json(); ``` #### Python Example ```python import requests headers = { 'x-api-key': 'your_api_key_here', 'Content-Type': 'application/json' } response = requests.get('https://apisign.io/api/contract/find', headers=headers) contracts = response.json() ``` ### Error Responses #### 401 Unauthorized ```json { "error": "unauthorized", "message": "Invalid API key" } ``` #### 403 Forbidden ```json { "error": "forbidden", "message": "API key does not have permission for this resource" } ``` ### Security Best Practices #### API Key Security - Never commit API keys to version control - Use environment variables to store keys - Rotate keys regularly (every 90 days recommended) - Use different keys for different environments - Revoke compromised keys immediately #### Network Security - Always use HTTPS for API requests - Implement proper SSL certificate validation - Use IP allowlisting when possible - Monitor API usage for suspicious activity --- ## Contracts API Create, manage, and track contracts for signing. **Base URL:** https://apisign.io/api ### Create Contract **POST /contract/create** Create a new contract from a template or custom content. Returns the created contract with signing links for each signer. #### Request Body | Field | Type | Required | Description | |-------|------|----------|-------------| | `name` | string | Yes | Contract name (1-255 characters) | | `template_id` | string | No | Template ID to create contract from | | `content` | string | No | Markdown content (required if no template_id) | | `variables` | object | No | Values for creator-completed template variables | | `fields` | object | No | Field definitions and signer assignments | | `expires_in_days` | integer | No | Days until expiration (1-365, default: 30) | | `signers` | array | Yes | Array of signer objects | #### Example Request ```json { "name": "Service Agreement - Acme Corp", "template_id": "clx123abc", "variables": { "company_name": "Acme Corporation", "effective_date": "2024-01-15" }, "expires_in_days": 14, "signers": [ { "email": "john@example.com", "name": "John Smith", "company": "Acme Corp", "signing_order": 1 } ] } ``` #### Response (200 OK) ```json { "success": true, "contract": { "id": "clx456def", "name": "Service Agreement - Acme Corp", "status": "draft" }, "signers": [ { "id": "sig_789", "email": "john@example.com", "name": "John Smith", "signing_link": "https://apisign.io/sign/abc123" } ] } ``` #### Signer Object Each signer in the `signers` array should include: | Field | Type | Required | Description | |-------|------|----------|-------------| | `email` | string | Yes | Signer's email address | | `name` | string | Yes | Signer's full name | | `company` | string | No | Signer's company name | | `signing_order` | integer | Yes | Order in which to sign (1, 2, 3...) | ### Get Contract **GET /contract/get** Retrieve a contract by its ID, including current status, signers, and content. #### Parameters | Name | Type | Required | Location | Description | |------|------|----------|----------|-------------| | `id` | string | Yes | query | Contract ID | #### Response (200 OK) ```json { "id": "clx456def", "name": "Service Agreement", "status": "sent", "created_at": "2024-01-10T10:00:00Z", "expires_at": "2024-02-10T10:00:00Z", "signers": [ { "id": "sig_789", "email": "john@example.com", "name": "John Smith", "status": "pending" } ] } ``` ### List Contracts **GET /contract/find** List all contracts for your organization with optional filtering and pagination. #### Parameters | Name | Type | Required | Location | Description | |------|------|----------|----------|-------------| | `status` | string | No | query | Filter by status: draft, sent, signed, cancelled, expired | | `limit` | integer | No | query | Results per page (default: 20) | | `offset` | integer | No | query | Pagination offset (default: 0) | #### Response (200 OK) ```json { "contracts": [ { "id": "clx456def", "name": "Service Agreement", "status": "sent" }, { "id": "clx789ghi", "name": "NDA", "status": "signed" } ], "total": 42 } ``` ### Contract Statuses | Status | Description | |--------|-------------| | `draft` | Contract created but not yet sent | | `sent` | Contract sent to signers, awaiting signatures | | `signed` | All signers have completed their signatures | | `cancelled` | Contract was cancelled before completion | | `expired` | Contract expired before all signatures were collected | ### Send Contract **POST /contract/send** Send a draft contract to all signers. This triggers email notifications with signing links. #### Request Body | Field | Type | Required | Description | |-------|------|----------|-------------| | `contract_id` | string | Yes | Contract ID to send | #### Example Request ```json { "contract_id": "clx456def" } ``` #### Response (200 OK) ```json { "success": true, "message": "Contract sent to 2 signers" } ``` ### Cancel Contract **POST /contract/cancel** Cancel a sent contract. Signers will no longer be able to sign. #### Request Body | Field | Type | Required | Description | |-------|------|----------|-------------| | `contract_id` | string | Yes | Contract ID to cancel | #### Response (200 OK) ```json { "success": true } ``` ### Download Contract PDF **GET /contract/download** Download the signed contract as a PDF. Only available for completed contracts. #### Parameters | Name | Type | Required | Location | Description | |------|------|----------|----------|-------------| | `id` | string | Yes | query | Contract ID | #### Response - 200: PDF file download - 400: Contract not yet completed - 404: Contract not found --- ## Templates API Manage reusable contract templates with variables. **Base URL:** https://apisign.io/api ### Create Template **POST /template/create** Create a new contract template with variables that can be filled when creating contracts. #### Request Body | Field | Type | Required | Description | |-------|------|----------|-------------| | `name` | string | Yes | Template name | | `description` | string | No | Template description | | `content` | string | Yes | Markdown content with {{variables}} | | `fields` | object | No | Field definitions | #### Example Request ```json { "name": "Standard NDA", "description": "Non-disclosure agreement template", "content": "# Non-Disclosure Agreement\n\nThis agreement is between {{company_name}} and {{signer_name}}...\n\n**Signature:** {{signature}}" } ``` #### Response (200 OK) ```json { "id": "tmpl_abc123", "name": "Standard NDA", "created_at": "2024-01-10T10:00:00Z" } ``` ### Template Variables Use double curly braces to define variables in your template content: | Variable Type | Example | Description | |--------------|---------|-------------| | Text | `{{company_name}}` | Simple text field | | Signature | `{{signature}}` | Signature capture field | | Date | `{{effective_date}}` | Date picker field | | Signer Name | `{{signer_name}}` | Auto-filled with signer's name | ### Get Template **GET /template/get** Retrieve a template by ID. #### Parameters | Name | Type | Required | Location | Description | |------|------|----------|----------|-------------| | `id` | string | Yes | query | Template ID | #### Response (200 OK) ```json { "id": "tmpl_abc123", "name": "Standard NDA", "content": "# Non-Disclosure Agreement...", "created_at": "2024-01-10T10:00:00Z" } ``` ### List Templates **GET /template/find** List all templates for your organization. #### Response (200 OK) ```json { "templates": [ { "id": "tmpl_abc123", "name": "Standard NDA" }, { "id": "tmpl_def456", "name": "Service Agreement" } ] } ``` ### Update Template **PUT /template/update** Update an existing template. #### Request Body | Field | Type | Required | Description | |-------|------|----------|-------------| | `id` | string | Yes | Template ID | | `name` | string | No | New name | | `description` | string | No | New description | | `content` | string | No | New content | | `fields` | object | No | New field definitions | #### Example Request ```json { "id": "tmpl_abc123", "name": "Updated NDA Template" } ``` #### Response (200 OK) ```json { "id": "tmpl_abc123", "name": "Updated NDA Template" } ``` ### Archive Template **POST /template/archive** Archive a template (soft delete). Archived templates cannot be used to create new contracts. #### Request Body | Field | Type | Required | Description | |-------|------|----------|-------------| | `id` | string | Yes | Template ID to archive | #### Response (200 OK) ```json { "success": true } ``` ### Field Definitions When creating or updating a template, you can specify field definitions to control how variables behave: ```json { "fields": { "fields": [ { "name": "company_name", "type": "text", "completedBy": "creator" }, { "name": "signature", "type": "signature", "completedBy": "signer" }, { "name": "effective_date", "type": "date", "completedBy": "creator" } ] } } ``` ### Field Types | Type | Description | |------|-------------| | `text` | Plain text input | | `signature` | Signature capture | | `initials` | Initials capture | | `date` | Date picker | | `email` | Email input with validation | | `signer_name` | Auto-filled with signer's name | ### Completed By | Value | Description | |-------|-------------| | `creator` | Filled when creating the contract | | `signer` | Filled by the signer during signing | --- ## Webhooks Webhooks allow your application to receive real-time notifications when events occur in API Sign. Instead of repeatedly polling our API, webhooks push event data to your application immediately when something happens. **Base URL:** https://apisign.io/api ### Create Webhook **POST /webhook/create** Create a new webhook endpoint to receive event notifications. #### Request Body | Field | Type | Required | Description | |-------|------|----------|-------------| | `url` | string | Yes | Webhook endpoint URL (HTTPS required) | | `events` | array | Yes | Array of event types to subscribe to | #### Example Request ```json { "url": "https://yourapp.com/webhooks/apisign", "events": ["contract.signed", "contract.completed"] } ``` #### Response (200 OK) ```json { "id": "whk_xyz789", "url": "https://yourapp.com/webhooks/apisign", "events": ["contract.signed", "contract.completed"], "secret": "whsec_abc123...", "active": true } ``` ### List Webhooks **GET /webhook/list** List all webhook endpoints for your organization. #### Response (200 OK) ```json { "webhooks": [ { "id": "whk_xyz789", "url": "https://yourapp.com/webhooks/apisign", "events": ["contract.signed", "contract.completed"], "active": true } ] } ``` ### Delete Webhook **DELETE /webhook/delete** Delete a webhook endpoint. #### Parameters | Name | Type | Required | Location | Description | |------|------|----------|----------|-------------| | `id` | string | Yes | query | Webhook ID | #### Response (200 OK) ```json { "success": true } ``` ### Available Events | Event | Description | |-------|-------------| | `contract.created` | A new contract was created | | `contract.sent` | A contract was sent to signers | | `contract.viewed` | A signer viewed the contract | | `contract.signed` | A signer completed their signature | | `contract.completed` | All signers have signed | | `contract.cancelled` | A contract was cancelled | | `contract.expired` | A contract expired | | `template.created` | A new template was created | | `template.updated` | A template was modified | | `template.deleted` | A template was deleted | ### Webhook Payload All webhook payloads follow this structure: ```json { "id": "evt_1234567890", "type": "contract.signed", "created": 1642253100, "data": { "contract": { "id": "ctr_1234567890", "title": "Service Agreement", "status": "partially_signed" }, "signer": { "id": "sgn_client_123", "email": "john@acme.com", "signed_at": "2024-01-15T14:30:00Z" } } } ``` ### Webhook Headers All webhook requests include these headers: | Header | Description | |--------|-------------| | `X-APISign-Event` | The event type that triggered the webhook | | `X-APISign-Signature` | HMAC signature for verification | | `X-APISign-Timestamp` | Unix timestamp when event occurred | | `X-APISign-Webhook-ID` | Unique identifier for this webhook | ### Signature Verification Always verify webhook signatures to ensure requests are genuine. API Sign includes a signature in the webhook headers that you should validate. #### Node.js Example ```javascript const crypto = require('crypto'); function verifyWebhookSignature(payload, signature, secret, timestamp) { // Check timestamp to prevent replay attacks (within 5 minutes) const currentTime = Math.floor(Date.now() / 1000); if (Math.abs(currentTime - timestamp) > 300) { throw new Error('Request timestamp too old'); } // Create signed payload const signedPayload = timestamp + '.' + payload; // Generate expected signature const expectedSignature = crypto .createHmac('sha256', secret) .update(signedPayload, 'utf8') .digest('hex'); // Extract signature from header (format: sha256=signature) const receivedSignature = signature.split('=')[1]; // Compare signatures using time-safe comparison return crypto.timingSafeEqual( Buffer.from(expectedSignature, 'hex'), Buffer.from(receivedSignature, 'hex') ); } // Usage in Express.js app.post('/webhooks/apisign', express.raw({type: 'application/json'}), (req, res) => { const signature = req.get('X-APISign-Signature'); const timestamp = req.get('X-APISign-Timestamp'); const payload = req.body.toString(); try { const isValid = verifyWebhookSignature( payload, signature, process.env.APISIGN_WEBHOOK_SECRET, parseInt(timestamp) ); if (!isValid) { return res.status(401).send('Invalid signature'); } const event = JSON.parse(payload); handleWebhookEvent(event); res.status(200).send('OK'); } catch (error) { console.error('Webhook verification failed:', error); res.status(400).send('Verification failed'); } }); ``` #### Python Example ```python import hmac import hashlib import time def verify_webhook_signature(payload, signature, secret, timestamp): # Check timestamp (within 5 minutes) current_time = int(time.time()) if abs(current_time - int(timestamp)) > 300: raise ValueError('Request timestamp too old') # Create signed payload signed_payload = f"{timestamp}.{payload}" # Generate expected signature expected_signature = hmac.new( secret.encode('utf-8'), signed_payload.encode('utf-8'), hashlib.sha256 ).hexdigest() # Extract signature from header received_signature = signature.split('=')[1] # Compare signatures return hmac.compare_digest(expected_signature, received_signature) ``` ### Retry Policy API Sign implements automatic retry logic for failed webhook deliveries: | Attempt | Delay | |---------|-------| | Initial | Immediate | | Retry 1 | 1 minute | | Retry 2 | 5 minutes | | Retry 3 | 15 minutes | | Retry 4 | 1 hour | | Retry 5 | 6 hours | #### Failure Conditions Webhooks are considered failed if: - HTTP response code is not 2xx - Request times out (10 seconds) - Connection cannot be established - SSL/TLS handshake fails ### Best Practices #### Respond Quickly Return a 2xx response immediately, then process the event asynchronously: ```javascript app.post('/webhooks/apisign', (req, res) => { // Verify signature verifySignature(req); // Queue for async processing const event = JSON.parse(req.body); webhookQueue.add('process-event', event); // Respond immediately res.status(200).send('OK'); }); ``` #### Handle Duplicates Implement idempotency using event IDs: ```javascript const processedEvents = new Set(); function handleWebhookEvent(event) { if (processedEvents.has(event.id)) { console.log('Event already processed:', event.id); return; } processEvent(event); processedEvents.add(event.id); } ``` #### Use HTTPS Webhook endpoints must use HTTPS in production. HTTP endpoints are not allowed. ### Testing Webhooks #### Local Development Use ngrok to expose your local server: ```bash ngrok http 3000 # Use the HTTPS URL: https://abc123.ngrok.io/webhooks/apisign ``` #### Test Events Test events include a `test: true` property: ```json { "id": "evt_test_1234567890", "type": "contract.signed", "test": true, "data": { ... } } ``` Test events can be sent from the dashboard under Settings → Webhooks → Test Webhook. --- ## MCP Server APISign provides a Model Context Protocol (MCP) server that enables AI agents to manage templates and send contracts programmatically. ### Overview The MCP server uses the **Streamable HTTP** transport, which works with any MCP-compatible client including Claude Desktop, Cursor, and custom implementations. ### Connection Details | Property | Value | |----------|-------| | **Endpoint** | `POST /mcp` | | **Transport** | Streamable HTTP | | **Authentication** | API Key (`x-api-key` header) | ### Getting an API Key 1. Log into the APISign dashboard 2. Navigate to **Account > API Keys** 3. Click **Create API Key** 4. Copy the key (it won't be shown again) ### Client Configuration #### Claude Desktop Add to your Claude Desktop configuration file: **macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json` **Windows:** `%APPDATA%\Claude\claude_desktop_config.json` ```json { "mcpServers": { "apisign": { "url": "https://apisign.io/mcp", "headers": { "x-api-key": "your-api-key-here" } } } } ``` #### Cursor Add to your Cursor MCP configuration: ```json { "mcpServers": { "apisign": { "url": "https://apisign.io/mcp", "headers": { "x-api-key": "your-api-key-here" } } } } ``` #### Local Development When running locally, use: ```json { "mcpServers": { "apisign": { "url": "http://localhost:3553/mcp", "headers": { "x-api-key": "your-api-key-here" } } } } ``` ### Available Tools #### Template Tools ##### template_list List all templates in your organization. **Parameters:** None **Returns:** ```json { "templates": [ { "id": "clx...", "name": "NDA Template", "created_at": "2024-01-15T10:30:00Z", "updated_at": "2024-01-15T10:30:00Z" } ] } ``` ##### template_get Get a specific template with its content and field definitions. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `id` | string | Yes | Template ID (CUID format) | **Returns:** ```json { "template": { "id": "clx...", "name": "NDA Template", "content": "# Non-Disclosure Agreement\n\nThis agreement...", "fields": { "fields": [ { "name": "company_name", "type": "text", "completedBy": "creator" }, { "name": "signature", "type": "signature", "completedBy": "signer" } ] } } } ``` ##### template_create Create a new blank template. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `name` | string | Yes | Template name (min 3 characters) | | `content` | string | No | Markdown content | **Example:** ```json { "name": "Service Agreement", "content": "# Service Agreement\n\nBetween {{company_name}} and {{client_name}}..." } ``` ##### template_update Update an existing template. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `id` | string | Yes | Template ID | | `name` | string | No | New name | | `content` | string | No | New markdown content | | `fields` | array | No | Field definitions | **Fields array format:** ```json { "fields": [ { "name": "company_name", "type": "text", "completedBy": "creator" }, { "name": "signature", "type": "signature", "completedBy": "signer" } ] } ``` ##### template_upload Upload a DOCX or DOC file and convert it to a template. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `filename` | string | Yes | Original filename (must end in .doc or .docx) | | `fileData` | string | Yes | Base64-encoded file content | ##### template_archive Archive (soft delete) a template. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `id` | string | Yes | Template ID | #### Contract Tools ##### contract_list List contracts in your organization. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `status` | string | No | Filter by status: `draft`, `queued`, `sent`, `signed`, `cancelled`, `expired` | **Returns:** ```json { "contracts": [ { "id": "clx...", "name": "NDA - Acme Corp", "status": "sent", "created_at": "2024-01-15T10:30:00Z", "sent_at": "2024-01-15T11:00:00Z", "expires_at": "2024-02-14T11:00:00Z" } ] } ``` ##### contract_get Get a contract with its signers. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `id` | string | Yes | Contract ID | **Returns:** ```json { "contract": { "id": "clx...", "name": "NDA - Acme Corp", "status": "sent", "content": { "markdown": "..." } }, "signers": [ { "id": "clx...", "name": "John Doe", "email": "john@example.com", "status": "pending", "signing_order": 1 } ] } ``` ##### contract_create Create a new contract from a template or custom content. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `name` | string | Yes | Contract name | | `template_id` | string | No | Template ID (if using a template) | | `content` | string | No | Markdown content (required if no template_id) | | `variables` | object | No | Variables to substitute (for template-based contracts) | | `expires_in_days` | number | No | Days until expiration (default: 30, max: 365) | | `signers` | array | Yes | List of signers (at least one) | **Signers array format:** ```json { "signers": [ { "email": "john@example.com", "name": "John Doe", "company": "Acme Corp", "signing_order": 1 }, { "email": "jane@example.com", "name": "Jane Smith", "signing_order": 2 } ] } ``` **Example - From template:** ```json { "name": "NDA - Acme Corp", "template_id": "clx...", "variables": { "company_name": "Acme Corporation", "effective_date": "January 15, 2024" }, "signers": [ { "email": "john@acme.com", "name": "John Doe", "signing_order": 1 } ] } ``` **Example - Custom content:** ```json { "name": "Simple Agreement", "content": "# Agreement\n\nI, {{signer_name}}, agree to the terms.\n\n{{signature}}", "signers": [ { "email": "john@example.com", "name": "John Doe", "signing_order": 1 } ] } ``` ##### contract_update Update a draft contract. Only contracts with `draft` status can be updated. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `contract_id` | string | Yes | Contract ID | | `name` | string | No | New name | | `content` | object | No | New content object | | `signers` | array | No | Replace signers list | ##### contract_send Send a contract to signers for signing. This: - Changes status to `sent` - Charges your organization balance - Sends email notifications to all signers **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `contract_id` | string | Yes | Contract ID | **Returns:** ```json { "success": true, "contract_id": "clx...", "signers_notified": 2, "cost_charged": 0.25, "message": "Contract sent successfully" } ``` ##### contract_cancel Cancel a contract. Only `draft` and `sent` contracts can be cancelled. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `contract_id` | string | Yes | Contract ID | ### Template Variables Templates use handlebar-style variables: `{{variable_name}}` #### Variable Types | completedBy | Description | |-------------|-------------| | `creator` | Filled when creating the contract | | `signer` | Filled by the signer when signing | #### Common Variables - `{{company_name}}` - Company name (creator) - `{{client_name}}` - Client name (creator) - `{{effective_date}}` - Contract effective date (creator) - `{{signer_name}}` - Signer's name (signer) - `{{signature}}` - Signature field (signer) - `{{date}}` - Signing date (signer) ### Error Handling All tools return errors in a consistent format: ```json { "error": "Error message here", "details": [ { "field": "name", "message": "Name is required" } ] } ``` #### Common Errors | Error | Description | |-------|-------------| | `Missing x-api-key header` | No API key provided | | `Invalid or disabled API key` | API key not found or disabled | | `API key has expired` | API key past expiration date | | `Template not found` | Template ID doesn't exist or is archived | | `Contract not found` | Contract ID doesn't exist | | `Insufficient balance` | Organization needs to add funds | | `Only draft contracts can be updated` | Cannot update sent/signed contracts | ### Usage Examples #### Create and Send a Contract ``` 1. Use template_list to find available templates 2. Use template_get to view template content and fields 3. Use contract_create with template_id and variables 4. Use contract_send to send to signers ``` #### Upload a Document Template ``` 1. Read document file and base64 encode it 2. Use template_upload with filename and fileData 3. Use template_update to set field definitions ``` #### Check Contract Status ``` 1. Use contract_list with status filter 2. Use contract_get for detailed signer status ``` ### Rate Limits API keys have configurable rate limits. Default limits: - 1000 requests per minute - Refills automatically Contact support to increase limits for high-volume use cases. --- # END OF DOCUMENTATION For more information, visit https://apisign.io/docs For support, visit https://apisign.io/support