# Custom Templates

Custom templates let you define your own agreement Cover Page as a YAML document. The YAML describes the sections and fields of your agreement, and Common Paper renders it as a fillable form, a web agreement, a PDF, and a Word export. Custom templates must be enabled for your organization; the endpoints below return 404 otherwise.

## Working with custom templates via the API

| Endpoint | What it does |
| --- | --- |
| `GET /v1/custom_templates` | List your organization's custom templates. |
| `POST /v1/custom_templates` | Create a template from a YAML definition. |
| `GET /v1/custom_templates/{id}` | Get one template, including its current YAML as `current_definition`. |
| `POST /v1/custom_templates/{id}/versions` | Publish a new version from a YAML definition. |
| `PATCH /v1/custom_templates/{id}` | Rename a template. |
| `DELETE /v1/custom_templates/{id}` | Archive a template. |

Creating a template and publishing a version both take a `definition` (the YAML) and a `user_email` or `user_id` identifying the user in your organization to record as the creator.

```bash
curl -X POST "https://api.commonpaper.com/v1/custom_templates" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Consulting Agreement",
    "user_email": "you@example.com",
    "definition": "title: Consulting Agreement\nsections:\n  - heading: Payment\n    fields:\n      payment_terms:\n        label: Payment terms\n        input: text\n        default: Net 30\n"
  }'
```

Every publish creates a new version and makes it current immediately. Agreements pin the version they were created from, so publishing never changes an agreement that is already in flight.

### Creating agreements from a custom template

Pass the custom template's UUID as `template_id` to `POST /v1/agreements`, and put field values in `agreement.custom_field_values`, keyed by the field keys in the YAML definition. Template defaults fill any fields you omit. A required field with no default and no submitted value returns a 400 naming the field.

```bash
curl -X POST "https://api.commonpaper.com/v1/agreements" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "template_id": "CUSTOM_TEMPLATE_UUID",
    "owner_email": "you@example.com",
    "signer_email": "you@example.com",
    "agreement": {
      "recipient_name": "Art Vandelay",
      "recipient_email": "art@example.com",
      "custom_field_values": {
        "payment_terms": "Net 45",
        "start_date": "2026-01-01"
      }
    }
  }'
```

Fields with a mapping value, like `address` and `rate` inputs, take an object using the same component keys as their YAML defaults. Set `draft` to `true` to save without sending, the same as any other agreement.

## Custom terms

Custom terms are the standard terms that follow the Cover Page. A template's terms are attached to it in the Common Paper app and carry over to agreements created through the API, but the terms themselves can be managed via the API:

| Endpoint | What it does |
| --- | --- |
| `GET /v1/custom_terms` | List your organization's custom terms. Ids and metadata only; the terms text is omitted because it can be very large. |
| `GET /v1/custom_terms/{id}` | Get one term, including the full terms text of its released version as `body`. |
| `POST /v1/custom_terms` | Create text terms. The markdown `body` is published as released version 1. |
| `POST /v1/custom_terms/{id}/versions` | Publish a new version. The new body immediately becomes the released version; existing versions are immutable. |
| `PATCH /v1/custom_terms/{id}` | Rename terms. Only the name changes here; content changes go through publishing a version. |

Creating terms and publishing versions take a `user_email` or `user_id` identifying the user in your organization to record as the creator. Only text terms can be created or versioned through the API; file type terms (uploaded Word documents) are managed in the Common Paper app.

```bash
curl -s -X POST "https://api.commonpaper.com/v1/custom_terms" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Acme Standard Terms",
    "user_email": "you@example.com",
    "body": "## 1. Services\n\nProvider will make the services available to Customer..."
  }' | jq
```

## The basic shape

A template has a title and a list of sections. Each section groups related fields.

```yaml
title: Consulting Agreement
sections:
  - heading: Services
    fields:
      services_description:
        label: Description of services
        input: textarea
  - heading: Payment
    fields:
      payment_terms:
        label: Payment terms
        input: text
        default: Net 30
```

Field keys (like `services_description`) are internal identifiers. They must start with a lowercase letter and contain only lowercase letters, numbers, and underscores. Each key must be unique across the whole template. These keys are also the keys you use in `custom_field_values` when creating agreements.

## Top-level settings

All of these are optional except title.

| Key | What it does |
| --- | --- |
| `title` | The display name of the agreement, shown as the heading on the agreement, PDF, and Word export. Required. |
| `terms_label` | Renames the "Cover Page" heading. Use this when your agreement calls its terms something else, like Key Terms, Order Form, or Statement of Work. In the Word export it also appears uppercased in the page header. |
| `terms_sublabel` | Smaller text under the terms label in the Word export, such as "The key legal terms of this Agreement are as follows:". |
| `info_box` | Explanatory text shown in a highlighted box above the Cover Page, like the framework explanation on Common Paper standard agreements. |
| `terms_heading` | A heading row rendered at the top of the terms table, such as "Key Terms". |
| `terms_subheading` | Smaller text under the terms heading. |
| `signing_disclaimer` | The sentence above the signature blocks. Defaults to "By signing this Cover Page, each party agrees to enter into the Agreement." |
| `footer` | Text shown at the bottom of every page in PDF and Word exports. Write `{terms_version}` anywhere in the text to insert the current custom terms version number, for example `Acme Terms Version {terms_version}`. Defaults to the custom terms name and version number. |
| `parties` | Renames the two parties. Takes `sender:` and `recipient:` keys, for example Vendor and Client. Defaults are Provider and Customer. |

Example:

```yaml
title: Independent Contractor Agreement
terms_label: Framework Terms
info_box: The Framework Terms have 2 parts...
signing_disclaimer: By signing below, both parties accept these Framework Terms.
parties:
  sender: Company
  recipient: Contractor
sections:
  ...
```

## Sections

Each entry in `sections:` is one row of the Cover Page, with the heading on the left and its fields on the right.

| Key | What it does |
| --- | --- |
| `heading` | The section name shown on the left. |
| `subheading` | Smaller text under the heading. |
| `required: true` | The section always appears on the agreement and cannot be excluded by the sender. |
| `included: false` | The section is excluded by default. Senders can include it per agreement with a checkbox when creating the agreement. |
| `header` | Makes the section a full-width header row instead of a fields row. Use it to divide the Cover Page, for example "Additions and Modifications". A header section has no fields. |
| `import` | Pulls in a ready-made section. See Imports below. |
| `access` | Who can edit the section's fields. See Access levels below. |

```yaml
sections:
  - heading: Optional rider
    subheading: Only applies to enterprise deals
    included: false
    fields:
      rider_details:
        label: Rider details
        input: textarea
  - header: Additions and Modifications
```

## Fields

Fields live in a `fields:` mapping inside a section. The mapping key is the field key; everything else is configuration.

| Key | What it does |
| --- | --- |
| `label` | The name shown above the input and next to the value on the agreement. |
| `input` | The input type. See the table below. Required. |
| `instructions` | Guidance shown only on the form while filling it in. It does not appear on the finished agreement. |
| `placeholder` | Placeholder text inside the empty input. |
| `required: true` | The field always appears on the agreement, and a value must be entered before the agreement can be sent. |
| `default` | Prefills the field. Senders can change it when creating an agreement. |
| `options` | The choices for radio, select, multiselect, and rate inputs. |
| `currency` | The currency code for currency and rate inputs. Defaults to USD. |
| `access` | Who can edit the field. Overrides the section's `access`. See Access levels below. |

Fields without a value are left off the finished agreement, unless they are required or fixed.

## Access levels

By default only organization admins can edit field values when creating an agreement. Add `access` to a field or a whole section to open it up:

| Value | Who can edit |
| --- | --- |
| `admin` | Organization admins only. This is the default. |
| `standard` | Standard members and admins. |
| `recipient` | The agreement recipient, plus standard members and admins. |

A field-level `access` overrides its section's. Locked fields show read-only on the form and keep their template defaults.

Recipients are a special case. While negotiation is enabled they can propose changes to any field as before. `access: recipient` fields also appear as inputs directly on the recipient's view of the agreement so they can fill them in alongside the signature block. Marking one of these fields `required: true` means the recipient must fill it in before signing; it does not block the sender from sending.

```yaml
sections:
  - heading: Fees
    access: standard
    fields:
      fee:
        label: Monthly fee
        input: currency
      po_number:
        label: PO number
        input: text
        access: recipient
```

## Input types

| Input | Renders as |
| --- | --- |
| `text` | Single-line text box |
| `textarea` | Multi-line text box |
| `markdown` | Multi-line text box with formatting (bold, lists, links) preserved on the agreement |
| `number` | Number input |
| `currency` | Money input with a currency symbol. Set `currency: EUR` to change from USD. |
| `rate` | A money amount plus a per-unit select, shown on one line like "$500.00 per hour". `options` lists the units (hour, day, week). Defaults and submitted values use a mapping with `amount:` and `per:` keys. |
| `date` | Date picker |
| `email` | Email input |
| `radio` | One choice from `options`, all visible |
| `select` | One choice from `options`, in a dropdown |
| `multiselect` | Multiple choices from `options`, shown as checkboxes |
| `states` | Dropdown of US states |
| `address` | A full address block (country, street, city, state, ZIP). Defaults and submitted values use a mapping with those component keys. |
| `attachment` | Pick a PDF from your organization's attachment library. The file is referenced on the agreement and appended to the PDF. |
| `fixed` | Uneditable text set by `default`. Always appears on the agreement. Use it for standard language that senders should not change. The text renders as markdown. For multi-line markdown like bullet lists or tables, write the default as a block scalar (`default: |` with the text indented below), because plain and quoted YAML values fold line breaks into spaces. |

Rate example:

```yaml
fee:
  label: Rate
  input: rate
  options:
    - hour
    - day
  default:
    amount: 500
    per: hour
```

Address example:

```yaml
contractor_address:
  label: Contractor address
  input: address
  default:
    country: USA
    city: New York
    state: New York
```

## Imports

Imports drop in a ready-made section with one line. Today there is one import available:

```yaml
sections:
  - import: governing_law
```

This renders a Governing Law & Chosen Courts section backed by the same pickers Common Paper standard agreements use. To preset answers, add a `defaults:` mapping, and to limit the pickers to specific jurisdictions, add `options:`:

```yaml
sections:
  - import: governing_law
    options:
      - New York
      - Delaware
      - California
    defaults:
      governing_law_region: Delaware
      chosen_courts_region: Delaware
```

The state pickers list US states, and `options` restricts them to a subset. Organizations allowed to use additional courts get the same country selector as standard agreements: pick a country and the region control adapts (US states, Canadian provinces, or a free-text region elsewhere).

## Versions

Every publish creates a new version and makes it current immediately. Agreements pin the version they were created from, so they always render exactly what the signer saw. The version history is also available in the template editor in the Common Paper app, where the YAML can be edited alongside a live form preview.
