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
Sign up
Verify your email
Complete your profile
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
Click "New Document"
Choose "Blank Document"
Write your content
Save
Upload an Existing Document
Click "New Document" → "Upload"
Select your file
PDF tip
From a Template
Browse templates
Pick a template
Fill in the details
Review and customize
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
Open the signing panel
Add signers
Place signing fields
Add a message (optional)
Send
Tracking
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
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:
Open a document
Click "Save as Signing Template"
Define roles and fields
Save
Negotiations
Negotiate contracts collaboratively with counterparties in real time. Propose changes, counter-offer, and chat — all within the platform.
How Negotiations Work
Create a negotiation
Invite parties
Propose changes
Accept, reject, or counter
Chat in context
Generate final contract
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.
Create a bundle
Add documents
Batch operations
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
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.
Choose contract type
Add details
Generate
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:
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
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.
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
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_hereComplete Example: Create → Send → Check Status
1# 1. Create a document2curl -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": 5033 },34 {35 "type": "signature",36 "signerEmail": "[email protected]",37 "page": 1,38 "x": 100,39 "y": 600,40 "width": 200,41 "height": 5042 },43 {44 "type": "date",45 "signerEmail": "[email protected]",46 "page": 1,47 "x": 320,48 "y": 520,49 "width": 100,50 "height": 2051 }52 ]53 }'54 55# Response: { "id": "env_Qr8sT4kL", "status": "sent", ... }56 57# 3. Check status58curl https://api.agreements.ai/v1/envelopes/env_Qr8sT4kL \59 -H "Authorization: Bearer sk_live_abc123"60 61# 4. Download completed document62curl https://api.agreements.ai/v1/envelopes/env_Qr8sT4kL/document \63 -H "Authorization: Bearer sk_live_abc123" \64 -o signed_agreement.pdfAuthentication
API Keys vs Firebase Tokens
Agreements.ai supports two authentication methods:
| Method | Format | Use Case |
|---|---|---|
| sk_live_... | API Key | Server-to-server integrations, scripts, backend automation |
| eyJhbG... | Firebase JWT | Frontend/mobile apps using Firebase Auth (short-lived) |
Both use the same header: Authorization: Bearer <token>
Creating and Managing Keys
- Go to Settings → Developers
- Click Create API Key
- Give it a descriptive name (e.g., "CRM Integration", "CI/CD Pipeline")
- 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.
| Operation | Limit | Window | Endpoints |
|---|---|---|---|
| Reads | 30 requests | Per minute | All GET endpoints |
| Writes | 10 requests | Per minute | POST, PUT, PATCH, DELETE |
| Reminders | 5 requests | Per minute | POST /envelopes/:id/remind |
Rate limit headers are included in every response: X-RateLimit-Remaining, X-RateLimit-Reset
Auth Error Responses
1{2 "error": "Invalid or expired API key",3 "code": "AUTH_INVALID_KEY"4}1{2 "error": "Rate limit exceeded. Try again in 45 seconds.",3 "code": "RATE_LIMIT_EXCEEDED",4 "retryAfter": 455}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:
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 }'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": 114 },15 {16 "name": "Bob Johnson",17 "email": "[email protected]",18 "role": "signer",19 "order": 220 }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": 3031 }32 }'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"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.pdfGuide: 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"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": 2021}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 }'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 }'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 signature9 const signature = req.headers['x-agreements-signature'];10 const expected = crypto11 .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 event20 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 = crypto5 .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
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-Idheader. 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
200immediately, 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 }'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 envelope2curl -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 document8curl -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
| DocuSign | Agreements.ai | Notes |
|---|---|---|
| Envelope | Envelope | Same concept — a signing transaction |
| Tab | Field | signHereTab → signature field, dateSignedTab → date field |
| Recipient | Signer | Same roles: signer, CC, witness |
| Template | Template | Same concept, simpler API |
| Connect (Webhooks) | Webhooks | Simpler setup, HMAC verification included |
| PowerForm | PowerForm | Self-service signing links |
| Account / User | Account | Simplified — one level, no sub-accounts |
API Endpoint Mapping
| DocuSign Endpoint | Agreements.ai Equivalent |
|---|---|
| POST /envelopes | POST /v1/envelopes |
| GET /envelopes/{id} | GET /v1/envelopes/:id |
| PUT /envelopes/{id}/recipients | PUT /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}/tabs | Included in envelope creation body |
| GET /templates | GET /v1/templates |
| POST /templates/{id}/createEnvelope | POST /v1/templates/:id/use + POST /v1/envelopes |
| POST /connect/configurations | POST /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
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.
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.
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).
/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
| Event | Data | Description |
|---|---|---|
| agreements:signing:ready | documentId | Signing view has loaded and is ready |
| agreements:signing:completed | documentId, signerEmail | Signer has successfully signed |
| agreements:signing:declined | documentId, signerEmail | Signer declined to sign |
| agreements:signing:error | documentId, message | An 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
returnUrlto 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.sentTriggered when an envelope is sent to signers.
1{ "event": "envelope.sent", "timestamp": "2026-02-12T10:00:01Z", "data": { "envelopeId": "env_Qr8sT4kL", "name": "Service Agreement", "status": "sent", "signerCount": 2 } }envelope.completedTriggered when all signers have signed and the envelope is finalized.
1{ "event": "envelope.completed", "timestamp": "2026-02-12T14:30:00Z", "data": { "envelopeId": "env_Qr8sT4kL", "name": "Service Agreement", "status": "completed", "documentHash": "sha256:a1b2c3d4e5f6..." } }envelope.voidedTriggered when the sender voids an envelope.
1{ "event": "envelope.voided", "timestamp": "2026-02-12T11:00:00Z", "data": { "envelopeId": "env_Qr8sT4kL", "status": "voided", "voidReason": "Document updated with revised terms" } }envelope.declinedTriggered when a signer declines to sign.
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.completedTriggered when an individual signer completes all their assigned fields.
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.declinedTriggered when an individual signer declines to sign.
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
| Status | Meaning | When |
|---|---|---|
| 200 | OK | Successful GET, PUT, or DELETE request |
| 201 | Created | Successful POST that creates a resource |
| 400 | Bad Request | Missing required fields, invalid values |
| 401 | Unauthorized | Missing or invalid API key |
| 403 | Forbidden | Insufficient permissions |
| 404 | Not Found | Resource does not exist |
| 409 | Conflict | Action conflicts with current state |
| 413 | Payload Too Large | File upload exceeds 25MB |
| 429 | Too Many Requests | Rate limit exceeded |
| 500 | Internal Server Error | Unexpected server error |
Error Codes
| Code | HTTP | Description |
|---|---|---|
| AUTH_INVALID_KEY | 401 | API key is invalid, revoked, or malformed |
| AUTH_EXPIRED_TOKEN | 401 | Firebase JWT token has expired |
| RATE_LIMIT_EXCEEDED | 429 | Too many requests — wait and retry |
| VALIDATION_ERROR | 400 | Request body failed validation |
| RESOURCE_NOT_FOUND | 404 | Resource does not exist |
| ENVELOPE_NOT_DRAFT | 409 | Envelope is not in draft status |
| ENVELOPE_ALREADY_COMPLETED | 409 | Cannot void or modify a completed envelope |
| DOCUMENT_IN_USE | 409 | Document attached to an active envelope |
| TEMPLATE_MISSING_VARIABLES | 400 | Required template variables not provided |
| FILE_TOO_LARGE | 413 | File exceeds 25MB limit |
| INTERNAL_ERROR | 500 | Unexpected 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
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.
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
Connection Setup
Claude Desktop
Add this to your Claude Desktop config file:
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.