# Agree.com Agreements API

**Canonical:** https://apis.io/apis/agree-com/agree-com-agreements-api/  
**Provider:** Agree.com — https://apis.io/providers/agree-com/  
**Base URL:** https://secure.agree.com/api/v1  
**Documentation:** https://secure.agree.com/documentation

Agree.com Agreements API is one of 6 APIs that [Agree.com](https://apis.io/providers/agree-com/) publishes on the [APIs.io](https://apis.io/) network, described by a machine-readable OpenAPI specification and an AsyncAPI event-driven specification. Tagged areas include Agreements. The published artifact set on APIs.io includes an OpenAPI specification, API documentation, an API reference, a getting-started guide, authentication docs, and an AsyncAPI specification.

Create, send, and manage agreements with recipients and field assignments. ## Overview Agreements are documents that require signatures from one or more recipients. Each agreement is created from a template and can have specific fields (like signature fields, date fields, text fields) assigned to specific recipients. **Key concepts:** - Agreements are created from templates - Each agreement must have exactly one recipient with the `owner` role (the account holder) - Fields can be assigned to specific recipients via `assigned_fields` - Agreements can include invoices for payment collection - Recipients can be specified by `contact_id` or by providing contact details inline ## Creating an Agreement ### Basic Agreement Creation Here's a basic example of creating an agreement from a template: ```bash curl -X POST https://api.agree.com/api/v1/agreements \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "template_id": "550e8400-e29b-41d4-a716-446655440000", "name": "Service Agreement", "recipients": [ { "contact_id": "770e8400-e29b-41d4-a716-446655440000", "role": "owner" }, { "contact_id": "880e8400-e29b-41d4-a716-446655440000", "role": "signer" } ] }' ``` ### The Owner Role Requirement **Important:** When creating an agreement, exactly one recipient must be assigned the `owner` role. This recipient must be the account holder (the person whose API key is being used). The owner is the person initiating the agreement creation. **Common mistake:** If you assign yourself as a `signer` instead of `owner`, the request will fail with a validation error. **Correct approach:** ```json { "recipients": [ { "contact_id": "YOUR_CONTACT_ID", "role": "owner" }, { "contact_id": "CLIENT_CONTACT_ID", "role": "signer" } ] } ``` **Incorrect approach (will fail):** ```json { "recipients": [ { "contact_id": "YOUR_CONTACT_ID", "role": "signer" // ❌ Wrong - must be "owner" } ] } ``` ### Finding Your Contact ID The account holder (you) is also a contact in your organization. To find your own Contact ID: ```bash curl https://api.agree.com/api/v1/contacts \ -H "Authorization: Bearer YOUR_API_KEY" ``` This returns a list of all contacts in your organization, including yourself. Look for the contact with your email address - that's your Contact ID. You can also filter by email: ```bash curl "https://api.agree.com/api/v1/contacts?email=your-email@example.com" \ -H "Authorization: Bearer YOUR_API_KEY" ``` **Response:** ```json { "data": [ { "id": "770e8400-e29b-41d4-a716-446655440000", "name": "Your Name", "email": "your-email@example.com", "company": "Your Company", ... } ], "pagination": { "page": 1, "page_size": 10, "total_pages": 1, "total_entries": 1 } } ``` Use the `id` field from the contact that matches your email address as your `contact_id` when creating agreements. ### Assigning Fields to Recipients When creating an agreement, you can assign specific fields to specific recipients. Fields are identified by their field IDs (as defined in the template). **Example: Assigning Fields** ```bash curl -X POST https://api.agree.com/api/v1/agreements \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "template_id": "550e8400-e29b-41d4-a716-446655440000", "name": "Service Agreement", "recipients": [ { "contact_id": "770e8400-e29b-41d4-a716-446655440000", "role": "owner", "assigned_fields": ["company_address", "date"] }, { "contact_id": "880e8400-e29b-41d4-a716-446655440000", "role": "signer", "assigned_fields": ["signature_field", "date_field"] } ] }' ``` In this example: - The owner is assigned `company_address` and `date` fields - The signer is assigned `signature_field` and `date_field` fields **Field Assignment Rules:** - Field IDs must match exactly as defined in the template - Fields not assigned to any recipient will be assigned to the owner by default - You can assign multiple fields to the same recipient - The same field cannot be assigned to multiple recipients **Complete Example with All Options:** ```bash curl -X POST https://api.agree.com/api/v1/agreements \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "template_id": "550e8400-e29b-41d4-a716-446655440000", "name": "Service Agreement with Invoice", "delivery_mode": "managed", "field_values": { "field_1": "John Doe", "field_2": "2024-01-01" }, "recipients": [ { "contact_id": "770e8400-e29b-41d4-a716-446655440000", "role": "owner", "assigned_fields": ["company_address", "date"] }, { "contact": { "email": "client@example.com", "name": "Jane Smith", "company": "Client Corp" }, "role": "signer", "assigned_fields": ["signature_field", "date_field"] } ], "signing_order_enabled": false, "payments_enabled": true, "reminder_schedule": "weekly", "invoice": { "billing_contact": { "email": "client@example.com", "name": "Jane Smith" }, "amount": 15000, "currency": "USD", "memo": "Payment for services", "payment_methods": ["card", "ach"], "payment_terms_type": "net", "payment_terms_days": 30 } }' ``` ## Daisy-Chaining: Attaching an Invoice to an Agreement There are two ways to attach an invoice to an agreement: ### Option 1: Create Agreement with Invoice (Single Request) The simplest approach is to include the invoice in the agreement creation request: ```bash curl -X POST https://api.agree.com/api/v1/agreements \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "template_id": "550e8400-e29b-41d4-a716-446655440000", "name": "Service Agreement with Invoice", "recipients": [ { "contact_id": "YOUR_CONTACT_ID", "role": "owner" }, { "contact_id": "CLIENT_CONTACT_ID", "role": "signer" } ], "invoice": { "billing_contact": { "email": "client@example.com", "name": "Jane Smith" }, "amount": 15000, "currency": "USD", "memo": "Payment for services rendered", "payment_methods": ["card", "ach"], "payment_terms_type": "net", "payment_terms_days": 30 } }' ``` This creates both the agreement and an associated invoice template in a single API call. The invoice template is linked to the agreement via the `invoice_template_id` field. ### Option 2: Two-Step Process (Create Agreement, Then Create Invoice) If you need more control or want to create the invoice separately: **Step 1: Create the Agreement** ```bash curl -X POST https://api.agree.com/api/v1/agreements \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "template_id": "550e8400-e29b-41d4-a716-446655440000", "name": "Service Agreement", "recipients": [ { "contact_id": "YOUR_CONTACT_ID", "role": "owner" }, { "contact_id": "CLIENT_CONTACT_ID", "role": "signer" } ] }' ``` **Response includes agreement ID:** ```json { "data": { "id": "990e8400-e29b-41d4-a716-446655440000", ... } } ``` **Step 2: Create Invoice and Link to Agreement** ```bash curl -X POST https://api.agree.com/api/v1/invoices \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "invoice": { "agreement_id": "990e8400-e29b-41d4-a716-446655440000", "billing_contact": { "email": "client@example.com", "name": "Jane Smith" }, "amount": 15000, "currency": "USD", "memo": "Payment for services rendered", "payment_methods": ["card", "ach"], "payment_terms_type": "net", "payment_terms_days": 30 } }' ``` **When to use each approach:** - **Option 1 (single request):** Use when you want to create the agreement and invoice together atomically. This is simpler and ensures the invoice is always linked to the agreement. - **Option 2 (two-step):** Use when you need to: - Create the agreement first and review it before adding the invoice - Create multiple invoices for the same agreement - Have more control over the invoice creation timing - Handle errors separately for agreement vs invoice creation ## Recipient Roles | Role | Description | |------|-------------| | `owner` | The account holder initiating the agreement. Exactly one recipient must have this role. | | `signer` | A recipient who needs to sign the agreement | | `viewer` | A recipient who can view but not sign the agreement | | `payee` | A recipient who will receive payment (used with invoices) | ## Field Values (Prefilling) You can prefill field values when creating an agreement: ```json { "template_id": "550e8400-e29b-41d4-a716-446655440000", "name": "Service Agreement", "field_values": { "field_1": "John Doe", "field_2": "2024-01-01", "company_name": "Acme Corp" }, "recipients": [...] } ``` Keys in `field_values` must match **`field_id`** values from your template. Fetch the template to list `field_names` (non-variable fields) and `variables` (each variable’s `field_id` and display `name`): ```bash curl https://api.agree.com/api/v1/agreements/templates/550e8400-e29b-41d4-a716-446655440000 \ -H "Authorization: Bearer YOUR_API_KEY" ``` The response includes a `field_names` array listing all available fields in the template, plus a `variables` array for template variables (see below). Use each field’s **`field_id`** as the key in `field_values` (for variables, use the `field_id` from the `variables` entry, not the display `name`). ### Typed values and rich text Each entry in `field_values` can be either: 1. **A string** (legacy): plain text. Works for any field or variable. 2. **An object** with a `content` string and optional `content_type`: ```json { "content": "<strong>Renewal</strong> 2026-05-01", "content_type": "html" } ``` - `content` (required): the payload. - `content_type` (optional): `plaintext`, `html`, or `markdown`. If omitted, **`plaintext`** is used. **Rich text applies only to template variables.** If the `field_values` key matches a **variable** `field_id` (from `GET /api/v1/agreements/templates/:id` → `data.variables`), then `content_type` **`html`** or **`markdown`** is converted into styled inline content in the agreement body (bold, italics, line breaks, HTML lists, markdown list lines with `-` / `*`, etc.). For **all non-variable fields** (text, date, signature, checkbox, and every other fillable field), typed objects are accepted, but **only the plain-text form** is stored on the field—**formatting is not preserved**. Use plain strings for those unless you only need a simple string payload. Invalid typed objects (for example missing `content` or an invalid `content_type`) return **400 Bad Request** with an error referencing `field_values`. ## Custom Variables (Template Variables) Templates can contain **custom variables** — placeholder fields for dynamic content like names, dates, or amounts. Variables remain as live fields in the agreement until it is sent, at which point they are resolved into plain text. Variable values can be provided at creation time via `field_values`, or filled in later through the editor UI. **All variables must have values before the agreement can be sent.** **Rich text:** Only keys that correspond to **variables** (see `variables[].field_id`) honor `content_type` of `html` or `markdown` and keep formatting in the document. Other fields always receive plain text only—see [Typed values and rich text](#typed-values-and-rich-text). ### Step 1: Discover Template Variables Fetch the template to see its variables: ```bash curl https://api.agree.com/api/v1/agreements/templates/TEMPLATE_ID \ -H "Authorization: Bearer YOUR_API_KEY" ``` **Response:** ```json { "data": { "id": "550e8400-e29b-41d4-a716-446655440000", "name": "Employment Agreement", "field_names": ["signature_field", "date_field"], "variables": [ { "name": "Employee Name", "field_id": "var_abc123" }, { "name": "Start Date", "field_id": "var_def456" }, { "name": "Salary", "field_id": "var_ghi789" } ] } } ``` The `variables` array lists each custom variable with its `name` (display label) and `field_id` (the key to use in `field_values`). ### Step 2: Provide Variable Values (Optional at Creation) When creating the agreement, you can pre-fill variable values via `field_values`. Any variables not provided will remain as unfilled live fields in the agreement. ```bash curl -X POST https://api.agree.com/api/v1/agreements \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "template_id": "550e8400-e29b-41d4-a716-446655440000", "name": "Employment Agreement - Jane Smith", "field_values": { "var_abc123": "Jane Smith", "var_def456": "2025-03-01", "var_ghi789": "$120,000" }, "recipients": [ { "contact_id": "YOUR_CONTACT_ID", "role": "owner" }, { "contact": { "email": "jane@example.com", "name": "Jane Smith" }, "role": "signer", "assigned_fields": ["signature_field", "date_field"] } ] }' ``` When the agreement is sent, variable values are resolved into plain text — recipients will see "Jane Smith" rather than a placeholder (rich variable content is flattened at send time). ### Rich text examples (variables only) Plain string (unchanged): ```json "var_abc123": "Jane Smith" ``` HTML (lists, emphasis, etc.): ```json "var_schedule": { "content_type": "html", "content": "<ul><li>Payment 1 on 2026-03-17</li><li>Payment 2 on 2026-04-17</li></ul>" } ``` Markdown (line breaks, `-` / `*` list lines, `**bold**`, `*italic*`, `_italic_`): ```json "var_schedule": { "content_type": "markdown", "content": "- **First** payment on 2026-03-17\n- Second payment on 2026-04-17" } ``` Default to plaintext when `content_type` is omitted: ```json "var_note": { "content": "Shown as plain text only" } ``` ### Error Handling If you attempt to send an agreement with unfilled variables, the API returns a `400 Bad Request`: ```json { "error": "Unfilled variables: Employee Name, Start Date. All variables must have values before sending." } ``` ## Listing Agreements Retrieve agreements with optional filtering: ```bash # Get all agreements curl https://api.agree.com/api/v1/agreements \ -H "Authorization: Bearer YOUR_API_KEY" # Filter by status curl "https://api.agree.com/api/v1/agreements?status=drafted" \ -H "Authorization: Bearer YOUR_API_KEY" ``` ### Query Parameters | Parameter | Type | Description | |-----------|------|-------------| | `page` | integer | Page number (default: 1) | | `page_size` | integer | Items per page (default: 10, max: 100) | | `status` | string | Filter by status: `created`, `drafted`, `sent`, `signed`, `executed`, `terminated` | ## Sending an Agreement After creating an agreement, send it to recipients: ```bash curl -X POST https://api.agree.com/api/v1/agreements/990e8400-e29b-41d4-a716-446655440000/send \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "delivery_mode": "managed" }' ``` **Delivery Modes:** - `managed` - Agree sends emails to recipients automatically - `embedded` - Emails are suppressed (you handle delivery yourself) ## Create and Send in One Step For convenience, create and send an agreement in a single request: ```bash curl -X POST https://api.agree.com/api/v1/agreements/create_and_send \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "template_id": "550e8400-e29b-41d4-a716-446655440000", "name": "Service Agreement", "delivery_mode": "managed", "recipients": [ { "contact_id": "YOUR_CONTACT_ID", "role": "owner" }, { "contact_id": "CLIENT_CONTACT_ID", "role": "signer" } ] }' ``` ## Updating an Agreement Update agreement details and recipients. You can include `field_values` inside `agreement` the same way as on create; **rich text (`html` / `markdown`) still applies only to template variables**—see [Typed values and rich text](#typed-values-and-rich-text). ```bash curl -X PUT https://api.agree.com/api/v1/agreements/990e8400-e29b-41d4-a716-446655440000 \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "agreement": { "name": "Updated Service Agreement", "recipients": [ { "contact_id": "YOUR_CONTACT_ID", "role": "owner", "assigned_fields": ["company_address"] }, { "contact_id": "CLIENT_CONTACT_ID", "role": "signer", "assigned_fields": ["signature_field"] } ] } }' ``` **Note:** Updating recipients replaces all existing recipients. Make sure to include all recipients you want to keep. ## Agreement Statuses | Status | Description | |--------|-------------| | `created` | Agreement created but not yet finalized | | `drafted` | Agreement is in draft state (default when created) | | `sent` | Agreement has been sent to recipients | | `viewed` | At least one recipient has viewed the agreement | | `signed` | At least one recipient has signed | | `executed` | Agreement is fully executed (all required signatures collected) | | `renewed` | Agreement has been renewed | | `terminated` | Agreement has been terminated | ## Fields Reference ### Core Fields | Field | Type | Description | |-------|------|-------------| | `id` | UUID | Unique agreement identifier | | `name` | string | Agreement name | | `status` | string | Current status (see statuses above) | | `template_id` | UUID | Template used to create this agreement | | `organization_id` | UUID | Your organization's ID | | `invoice_template_id` | UUID | Associated invoice template (if invoice was created) | ### Recipient Fields | Field | Type | Description | |-------|------|-------------| | `recipients` | array | List of recipients with their roles and assigned fields | | `signing_order` | array | List of recipient IDs in signing order (if enabled) | | `signing_order_enabled` | boolean | Whether signing order is enforced | ### Delivery Fields | Field | Type | Description | |-------|------|-------------| | `delivery_mode` | string | `embedded` or `managed` | | `reminder_schedule` | string | `none`, `daily`, `weekly`, or `monthly` | | `reminder_scheduled_at` | datetime | When the next reminder will be sent | ### Date Fields | Field | Type | Description | |-------|------|-------------| | `starts_at` | datetime | When the agreement starts | | `ends_at` | datetime | When the agreement ends | | `executed_at` | datetime | When the agreement was fully executed | | `last_reminder_sent_at` | datetime | When the last reminder was sent |

## Operations (11)

| Method | Path | Summary |
|---|---|---|
| GET | `/api/v1/agreements/{id}/pdf` | Download agreement PDF |
| POST | `/api/v1/agreements/{id}/send` | Send agreement |
| POST | `/api/v1/agreements/create_and_send` | Create and send agreement |
| GET | `/api/v1/agreements/templates` | List agreement templates |
| GET | `/api/v1/agreements` | List agreements |
| POST | `/api/v1/agreements` | Create agreement from template |
| GET | `/api/v1/agreements/templates/{id}` | Get template |
| DELETE | `/api/v1/agreements/{id}` | Delete agreement |
| GET | `/api/v1/agreements/{id}` | Get agreement |
| PATCH | `/api/v1/agreements/{id}` | Update agreement |
| PUT | `/api/v1/agreements/{id}` | Update agreement |

## Machine-readable artifacts (12)

- **OpenAPI** — https://raw.githubusercontent.com/api-evangelist/agree-com/refs/heads/main/openapi/agree-com-agreements-api-openapi.yml
- **Documentation** — https://secure.agree.com/documentation
- **APIReference** — https://secure.agree.com/documentation
- **GettingStarted** — https://secure.agree.com/documentation#section/Introduction/Quick-Start
- **Authentication** — https://secure.agree.com/documentation#section/Introduction/Authentication
- **ErrorCatalog** — https://raw.githubusercontent.com/api-evangelist/agree-com/refs/heads/main/errors/agree-com-problem-types.yml
- **DataModel** — https://raw.githubusercontent.com/api-evangelist/agree-com/refs/heads/main/data-model/agree-com-data-model.yml
- **Conventions** — https://raw.githubusercontent.com/api-evangelist/agree-com/refs/heads/main/conventions/agree-com-conventions.yml
- **AsyncAPI** — https://raw.githubusercontent.com/api-evangelist/agree-com/refs/heads/main/asyncapi/agree-com-webhooks-asyncapi.yml
- **Webhooks** — https://raw.githubusercontent.com/api-evangelist/agree-com/refs/heads/main/asyncapi/agree-com-webhooks-asyncapi.yml
- **ToolCrosswalk** — https://raw.githubusercontent.com/api-evangelist/agree-com/refs/heads/main/mcp/agree-com-tool-crosswalk.yml
- **APIsJSON** — https://raw.githubusercontent.com/api-evangelist/agree-com/refs/heads/main/apis.yml

## Other Agree.com APIs (5)

- [Agree.com Contacts API](https://apis.io/apis/agree-com/agree-com-contacts-api/)
- [Agree.com Customers API](https://apis.io/apis/agree-com/agree-com-customers-api/)
- [Agree.com Invoices API](https://apis.io/apis/agree-com/agree-com-invoices-api/)
- [Agree.com Reports API](https://apis.io/apis/agree-com/agree-com-reports-api/)
- [Agree.com Webhooks API](https://apis.io/apis/agree-com/agree-com-webhooks-api/)

## Tags

Agreements

---

Profiled by [API Evangelist](https://apievangelist.com) and published on [APIs.io](https://apis.io/apis/agree-com/agree-com-agreements-api/). The API's provider profile, Kin Score and agent-readiness rating are at https://apis.io/providers/agree-com/.
