Documentation

Agreements.ai Docs

Everything you need to use the platform and integrate with our API — user guides, developer reference, and MCP tools.

Getting Started

Creating Your Account

1

Sign up

Visit agreements.ai/register and create your account with email or Google sign-in. No credit card required — you get a free tier to start.
2

Verify your email

Check your inbox for a verification email and click the link to activate your account.
3

Complete your profile

Add your name, company, and optionally upload a logo for branded signing experiences.

Navigating the Dashboard

Your dashboard is the central hub for all your contract activities. Here's what you'll find:

  • Documents — All your agreements, drafts, and signed contracts
  • Templates — Reusable contract templates for common agreements
  • Negotiations — Active negotiation sessions with counterparties
  • Bundles — Groups of related documents
  • CRM — Your contacts and contract relationships
  • Settings — Team management, branding, API keys, and billing

Creating Documents

From Scratch

1

Click "New Document"

From the dashboard, click the New Document button in the top right corner.
2

Choose "Blank Document"

Select the blank document option to start with a clean editor.
3

Write your content

Use the rich text editor to draft your agreement. You can format text, add headings, insert lists, and structure your contract as needed.
4

Save

Your document auto-saves, but you can also manually save at any time. Give it a descriptive title.

Upload an Existing Document

1

Click "New Document" → "Upload"

Choose the upload option from the new document menu.
2

Select your file

Upload a PDF, DOCX, or DOC file. The platform will extract the text and convert it to an editable format.
💡

PDF tip

For best results with PDFs, use text-based PDFs rather than scanned images. The AI can still process scanned documents, but text-based files give better formatting.

From a Template

1

Browse templates

Go to Templates in the sidebar, or click New Document → From Template.
2

Pick a template

Browse by category (NDA, Employment, Services, etc.) or search for what you need.
3

Fill in the details

The template will prompt you to fill in variables like party names, dates, and specific terms.
4

Review and customize

The generated document is fully editable — adjust any clause or term to fit your needs.

AI Features

Agreements.ai uses AI throughout the platform to help you understand, improve, and create contracts faster.

📊 Contract Analysis

Click Analyze on any document to get an instant AI-powered review. You'll see:

  • Risk assessment with severity ratings
  • Key clause identification (termination, liability, IP, etc.)
  • Plain-language summary of obligations for each party
  • Missing clause recommendations

💬 Document Chat

Open the chat panel on any document and ask questions in natural language:

  • "What are my termination rights?"
  • "Summarize the payment terms"
  • "Are there any non-compete clauses?"
  • "What happens if either party breaches?"

✏️ AI Rewrite

Select any text in your document and click AI Rewrite. You can ask the AI to make the language more formal, simplify complex terms, strengthen a clause, or adjust the tone. The original text is preserved until you accept the changes.

📝 Clause Insertion

Need to add a standard clause? Use Insert Clause to browse the clause library or ask the AI to generate one. Common options include confidentiality, indemnification, force majeure, and dispute resolution clauses.

Sending for Signing

Sign hereDraftSentSignedComplete
1

Open the signing panel

From your document, click the Send for Signing button. This opens the signing configuration panel.
2

Add signers

Enter the name and email address for each person who needs to sign. You can add multiple signers and set the signing order if needed.
3

Place signing fields

Drag and drop signature, initial, date, and text fields onto the document. You can also click Auto-detect Fields to let the AI place them automatically.
4

Add a message (optional)

Write a custom message that signers will see in their signing email.
5

Send

Click Send. Each signer receives an email with a secure link to review and sign the document.
ℹ️

Tracking

Once sent, you can track the signing status in real time on the document page. You'll see who has viewed, signed, or is still pending.

Managing Signatures

Send Reminders

If a signer hasn't completed their signature, click Remind on the document page. This sends a gentle email reminder with the signing link.

Void a Signing Request

Need to cancel? Click Void on the document page. This invalidates all existing signing links. You can optionally provide a reason that signers will see.

Correct Signer Details

Entered the wrong email? Click Correct next to the signer's name to update their email or name. A new signing link will be sent to the corrected address.

Download Signed PDF

Once all parties have signed, click Download PDF to get the final signed document with a certificate of completion, timestamps, and audit trail.

Templates

NDAEmploymentSaaSConsultingFreelance

Browse Templates

Go to Templates in the sidebar to browse our library of professionally drafted contract templates. Filter by category (NDA, Employment, Services, Real Estate, etc.) or search by keyword.

Use a Template

Click on any template to preview it, then click Use Template. Fill in the variables (party names, dates, amounts) and the platform generates a ready-to-edit document.

Create Signing Templates

Turn any document into a reusable signing template with pre-placed signature fields and roles:

1

Open a document

Navigate to the document you want to use as a template.
2

Click "Save as Signing Template"

This option is in the document menu (⋮).
3

Define roles and fields

Assign each signing field to a role (e.g., "Sender", "Recipient") rather than specific people.
4

Save

Your template is now available for quick reuse — just assign real people to the roles when sending.

Negotiations

Negotiate contracts collaboratively with counterparties in real time. Propose changes, counter-offer, and chat — all within the platform.

Edit

How Negotiations Work

1

Create a negotiation

From any document, click Negotiate. This creates a negotiation session with the document as the starting point.
2

Invite parties

Add counterparties by email. They'll receive an invitation to join the negotiation.
3

Propose changes

Each section of the contract becomes a "block" that either party can propose changes to. Highlight text and click Propose Change.
4

Accept, reject, or counter

The other party can accept the proposed change, reject it, or make a counter-proposal. All changes are tracked.
5

Chat in context

Use the built-in chat to discuss terms alongside the document. Messages stay linked to specific sections.
6

Generate final contract

Once all blocks are agreed, click Generate Contract to produce the final document ready for signing.

Team Settings

Team Members

Go to Settings → Team to invite team members, assign roles (Admin, Member, Viewer), and manage access. Team members share the same document library and templates.

Branding

Under Settings → Branding, upload your company logo and set brand colors. These appear on signing pages, emails, and PDF certificates — giving your documents a professional, branded look.

Signing Configuration

Configure default signing options like reminder schedules, expiration periods, and redirect URLs under Settings → Signing.

Bundles

Bundles let you group related documents together for easier management and batch operations.

1

Create a bundle

Go to Bundles in the sidebar and click New Bundle. Give it a name (e.g., "Q1 Vendor Agreements").
2

Add documents

Add existing documents to the bundle, or create new ones directly within it.
3

Batch operations

Send all documents in a bundle for signing at once, download them as a ZIP, or track their collective status.

CRM

The built-in CRM helps you manage your contacts and their contract relationships.

Contacts

Go to CRM in the sidebar to manage your contacts. Each contact shows their name, email, company, and all contracts they're associated with. Add contacts manually or let them auto-populate from signing activity.

Groups

Organize contacts into groups (e.g., "Vendors", "Clients", "Partners") for easier filtering and batch actions like sending the same contract to an entire group.

Contract Linking

Every contract is linked to its signers in the CRM. Click on any contact to see their complete contract history — signed, pending, and draft documents.

Word Plugin

The Agreements.ai Word Add-in brings the full power of the platform directly into Microsoft Word. Create, review, rewrite, and sign contracts without leaving your document.

ℹ️

Installation

Open Word → InsertMy Add-insUpload My Add-in → select the Agreements.ai manifest file. The plugin appears as a button in the Home tab ribbon.

Create Contract

Generate professional contracts from natural language descriptions. Choose from 12 contract type presets (NDA, Service Agreement, Employment, SaaS, IP Assignment, and more) or describe any custom contract.

1

Choose contract type

Select a preset or choose Custom for any other contract type.
2

Add details

Enter party names, jurisdiction, and describe the key terms and obligations.
3

Generate

AI generates the full contract and inserts it directly into your Word document. The contract is also saved to your Agreements.ai account.

AI Review

Analyze any contract for risks, missing protections, and legal issues. Returns a risk score (0–100), categorized issues by severity, missing clauses, key terms analysis, and strengths.

  • Click-to-navigate — clicking an issue highlights the relevant text in your document
  • Three views — Issues (with severity cards), Key Terms (with risk indicators), and Summary
  • Missing clauses — identifies standard protections your contract is missing
  • Actionable suggestions — each issue includes a specific fix recommendation

Clause Library

Browse 72+ system clauses and your team's custom clauses. Filter by category, search by keyword, and see stance indicators (Pro-Sender, Balanced, Pro-Receiver).

  • Insert at cursor position or end of document
  • Categories: General, IP, Payment, Liability, Termination, Employment, Compliance, Dispute Resolution, Data Privacy, and more
  • Custom clauses shared across your team
  • Full clause preview before inserting

AI Rewrite

Select text in your document and rewrite it with AI. Six built-in modes plus custom instructions:

Simplify — Plain English, clearer language
Formal — Legal precision and terminology
Expand — More detail and specificity
Strengthen — More favorable terms
Neutralize — Balance one-sided language
Fix Issues — Grammar and formatting

Each rewrite shows a word-level diff of what changed and why. Preview before applying to your document.

Document Chat

Ask questions about your contract in a conversational interface. Quick action presets for common tasks:

  • Summarize the contract
  • List obligations per party
  • Find risks
  • Explain defined terms in plain English
  • Identify missing clauses
  • Summarize termination rights

When you ask for changes, the AI proposes edits and automatically applies them to your Word document.

Compare & Check

Two modes for contract comparison:

  • Playbook Check — Analyze your document against standard legal best practices
  • Compare Versions — Paste a reference contract and get a detailed diff of all material differences

Send for Signing

Send your document for e-signatures directly from Word. Add multiple signers with roles (Signer, Approver, or CC), include an optional message, and the document is uploaded to Agreements.ai and signers receive email notifications.

💡

Security

The Word plugin has zero third-party API keys or SDKs on the client side. All authentication, AI processing, and data operations go exclusively through the Agreements.ai backend server. No Firebase, OpenAI, or other credentials are stored in the plugin.
⚡ Developer Documentation

Getting Started

Go from zero to your first API call in 5 minutes. Create an account, grab your API key, and send a document for signing.

POST /envelopesGET /documentsGET /templatesRequestResponseAPI Server

Step 1: Create an Account

Sign up at agreements.ai/register — free, no credit card required.

Step 2: Get Your API Key

Navigate to Settings → Developers and click Create API Key. Copy the key — it starts with sk_ and is only shown once.

⚠️

Store securely

Your API key is only displayed once at creation. Store it in an environment variable or secrets manager — never commit it to source control.

Step 3: Make Your First API Call

Base URL: https://api.agreements.ai/v1

All requests require the Authorization header:

1Authorization: Bearer sk_live_your_api_key_here

Complete Example: Create → Send → Check Status

1# 1. Create a document
2curl -X POST https://api.agreements.ai/v1/documents \
3 -H "Authorization: Bearer sk_live_abc123" \
4 -H "Content-Type: application/json" \
5 -d '{
6 "title": "Service Agreement — Acme Corp",
7 "content": "<h1>Service Agreement</h1><p>This agreement is entered into between...</p>"
8 }'
9
10# Response: { "id": "doc_7kXm2pQ9", "title": "Service Agreement — Acme Corp", ... }
11
12# 2. Create an envelope (sends for signing)
13curl -X POST https://api.agreements.ai/v1/envelopes \
14 -H "Authorization: Bearer sk_live_abc123" \
15 -H "Content-Type: application/json" \
16 -d '{
17 "documentId": "doc_7kXm2pQ9",
18 "name": "Service Agreement — Acme Corp",
19 "message": "Please review and sign this agreement.",
20 "signers": [
21 { "name": "Jane Smith", "email": "[email protected]", "role": "signer" },
22 { "name": "Bob Johnson", "email": "[email protected]", "role": "signer" }
23 ],
24 "fields": [
25 {
26 "type": "signature",
27 "signerEmail": "[email protected]",
28 "page": 1,
29 "x": 100,
30 "y": 500,
31 "width": 200,
32 "height": 50
33 },
34 {
35 "type": "signature",
36 "signerEmail": "[email protected]",
37 "page": 1,
38 "x": 100,
39 "y": 600,
40 "width": 200,
41 "height": 50
42 },
43 {
44 "type": "date",
45 "signerEmail": "[email protected]",
46 "page": 1,
47 "x": 320,
48 "y": 520,
49 "width": 100,
50 "height": 20
51 }
52 ]
53 }'
54
55# Response: { "id": "env_Qr8sT4kL", "status": "sent", ... }
56
57# 3. Check status
58curl https://api.agreements.ai/v1/envelopes/env_Qr8sT4kL \
59 -H "Authorization: Bearer sk_live_abc123"
60
61# 4. Download completed document
62curl https://api.agreements.ai/v1/envelopes/env_Qr8sT4kL/document \
63 -H "Authorization: Bearer sk_live_abc123" \
64 -o signed_agreement.pdf

Authentication

sk_live_a3f8...x9z2CopyAuthorized

API Keys vs Firebase Tokens

Agreements.ai supports two authentication methods:

MethodFormatUse Case
sk_live_...API KeyServer-to-server integrations, scripts, backend automation
eyJhbG...Firebase JWTFrontend/mobile apps using Firebase Auth (short-lived)

Both use the same header: Authorization: Bearer <token>

Creating and Managing Keys

  1. Go to Settings → Developers
  2. Click Create API Key
  3. Give it a descriptive name (e.g., "CRM Integration", "CI/CD Pipeline")
  4. Copy the key immediately — it won't be shown again
💡

Key rotation best practices

  • Rotate keys every 90 days
  • Create the new key before revoking the old one
  • Use separate keys for each integration
  • Never hardcode keys — use environment variables

Rate Limits

Rate limits are applied per API key. Exceeding them returns 429 Too Many Requests.

OperationLimitWindowEndpoints
Reads30 requestsPer minuteAll GET endpoints
Writes10 requestsPer minutePOST, PUT, PATCH, DELETE
Reminders5 requestsPer minutePOST /envelopes/:id/remind

Rate limit headers are included in every response: X-RateLimit-Remaining, X-RateLimit-Reset

Auth Error Responses

json401 Unauthorized
1{
2 "error": "Invalid or expired API key",
3 "code": "AUTH_INVALID_KEY"
4}
json429 Too Many Requests
1{
2 "error": "Rate limit exceeded. Try again in 45 seconds.",
3 "code": "RATE_LIMIT_EXCEEDED",
4 "retryAfter": 45
5}

Core Concepts

📄

Documents

The contract or agreement content. Created from scratch, uploaded as PDF/DOCX, or generated from a template. Documents contain the actual text that gets signed.

✉️

Envelopes

A document packaged for signing. An envelope wraps a document together with its signers, fields, and configuration. Think of it as the "transaction" — one envelope = one signing session.

👤

Signers

Recipients who need to take action on an envelope. Each signer has a name, email, and role (signer, witness, notary, or CC). Signers receive email notifications with a unique signing link.

📋

Fields

Interactive elements placed on the document — signature, initials, text input, date, checkbox, and dropdown. Each field is assigned to a specific signer and positioned at exact coordinates on a page.

📑

Templates

Reusable document blueprints with merge fields like [Client Name] and [Effective Date]. Use a template to generate a pre-filled document, then send it for signing.

🔔

Webhooks

Real-time HTTP callbacks that notify your server when events occur — an envelope is sent, a signer completes, an envelope is voided. Signed with HMAC-SHA256 for verification.

📊 Envelope Lifecycle

Every envelope moves through a defined set of statuses:

DraftSentIn ProgressCompleted

An envelope can also be Voided by the sender or Declined by a signer at any point after sending.

  • Draft — Created but not yet sent. Signers have not been notified.
  • Sent — Signing invitations delivered to all signers.
  • In Progress — At least one signer has signed, but not all.
  • Completed — All signers have signed. The document is finalized and tamper-sealed.
  • Voided — Cancelled by the sender. No further signing possible.
  • Declined — A signer refused to sign. The sender is notified with the reason.

Guide: Send Your First Document

A complete walkthrough: create a document, configure an envelope with signers and fields, send it, monitor status, and download the signed PDF.

Step 1: Create a Document

Upload your contract content. The content field accepts HTML.

1curl -X POST https://api.agreements.ai/v1/documents \
2 -H "Authorization: Bearer sk_live_abc123" \
3 -H "Content-Type: application/json" \
4 -d '{
5 "title": "Consulting Agreement",
6 "content": "<h1>Consulting Agreement</h1><p>This Consulting Agreement (\"Agreement\") is entered into as of [Effective Date] by and between [Client Name] (\"Client\") and [Consultant Name] (\"Consultant\").</p><h2>1. Services</h2><p>Consultant shall provide the services described in Exhibit A attached hereto.</p><h2>2. Compensation</h2><p>Client shall pay Consultant a fee of $[Amount] per hour for services rendered.</p><h2>3. Term</h2><p>This Agreement shall commence on [Start Date] and continue for a period of [Term Length] months.</p><p>IN WITNESS WHEREOF, the parties have executed this Agreement:</p><p>Client: [Signature]</p><p>Consultant: [Signature]</p>"
7 }'
jsonResponse
1{
2 "id": "doc_7kXm2pQ9",
3 "title": "Consulting Agreement",
4 "createdAt": "2026-02-12T10:00:00Z",
5 "updatedAt": "2026-02-12T10:00:00Z",
6 "wordCount": 156,
7 "status": "draft"
8}

Step 2: Create an Envelope

Wrap your document in an envelope with signers and field placements. The envelope is sent immediately upon creation (or set "status": "draft" to hold it).

1curl -X POST https://api.agreements.ai/v1/envelopes \
2 -H "Authorization: Bearer sk_live_abc123" \
3 -H "Content-Type: application/json" \
4 -d '{
5 "documentId": "doc_7kXm2pQ9",
6 "name": "Consulting Agreement — Jane Smith",
7 "message": "Hi Jane, please review and sign the attached consulting agreement.",
8 "signers": [
9 {
10 "name": "Jane Smith",
11 "email": "[email protected]",
12 "role": "signer",
13 "order": 1
14 },
15 {
16 "name": "Bob Johnson",
17 "email": "[email protected]",
18 "role": "signer",
19 "order": 2
20 }
21 ],
22 "fields": [
23 { "type": "signature", "signerEmail": "[email protected]", "page": 1, "x": 72, "y": 680, "width": 200, "height": 50 },
24 { "type": "date", "signerEmail": "[email protected]", "page": 1, "x": 300, "y": 695, "width": 120, "height": 20 },
25 { "type": "signature", "signerEmail": "[email protected]", "page": 1, "x": 72, "y": 740, "width": 200, "height": 50 },
26 { "type": "date", "signerEmail": "[email protected]", "page": 1, "x": 300, "y": 755, "width": 120, "height": 20 }
27 ],
28 "settings": {
29 "reminderDays": 3,
30 "expirationDays": 30
31 }
32 }'
jsonResponse
1{
2 "id": "env_Qr8sT4kL",
3 "name": "Consulting Agreement — Jane Smith",
4 "status": "sent",
5 "documentId": "doc_7kXm2pQ9",
6 "createdAt": "2026-02-12T10:01:00Z",
7 "sentAt": "2026-02-12T10:01:00Z",
8 "expiresAt": "2026-03-14T10:01:00Z",
9 "signers": [
10 {
11 "id": "sig_A1b2C3",
12 "name": "Jane Smith",
13 "email": "[email protected]",
14 "role": "signer",
15 "order": 1,
16 "status": "pending"
17 },
18 {
19 "id": "sig_D4e5F6",
20 "name": "Bob Johnson",
21 "email": "[email protected]",
22 "role": "signer",
23 "order": 2,
24 "status": "pending"
25 }
26 ]
27}

Step 3: Check Status

Poll the envelope to check signing progress. Each signer has their own status.

1curl https://api.agreements.ai/v1/envelopes/env_Qr8sT4kL \
2 -H "Authorization: Bearer sk_live_abc123"
💡
Instead of polling, set up a webhook to get notified instantly when signers complete.

Step 4: Download the Signed Document

Once the envelope status is completed, download the signed PDF with the certificate of completion embedded.

1curl https://api.agreements.ai/v1/envelopes/env_Qr8sT4kL/document \
2 -H "Authorization: Bearer sk_live_abc123" \
3 -o signed_consulting_agreement.pdf

Guide: Using Templates

Templates let you create reusable document blueprints with merge fields. Generate personalized documents by filling in variables, then send them for signing.

Step 1: Browse Available Templates

1curl https://api.agreements.ai/v1/templates \
2 -H "Authorization: Bearer sk_live_abc123"
jsonResponse
1{
2 "data": [
3 {
4 "id": "tpl_NdA9Kx",
5 "title": "Non-Disclosure Agreement",
6 "category": "Business",
7 "variables": ["party_a_name", "party_b_name", "effective_date", "duration_months"],
8 "createdAt": "2026-01-15T08:00:00Z"
9 },
10 {
11 "id": "tpl_Srv3Mx",
12 "title": "Service Agreement",
13 "category": "Services",
14 "variables": ["client_name", "provider_name", "scope", "hourly_rate", "start_date"],
15 "createdAt": "2026-01-20T12:00:00Z"
16 }
17 ],
18 "total": 374,
19 "page": 1,
20 "pageSize": 20
21}

Step 2: Create a Document from a Template

Pass variable values to generate a fully populated document.

1curl -X POST https://api.agreements.ai/v1/templates/tpl_NdA9Kx/use \
2 -H "Authorization: Bearer sk_live_abc123" \
3 -H "Content-Type: application/json" \
4 -d '{
5 "variables": {
6 "party_a_name": "Acme Corporation",
7 "party_b_name": "Jane Smith",
8 "effective_date": "February 12, 2026",
9 "duration_months": "24"
10 }
11 }'
jsonResponse
1{
2 "id": "doc_Pm4nR7",
3 "title": "Non-Disclosure Agreement",
4 "templateId": "tpl_NdA9Kx",
5 "createdAt": "2026-02-12T10:05:00Z",
6 "status": "draft"
7}

Step 3: Send for Signing

Use the returned document ID to create an envelope, exactly as shown in the First Document guide.

1curl -X POST https://api.agreements.ai/v1/envelopes \
2 -H "Authorization: Bearer sk_live_abc123" \
3 -H "Content-Type: application/json" \
4 -d '{
5 "documentId": "doc_Pm4nR7",
6 "name": "NDA — Jane Smith",
7 "signers": [
8 { "name": "Jane Smith", "email": "[email protected]", "role": "signer" }
9 ],
10 "fields": [
11 { "type": "signature", "signerEmail": "[email protected]", "page": 1, "x": 72, "y": 700, "width": 200, "height": 50 }
12 ]
13 }'

Guide: Setting Up Webhooks

Webhooks let your application react to signing events in real time — no polling required. You provide a URL, we send HTTP POST requests when events occur.

Step 1: Create a Webhook

1curl -X POST https://api.agreements.ai/v1/webhooks \
2 -H "Authorization: Bearer sk_live_abc123" \
3 -H "Content-Type: application/json" \
4 -d '{
5 "url": "https://your-app.com/webhooks/agreements",
6 "events": [
7 "envelope.sent",
8 "envelope.completed",
9 "envelope.voided",
10 "envelope.declined",
11 "signer.completed",
12 "signer.declined"
13 ],
14 "secret": "whsec_your_webhook_secret_key"
15 }'
jsonResponse
1{
2 "id": "wh_Kj9mN2",
3 "url": "https://your-app.com/webhooks/agreements",
4 "events": ["envelope.sent", "envelope.completed", "envelope.voided", "envelope.declined", "signer.completed", "signer.declined"],
5 "active": true,
6 "createdAt": "2026-02-12T10:10:00Z"
7}

Step 2: Handle Events

Your endpoint receives POST requests with a JSON body. Respond with 200 within 30 seconds to acknowledge receipt.

1const express = require('express');
2const crypto = require('crypto');
3const app = express();
4
5app.use('/webhooks/agreements', express.raw({ type: 'application/json' }));
6
7app.post('/webhooks/agreements', (req, res) => {
8 // 1. Verify signature
9 const signature = req.headers['x-agreements-signature'];
10 const expected = crypto
11 .createHmac('sha256', process.env.WEBHOOK_SECRET)
12 .update(req.body)
13 .digest('hex');
14
15 if (!crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected))) {
16 return res.status(401).send('Invalid signature');
17 }
18
19 // 2. Parse and handle event
20 const event = JSON.parse(req.body);
21
22 switch (event.event) {
23 case 'envelope.completed':
24 console.log(`Envelope ${event.data.envelopeId} completed!`);
25 // Update your database, notify your team, trigger next steps...
26 break;
27
28 case 'signer.completed':
29 console.log(`${event.data.signerName} signed envelope ${event.data.envelopeId}`);
30 break;
31
32 case 'envelope.declined':
33 console.log(`Envelope ${event.data.envelopeId} declined: ${event.data.reason}`);
34 // Alert sales team, follow up...
35 break;
36 }
37
38 res.status(200).json({ received: true });
39});
40
41app.listen(3000);

Step 3: Verify HMAC Signatures

Every webhook delivery includes a X-Agreements-Signature header containing an HMAC-SHA256 hex digest. Always verify this before processing the payload.

1const crypto = require('crypto');
2
3function verifyWebhookSignature(rawBody, signature, secret) {
4 const expected = crypto
5 .createHmac('sha256', secret)
6 .update(rawBody)
7 .digest('hex');
8
9 return crypto.timingSafeEqual(
10 Buffer.from(signature, 'utf8'),
11 Buffer.from(expected, 'utf8')
12 );
13}
14
15// Usage:
16const isValid = verifyWebhookSignature(req.body, req.headers['x-agreements-signature'], process.env.WEBHOOK_SECRET);
17if (!isValid) return res.status(401).send('Invalid signature');
⚠️

Security: Always verify signatures

Never process a webhook payload without verifying the HMAC signature. Use constant-time comparison (timingSafeEqual / compare_digest) to prevent timing attacks.

Retry Behavior & Best Practices

  • Retries: Failed deliveries (non-2xx response or timeout) are retried up to 5 times with exponential backoff: 1 min, 5 min, 30 min, 2 hours, 24 hours.
  • Timeout: Your endpoint must respond within 30 seconds or the delivery is marked as failed.
  • Idempotency: Each delivery includes a unique X-Delivery-Id header. Store processed IDs to handle duplicate deliveries.
  • Order: Events are delivered in approximately chronological order but are not guaranteed. Design your handler to be order-independent.
  • Respond fast: Return 200 immediately, then process asynchronously. Don't do heavy work in the request handler.

Guide: Managing Recipients

Update Signers on a Live Envelope

Correct a signer's email or add new recipients after sending. Only pending signers can be modified — completed signatures are protected.

1curl -X PUT https://api.agreements.ai/v1/envelopes/env_Qr8sT4kL/recipients \
2 -H "Authorization: Bearer sk_live_abc123" \
3 -H "Content-Type: application/json" \
4 -d '{
5 "signers": [
6 {
7 "id": "sig_A1b2C3",
8 "name": "Jane Smith-Williams",
9 "email": "[email protected]"
10 },
11 {
12 "name": "Carol Davis",
13 "email": "[email protected]",
14 "role": "cc"
15 }
16 ]
17 }'

Send Reminders

Nudge pending signers with a reminder email. Rate-limited to 5 per minute.

1curl -X POST https://api.agreements.ai/v1/envelopes/env_Qr8sT4kL/remind \
2 -H "Authorization: Bearer sk_live_abc123" \
3 -H "Content-Type: application/json" \
4 -d '{
5 "message": "Friendly reminder: this agreement is awaiting your signature.",
6 "signerIds": ["sig_D4e5F6"]
7 }'
jsonResponse
1{
2 "reminded": ["sig_D4e5F6"],
3 "skipped": [],
4 "message": "Reminder sent to 1 signer"
5}

Void and Resend

If you need to make changes to the document itself, void the envelope and create a new one.

1# Void the existing envelope
2curl -X POST https://api.agreements.ai/v1/envelopes/env_Qr8sT4kL/void \
3 -H "Authorization: Bearer sk_live_abc123" \
4 -H "Content-Type: application/json" \
5 -d '{ "reason": "Document updated with revised payment terms" }'
6
7# Create a new envelope with the updated document
8curl -X POST https://api.agreements.ai/v1/envelopes \
9 -H "Authorization: Bearer sk_live_abc123" \
10 -H "Content-Type: application/json" \
11 -d '{ "documentId": "doc_Updated1", "name": "Revised Agreement", ... }'

Guide: Migrating from DocuSign

If you're moving from DocuSign's eSignature API, this guide maps concepts and endpoints to help you migrate quickly.

Concept Mapping

DocuSignAgreements.aiNotes
EnvelopeEnvelopeSame concept — a signing transaction
TabFieldsignHereTab → signature field, dateSignedTab → date field
RecipientSignerSame roles: signer, CC, witness
TemplateTemplateSame concept, simpler API
Connect (Webhooks)WebhooksSimpler setup, HMAC verification included
PowerFormPowerFormSelf-service signing links
Account / UserAccountSimplified — one level, no sub-accounts

API Endpoint Mapping

DocuSign EndpointAgreements.ai Equivalent
POST /envelopesPOST /v1/envelopes
GET /envelopes/{id}GET /v1/envelopes/:id
PUT /envelopes/{id}/recipientsPUT /v1/envelopes/:id/recipients
GET /envelopes/{id}/documents/{docId}GET /v1/envelopes/:id/document
PUT /envelopes/{id} (void)POST /v1/envelopes/:id/void
POST /envelopes/{id}/recipients/{id}/tabsIncluded in envelope creation body
GET /templatesGET /v1/templates
POST /templates/{id}/createEnvelopePOST /v1/templates/:id/use + POST /v1/envelopes
POST /connect/configurationsPOST /v1/webhooks

Key Differences

  • No OAuth dance — Use simple API keys instead of OAuth 2.0 JWT grants
  • Flat API structure — No account/user nesting; all endpoints are top-level
  • Fields in envelope body — No separate tab placement calls; fields are included when creating the envelope
  • Simpler webhooks — One POST to register, HMAC verification built in, no Connect configuration XML
  • Documents as a first-class resource — Create and manage documents independently, then attach to envelopes
  • Embedded signing supported — Use the Embed SDK to embed signing in your own app via iframe

Migration Checklist

  • ☐ Create an Agreements.ai account and generate an API key
  • ☐ Replace OAuth token logic with API key header
  • ☐ Map DocuSign envelope creation to Agreements.ai format (tabs → fields)
  • ☐ Update recipient management calls
  • ☐ Replace DocuSign Connect with Agreements.ai webhooks
  • ☐ Update status checking logic (DocuSign statuses map 1:1)
  • ☐ Update document download endpoints
  • ☐ Test end-to-end in sandbox before switching production
  • ☐ Update error handling for new error format
  • ☐ Monitor webhook deliveries for 48 hours after migration

Guide: Embedded Signing

Embed the Agreements.ai signing experience directly inside your application using an iframe. Your users never leave your app.

How It Works

1

Generate an Embed URL

From your backend, call POST /v2/signing/embed with the document ID and signer email. This returns a short-lived, single-use URL.

2

Embed the iframe

Pass the URL to your frontend and render it in an iframe -- either directly or using the Agreements.ai Embed SDK for convenience.

3

Handle events

Listen for postMessage events from the iframe to know when signing is ready, completed, declined, or errored.

Generate Embed URL

Requires authentication (API key or Firebase token).

POST /v2/signing/embed
// Request
{
  "documentId": "abc123",
  "signerEmail": "[email protected]",
  "returnUrl": "https://yourapp.com/done",  // optional
  "expiresInMinutes": 30                     // optional, max 60
}

// Response
{
  "url": "https://agreements.ai/sign/abc123?embedToken=...&embed=1",
  "embedToken": "...",
  "expiresAt": "2025-01-15T12:30:00.000Z"
}

Using the Embed SDK

Include the lightweight SDK (~2KB) on your page for easy integration.

<script src="https://agreements.ai/sdk/embed.js"></script>
<div id="sign-here"></div>

<script>
const signing = AgreementsAI.embed({
  url: embedUrl,             // from POST /v2/signing/embed
  container: '#sign-here',   // CSS selector or DOM element
  width: '100%',
  height: '700px',
  onReady: ({ documentId }) => {
    console.log('Signing view loaded');
  },
  onCompleted: ({ documentId, signerEmail }) => {
    console.log('Document signed by', signerEmail);
  },
  onDeclined: ({ documentId, signerEmail }) => {
    console.log('Signing declined');
  },
  onError: ({ documentId, message }) => {
    console.error('Signing error:', message);
  },
});

// To remove the iframe:
// signing.close();
</script>

Direct iframe (without SDK)

<iframe
  src="https://agreements.ai/sign/DOC_ID?embedToken=TOKEN&embed=1"
  width="100%"
  height="700"
  style="border: none; border-radius: 8px;"
  title="Sign Document"
></iframe>

<script>
window.addEventListener('message', (event) => {
  if (!event.data?.event?.startsWith('agreements:signing:')) return;
  console.log(event.data.event, event.data);
});
</script>

Events Reference

EventDataDescription
agreements:signing:readydocumentIdSigning view has loaded and is ready
agreements:signing:completeddocumentId, signerEmailSigner has successfully signed
agreements:signing:declineddocumentId, signerEmailSigner declined to sign
agreements:signing:errordocumentId, messageAn error occurred during signing

Security Considerations

  • Embed tokens are single-use and expire after 30 minutes (configurable up to 60 minutes)
  • Tokens are validated server-side before the signing view loads
  • Generate embed URLs from your backend only -- never expose your API key to the browser
  • The embed token is separate from the standard signing token system
  • Use returnUrl to redirect users back to your application after signing

API Reference: Envelopes

Envelopes are the core signing resource. Create, send, track, and manage signing transactions.

API Reference: Documents

Documents contain the actual contract content. Create them from HTML, upload files, or generate from templates.

API Reference: Templates

Reusable document blueprints with merge variables.

API Reference: Webhooks

Register endpoints to receive real-time notifications for signing events.

API Reference: Account

Webhook Events Reference

All events delivered to your webhook endpoint. Each delivery includes headers: X-Agreements-Signature, X-Delivery-Id, X-Event-Type.

envelope.sent

Triggered when an envelope is sent to signers.

jsonPayload
1{ "event": "envelope.sent", "timestamp": "2026-02-12T10:00:01Z", "data": { "envelopeId": "env_Qr8sT4kL", "name": "Service Agreement", "status": "sent", "signerCount": 2 } }
envelope.completed

Triggered when all signers have signed and the envelope is finalized.

jsonPayload
1{ "event": "envelope.completed", "timestamp": "2026-02-12T14:30:00Z", "data": { "envelopeId": "env_Qr8sT4kL", "name": "Service Agreement", "status": "completed", "documentHash": "sha256:a1b2c3d4e5f6..." } }
envelope.voided

Triggered when the sender voids an envelope.

jsonPayload
1{ "event": "envelope.voided", "timestamp": "2026-02-12T11:00:00Z", "data": { "envelopeId": "env_Qr8sT4kL", "status": "voided", "voidReason": "Document updated with revised terms" } }
envelope.declined

Triggered when a signer declines to sign.

jsonPayload
1{ "event": "envelope.declined", "timestamp": "2026-02-12T12:00:00Z", "data": { "envelopeId": "env_Qr8sT4kL", "status": "declined", "declinedBy": { "name": "Jane Smith", "email": "[email protected]" }, "reason": "Payment terms not acceptable" } }
signer.completed

Triggered when an individual signer completes all their assigned fields.

jsonPayload
1{ "event": "signer.completed", "timestamp": "2026-02-12T13:15:00Z", "data": { "envelopeId": "env_Qr8sT4kL", "signerId": "sig_A1b2C3", "signerName": "Jane Smith", "signerEmail": "[email protected]", "remainingSigners": 1 } }
signer.declined

Triggered when an individual signer declines to sign.

jsonPayload
1{ "event": "signer.declined", "timestamp": "2026-02-12T12:00:00Z", "data": { "envelopeId": "env_Qr8sT4kL", "signerId": "sig_A1b2C3", "signerName": "Jane Smith", "reason": "Payment terms not acceptable" } }

Error Reference

Error Response Format

All errors return a consistent JSON structure:

1{ "error": "Human-readable error message", "code": "MACHINE_READABLE_CODE" }

HTTP Status Codes

StatusMeaningWhen
200OKSuccessful GET, PUT, or DELETE request
201CreatedSuccessful POST that creates a resource
400Bad RequestMissing required fields, invalid values
401UnauthorizedMissing or invalid API key
403ForbiddenInsufficient permissions
404Not FoundResource does not exist
409ConflictAction conflicts with current state
413Payload Too LargeFile upload exceeds 25MB
429Too Many RequestsRate limit exceeded
500Internal Server ErrorUnexpected server error

Error Codes

CodeHTTPDescription
AUTH_INVALID_KEY401API key is invalid, revoked, or malformed
AUTH_EXPIRED_TOKEN401Firebase JWT token has expired
RATE_LIMIT_EXCEEDED429Too many requests — wait and retry
VALIDATION_ERROR400Request body failed validation
RESOURCE_NOT_FOUND404Resource does not exist
ENVELOPE_NOT_DRAFT409Envelope is not in draft status
ENVELOPE_ALREADY_COMPLETED409Cannot void or modify a completed envelope
DOCUMENT_IN_USE409Document attached to an active envelope
TEMPLATE_MISSING_VARIABLES400Required template variables not provided
FILE_TOO_LARGE413File exceeds 25MB limit
INTERNAL_ERROR500Unexpected error — contact support

SDKs & Libraries

🚧 Official SDKs Coming Soon

We're building official client libraries for Node.js, Python, Ruby, and Go. In the meantime, the REST API works with any HTTP client.

🟢

Node.js / TypeScript

In development

🐍

Python

In development

💎

Ruby

Planned

🔵

Go

Planned

MCP (AI Agents)

Model Context Protocol (MCP)

The Model Context Protocol (MCP) lets AI assistants — like Claude, ChatGPT, and Cursor — interact with Agreements.ai directly. Create documents, analyze contracts, send for signing, and manage negotiations through natural language.

MCPServerCreate DocAnalyzeSignTemplatesNegotiateCRMWebhooksSearch

How It Works

MCP is an open standard that connects AI assistants to external tools. Agreements.ai exposes 36 tools via a single endpoint using Streamable HTTP transport (JSON-RPC 2.0).

Endpoint: POST https://api.agreements.ai/v2/mcp

Authentication: Same Authorization: Bearer sk_... header as REST API

Transport: Streamable HTTP (JSON-RPC 2.0)

💡

When to use MCP vs REST API

Use MCP when integrating with AI assistants (Claude Desktop, Cursor, etc.). Use the REST API for programmatic server-to-server integrations. Both use the same API key.

Connection Setup

Claude Desktop

Add this to your Claude Desktop config file:

jsonClaude Desktop Configuration
1{
2 "mcpServers": {
3 "agreements": {
4 "command": "npx",
5 "args": [
6 "mcp-remote",
7 "https://api.agreements.ai/v2/mcp",
8 "--header",
9 "Authorization: Bearer sk_live_your_api_key_here"
10 ]
11 }
12 }
13}

Cursor IDE

In Cursor Settings → MCP, add a new server with the same configuration as above.

Raw JSON-RPC Examples

1curl -X POST https://api.agreements.ai/v2/mcp \
2 -H "Authorization: Bearer sk_live_your_key" \
3 -H "Content-Type: application/json" \
4 -d '{ "jsonrpc": "2.0", "id": 1, "method": "initialize", "params": { "protocolVersion": "2025-01-01", "capabilities": {}, "clientInfo": { "name": "my-app", "version": "1.0.0" } } }'

Document Tools

AI Tools

Signing Tools

Negotiation Tools

MCP: Templates & Bundles

MCP: Account & Config

Ready to get started?

Create your free account and send your first document for signing in minutes.

Enterprise-grade security. Your contracts are encrypted at rest and in transit.

SOC 2 Type IIGDPR256-bit EncryptionESIGN / UETACCPA

© 2026 Agreements.ai. All rights reserved.