DEVELOPER DOCS

Webhooks API

Receive real-time HTTP notifications when signing events occur in your Agreements.ai account. Automate your workflows by integrating with your existing systems.

Getting Started

  1. 1. Go to Settings → Webhooks
  2. 2. Enter your HTTPS endpoint URL
  3. 3. Select the events you want to receive
  4. 4. Copy your signing secret for signature verification
  5. 5. Click "Test Webhook" to verify your endpoint

Payload Format

All webhook payloads follow this structure:

POST https://your-server.com/webhook
{
  "event": "signing.completed",
  "timestamp": "2026-02-10T12:00:00Z",
  "data": {
    "documentId": "abc123",
    "documentTitle": "Employment Agreement",
    "signers": [
      {
        "name": "John Doe",
        "email": "john@example.com",
        "status": "signed",
        "signedAt": "2026-02-10T12:00:00Z"
      }
    ],
    "completedAt": "2026-02-10T12:00:00Z"
  }
}

Headers

Content-Type: application/json
X-Agreements-Event: signing.completed
X-Agreements-Signature: a1b2c3d4...

Events Reference

EventDescription
signing.sentTriggered when a document is sent for signing.
signing.completedTriggered when all signers have completed signing.
signing.voidedTriggered when the sender voids a signing request.
signing.declinedTriggered when a signer declines to sign.
signing.openedTriggered when a signer opens the signing link.
signing.reminder_sentTriggered when a reminder email is sent to a signer.

Verifying Signatures

Every webhook request includes an X-Agreements-Signature header containing an HMAC-SHA256 hex digest of the request body, signed with your secret key. Always verify this signature to ensure the request is authentic.

JavaScript (Node.js)
const crypto = require('crypto');

function verifyWebhook(body, signature, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(body)
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}

// Express.js example
app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
  const signature = req.headers['x-agreements-signature'];
  if (!verifyWebhook(req.body, signature, process.env.WEBHOOK_SECRET)) {
    return res.status(401).send('Invalid signature');
  }
  const event = JSON.parse(req.body);
  // Handle event...
  res.status(200).send('OK');
});
Python
import hmac
import hashlib

def verify_webhook(body: bytes, signature: str, secret: str) -> bool:
    expected = hmac.new(
        secret.encode(),
        body,
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(signature, expected)

# Flask example
@app.route('/webhook', methods=['POST'])
def webhook():
    signature = request.headers.get('X-Agreements-Signature')
    if not verify_webhook(request.data, signature, WEBHOOK_SECRET):
        return 'Invalid signature', 401
    event = request.json
    # Handle event...
    return 'OK', 200
REST API

REST API

Programmatically create and manage signing envelopes. Authenticate with an API key from Settings → API Keys.

Authentication

Include your API key in the Authorization header:

Header
Authorization: Bearer sk_your_api_key_here

Endpoints

POST/api/v1/envelopes— Create & send envelope
{
  "documentId": "abc123",
  "signers": [
    { "id": "signer-1", "label": "Tenant", "name": "John Doe", "email": "john@example.com" },
    { "id": "signer-2", "label": "Any Approver", "name": "Jane", "email": "jane@example.com",
      "group": "approvers", "groupLabel": "Any Approver" }
  ],
  "fields": [
    { "id": "field-1", "type": "signature", "signerId": "signer-1", "label": "Tenant Signature" }
  ],
  "options": {
    "signingOrder": "parallel",
    "message": "Please sign this lease",
    "expiresAt": "2026-03-01T00:00:00Z"
  }
}
GET/api/v1/envelopes— List envelopes

Query params: ?status=pending&limit=20

GET/api/v1/envelopes/:id— Get envelope details
DELETE/api/v1/envelopes/:id— Void envelope

Example: Create Envelope

cURL
curl -X POST https://www.agreements.ai/api/v1/envelopes \
  -H "Authorization: Bearer sk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "documentId": "abc123",
    "signers": [{ "id": "s1", "label": "Client", "name": "John", "email": "john@example.com" }],
    "fields": [{ "id": "f1", "type": "signature", "signerId": "s1", "label": "Signature" }]
  }'

Best Practices

  • Respond quickly. Return a 2xx status within 10 seconds. Process events asynchronously.
  • Verify signatures. Always validate the HMAC signature before processing.
  • Handle duplicates. Use the event timestamp and document ID for idempotency.
  • Use HTTPS only. Webhook URLs must use HTTPS for security.

© 2026 Agreements.ai. All rights reserved.