# DocJacket API — v1 reference

> Generated from the live OpenAPI document at [/openapi.json](https://api.docjacket.com/openapi.json). That specification is the canonical source of truth; this page is a rendering of it for readers and tools that do not execute JavaScript.

- **Base URL:** `https://api.docjacket.com`
- **Interactive reference:** https://api.docjacket.com/reference
- **OpenAPI JSON:** https://api.docjacket.com/openapi.json
- **OpenAPI YAML:** https://api.docjacket.com/openapi.yaml
- **Integration guide:** https://api.docjacket.com/integration-guide.md
- **Guides:** https://help.docjacket.com/docs/api

## Overview

The DocJacket integration API. One `/api/v1` surface, capability-scoped by credential:

- **Org API key** (`mcp_at_…`) — acts within a single organization. Mint one in DocJacket under **Settings → Advanced → API Keys**. Key scopes: `read` (GETs), `draft` (low-risk writes like completing a task), `actions` (side-effect writes like sending email).
- **Reseller API key** (`rsk_…`) — cross-tenant provisioning for white-label partners.

Send the key as a bearer token: `Authorization: Bearer <key>`.

Errors use one envelope: `{ "error": { "code", "message", "fields"? } }`. Cross-tenant lookups return `404` (never disclosing existence).

**Rate limits.** Per key, per minute, in a fixed window: **300 reads** (GET) and **60 writes** (POST/PUT/PATCH/DELETE). Exceeding a bucket returns `429` with a `Retry-After: 60` header and the standard error envelope (`code: "rate_limited"`); retry after the window resets.

**Versioning & deprecation.** The API is **additive by default** — new fields and operations may appear at any time, so clients **must ignore unknown response fields** and not depend on property order. Changes that would break an existing client (removing/renaming a field, tightening a type, changing an error contract) ship only as a **new major version** at a new path (`/api/v2`); `/api/v1` is not broken in place. When a version is deprecated it remains available for at least **6 months** after the successor ships, and the retirement is announced in the release notes. Idempotency-Key is honored on side-effecting writes so retries are safe.

Start with `GET /api/v1/health` (verifies your key), then `GET /api/v1/catalog` (lists every operation and whether your key can call it) and `GET /api/v1/usage` (your key's call volume, top operations, and error rate). The same key also works with AI agents via the DocJacket MCP server at `https://mcp.docjacket.com/mcp`.

**Prefer reading over clicking?** Every operation is also listed on one statically rendered page — no JavaScript required, crawlable and quotable — at [help.docjacket.com/docs/api/reference](https://help.docjacket.com/docs/api/reference), alongside guides for [authentication, requests, webhooks, and the partner tier](https://help.docjacket.com/docs/api). The machine-readable spec is at [api.docjacket.com/openapi.json](https://api.docjacket.com/openapi.json).

## Authentication

Every operation requires a bearer token: `Authorization: Bearer <key>`.

### OAuth2

OAuth 2.1 access token — `Authorization: Bearer <access token>`

Reaches the same operations as an organization API key, with the same `read` / `draft` / `actions` scopes. Use it when your application acts for many users: register once, then each user authorizes their own DocJacket account and you hold a token per user. The organization is carried in the token's `org_id` claim — key your storage on it.

Authorization code + PKCE (`S256` only). Public client: there is no client secret. Register dynamically (RFC 7591) at `/oauth/register`, and read the endpoints from `/.well-known/oauth-authorization-server` rather than hardcoding them.

Access tokens last 1 hour; refresh tokens last 90 days and **rotate on every use**. Presenting an already-used refresh token is treated as a replay and revokes every live token for that user and client — store the new one before using it, and never retry a failed refresh with the old one. Membership is re-read on every call, so a user removed from the organization loses access immediately rather than at token expiry: treat `401` as "reconnect this account", not as a transient error.

### OrgApiKey

Organization API key — `Authorization: Bearer mcp_at_…`

Mint one in DocJacket under **Settings → Advanced → API Keys**. The key acts within a single organization and carries one or more scopes:

- `read` — GETs.
- `draft` — low-risk writes (completing a task, saving a status summary).
- `actions` — side-effecting writes (sending email, deleting, provisioning).

Each operation below notes the scope it requires. `GET /api/v1/catalog` returns the same list with a `callable` flag computed against *your* key. The identical key also connects AI assistants over MCP at `https://mcp.docjacket.com/mcp`.

### PartnerApiKey

White-label partner key — `Authorization: Bearer rsk_…`

Cross-tenant credential for resellers, accepted only on the `/api/v1/orgs/*` operations (the **Organizations (Partner)** section). Organization API keys (`mcp_at_…`) are rejected there, and a partner key is rejected everywhere else. Requests for an organization the key does not own return `404` rather than `403`, so ownership is never disclosed.

## Resource groups

- [Meta](#meta) — 4 operations
- [Transactions](#transactions) — 25 operations
- [Messaging](#messaging) — 17 operations
- [Key Dates](#key-dates) — 1 operation
- [Tasks](#tasks) — 8 operations
- [Documents](#documents) — 11 operations
- [Extractions](#extractions) — 3 operations
- [Contacts](#contacts) — 6 operations
- [Disclosure Packages](#disclosure-packages) — 7 operations
- [Proposals](#proposals) — 5 operations
- [Templates & Forms](#templates--forms) — 7 operations
- [Webhooks](#webhooks) — 9 operations
- [Organization](#organization) — 10 operations
- [Organizations (Partner)](#organizations-partner) — 7 operations

## Meta

Start here. Verify your key, discover the operations it can call, and see your own call volume.

### `GET` `/api/v1/catalog`

**List operations available to your API key**

**Requires the `read` scope.**

- **Operation ID:** `OrgCatalog`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `GET` `/api/v1/health`

**Check API key authentication and service health**

**Requires the `read` scope.**

- **Operation ID:** `OrgHealth`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `GET` `/api/v1/next-actions`

**Get the ranked next-actions feed (tasks + key dates)**

**Requires the `read` scope.**

- **Operation ID:** `GetNextActions`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Query parameters:**
  - `limit` — `string|integer` (int32) *(optional)*
  - `transactionId` — `uuid` *(optional)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `GET` `/api/v1/usage`

**Get call-volume, daily breakdown, top operations, and error rate for your API key**

**Requires the `read` scope.**

- **Operation ID:** `GetUsage`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Query parameters:**
  - `days` — `string|integer` (int32) *(optional)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

## Transactions

The transaction record itself — create, list, read, and update deals, and manage the checklists, contingencies, notes, and reminders attached to them.

### `GET` `/api/v1/transactions`

**List or search transactions**

**Requires the `read` scope.**

- **Operation ID:** `ListTransactions`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Query parameters:**
  - `page` — `string|integer` (int32) *(optional)*
  - `pageSize` — `string|integer` (int32) *(optional)*
  - `q` — `string` *(optional)*
  - `status` — `string` *(optional)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `POST` `/api/v1/transactions`

**Apply a completed extraction — create a new transaction, or attach to an existing one via transactionId**

**Requires the `actions` scope.**

- **Operation ID:** `ApplyExtraction`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Request body:** `application/json` — `ApplyExtractionRequest`
  - `extractionJobId` — `string` (uuid), nullable *(required)*
  - `overrides` — `JsonElement` *(optional)*
  - `side` — `string`, nullable *(optional)*
  - `transactionId` — `string`, nullable *(optional)*
  - `transactionType` — `string`, nullable *(optional)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `422`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `GET` `/api/v1/transactions/resolve`

**Resolve a property reference to ranked transaction matches**

**Requires the `read` scope.**

- **Operation ID:** `ResolveTransactionByProperty`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Query parameters:**
  - `limit` — `string|integer` (int32) *(optional)*
  - `property` — `string` *(optional)*
  - `status` — `string` *(optional)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `GET` `/api/v1/transactions/{transactionId}`

**Get a transaction by ID**

**Requires the `read` scope.**

- **Operation ID:** `GetTransaction`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `transactionId` — `string` (uuid) *(required)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `POST` `/api/v1/transactions/{transactionId}/activity`

**Log an activity on a transaction**

**Requires the `draft` scope.**

- **Operation ID:** `LogActivity`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `transactionId` — `string` (uuid) *(required)*
- **Request body:** `application/json` — `LogActivityRequest`
  - `details` — `string`, nullable *(optional)*
  - `summary` — `string` *(required)*
  - `type` — `string` *(required)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `422`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `GET` `/api/v1/transactions/{transactionId}/checklist`

**Get aggregate checklist status for a transaction**

**Requires the `read` scope.**

- **Operation ID:** `GetChecklistStatus`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `transactionId` — `string` (uuid) *(required)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `POST` `/api/v1/transactions/{transactionId}/checklist`

**Apply a checklist template to a transaction**

**Requires the `draft` scope.**

- **Operation ID:** `ApplyChecklist`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `transactionId` — `string` (uuid) *(required)*
- **Request body:** `application/json` — `ApplyChecklistRequest`
  - `replaceExisting` — `boolean`, nullable *(optional)*
  - `scope` — `string`, nullable *(optional)*
  - `templateId` — `string` (uuid) *(required)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `422`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `POST` `/api/v1/transactions/{transactionId}/contacts`

**Link an existing contact to a transaction with a role**

**Requires the `actions` scope.**

- **Operation ID:** `AddContactToTransaction`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `transactionId` — `string` (uuid) *(required)*
- **Request body:** `application/json` — `LinkContactRequest`
  - `contactId` — `string` (uuid), nullable *(optional)*
  - `isPrimary` — `boolean`, nullable *(optional)*
  - `role` — `string`, nullable *(optional)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `422`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `GET` `/api/v1/transactions/{transactionId}/contingencies`

**List open contingencies for a transaction**

**Requires the `read` scope.**

- **Operation ID:** `ListOpenContingencies`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `transactionId` — `string` (uuid) *(required)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `POST` `/api/v1/transactions/{transactionId}/documents/reorder`

**Set the order of a transaction's documents**

**Requires the `draft` scope.**

- **Operation ID:** `ReorderDocuments`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `transactionId` — `string` (uuid) *(required)*
- **Request body:** `application/json` — `ReorderDocumentsRequest`
  - `orderedDocumentIds` — `array`, nullable *(optional)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `422`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `POST` `/api/v1/transactions/{transactionId}/documents/{documentId}/share`

**Share a document to a party on a deal via secure SMS link**

**Requires the `actions` scope.**

- **Operation ID:** `ShareDocumentToParty`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `documentId` — `string` (uuid) *(required)*
  - `transactionId` — `string` (uuid) *(required)*
- **Headers:**
  - `Idempotency-Key` — `string` *(optional)* — Optional. Send a unique value (max 200 characters — a UUID is ideal) to make this call safe to retry. The first request executes and its response is stored; an identical retry replays that stored response verbatim with an `Idempotency-Replayed: true` header instead of performing the side effect again. Reusing a key for a *different* operation is rejected with `422`.
- **Request body:** `application/json` — `ShareToPartyRequest`
  - `contactId` — `string` (uuid), nullable *(optional)*
  - `expirationHours` — `integer` (int32), nullable *(optional)*
  - `message` — `string`, nullable *(optional)*
  - `toPhoneNumber` — `string`, nullable *(optional)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `409`, `422`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `GET` `/api/v1/transactions/{transactionId}/form-links`

**List form links sent on a transaction**

**Requires the `read` scope.**

- **Operation ID:** `ListFormLinks`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `transactionId` — `string` (uuid) *(required)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `GET` `/api/v1/transactions/{transactionId}/intake-status`

**Get the intake-progress snapshot for a transaction**

**Requires the `read` scope.**

- **Operation ID:** `GetIntakeStatus`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `transactionId` — `string` (uuid) *(required)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `GET` `/api/v1/transactions/{transactionId}/key-dates`

**List key dates for a transaction**

**Requires the `read` scope.**

- **Operation ID:** `GetKeyDates`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `transactionId` — `string` (uuid) *(required)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `POST` `/api/v1/transactions/{transactionId}/key-dates`

**Add key dates to a transaction (batch)**

**Requires the `draft` scope.**

- **Operation ID:** `AddKeyDates`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `transactionId` — `string` (uuid) *(required)*
- **Request body:** `application/json` — `AddKeyDatesRequest`
  - `keyDates` — `array` *(required)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `422`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `PATCH` `/api/v1/transactions/{transactionId}/key-dates/{keyDateType}`

**Update a key date on a transaction**

**Requires the `draft` scope.**

- **Operation ID:** `UpdateKeyDate`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `keyDateType` — `string` *(required)*
  - `transactionId` — `string` (uuid) *(required)*
- **Request body:** `application/json` — `UpdateKeyDateRequest`
  - `calculationNotes` — `string`, nullable *(optional)*
  - `newValue` — `string`, nullable *(optional)*
  - `source` — `string`, nullable *(optional)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `422`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `GET` `/api/v1/transactions/{transactionId}/merge-fields`

**Get all merge field values for a transaction**

**Requires the `read` scope.**

- **Operation ID:** `GetMergeFields`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `transactionId` — `string` (uuid) *(required)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `GET` `/api/v1/transactions/{transactionId}/missing-documents`

**List documents missing against the purchase baseline**

**Requires the `read` scope.**

- **Operation ID:** `GetMissingDocuments`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `transactionId` — `string` (uuid) *(required)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `PATCH` `/api/v1/transactions/{transactionId}/notes`

**Set or clear a transaction's general notes**

**Requires the `draft` scope.**

- **Operation ID:** `UpdateTransactionNotes`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `transactionId` — `string` (uuid) *(required)*
- **Request body:** `application/json` — `UpdateNotesRequest`
  - `notes` — `string`, nullable *(optional)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `422`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `GET` `/api/v1/transactions/{transactionId}/portal-link`

**Get the active client-portal link for a transaction**

**Requires the `read` scope.**

- **Operation ID:** `GetPortalLink`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `transactionId` — `string` (uuid) *(required)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `POST` `/api/v1/transactions/{transactionId}/reminders`

**Schedule a reminder on a transaction**

**Requires the `actions` scope.**

- **Operation ID:** `CreateReminder`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `transactionId` — `string` (uuid) *(required)*
- **Request body:** `application/json` — `CreateReminderRequest`
  - `daysBeforeReminder` — `integer` (int32), nullable *(optional)*
  - `deadlineDate` — `string` (date-time), nullable *(optional)*
  - `deadlineType` — `string`, nullable *(optional)*
  - `emailTemplateId` — `string` (uuid), nullable *(optional)*
  - `milestoneId` — `string` (uuid), nullable *(optional)*
  - `note` — `string`, nullable *(optional)*
  - `recipientEmails` — `string`, nullable *(optional)*
  - `recipientRoles` — `string`, nullable *(optional)*
  - `reminderTimeOfDay` — `string`, nullable *(optional)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `422`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `POST` `/api/v1/transactions/{transactionId}/render-template`

**Render an email template against a transaction (preview-only)**

**Requires the `read` scope.**

- **Operation ID:** `RenderEmailTemplate`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `transactionId` — `string` (uuid) *(required)*
- **Request body:** `application/json` — `RenderTemplateRequest`
  - `slug` — `string`, nullable *(optional)*
  - `templateId` — `string` (uuid), nullable *(optional)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `422`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `PATCH` `/api/v1/transactions/{transactionId}/status`

**Change a transaction's status (runs the same cascade as the web app)**

**Requires the `actions` scope.**

- **Operation ID:** `ChangeTransactionStatus`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `transactionId` — `string` (uuid) *(required)*
- **Request body:** `application/json` — `ChangeStatusRequest`
  - `status` — `string`, nullable *(optional)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `422`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `POST` `/api/v1/transactions/{transactionId}/status-summary`

**Save a status summary on a transaction**

**Requires the `draft` scope.**

- **Operation ID:** `SaveStatusSummary`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `transactionId` — `string` (uuid) *(required)*
- **Request body:** `application/json` — `StatusSummaryRequest`
  - `audience` — `string`, nullable *(optional)*
  - `bodyMarkdown` — `string`, nullable *(optional)*
  - `keyPointBullets` — `array`, nullable *(optional)*
  - `subject` — `string`, nullable *(optional)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `422`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `POST` `/api/v1/transactions/{transactionId}/tasks`

**Create a task on a transaction**

**Requires the `draft` scope.**

- **Operation ID:** `CreateTask`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `transactionId` — `string` (uuid) *(required)*
- **Request body:** `application/json` — `CreateTaskRequest`
  - `assigneeUserId` — `string` (uuid), nullable *(optional)*
  - `description` — `string`, nullable *(optional)*
  - `dueDate` — `string` (date-time), nullable *(optional)*
  - `linkedMilestoneName` — `string`, nullable *(optional)*
  - `priority` — `integer` (int32), nullable *(optional)*
  - `title` — `string`, nullable *(required)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `422`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

## Messaging

Email and messaging on a deal — send client updates and document requests, draft and schedule messages, and read the communication log.

### `GET` `/api/v1/conversations`

**List the organization's message threads**

**Requires the `read` scope.**

- **Operation ID:** `ListConversations`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Query parameters:**
  - `limit` — `string|integer` (int32) *(optional)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `POST` `/api/v1/conversations/{threadId}/documents`

**Share a document into an existing conversation via secure SMS link**

**Requires the `actions` scope.**

- **Operation ID:** `ShareDocumentToConversation`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `threadId` — `string` (uuid) *(required)*
- **Headers:**
  - `Idempotency-Key` — `string` *(optional)* — Optional. Send a unique value (max 200 characters — a UUID is ideal) to make this call safe to retry. The first request executes and its response is stored; an identical retry replays that stored response verbatim with an `Idempotency-Replayed: true` header instead of performing the side effect again. Reusing a key for a *different* operation is rejected with `422`.
- **Request body:** `application/json` — `ShareToThreadRequest`
  - `documentId` — `string` (uuid), nullable *(optional)*
  - `expirationHours` — `integer` (int32), nullable *(optional)*
  - `message` — `string`, nullable *(optional)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `409`, `422`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `GET` `/api/v1/conversations/{threadId}/messages`

**List messages in a conversation thread**

**Requires the `read` scope.**

- **Operation ID:** `ListConversationMessages`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `threadId` — `string` (uuid) *(required)*
- **Query parameters:**
  - `limit` — `string|integer` (int32) *(optional)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `POST` `/api/v1/conversations/{threadId}/messages`

**Reply with an SMS in an existing conversation thread**

**Requires the `actions` scope.**

- **Operation ID:** `SendConversationMessage`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `threadId` — `string` (uuid) *(required)*
- **Headers:**
  - `Idempotency-Key` — `string` *(optional)* — Optional. Send a unique value (max 200 characters — a UUID is ideal) to make this call safe to retry. The first request executes and its response is stored; an identical retry replays that stored response verbatim with an `Idempotency-Replayed: true` header instead of performing the side effect again. Reusing a key for a *different* operation is rejected with `422`.
- **Request body:** `application/json` — `ReplyMessageRequest`
  - `forceOverride` — `boolean` *(optional)*
  - `messageContent` — `string`, nullable *(optional)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `409`, `422`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `DELETE` `/api/v1/scheduled-messages/{messageId}`

**Cancel a pending scheduled message**

**Requires the `actions` scope.**

- **Operation ID:** `CancelScheduledMessage`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `messageId` — `string` (uuid) *(required)*
- **Headers:**
  - `Idempotency-Key` — `string` *(optional)* — Optional. Send a unique value (max 200 characters — a UUID is ideal) to make this call safe to retry. The first request executes and its response is stored; an identical retry replays that stored response verbatim with an `Idempotency-Replayed: true` header instead of performing the side effect again. Reusing a key for a *different* operation is rejected with `422`.
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `409`, `422`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `GET` `/api/v1/transactions/{transactionId}/communications`

**List every message for a transaction across channels (SMS + email + in-app)**

**Requires the `read` scope.**

- **Operation ID:** `ListCommunications`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `transactionId` — `string` (uuid) *(required)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `POST` `/api/v1/transactions/{transactionId}/conversations`

**Start a conversation by sending the first SMS on a deal**

**Requires the `actions` scope.**

- **Operation ID:** `StartConversation`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `transactionId` — `string` (uuid) *(required)*
- **Headers:**
  - `Idempotency-Key` — `string` *(optional)* — Optional. Send a unique value (max 200 characters — a UUID is ideal) to make this call safe to retry. The first request executes and its response is stored; an identical retry replays that stored response verbatim with an `Idempotency-Replayed: true` header instead of performing the side effect again. Reusing a key for a *different* operation is rejected with `422`.
- **Request body:** `application/json` — `StartConversationRequest`
  - `contactId` — `string`, nullable *(optional)*
  - `forceOverride` — `boolean` *(optional)*
  - `messageContent` — `string`, nullable *(optional)*
  - `toPhoneNumber` — `string`, nullable *(optional)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `409`, `422`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `POST` `/api/v1/transactions/{transactionId}/draft-message`

**Generate an AI message draft (never sends)**

**Requires the `draft` scope.**

- **Operation ID:** `DraftMessage`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `transactionId` — `string` (uuid) *(required)*
- **Request body:** `application/json` — `MessageDraftRequest`
  - `additionalContext` — `string`, nullable *(optional)*
  - `intent` — `string` *(required)*
  - `recipientName` — `string`, nullable *(optional)*
  - `recipientRole` — `string`, nullable *(optional)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `422`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `POST` `/api/v1/transactions/{transactionId}/emails/agent`

**Send an email to an agent on the deal**

**Requires the `actions` scope.**

- **Operation ID:** `SendEmailToAgent`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `transactionId` — `string` (uuid) *(required)*
- **Headers:**
  - `Idempotency-Key` — `string` *(optional)* — Optional. Send a unique value (max 200 characters — a UUID is ideal) to make this call safe to retry. The first request executes and its response is stored; an identical retry replays that stored response verbatim with an `Idempotency-Replayed: true` header instead of performing the side effect again. Reusing a key for a *different* operation is rejected with `422`.
- **Request body:** `application/json` — `AgentEmailRequest`
  - `bodyHtml` — `string`, nullable *(required)*
  - `bodyPlainText` — `string`, nullable *(optional)*
  - `intent` — `string`, nullable *(required)*
  - `recipientContactId` — `string` (uuid), nullable *(required)*
  - `recipientRole` — `string`, nullable *(required)*
  - `subject` — `string`, nullable *(required)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `409`, `422`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `POST` `/api/v1/transactions/{transactionId}/emails/agent-followup`

**Send a follow-up email to an agent or vendor**

**Requires the `actions` scope.**

- **Operation ID:** `SendAgentFollowupEmail`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `transactionId` — `string` (uuid) *(required)*
- **Headers:**
  - `Idempotency-Key` — `string` *(optional)* — Optional. Send a unique value (max 200 characters — a UUID is ideal) to make this call safe to retry. The first request executes and its response is stored; an identical retry replays that stored response verbatim with an `Idempotency-Replayed: true` header instead of performing the side effect again. Reusing a key for a *different* operation is rejected with `422`.
- **Request body:** `application/json` — `AgentFollowupEmailRequest`
  - `bodyHtml` — `string`, nullable *(required)*
  - `bodyPlainText` — `string`, nullable *(optional)*
  - `recipientContactId` — `string` (uuid), nullable *(required)*
  - `recipientRole` — `string`, nullable *(required)*
  - `sourceContextSummary` — `string`, nullable *(optional)*
  - `subject` — `string`, nullable *(required)*
  - `tone` — `string`, nullable *(optional)*
  - `topic` — `string`, nullable *(required)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `409`, `422`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `POST` `/api/v1/transactions/{transactionId}/emails/client-update`

**Send a status-update email to a deal party**

**Requires the `actions` scope.**

- **Operation ID:** `SendClientUpdateEmail`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `transactionId` — `string` (uuid) *(required)*
- **Headers:**
  - `Idempotency-Key` — `string` *(optional)* — Optional. Send a unique value (max 200 characters — a UUID is ideal) to make this call safe to retry. The first request executes and its response is stored; an identical retry replays that stored response verbatim with an `Idempotency-Replayed: true` header instead of performing the side effect again. Reusing a key for a *different* operation is rejected with `422`.
- **Request body:** `application/json` — `ClientUpdateEmailRequest`
  - `attachmentDocumentIds` — `array`, nullable *(optional)*
  - `audience` — `string`, nullable *(required)*
  - `bodyHtml` — `string`, nullable *(required)*
  - `bodyPlainText` — `string`, nullable *(optional)*
  - `focus` — `string`, nullable *(required)*
  - `recipientContactId` — `string` (uuid), nullable *(required)*
  - `subject` — `string`, nullable *(required)*
  - `tone` — `string`, nullable *(optional)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `409`, `422`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `POST` `/api/v1/transactions/{transactionId}/emails/document-request`

**Send a document-request email to a deal party**

**Requires the `actions` scope.**

- **Operation ID:** `SendDocumentRequestEmail`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `transactionId` — `string` (uuid) *(required)*
- **Headers:**
  - `Idempotency-Key` — `string` *(optional)* — Optional. Send a unique value (max 200 characters — a UUID is ideal) to make this call safe to retry. The first request executes and its response is stored; an identical retry replays that stored response verbatim with an `Idempotency-Replayed: true` header instead of performing the side effect again. Reusing a key for a *different* operation is rejected with `422`.
- **Request body:** `application/json` — `DocumentRequestEmailRequest`
  - `bodyHtml` — `string`, nullable *(required)*
  - `bodyPlainText` — `string`, nullable *(optional)*
  - `documentTypes` — `array`, nullable *(required)*
  - `recipientContactId` — `string` (uuid), nullable *(required)*
  - `recipientRole` — `string`, nullable *(required)*
  - `subject` — `string`, nullable *(required)*
  - `tone` — `string`, nullable *(optional)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `409`, `422`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `POST` `/api/v1/transactions/{transactionId}/messages`

**Send an email on a deal (appears in the merged thread as channel=email)**

**Requires the `actions` scope.**

- **Operation ID:** `SendMessage`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `transactionId` — `string` (uuid) *(required)*
- **Headers:**
  - `Idempotency-Key` — `string` *(optional)* — Optional. Send a unique value (max 200 characters — a UUID is ideal) to make this call safe to retry. The first request executes and its response is stored; an identical retry replays that stored response verbatim with an `Idempotency-Replayed: true` header instead of performing the side effect again. Reusing a key for a *different* operation is rejected with `422`.
- **Request body:** `application/json` — `SendEmailMessageRequest`
  - `bccAddresses` — `string`, nullable *(optional)*
  - `body` — `string`, nullable *(optional)*
  - `ccAddresses` — `string`, nullable *(optional)*
  - `fromAccountId` — `string`, nullable *(optional)*
  - `htmlBody` — `string`, nullable *(optional)*
  - `replyToMessageId` — `string`, nullable *(optional)*
  - `subject` — `string`, nullable *(optional)*
  - `templateId` — `string`, nullable *(optional)*
  - `toEmail` — `string`, nullable *(optional)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `409`, `422`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `GET` `/api/v1/transactions/{transactionId}/recipients`

**List a deal's participants with role and per-channel availability**

**Requires the `read` scope.**

- **Operation ID:** `ListRecipients`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `transactionId` — `string` (uuid) *(required)*
- **Query parameters:**
  - `channel` — `string` *(optional)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `GET` `/api/v1/transactions/{transactionId}/reports/communication-log`

**Export a transaction's communication log (email + SMS) as a PDF, ZIP (with documents), or JSON**

**Requires the `read` scope.**

- **Operation ID:** `ExportCommunicationLog`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `transactionId` — `string` (uuid) *(required)*
- **Query parameters:**
  - `format` — `string` *(optional)*
  - `from` — `date-time` *(optional)*
  - `to` — `date-time` *(optional)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `GET` `/api/v1/transactions/{transactionId}/scheduled-messages`

**List active scheduled messages on a deal**

**Requires the `read` scope.**

- **Operation ID:** `ListScheduledMessages`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `transactionId` — `string` (uuid) *(required)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `POST` `/api/v1/transactions/{transactionId}/scheduled-messages`

**Schedule an email to send later on a deal**

**Requires the `actions` scope.**

- **Operation ID:** `ScheduleMessage`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `transactionId` — `string` (uuid) *(required)*
- **Headers:**
  - `Idempotency-Key` — `string` *(optional)* — Optional. Send a unique value (max 200 characters — a UUID is ideal) to make this call safe to retry. The first request executes and its response is stored; an identical retry replays that stored response verbatim with an `Idempotency-Replayed: true` header instead of performing the side effect again. Reusing a key for a *different* operation is rejected with `422`.
- **Request body:** `application/json` — `ScheduleMessageRequest`
  - `attachments` — `array`, nullable *(optional)*
  - `bccAddresses` — `string`, nullable *(optional)*
  - `body` — `string`, nullable *(optional)*
  - `ccAddresses` — `string`, nullable *(optional)*
  - `documentFileNames` — `object`, nullable *(optional)*
  - `documentIds` — `array`, nullable *(optional)*
  - `fromAccountId` — `string`, nullable *(optional)*
  - `htmlBody` — `string`, nullable *(optional)*
  - `scheduledAt` — `string`, nullable *(optional)*
  - `scheduledTimezone` — `string`, nullable *(optional)*
  - `subject` — `string`, nullable *(optional)*
  - `toEmail` — `string`, nullable *(optional)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `409`, `422`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

## Key Dates

Deadlines across your book of business. Key dates for a single transaction live under Transactions.

### `GET` `/api/v1/key-dates/upcoming`

**List upcoming key dates across active transactions**

**Requires the `read` scope.**

- **Operation ID:** `UpcomingKeyDates`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Query parameters:**
  - `horizonDays` — `string|integer` (int32) *(optional)*
  - `limit` — `string|integer` (int32) *(optional)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

## Tasks

Task lists on a deal — create, list, comment on, complete, and delete tasks.

### `GET` `/api/v1/tasks`

**List open tasks**

**Requires the `read` scope.**

- **Operation ID:** `ListTasks`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Query parameters:**
  - `assignedTo` — `string` *(optional)*
  - `limit` — `string|integer` (int32) *(optional)*
  - `transactionId` — `uuid` *(optional)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `POST` `/api/v1/tasks/delete`

**Delete tasks (bulk, permanent)**

**Requires the `actions` scope.**

- **Operation ID:** `DeleteTasks`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Request body:** `application/json` — `DeleteTasksRequest`
  - `taskIds` — `array` *(required)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `422`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `POST` `/api/v1/tasks/{taskId}/assign`

**Reassign a task to a team member**

**Requires the `draft` scope.**

- **Operation ID:** `AssignTask`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `taskId` — `string` (uuid) *(required)*
- **Request body:** `application/json` — `AssignTaskRequest`
  - `assigneeUserId` — `string` (uuid), nullable *(optional)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `422`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `GET` `/api/v1/tasks/{taskId}/comments`

**List a task's comment thread**

**Requires the `read` scope.**

- **Operation ID:** `ListTaskComments`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `taskId` — `string` (uuid) *(required)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `POST` `/api/v1/tasks/{taskId}/comments`

**Add a comment to a task**

**Requires the `draft` scope.**

- **Operation ID:** `CreateTaskComment`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `taskId` — `string` (uuid) *(required)*
- **Request body:** `application/json` — `CreateTaskCommentRequest`
  - `content` — `string` *(required)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `422`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `DELETE` `/api/v1/tasks/{taskId}/comments/{commentId}`

**Delete a task comment (author only)**

**Requires the `draft` scope.**

- **Operation ID:** `DeleteTaskComment`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `commentId` — `string` (uuid) *(required)*
  - `taskId` — `string` (uuid) *(required)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `422`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `POST` `/api/v1/tasks/{taskId}/complete`

**Mark a task complete**

**Requires the `draft` scope.**

- **Operation ID:** `CompleteTask`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `taskId` — `string` (uuid) *(required)*
- **Request body:** `application/json` — `CompleteTaskRequest`
  - `completionNotes` — `string`, nullable *(optional)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `422`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `POST` `/api/v1/tasks/{taskId}/reschedule`

**Reschedule (postpone) a task's due date**

**Requires the `draft` scope.**

- **Operation ID:** `RescheduleTask`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `taskId` — `string` (uuid) *(required)*
- **Request body:** `application/json` — `RescheduleTaskRequest`
  - `dueDate` — `string` (date-time), nullable *(optional)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `422`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

## Documents

Files on a deal — request an upload URL, list and classify documents, share them, and manage versions.

### `GET` `/api/v1/documents`

**List recently-uploaded documents with extraction state**

**Requires the `read` scope.**

- **Operation ID:** `ListDocuments`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Query parameters:**
  - `hasExtraction` *(optional)*
  - `limit` — `string|integer` (int32) *(optional)*
  - `since` — `date-time` *(optional)*
  - `transactionId` — `uuid` *(optional)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `POST` `/api/v1/documents`

**Upload a document (base64) and start extraction**

**Requires the `actions` scope.**

- **Operation ID:** `UploadDocumentForExtraction`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Request body:** `application/json` — `UploadDocumentRequest`
  - `documentTypeHint` — `string`, nullable *(optional)*
  - `fileBase64` — `string`, nullable *(required)*
  - `filename` — `string`, nullable *(optional)*
  - `side` — `string`, nullable *(optional)*
  - `state` — `string`, nullable *(optional)*
  - `transactionId` — `string` (uuid), nullable *(optional)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `422`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `POST` `/api/v1/documents/classify`

**Classify a document by filename and/or content preview**

**Requires the `read` scope.**

- **Operation ID:** `ClassifyDocument`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Request body:** `application/json` — `ClassifyDocumentRequest`
  - `contentPreview` — `string`, nullable *(optional)*
  - `filename` — `string`, nullable *(optional)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `422`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `GET` `/api/v1/documents/types`

**List the canonical document-type vocabulary**

**Requires the `read` scope.**

- **Operation ID:** `ListDocumentTypes`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `POST` `/api/v1/documents/upload-url`

**Get a presigned PUT URL for a document upload**

**Requires the `actions` scope.**

- **Operation ID:** `RequestUploadUrl`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Request body:** `application/json` — `UploadUrlRequest`
  - `contentType` — `string`, nullable *(optional)*
  - `filename` — `string`, nullable *(required)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `422`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `PATCH` `/api/v1/documents/{documentId}`

**Rename or re-classify a document**

**Requires the `draft` scope.**

- **Operation ID:** `UpdateDocument`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `documentId` — `string` (uuid) *(required)*
- **Request body:** `application/json` — `UpdateDocumentRequest`
  - `category` — `string`, nullable *(optional)*
  - `documentType` — `string`, nullable *(optional)*
  - `name` — `string`, nullable *(optional)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `422`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `DELETE` `/api/v1/documents/{documentId}`

**Soft-delete a document**

**Requires the `draft` scope.**

- **Operation ID:** `DeleteDocument`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `documentId` — `string` (uuid) *(required)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `422`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `POST` `/api/v1/documents/{documentId}/extract`

**Start extraction for a document already in DocJacket**

**Requires the `actions` scope.**

- **Operation ID:** `ExtractExistingDocument`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `documentId` — `string` (uuid) *(required)*
- **Request body:** `application/json` — `ExtractExistingRequest`
  - `documentTypeHint` — `string`, nullable *(optional)*
  - `side` — `string`, nullable *(optional)*
  - `state` — `string`, nullable *(optional)*
  - `transactionIdOverride` — `string` (uuid), nullable *(optional)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `422`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `POST` `/api/v1/documents/{documentId}/split`

**Split a multi-page PDF into separate documents**

**Requires the `draft` scope.**

- **Operation ID:** `SplitDocument`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `documentId` — `string` (uuid) *(required)*
- **Request body:** `application/json` — `SplitDocumentRequest`
  - `segments` — `array`, nullable *(optional)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `422`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `POST` `/api/v1/documents/{documentId}/versions`

**Replace a document with a new uploaded version**

**Requires the `draft` scope.**

- **Operation ID:** `ReplaceDocumentVersion`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `documentId` — `string` (uuid) *(required)*
- **Request body:** `application/json` — `ReplaceDocumentVersionRequest`
  - `contentType` — `string`, nullable *(optional)*
  - `filename` — `string`, nullable *(optional)*
  - `sizeBytes` — `integer` (int64), nullable *(optional)*
  - `uploadId` — `string`, nullable *(optional)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `422`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `GET` `/api/v1/documents/{documentId}/view-url`

**Get a short-lived presigned URL to view a document**

**Requires the `read` scope.**

- **Operation ID:** `GetDocumentViewUrl`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `documentId` — `string` (uuid) *(required)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

## Extractions

AI contract extraction — kick off a run, poll results, and apply extracted fields to a transaction.

### `POST` `/api/v1/extractions`

**Start extraction from a presigned upload**

**Requires the `actions` scope.**

- **Operation ID:** `KickOffExtraction`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Request body:** `application/json` — `KickOffExtractionRequest`
  - `documentTypeHint` — `string`, nullable *(optional)*
  - `filename` — `string`, nullable *(optional)*
  - `side` — `string`, nullable *(optional)*
  - `state` — `string`, nullable *(optional)*
  - `transactionId` — `string` (uuid), nullable *(optional)*
  - `uploadId` — `string`, nullable *(required)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `422`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `GET` `/api/v1/extractions/{jobId}`

**Get the state and results of an extraction job**

**Requires the `read` scope.**

- **Operation ID:** `GetExtractionResults`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `jobId` — `string` (uuid) *(required)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `GET` `/api/v1/extractions/{jobId}/source-url`

**Get a short-lived presigned URL to view an extraction's source PDF**

**Requires the `read` scope.**

- **Operation ID:** `GetExtractionSourceUrl`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `jobId` — `string` (uuid) *(required)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

## Contacts

People and companies — search, create, and update contacts, and read the role vocabulary they are assigned to.

### `POST` `/api/v1/contact-roles`

**Create a custom contact role**

**Requires the `actions` scope.**

- **Operation ID:** `CreateContactRole`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Request body:** `application/json` — `CreateContactRoleRequest`
  - `allowMultiple` — `boolean`, nullable *(optional)*
  - `category` — `string`, nullable *(optional)*
  - `description` — `string`, nullable *(optional)*
  - `ignoreSimilar` — `boolean`, nullable *(optional)*
  - `maxInstances` — `integer` (int32), nullable *(optional)*
  - `name` — `string`, nullable *(optional)*
  - `partyKey` — `string`, nullable *(optional)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `422`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `GET` `/api/v1/contacts`

**List or search contacts**

**Requires the `read` scope.**

- **Operation ID:** `ListContacts`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Query parameters:**
  - `page` — `string|integer` (int32) *(optional)*
  - `pageSize` — `string|integer` (int32) *(optional)*
  - `q` — `string` *(optional)*
  - `type` — `string` *(optional)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `POST` `/api/v1/contacts`

**Create a contact**

**Requires the `actions` scope.**

- **Operation ID:** `CreateContact`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Request body:** `application/json` — `CreateContactRequest`
  - `city` — `string`, nullable *(optional)*
  - `company` — `string`, nullable *(optional)*
  - `contactType` — `string`, nullable *(optional)*
  - `email` — `string`, nullable *(optional)*
  - `firstName` — `string`, nullable *(optional)*
  - `kind` — `string`, nullable *(optional)*
  - `lastName` — `string`, nullable *(optional)*
  - `licenseNumber` — `string`, nullable *(optional)*
  - `notes` — `string`, nullable *(optional)*
  - `phone` — `string`, nullable *(optional)*
  - `state` — `string`, nullable *(optional)*
  - `streetAddress` — `string`, nullable *(optional)*
  - `zipCode` — `string`, nullable *(optional)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `422`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `GET` `/api/v1/contacts/by-email`

**Find contacts by exact email, with their transactions**

**Requires the `read` scope.**

- **Operation ID:** `FindContactByEmail`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Query parameters:**
  - `email` — `string` *(optional)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `GET` `/api/v1/contacts/search`

**Fuzzy-search contacts by name, email, phone, or company**

**Requires the `read` scope.**

- **Operation ID:** `SearchContacts`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Query parameters:**
  - `contactType` — `string` *(optional)*
  - `limit` — `string|integer` (int32) *(optional)*
  - `q` — `string` *(optional)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `GET` `/api/v1/contacts/{contactId}`

**Get a contact by ID**

**Requires the `read` scope.**

- **Operation ID:** `GetContact`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `contactId` — `string` (uuid) *(required)*
- **Query parameters:**
  - `activityLimit` — `string|integer` (int32) *(optional)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

## Disclosure Packages

Seller disclosure packages — assemble documents, activate, invite and revoke recipients, and read access activity.

### `POST` `/api/v1/disclosure-packages`

**Create a disclosure package (optionally attach documents and activate)**

**Requires the `actions` scope.**

- **Operation ID:** `CreateDisclosurePackage`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Request body:** `application/json` — `CreatePackageRequest`
  - `allowDownloads` — `boolean`, nullable *(optional)*
  - `coverMessage` — `string`, nullable *(optional)*
  - `documentIds` — `array`, nullable *(optional)*
  - `expiresAt` — `string` (date-time), nullable *(optional)*
  - `name` — `string`, nullable *(optional)*
  - `requireAck` — `boolean`, nullable *(optional)*
  - `transactionId` — `string` (uuid), nullable *(optional)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `422`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `GET` `/api/v1/disclosure-packages/{packageId}`

**Get a disclosure package with items and recipients**

**Requires the `read` scope.**

- **Operation ID:** `GetDisclosurePackage`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `packageId` — `string` (uuid) *(required)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `POST` `/api/v1/disclosure-packages/{packageId}/activate`

**Activate a disclosure package (idempotent)**

**Requires the `actions` scope.**

- **Operation ID:** `ActivateDisclosurePackage`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `packageId` — `string` (uuid) *(required)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `422`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `GET` `/api/v1/disclosure-packages/{packageId}/activity`

**Get the recipient-activity report for a disclosure package**

**Requires the `read` scope.**

- **Operation ID:** `GetDisclosureActivity`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `packageId` — `string` (uuid) *(required)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `PUT` `/api/v1/disclosure-packages/{packageId}/documents`

**Replace a disclosure package's document list**

**Requires the `actions` scope.**

- **Operation ID:** `UpdateDisclosurePackageDocuments`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `packageId` — `string` (uuid) *(required)*
- **Request body:** `application/json` — `ReplaceDocumentsRequest`
  - `documentIds` — `array`, nullable *(optional)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `422`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `POST` `/api/v1/disclosure-packages/{packageId}/recipients`

**Invite a recipient to a disclosure package (sends the share email)**

**Requires the `actions` scope.**

- **Operation ID:** `InviteDisclosureRecipient`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `packageId` — `string` (uuid) *(required)*
- **Headers:**
  - `Idempotency-Key` — `string` *(optional)* — Optional. Send a unique value (max 200 characters — a UUID is ideal) to make this call safe to retry. The first request executes and its response is stored; an identical retry replays that stored response verbatim with an `Idempotency-Replayed: true` header instead of performing the side effect again. Reusing a key for a *different* operation is rejected with `422`.
- **Request body:** `application/json` — `InviteRecipientRequest`
  - `audienceTier` — `string`, nullable *(optional)*
  - `contactId` — `string` (uuid), nullable *(optional)*
  - `displayLabel` — `string`, nullable *(optional)*
  - `email` — `string`, nullable *(optional)*
  - `expiresAt` — `string` (date-time), nullable *(optional)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `409`, `422`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `DELETE` `/api/v1/disclosure-packages/{packageId}/recipients/{recipientId}`

**Revoke a disclosure recipient's access (idempotent)**

**Requires the `actions` scope.**

- **Operation ID:** `RevokeDisclosureRecipient`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `packageId` — `string` (uuid) *(required)*
  - `recipientId` — `string` (uuid) *(required)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `422`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

## Proposals

AI-generated proposals awaiting human review — list, inspect, approve, and reject.

### `GET` `/api/v1/proposals`

**List pending AI proposals for the organization**

**Requires the `read` scope.**

- **Operation ID:** `ListProposals`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Query parameters:**
  - `limit` — `int32` *(optional)*
  - `offset` — `int32` *(optional)*
  - `status` — `string` *(optional)*
  - `transactionId` — `uuid` *(optional)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `GET` `/api/v1/proposals/{id}`

**Get one AI proposal with its evidence**

**Requires the `read` scope.**

- **Operation ID:** `GetProposal`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `id` — `string` (uuid) *(required)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `POST` `/api/v1/proposals/{id}/approve`

**Approve an AI proposal**

**Requires the `actions` scope.**

- **Operation ID:** `ApproveProposal`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `id` — `string` (uuid) *(required)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `422`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `PUT` `/api/v1/proposals/{id}/payload`

**Edit a proposal's proposed value before approving**

**Requires the `actions` scope.**

- **Operation ID:** `EditProposalPayload`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `id` — `string` (uuid) *(required)*
- **Request body:** `application/json` — `EditProposalPayloadRequest`
  - `parameters` — `JsonElement` *(optional)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `422`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `POST` `/api/v1/proposals/{id}/reject`

**Reject an AI proposal**

**Requires the `actions` scope.**

- **Operation ID:** `RejectProposal`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `id` — `string` (uuid) *(required)*
- **Request body:** `application/json` — `RejectProposalRequest`
  - `reason` — `string`, nullable *(optional)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `422`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

## Templates & Forms

Reusable content — email templates, checklist templates, intake forms, and the submissions they produce.

### `GET` `/api/v1/checklist-templates`

**List timeline/checklist templates (org + system)**

**Requires the `read` scope.**

- **Operation ID:** `ListChecklistTemplates`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Query parameters:**
  - `activeOnly` — `boolean` *(optional)*
  - `category` — `string` *(optional)*
  - `complexity` — `string` *(optional)*
  - `side` — `string` *(optional)*
  - `state` — `string` *(optional)*
  - `transactionType` — `string` *(optional)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `GET` `/api/v1/email-templates`

**List email templates (org + system, active only)**

**Requires the `read` scope.**

- **Operation ID:** `ListEmailTemplates`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Query parameters:**
  - `audience` — `string` *(optional)*
  - `category` — `string` *(optional)*
  - `limit` — `string|integer` (int32) *(optional)*
  - `search` — `string` *(optional)*
  - `side` — `string` *(optional)*
  - `stage` — `string` *(optional)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `POST` `/api/v1/email-templates`

**Create an email template**

**Requires the `actions` scope.**

- **Operation ID:** `CreateEmailTemplate`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Request body:** `application/json` — `CreateEmailTemplateRequest`
  - `audience` — `string`, nullable *(optional)*
  - `body` — `string`, nullable *(optional)*
  - `category` — `string`, nullable *(optional)*
  - `description` — `string`, nullable *(optional)*
  - `isActive` — `boolean`, nullable *(optional)*
  - `name` — `string`, nullable *(optional)*
  - `side` — `string`, nullable *(optional)*
  - `stage` — `string`, nullable *(optional)*
  - `subject` — `string`, nullable *(optional)*
  - `tone` — `string`, nullable *(optional)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `422`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `GET` `/api/v1/email-templates/{idOrSlug}`

**Get an email template by ID or slug**

**Requires the `read` scope.**

- **Operation ID:** `GetEmailTemplate`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `idOrSlug` — `string` *(required)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `GET` `/api/v1/form-submissions`

**List form submissions (org-wide or per transaction)**

**Requires the `read` scope.**

- **Operation ID:** `ListFormSubmissions`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Query parameters:**
  - `formDefinitionId` — `uuid` *(optional)*
  - `formPurpose` — `string` *(optional)*
  - `limit` — `string|integer` (int32) *(optional)*
  - `since` — `date-time` *(optional)*
  - `status` — `string` *(optional)*
  - `transactionId` — `uuid` *(optional)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `GET` `/api/v1/form-submissions/{submissionId}`

**Get field-level detail for a form submission**

**Requires the `read` scope.**

- **Operation ID:** `GetFormSubmission`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `submissionId` — `string` (uuid) *(required)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `GET` `/api/v1/forms/{formId}`

**Get a form template with its field list**

**Requires the `read` scope.**

- **Operation ID:** `GetFormDefinition`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `formId` — `string` (uuid) *(required)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

## Webhooks

Push instead of poll — subscribe to events, manage subscriptions, and read the event catalog.

### `GET` `/api/v1/webhook-events`

**List the webhook event types you can subscribe to**

**Requires the `read` scope.**

- **Operation ID:** `ListWebhookEvents`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `GET` `/api/v1/webhooks`

**List your webhook subscriptions**

**Requires the `read` scope.**

- **Operation ID:** `ListWebhooks`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Query parameters:**
  - `includeInactive` — `boolean` *(optional)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `POST` `/api/v1/webhooks`

**Create a webhook subscription**

**Requires the `actions` scope.**

- **Operation ID:** `CreateWebhook`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Request body:** `application/json` — `CreateWebhookApiRequest`
  - `description` — `string`, nullable *(optional)*
  - `events` — `array`, nullable *(required)*
  - `headers` — `object`, nullable *(optional)*
  - `name` — `string`, nullable *(required)*
  - `url` — `string`, nullable *(required)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `422`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `GET` `/api/v1/webhooks/{id}`

**Get a webhook subscription by ID**

**Requires the `read` scope.**

- **Operation ID:** `GetWebhook`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `id` — `string` (uuid) *(required)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `PUT` `/api/v1/webhooks/{id}`

**Update a webhook subscription**

**Requires the `actions` scope.**

- **Operation ID:** `UpdateWebhook`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `id` — `string` (uuid) *(required)*
- **Request body:** `application/json` — `UpdateWebhookApiRequest`
  - `circuitBreakerEnabled` — `boolean`, nullable *(optional)*
  - `description` — `string`, nullable *(optional)*
  - `events` — `array`, nullable *(required)*
  - `headers` — `object`, nullable *(optional)*
  - `isActive` — `boolean`, nullable *(optional)*
  - `name` — `string`, nullable *(required)*
  - `timeoutSeconds` — `integer` (int32), nullable *(optional)*
  - `url` — `string`, nullable *(required)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `422`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `DELETE` `/api/v1/webhooks/{id}`

**Delete a webhook subscription**

**Requires the `actions` scope.**

- **Operation ID:** `DeleteWebhook`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `id` — `string` (uuid) *(required)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `422`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `GET` `/api/v1/webhooks/{id}/deliveries`

**List recent delivery attempts for a webhook subscription**

**Requires the `read` scope.**

- **Operation ID:** `ListWebhookDeliveries`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `id` — `string` (uuid) *(required)*
- **Query parameters:**
  - `limit` — `string|integer` (int32) *(optional)*
  - `offset` — `string|integer` (int32) *(optional)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `POST` `/api/v1/webhooks/{id}/regenerate-secret`

**Rotate a webhook subscription's signing secret**

**Requires the `actions` scope.**

- **Operation ID:** `RegenerateWebhookSecret`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `id` — `string` (uuid) *(required)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `422`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `POST` `/api/v1/webhooks/{id}/test`

**Send a test delivery to a webhook subscription**

**Requires the `actions` scope.**

- **Operation ID:** `TestWebhook`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Path parameters:**
  - `id` — `string` (uuid) *(required)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `422`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

## Organization

Your own organization — settings, the transaction-status vocabulary, notifications, and registered devices.

### `POST` `/api/v1/account/deletion/cancel`

**Cancel a scheduled workspace deletion**

Cancels a pending deletion and unfreezes the workspace — the in-app equivalent of the emailed cancel link, for an owner who is still signed in. Owner only. Returns `cancelled: false` when there was nothing scheduled.

**Requires the `actions` scope.**

- **Operation ID:** `CancelAccountDeletion`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `422`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `POST` `/api/v1/account/deletion/request`

**Schedule this workspace for deletion after the grace period**

Schedules the workspace for permanent deletion once the grace period elapses, freezes it, and emails a cancel link. Nothing is deleted at the time of the call. Owner only, and `confirmName` must equal the workspace name exactly — a mismatch returns 422 and schedules nothing.

**Requires the `actions` scope.**

- **Operation ID:** `RequestAccountDeletion`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Request body:** `application/json` — `RequestAccountDeletionBody`
  - `confirmName` — `string`, nullable *(optional)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `422`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `GET` `/api/v1/account/deletion/status`

**Whether workspace deletion is scheduled, and whether the caller may act on it**

Reports whether this workspace is scheduled for deletion, when the purge falls due, and how long the grace period is. Readable by any member with the read scope, because a pending deletion ends the workspace for all of them. The `isOwner` flag tells a client whether to offer the delete and export controls at all, so it can hide them rather than render a button that fails.

**Requires the `read` scope.**

- **Operation ID:** `AccountDeletionStatus`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `GET` `/api/v1/account/export/latest`

**Status of the most recent workspace data export**

Returns the most recent export for this workspace with its build progress, or `exists: false` if one has never been requested. A completed export whose artifact has passed its expiry reports as `expired`, since the file is gone. Owner only.

**Requires the `read` scope.**

- **Operation ID:** `LatestAccountExport`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `POST` `/api/v1/account/export/request`

**Start building a full export of this workspace's data**

Starts building a full archive of this workspace's data; the finished download arrives by email, so there is nothing to fetch from this response. Owner only. One export runs at a time — calling again while one is building returns that one with `alreadyRunning: true` rather than starting a second.

**Requires the `actions` scope.**

- **Operation ID:** `RequestAccountExport`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `422`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `POST` `/api/v1/devices/register`

**Register or refresh a mobile device for the authenticated user**

**Requires the `actions` scope.**

- **Operation ID:** `RegisterDevice`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Request body:** `application/json` — `RegisterDeviceRequest`
  - `appVersion` — `string`, nullable *(optional)*
  - `capabilities` — `array`, nullable *(optional)*
  - `installationId` — `string`, nullable *(optional)*
  - `permissions` — `object`, nullable *(optional)*
  - `platform` — `string`, nullable *(optional)*
  - `pushToken` — `string`, nullable *(optional)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `422`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `GET` `/api/v1/notifications`

**List the signed-in user's notification inbox**

**Requires the `read` scope.**

- **Operation ID:** `ListNotifications`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Query parameters:**
  - `limit` — `string|integer` (int32) *(optional)*
  - `unreadOnly` *(optional)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `GET` `/api/v1/notifications/unread-count`

**Unread notification count for the signed-in user**

**Requires the `read` scope.**

- **Operation ID:** `NotificationUnreadCount`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `GET` `/api/v1/org/users`

**List the organization's assignable team members**

**Requires the `read` scope.**

- **Operation ID:** `ListOrgUsers`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `GET` `/api/v1/transaction-statuses`

**List the organization's selectable transaction statuses**

**Requires the `read` scope.**

- **Operation ID:** `ListTransactionStatuses`
- **Authentication:** organization API key — `Authorization: Bearer mcp_at_…`
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

## Organizations (Partner)

White-label partner tier. Provision and read the organizations in your book of business. Requires a partner key (rsk_…), not an organization key.

### `GET` `/api/v1/orgs`

**List your customer organizations**

**Requires a partner key** (`Authorization: Bearer rsk_…`), not an organization key. Scoped to the organizations your partner account owns — one you do not own returns `404`, never `403`, so ownership is never disclosed. Never infer access to a tenant from an id obtained elsewhere.

- **Operation ID:** `ListOrgs`
- **Authentication:** partner key — `Authorization: Bearer rsk_…`
- **Query parameters:**
  - `limit` — `string|integer` (int32) *(optional)*
  - `offset` — `string|integer` (int32) *(optional)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `POST` `/api/v1/orgs`

**Provision a customer organization**

**Requires a partner key** (`Authorization: Bearer rsk_…`), not an organization key. Scoped to the organizations your partner account owns — one you do not own returns `404`, never `403`, so ownership is never disclosed. Never infer access to a tenant from an id obtained elsewhere.

- **Operation ID:** `CreateOrg`
- **Authentication:** partner key — `Authorization: Bearer rsk_…`
- **Request body:** `application/json` *(required)* — `CreateOrgRequest`
  - `name` — `string` *(required)*
  - `owner` — `OwnerBody` *(required)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `422`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `GET` `/api/v1/orgs/{orgId}`

**Get a customer organization**

**Requires a partner key** (`Authorization: Bearer rsk_…`), not an organization key. Scoped to the organizations your partner account owns — one you do not own returns `404`, never `403`, so ownership is never disclosed. Never infer access to a tenant from an id obtained elsewhere.

- **Operation ID:** `GetOrg`
- **Authentication:** partner key — `Authorization: Bearer rsk_…`
- **Path parameters:**
  - `orgId` — `string` *(required)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `GET` `/api/v1/orgs/{orgId}/entitlements`

**Get an organization's plan, seats, and AI fair-use pool state**

**Requires a partner key** (`Authorization: Bearer rsk_…`), not an organization key. Scoped to the organizations your partner account owns — one you do not own returns `404`, never `403`, so ownership is never disclosed. Never infer access to a tenant from an id obtained elsewhere.

- **Operation ID:** `GetOrgEntitlements`
- **Authentication:** partner key — `Authorization: Bearer rsk_…`
- **Path parameters:**
  - `orgId` — `string` *(required)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `GET` `/api/v1/orgs/{orgId}/summary`

**Get an organization's activity summary (active deals, tasks due, last activity)**

**Requires a partner key** (`Authorization: Bearer rsk_…`), not an organization key. Scoped to the organizations your partner account owns — one you do not own returns `404`, never `403`, so ownership is never disclosed. Never infer access to a tenant from an id obtained elsewhere.

- **Operation ID:** `GetOrgSummary`
- **Authentication:** partner key — `Authorization: Bearer rsk_…`
- **Path parameters:**
  - `orgId` — `string` *(required)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `POST` `/api/v1/orgs/{orgId}/users`

**Invite a seat into an organization**

**Requires a partner key** (`Authorization: Bearer rsk_…`), not an organization key. Scoped to the organizations your partner account owns — one you do not own returns `404`, never `403`, so ownership is never disclosed. Never infer access to a tenant from an id obtained elsewhere.

- **Operation ID:** `AddSeat`
- **Authentication:** partner key — `Authorization: Bearer rsk_…`
- **Path parameters:**
  - `orgId` — `string` *(required)*
- **Request body:** `application/json` *(required)* — `AddSeatRequest`
  - `email` — `string` *(required)*
  - `firstName` — `string`, nullable *(optional)*
  - `lastName` — `string`, nullable *(optional)*
  - `role` — `string`, nullable *(optional)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `422`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

### `DELETE` `/api/v1/orgs/{orgId}/users/{userId}`

**Remove a seat from an organization**

**Requires a partner key** (`Authorization: Bearer rsk_…`), not an organization key. Scoped to the organizations your partner account owns — one you do not own returns `404`, never `403`, so ownership is never disclosed. Never infer access to a tenant from an id obtained elsewhere.

- **Operation ID:** `RemoveSeat`
- **Authentication:** partner key — `Authorization: Bearer rsk_…`
- **Path parameters:**
  - `orgId` — `string` *(required)*
  - `userId` — `string` (uuid) *(required)*
- **Success `200`:** OK
- **Errors:** `401`, `403`, `404`, `422`, `429` — all use the standard envelope `{ "error": { "code", "message" } }`.

## Webhooks

DocJacket POSTs these events to a URL you register with `POST /api/v1/webhooks`. Each delivery carries `X-Webhook-Signature` (`sha256=<hex>`, HMAC-SHA256 over the raw request body using your subscription secret), `X-Webhook-Event-Type`, `X-Webhook-Event-Id` (deduplicate on this — retries reuse it) and `X-Webhook-Timestamp`.

- `contact.created` — When a new contact is created
- `disclosure.recipient_viewed` — When a disclosure package recipient opens the disclosure
- `document.deleted` — When a document is deleted
- `document.uploaded` — When a document is uploaded to a transaction
- `extraction.completed` — When a document extraction job finishes (includes jobId + status)
- `form.submission_received` — When a public form submission is received
- `key_date.completed` — When a key date is marked complete
- `key_date.updated` — When a key date is added or changed on a transaction
- `task.completed` — When a task is marked complete
- `task.created` — When a new task is created
- `transaction.closed` — When a transaction is closed
- `transaction.created` — When a new transaction is created
- `transaction.status_changed` — When a transaction status changes
- `webhook.test` — Test webhook (triggered manually)

---

Interactive reference: https://api.docjacket.com/reference · Canonical specification: https://api.docjacket.com/openapi.json
