---
title: "Create, update or archive a library entry"
method: PUT
path: "/firm/crm/proposal-library/{id}"
tags: ["CRM Proposals"]
---

# Create, update or archive a library entry

`PUT /firm/crm/proposal-library/{id}`

## Request

- Base URL: `https://ledgerhq.pro/api/v1`
- URL: `https://ledgerhq.pro/api/v1/firm/crm/proposal-library/{id}`
- Auth: one of:
  - HTTP bearer and API key in header `x-organization-id`
  - HTTP bearer and API key in header `x-organization-id`

Firm-side proposals. Select the firm with x-organization-id. Reads require active staff membership and access to every linked company; prospects are visible to their creator or firm managers. Writes require Firm Owner/Admin and billing permission. OAuth requires the broad mcp grant. Saves are revision-checked and idempotent using a stable requestId. All amounts are integer USD cents. Historical service dates and separately priced backwork are supported; saves never send, sign, provision companies or charge. Invalid dates, overlapping backwork/ongoing coverage and deposits exceeding the fee are rejected.

## Path parameters

- `id` string, uuid, required

## Request body

- object
  - `requestId` string, uuid, required: Stable save request UUID
  - `expectedRevision` integer, required: Zero for creation; otherwise the last read revision
  - `archived` boolean: Archive without changing existing proposals
  - `content` union, required: Reusable service, package, template, terms or message
    - object
      - `kind` 'service', required
      - `name` string, required
      - `line` object, required
        - `id` string, uuid, required: Stable line identity
        - `name` string, required: Service name
        - `description` string: Agreed scope of work
        - `kind` 'service' | 'backwork' | 'setup': Ordinary service, catch-up bookkeeping, or setup
        - `amountCents` integer, required: Fixed total fee or recurring fee per period in USD cents
        - `cadence` 'once' | 'month' | 'quarter' | 'year', required: One-time or recurring billing cadence
        - `coverageStart` string, nullable: First date of covered work; required for backwork before sending
        - `coverageEnd` string, nullable: Last date of covered work; required for backwork before sending
        - `depositCents` integer: Part of a one-time fee, not an additional fee
        - `balanceTrigger` 'activation' | 'date' | 'completion': Balance is payable when billing starts, on a specified date, or when the firm marks the work complete
        - `balanceDueOn` string, nullable: Due date when the balance trigger is date
    - object
      - `kind` 'package', required
      - `name` string, required
      - `description` string, required
      - `lines` object[], required
        - `id` string, uuid, required: Stable line identity
        - `name` string, required: Service name
        - `description` string: Agreed scope of work
        - `kind` 'service' | 'backwork' | 'setup': Ordinary service, catch-up bookkeeping, or setup
        - `amountCents` integer, required: Fixed total fee or recurring fee per period in USD cents
        - `cadence` 'once' | 'month' | 'quarter' | 'year', required: One-time or recurring billing cadence
        - `coverageStart` string, nullable: First date of covered work; required for backwork before sending
        - `coverageEnd` string, nullable: Last date of covered work; required for backwork before sending
        - `depositCents` integer: Part of a one-time fee, not an additional fee
        - `balanceTrigger` 'activation' | 'date' | 'completion': Balance is payable when billing starts, on a specified date, or when the firm marks the work complete
        - `balanceDueOn` string, nullable: Due date when the balance trigger is date
      - `published` boolean, required
      - `recommended` boolean, required
    - object
      - `kind` 'terms', required
      - `name` string, required
      - `body` string, required
    - object
      - `kind` 'message', required
      - `name` string, required
      - `subject` string, required
      - `body` string, required
    - object
      - `kind` 'template', required
      - `name` string, required
      - `introduction` string, required
      - `terms` string, required
      - `emailSubject` string, required
      - `emailMessage` string, required
      - `options` object[], required
        - `id` string, uuid, required: Option identity
        - `name` string, required: Package or option name
        - `description` string: Package description
        - `lines` object[], required: Snapshotted services and agreed prices
          - `id` string, uuid, required: Stable line identity
          - `name` string, required: Service name
          - `description` string: Agreed scope of work
          - `kind` 'service' | 'backwork' | 'setup': Ordinary service, catch-up bookkeeping, or setup
          - `amountCents` integer, required: Fixed total fee or recurring fee per period in USD cents
          - `cadence` 'once' | 'month' | 'quarter' | 'year', required: One-time or recurring billing cadence
          - `coverageStart` string, nullable: First date of covered work; required for backwork before sending
          - `coverageEnd` string, nullable: Last date of covered work; required for backwork before sending
          - `depositCents` integer: Part of a one-time fee, not an additional fee
          - `balanceTrigger` 'activation' | 'date' | 'completion': Balance is payable when billing starts, on a specified date, or when the firm marks the work complete
          - `balanceDueOn` string, nullable: Due date when the balance trigger is date

## Response `200`

Success

- object
  - `entries` object[]
    - `id` string, uuid
    - `revision` integer
    - `content` union
      - object
        - `kind` 'service', required
        - `name` string, required
        - `line` object, required
          - `id` string, uuid, required: Stable line identity
          - `name` string, required: Service name
          - `description` string: Agreed scope of work
          - `kind` 'service' | 'backwork' | 'setup': Ordinary service, catch-up bookkeeping, or setup
          - `amountCents` integer, required: Fixed total fee or recurring fee per period in USD cents
          - `cadence` 'once' | 'month' | 'quarter' | 'year', required: One-time or recurring billing cadence
          - `coverageStart` string, nullable: First date of covered work; required for backwork before sending
          - `coverageEnd` string, nullable: Last date of covered work; required for backwork before sending
          - `depositCents` integer: Part of a one-time fee, not an additional fee
          - `balanceTrigger` 'activation' | 'date' | 'completion': Balance is payable when billing starts, on a specified date, or when the firm marks the work complete
          - `balanceDueOn` string, nullable: Due date when the balance trigger is date
      - object
        - `kind` 'package', required
        - `name` string, required
        - `description` string, required
        - `lines` object[], required
          - `id` string, uuid, required: Stable line identity
          - `name` string, required: Service name
          - `description` string: Agreed scope of work
          - `kind` 'service' | 'backwork' | 'setup': Ordinary service, catch-up bookkeeping, or setup
          - `amountCents` integer, required: Fixed total fee or recurring fee per period in USD cents
          - `cadence` 'once' | 'month' | 'quarter' | 'year', required: One-time or recurring billing cadence
          - `coverageStart` string, nullable: First date of covered work; required for backwork before sending
          - `coverageEnd` string, nullable: Last date of covered work; required for backwork before sending
          - `depositCents` integer: Part of a one-time fee, not an additional fee
          - `balanceTrigger` 'activation' | 'date' | 'completion': Balance is payable when billing starts, on a specified date, or when the firm marks the work complete
          - `balanceDueOn` string, nullable: Due date when the balance trigger is date
        - `published` boolean, required
        - `recommended` boolean, required
      - object
        - `kind` 'terms', required
        - `name` string, required
        - `body` string, required
      - object
        - `kind` 'message', required
        - `name` string, required
        - `subject` string, required
        - `body` string, required
      - object
        - `kind` 'template', required
        - `name` string, required
        - `introduction` string, required
        - `terms` string, required
        - `emailSubject` string, required
        - `emailMessage` string, required
        - `options` object[], required
          - `id` string, uuid, required: Option identity
          - `name` string, required: Package or option name
          - `description` string: Package description
          - `lines` object[], required: Snapshotted services and agreed prices
            - `id` string, uuid, required: Stable line identity
            - `name` string, required: Service name
            - `description` string: Agreed scope of work
            - `kind` 'service' | 'backwork' | 'setup': Ordinary service, catch-up bookkeeping, or setup
            - `amountCents` integer, required: Fixed total fee or recurring fee per period in USD cents
            - `cadence` 'once' | 'month' | 'quarter' | 'year', required: One-time or recurring billing cadence
            - `coverageStart` string, nullable: First date of covered work; required for backwork before sending
            - `coverageEnd` string, nullable: Last date of covered work; required for backwork before sending
            - `depositCents` integer: Part of a one-time fee, not an additional fee
            - `balanceTrigger` 'activation' | 'date' | 'completion': Balance is payable when billing starts, on a specified date, or when the firm marks the work complete
            - `balanceDueOn` string, nullable: Due date when the balance trigger is date
  - `canWrite` boolean

## Other responses

- `400`: Invalid input
- `403`: Insufficient firm authority
- `404`: Record not found or not accessible
- `409`: Revision, request identity or immutable-state conflict; preserve unsaved edits

---

[API](https://skmtc.dev/ledgerhq-pro/apis/ledgerhq-bookkeeping-api.md) · [All operations](https://skmtc.dev/ledgerhq-pro/apis/ledgerhq-bookkeeping-api/llms.txt) · [OpenAPI document](https://skmtc.dev/ledgerhq-pro/apis/ledgerhq-bookkeeping-api/revisions/9a8269f0a586?raw)
