Open this in Magpie

A proposal can be written as one JSON document and pasted into Magpie. New proposal → Paste JSON starts a proposal from it; Import JSON in a draft's File menu replaces the draft's content with it; New starter on the Starters page adds a team starter. Export JSON, in a draft's File menu or a sent proposal's More menu, downloads a proposal in the same format, and an export imports back unchanged.

Use Copy the prompt in the import box to copy these instructions for an assistant you use. It asks you what it needs, then writes the document.

Importing is all or nothing. The whole document is checked before anything is saved, and a mistake is named by its place in the document, such as "sections[2].lines[0].unitPrice" must be an amount. An imported proposal is a draft: nothing reaches a client until someone sends it, and the send check shows its totals first.

The document

{
  "schema": "magpie.proposal",
  "version": 1,
  "title": "Website design and build",
  "currency": "USD",
  "language": "en",
  "validForDays": 30,
  "sections": [],
  "discount": null,
  "schedule": [],
  "startWorkWhen": "deposit_paid",
  "recurringStart": { "on": "acceptance", "endAfter": 12 }
}
Field Type Notes
schema string, optional "magpie.proposal".
version number, optional 1.
title string, required The proposal's title.
currency string, optional A three-letter code such as USD, EUR or GBP. USD if left out.
language string, optional The client page's language: en, fr, es or de. en if left out. What you write is not translated.
validForDays number, optional How many days the proposal can be accepted for. Proposals settings decides if left out.
sections array, required The sections in order. See below.
discount object or null, optional { "type": "percent", "value": "10" } or { "type": "amount", "value": "250" }, on one-time lines only.
schedule array, optional The payments. See below. Empty for one final payment.
startWorkWhen string, optional "signed" or "deposit_paid". "deposit_paid" needs a deposit.
recurringStart object, optional When recurring invoices start. See below.

Every id is optional: letters, digits, - or _, different from every other id in the document. Magpie makes one when it is left out.

Sections

Every section has type and may have id, title and hidden (true keeps it out of the client's page).

type Fields
cover subtitle, imageUuid
text, terms markdown or blocks
pricing markdown or blocks for an introduction, then lines, or choice: "package" and packages
timeline markdown or blocks, and phases: { "name", "description", "start", "end", "days" } with dates as YYYY-MM-DD
team members: { "name", "role", "bio", "imageUuid" }
testimonials items: { "quote", "name", "role" }
faq items: { "question", "answer" }
images images: { "imageUuid", "alt", "caption" }
video video: { "url", "caption" } for a YouTube, Vimeo or Loom address
files files: { "fileUuid", "name" }

Pictures and files are uploaded in Magpie, not in the document: leave out imageUuid and the images, video and files sections, and add them in the editor.

Text

markdown takes Markdown: #, ## and ### headings, - bullets, 1. numbered items, > quotes, **bold**, *italic* and [links](https://example.com). Fields such as {{client.firstName}} are filled in for the client.

blocks is the exact form an export uses: a list of { "type", "level", "runs" }, where type is paragraph, heading (with level 1 to 3), bullet-list, numbered-list or quote, and each run is { "text", "marks" } with marks bold, italic, underline or link (with href). A run with "placeholder": true is text the writer must replace before sending.

Pricing lines

{ "name": "Design", "description": "Page designs for desktop and phone", "quantity": "1", "unit": "", "unitPrice": "2500.00", "taxRate": "none", "billing": "once" }
Field Type Notes
name string, required The line's name.
description string, optional Shown under the name.
quantity string or number, optional Up to 4 decimal places. 1 if left out.
unit string, optional Such as hour.
unitPrice string or number, required Typed as on an invoice: 2500, 2500.00 or 2,500.00.
taxRate string, optional The name of one of your tax rates in Invoicing, or "none".
billing string, optional once, monthly, quarterly or yearly. once if left out.
optional boolean, optional The client adds or removes it. Not allowed in a package.
selected boolean, optional Whether an optional line starts added.
adjustable object, optional { "min": "1", "max": "10", "step": "1" }: the client chooses the quantity.
example boolean, optional An example price the writer must replace before sending.

A package is { "name", "description", "recommended", "lines" }. A package choice has 2 to 4 packages and at most one recommended.

Payments

{ "kind": "deposit", "label": "Deposit", "percent": "50" }

kind is deposit (first only), date, milestone or final (last only). Give percent or amount; the final payment may leave both out and takes what is left. A date payment has date (YYYY-MM-DD) or daysAfter (days after acceptance). Percentages are of the one-time total before tax and add up to 100 at most.

recurringStart is { "on": "acceptance" }, { "on": "date", "date": "2026-11-01" } or { "on": "days_after", "days": 30 }, with an optional endAfter: how many invoices to send.

A complete example

A website proposal with two packages, an optional line, a monthly line and a deposit:

{
  "schema": "magpie.proposal",
  "version": 1,
  "title": "New website for Northwind Bakery",
  "currency": "USD",
  "validForDays": 30,
  "sections": [
    { "type": "cover", "title": "New website for Northwind Bakery", "subtitle": "Prepared for {{client.company}} by {{business.name}}" },
    { "type": "text", "title": "The project", "markdown": "A new website for Northwind Bakery that shows the menu, takes cake orders and works well on phones.\n\n## What you will provide\n\n- Photos of the shop and the cakes\n- The menu and prices" },
    { "type": "pricing", "title": "Website", "choice": "package", "packages": [
      { "name": "Essential", "description": "Up to 5 pages.", "lines": [
        { "name": "Design", "unitPrice": "2500" },
        { "name": "Build and launch", "unitPrice": "3000" }
      ] },
      { "name": "Complete", "description": "Up to 12 pages, with online cake orders.", "recommended": true, "lines": [
        { "name": "Design", "unitPrice": "3500" },
        { "name": "Build and launch", "unitPrice": "4500" },
        { "name": "Online cake orders", "unitPrice": "1500" }
      ] }
    ] },
    { "type": "pricing", "title": "Extras and care", "lines": [
      { "name": "Copywriting", "description": "Text for every page", "quantity": "1", "unit": "page", "unitPrice": "120", "optional": true, "adjustable": { "min": "1", "max": "12", "step": "1" } },
      { "name": "Hosting and updates", "unitPrice": "150", "billing": "monthly" }
    ] },
    { "type": "timeline", "title": "Timeline", "phases": [
      { "name": "Discovery and design", "days": 10 },
      { "name": "Build", "days": 15 },
      { "name": "Launch", "days": 2 }
    ] },
    { "type": "faq", "title": "Questions", "items": [
      { "question": "Can I update the menu myself?", "answer": "Yes. You can change the menu and prices at any time." }
    ] },
    { "type": "terms", "title": "Terms", "markdown": "The deposit is due on acceptance and the rest on completion. Hosting is billed monthly and can be cancelled with 30 days' notice." }
  ],
  "schedule": [
    { "kind": "deposit", "label": "Deposit", "percent": "50" },
    { "kind": "final", "label": "On completion" }
  ],
  "startWorkWhen": "deposit_paid",
  "recurringStart": { "on": "days_after", "days": 30 }
}

Price list

Import prices on the Price list takes a document of prices to add. It only adds; prices already in the list are not changed.

{
  "currency": "USD",
  "prices": [
    { "name": "Design", "unit": "hour", "unitPrice": "95", "taxRate": "none" },
    { "name": "Hosting and updates", "unitPrice": "150", "billing": "monthly" }
  ]
}

Each price has name (required), description, unit, unitPrice (required), taxRate (the name of one of your tax rates, or "none") and billing (once, monthly, quarterly or yearly). currency applies to every price, and is Proposals settings' currency if left out.

For more help, Contact support.

Ask Magpie support

Send Magpie staff a question about anything this article does not answer.