> ## Knowledge Base Index
> Fetch the complete knowledge base index at: https://help.swellsystem.com/sitemap.xml
> Use this file to discover available pages before exploring further.
> Pure-Markdown content can be obtained by appending a '.md' suffix to the content URLs listed in the sitemap (without the trailing slash).

# Proposal API Reference

Use the SWELL API to create, update, clone, and manage proposals programmatically. This is useful for automating proposal creation from external tools, AI assistants, or custom integrations.

All endpoints require authentication via Bearer token. Base URL: `https://dashboard.swellsystem.com/api/v1`

## Create a Proposal with Sections

**POST** `/proposals/proposals`

Create a new proposal with structured sections and line items in a single request.

**Required fields:**
- `title` (string) - The proposal title

**Optional fields:**
- `contact_id` (integer) - Link to a contact
- `company_id` (integer) - Link to a company
- `lead_id` (integer) - Link to a lead
- `status` (string) - One of: draft, sent, viewed, signed, rejected, expired (default: draft)
- `expires_at` (date) - Expiration date
- `subtotal` (decimal) - Subtotal amount
- `tax_rate` (decimal) - Tax rate percentage (0-100)
- `currency` (string) - 3-letter currency code (default: USD)
- `template_id` (integer) - Apply a template to auto-populate sections
- `sections` (array) - Array of section objects

### Section Object

Each section in the `sections` array accepts:

- `type` (string, required) - One of: cover, text, pricing_table, image, signature, divider, columns, video, spacer
- `title` (string) - Section title
- `content` (string) - HTML content for the section
- `settings` (object) - JSON settings for section configuration
- `sort_order` (integer) - Display order (auto-assigned if omitted)
- `is_visible` (boolean) - Whether section appears in the proposal (default: true)
- `items` (array) - Array of line items (for pricing_table sections)

### Item Object

Each item in a section's `items` array accepts:

- `description` (string) - Item description
- `quantity` (number) - Quantity (default: 1)
- `unit_price` (number) - Price per unit
- `is_optional` (boolean) - Whether the item is optional (default: false)

### Example: Full Proposal

```json
{
  "title": "Website Redesign Proposal",
  "contact_id": 42,
  "company_id": 10,
  "status": "draft",
  "expires_at": "2026-12-31",
  "tax_rate": 7,
  "currency": "USD",
  "sections": [
    {
      "type": "cover",
      "title": "Cover Page",
      "content": "<h1>Website Redesign</h1><p>Prepared for Acme Corp</p>"
    },
    {
      "type": "text",
      "title": "Project Overview",
      "content": "<p>We will redesign your website with modern UI/UX best practices, mobile-first responsive design, and SEO optimization.</p>"
    },
    {
      "type": "pricing_table",
      "title": "Investment",
      "items": [
        {
          "description": "Website Design & Development",
          "quantity": 1,
          "unit_price": 5000.00
        },
        {
          "description": "SEO Setup & Optimization",
          "quantity": 1,
          "unit_price": 1500.00
        },
        {
          "description": "Monthly Maintenance",
          "quantity": 12,
          "unit_price": 200.00,
          "is_optional": true
        }
      ]
    },
    {
      "type": "signature",
      "title": "Agreement",
      "content": "<p>By signing below, you agree to the terms outlined in this proposal.</p>"
    }
  ]
}
```

## Create from Template

Instead of defining sections manually, pass a `template_id` to auto-populate sections from a saved template:

```json
{
  "title": "New Client Proposal",
  "contact_id": 42,
  "template_id": 1
}
```

The template's sections and items will be copied into the new proposal. If you pass both `template_id` and `sections`, the explicit sections take priority.

## Update a Proposal

**PUT** `/proposals/proposals/{id}`

Update proposal fields and optionally replace all sections. When `sections` is provided, existing sections are removed and replaced with the new set.

```json
{
  "title": "Updated Proposal Title",
  "status": "sent",
  "sections": [
    {
      "type": "text",
      "title": "Revised Scope",
      "content": "<p>Updated project scope details.</p>"
    }
  ]
}
```

## Clone a Proposal

**POST** `/proposals/proposals/{id}/clone`

Creates a full copy of an existing proposal including all sections and items. The clone:
- Gets a new proposal number (PROP-XXX)
- Title is prefixed with "Copy of"
- Status is set to draft
- Client signatures and sent/viewed timestamps are cleared
- All sections and line items are duplicated

No request body is needed.

## Apply Template to Existing Proposal

**POST** `/proposals/proposals/{id}/apply-template`

Replaces all sections on an existing proposal with sections from a template.

```json
{
  "template_id": 3
}
```

**Warning:** This removes all existing sections and items on the proposal.

## List Proposals

**GET** `/proposals/proposals`

Query parameters:
- `search` - Search by title or proposal number
- `status` - Filter by status (draft, sent, viewed, signed, rejected, expired)
- `contact_id` - Filter by contact
- `company_id` - Filter by company
- `sort` - Sort field (prefix with - for descending, e.g. `-created_at`)
- `per_page` - Items per page (max 100)

## Get a Proposal

**GET** `/proposals/proposals/{id}`

Returns the full proposal with sections, items, contact, company, lead, template, activities, and converted invoice data.

## Delete a Proposal

**DELETE** `/proposals/proposals/{id}`

## Section Types Reference

| Type | Purpose | Supports Items |
|------|---------|---------------|
| cover | Cover page / title page | No |
| text | Rich text content section | No |
| pricing_table | Line items with pricing | Yes |
| image | Image display section | No |
| signature | E-signature capture section | No |
| divider | Visual divider / separator | No |
| columns | Multi-column layout | No |
| video | Embedded video section | No |
| spacer | Vertical spacing | No |

## Template API

Templates can also be managed via the API:

- **GET** `/templates/templates` - List templates (filter by `type=proposal`)
- **POST** `/templates/templates` - Create a template (include `sections_data` array)
- **GET** `/templates/templates/{id}` - Get a template with sections_data
- **PUT** `/templates/templates/{id}` - Update a template
- **DELETE** `/templates/templates/{id}` - Delete a template