---
title: "List proposals"
method: GET
path: "/firm/crm/proposals"
tags: ["CRM Proposals"]
---

# List proposals

`GET /firm/crm/proposals`

## Request

- Base URL: `https://ledgerhq.pro/api/v1`
- URL: `https://ledgerhq.pro/api/v1/firm/crm/proposals`
- 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.

## Query parameters

- `search` string
- `status` 'all' | 'draft' | 'sent' | 'accepted' | 'withdrawn' | 'declined'
- `companyId` string, uuid
- `page` integer
- `limit` integer

## Response `200`

Success

- object
  - `proposals` object[]
    - `id` string, uuid
    - `title` string
    - `status` 'draft' | 'sent' | 'accepted' | 'withdrawn' | 'declined'
    - `revision` integer
    - `draft` object
      - `billingChange` 'new' | 'next_cycle': Next-cycle amendments change recurring fees only after firm activation, without repricing earlier periods
      - `title` string, required: Proposal title
      - `signer` object, required: One person authorized to accept the complete offer
        - `name` string, required: Contact name
        - `email` union, required: Contact email; may be empty in a draft
          - ''
          - string, email
        - `title` string: Signer's role or title
      - `companies` object[], required: Each company has separate scope, payer, billing and onboarding
        - `billingSource` object, nullable: Optional accepted engagement for this same company whose recurring billing this offer changes at the next cycle
          - `kind` 'proposal', required
          - `id` string, uuid, required
        - `id` string, uuid, required: Stable company identity within this proposal
        - `companyOrganizationId` string, uuid, nullable: Existing accessible company ID, or null for a prospect
        - `legalName` string, required: Company legal name
        - `payer` object, required: This company's authorized billing contact
          - `name` string, required: Contact name
          - `email` union, required: Contact email; may be empty in a draft
            - ''
            - string, email
        - `serviceStartDate` string, nullable: Agreed service start, including historical dates
        - `recurringFrom` string, nullable: First date covered by recurring service, distinct from backwork
        - `serviceEndDate` string, nullable: Optional service end; otherwise ongoing until cancelled
        - `options` object[], required: One fixed package or up to three client choices
          - `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
        - `selectedOptionId` string, uuid, required: Default selection; client may choose another offered option before signing
      - `introduction` string: Personal introduction shown to the client
      - `terms` string: Engagement terms saved with this proposal
      - `emailSubject` string: Invitation email subject
      - `emailMessage` string: Invitation email message
      - `expiresOn` string, nullable: Optional last day to accept
      - `paymentMethods` string[]: Methods offered in Stripe-hosted setup; setup never starts charges
    - `totals` object
      - `once` integer: USD cents for selected options
      - `month` integer: USD cents for selected options
      - `quarter` integer: USD cents for selected options
      - `year` integer: USD cents for selected options
    - `sendIssues` string[]
    - `createdAt` string, date-time
    - `updatedAt` string, date-time
  - `counts` object
  - `total` integer
  - `page` integer
  - `limit` integer
  - `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)
