# PUT /v1/orders/{orderId}/lines/{lineId}

**Service:** Orders  
**Operation:** `OrderService_UpdateOrderLineItem`

Send the full replacement line content; the whole line is replaced and the order's totals are recomputed. Identify the line by the server-assigned id returned when you read the order. A line id that does not belong to the order is rejected with HTTP 404 (not_found). An order that has been invoiced is rejected with HTTP 400 (failed_precondition). A flashing line cannot yet be replaced and is rejected with HTTP 501 (not_implemented).

Concurrent writes to the same line are not detected: the last write wins. Re-read the order after writing if other clients may be editing it.

## Parameters

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orderId` | path | string | yes | The id of the order the line belongs to, as returned by CreateOrder. |
| `lineId` | path | string | yes | The server-assigned id of the line to replace, as returned when the order is read. This has a different form from the order id. |
| `fields` | query | string | no | Comma-separated response fields to include, using camelCase JSON names (e.g. `orderId,total.amountMicros`). Dot paths reach into nested objects and map transparently across arrays. Paths are relative to the resource, not the response envelope; envelope keys like `nextPageToken` are always preserved. Only 2xx JSON responses are filtered; error bodies pass through unmodified. Unknown names are silently ignored. Takes precedence over `excludeFields` when both are provided. |
| `excludeFields` | query | string | no | Comma-separated response fields to exclude, using camelCase JSON names. Dot paths and array-transparency work the same as `fields`. Paths are relative to the resource, not the response envelope. Only 2xx JSON responses are filtered; error bodies pass through unmodified. Ignored when `fields` is also provided. |

## Request body

`SalesLine` (application/json)

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `onTheFly` | OnTheFlyLine | no | A free-form line not tied to a catalogue product. Set exactly one of the six line-type fields. |
| `onTheFly.productName` | string | yes | Name of the item. Required. |
| `onTheFly.productDescription` | string | no | Optional longer description of the item. |
| `onTheFly.colour` | string | no | Optional colour for the item. |
| `onTheFly.pricing` | LinePricing | no | Pricing for this line. Unit price is required; the line total is required until server-side derivation is enabled for your account (see `totalPrice` on LinePricing), except on custom-formula lines, where it is always required. Pricing for a single priced line: quantity, prices, discount, cost, markup, margin, and pricing strategy. On priced lines the server validates — or, once derivation is enabled for your account, derives — the line total from the quantity, unit price, and discount; see `totalPrice` for the exact formula, the rounding rule, and what happens if it does not match. |
| `onTheFly.pricing.quantity` | string | no | Quantity for this line, as a decimal string (e.g. "2" or "2.5"). Supports up to 4 decimal places. It is the first factor of the line-total formula documented on `totalPrice` — EXCEPT on measurement-priced (lineal/square) lines, where the measured length or area alone sets the priced amount and this factor is treated as 1 whenever the server derives or checks the total. Do not multiply a measurement-priced total by quantity. (Only on free-text lines on accounts WITHOUT server-side derivation does the legacy formula still multiply by it — see `totalPrice`). |
| `onTheFly.pricing.unitPrice` | Money | no | Per-unit price. Required on priced lines — except on catalogue lines with server-side derivation enabled for your account, where you may omit it and supply `cost` plus `markup` instead: the server computes it as cost x (1 + markup/100) (or cost + markup for a fixed markup). If you can send the price directly, do; the derivation exists for callers whose source system stores only cost and markup. The server rounds this to 4 decimal places (half up) before pricing, so unit-price precision finer than that (micro amounts that are not a multiple of 100) is not preserved and can shift the computed line total. |
| `onTheFly.pricing.totalPrice` | Money | no | The line total, as a Money amount in micros.  Server-side derivation is rolling out account by account. Once it is enabled for your account, this field is optional on most priced lines — omit it (leave the whole Money object out; an empty Money is a supplied $0.00) and the server computes it. Until then it is required on priced lines, exactly as before.  The formula is:    quantity * `unitPrice` * (1 - discount / 100)  rounded to the nearest cent — 2 decimal places, half up (0.005 rounds up). For lineal or square measurement pricing the result is then multiplied by the measured length or area the server derives from the line's measurement details before rounding — and on measurement-priced lines the quantity factor is pinned to 1 once derivation is enabled for your account, whether the server derives the total or checks one you send: the measurements alone set the priced amount. (Without derivation, free-text lines still multiply by `quantity` — match it when computing such a total yourself.) Deriving needs a non-zero quantity or measurement set (deriving with a zero quantity or an empty measurement set is rejected rather than stored as $0.00; a zero unit price — a free line — still derives). On a product kit priced as a standard kit, an omitted parent total is derived as the sum of its components and sub-kits (omitted sub-kit totals are likewise derived from their components) — priced component totals must accompany the request; a missing one is rejected rather than summed as zero. A supplied kit total, at any tier, is stored as sent.  If you DO send a value on a catalogue (once derivation is enabled for your account), on-the-fly, or labour line, it is checked against the formula and a mismatch is rejected with HTTP 400. Send the amount as a whole number of cents (`amountMicros` a multiple of 10000); a sub-cent amount is rounded to the nearest cent before the check.  Exceptions, where the total is never derived — send a correct value, because these lines are stored as sent: |
| `onTheFly.pricing.discount` | string | no | Discount applied to the line, as a decimal percentage string (e.g. "10.00" means 10%). Supports up to 2 decimal places. In the line-total formula on `totalPrice` it enters as the factor (1 - discount / 100). |
| `onTheFly.pricing.cost` | Money | no | Unit cost for this line, used to compute margin — and, with derivation enabled, the base the server recomputes `markup` (and an omitted `unitPrice`) from. Rounded to 4 decimal places (half up) before use, so sub-4dp cost precision is not preserved. |
| `onTheFly.pricing.markup` | string | no | Markup applied to the line, as a decimal string — either a money amount or a percentage, depending on `markupIsPercentage`.  With server-side derivation enabled for your account: whenever `cost` is non-zero, the value you send here is DISCARDED and recomputed from `cost` and the unit price (as a percentage — `markupIsPercentage` reads back true), so the stored markup always agrees with the stored prices. Do not expect to read back the value you sent. With a zero or absent cost your value is kept as sent. |
| `onTheFly.pricing.markupIsPercentage` | boolean | no | Whether markup is a percentage (true) or a fixed amount (false). Omit it to use the default, true; send false only for a fixed-amount markup. Always present on reads, and reads back true whenever the server recomputed the markup (see `markup`). |
| `onTheFly.pricing.margin` | Money | no | Margin for the line. When supplied, it is validated against cost and quantity — and with derivation enabled it is recomputed alongside the total whenever `cost` is present, so (like `markup`) the stored value may differ from what you sent. Simplest: omit it and let the server compute. |
| `onTheFly.pricing.pricingStrategy` | PricingStrategy | no | How this line is priced (per-unit quantity, lineal, or square measurement). Defaults to per-unit quantity pricing. How a quantity is interpreted for pricing — whether it means a count of each, a length, or an area.  On a catalogue product this is the product's pricing basis. On an order or quote line, measurement-based strategies (lineal or square metres/feet) require the line's measurement details to be supplied.   - PRICING_STRATEGY_UNSPECIFIED: Unset, or a legacy product with no pricing strategy recorded.  - PRICING_STRATEGY_BASIC_QUANTITIES: Quantity is a simple per-each count.  - PRICING_STRATEGY_LINEAL_METRES: Quantity is a length in lineal metres.  - PRICING_STRATEGY_CUSTOM_FORMULA: Quantity is priced by a custom formula.  - PRICING_STRATEGY_SQUARE_METRES: Quantity is an area in square metres.  - PRICING_STRATEGY_LINEAL_FEET: Quantity is a length in lineal feet.  - PRICING_STRATEGY_SQUARE_FEET: Quantity is an area in square feet. One of: PRICING_STRATEGY_UNSPECIFIED, PRICING_STRATEGY_BASIC_QUANTITIES, PRICING_STRATEGY_LINEAL_METRES, PRICING_STRATEGY_CUSTOM_FORMULA, PRICING_STRATEGY_SQUARE_METRES, PRICING_STRATEGY_LINEAL_FEET, PRICING_STRATEGY_SQUARE_FEET. |
| `onTheFly.pricing.priceLevel` | string | no | Optional named price level applied to this line. |
| `onTheFly.pricing.isTaxFree` | boolean | no | Whether this line is exempt from tax. |
| `onTheFly.pricing.tax` | TaxDetail | no | The tax applied to this line: rate, code, and jurisdiction. Complements the `isTaxFree` flag. In v1 the server applies your account's tax settings to taxable lines; this object reserves the shape for richer per-line tax later. |
| `onTheFly.pricing.measurements` | MeasurementEntry[] | no | The measurements that price this line, for the lineal and square pricing strategies. Units follow the strategy: metres for *_METRES, feet for *_FEET (see MeasurementEntry). Requires an explicit, measurement-priced `pricingStrategy` on this same object. On these strategies the measured amount is the priced quantity — `quantity` is NOT a factor (on accounts without server-side derivation, free-text lines are the one legacy exception; see `quantity`); the server sums these pieces (applying your account's minimum-length setting on lineal strategies) to derive the amount that scales the line total. One measured piece (or panel) in a measurement-priced line or kit component. Values are decimal strings in the line's strategy-native unit: metres for the *_METRES pricing strategies, feet for *_FEET. |
| `onTheFly.pricing.measurements.length` | string | no | Length of this piece, as a decimal string in the strategy's unit (e.g. "2.4" metres, or "8" feet). |
| `onTheFly.pricing.measurements.width` | string | no | Width of this piece, as a decimal string in the strategy's unit. Square strategies only — a width on a lineal entry is rejected, and a square entry without one is rejected. |
| `onTheFly.pricing.measurements.amount` | string | no | How many pieces of this size, as a decimal string. Defaults to 1. |
| `onTheFly.pricing.asBuiltMeasurements` | MeasurementEntry[] | no | As-built measurements — what production actually cut, in the same shape and units as `measurements`. These drive cost, margin, and stock consumption, never the line price. Optional: whenever omitted (create and update alike) they default to `measurements`. Send them only when your as-built figures differ from what was quoted. One measured piece (or panel) in a measurement-priced line or kit component. Values are decimal strings in the line's strategy-native unit: metres for the *_METRES pricing strategies, feet for *_FEET. |
| `onTheFly.pricing.asBuiltMeasurements.length` | string | no | Length of this piece, as a decimal string in the strategy's unit (e.g. "2.4" metres, or "8" feet). |
| `onTheFly.pricing.asBuiltMeasurements.width` | string | no | Width of this piece, as a decimal string in the strategy's unit. Square strategies only — a width on a lineal entry is rejected, and a square entry without one is rejected. |
| `onTheFly.pricing.asBuiltMeasurements.amount` | string | no | How many pieces of this size, as a decimal string. Defaults to 1. |
| `onTheFly.attributes` | object[] | no | Additional named attributes for the line, as a JSON array of {name, value} entries (for example {name: "Size", value: "76x38mm"}). An entry may also carry flags that hide it from specific documents or views, such as the invoice PDF or the customer view. |
| `catalogue` | CatalogueLine | no | A line for a product from your catalogue. Set exactly one of the six line-type fields. |
| `catalogue.productId` | string | yes | The id of the catalogue product for this line. Required, and must match an existing catalogue product; an unknown id rejects the whole request. |
| `catalogue.productRowId` | string | no | Optional id of a specific row within the catalogue product. If set, it must resolve. |
| `catalogue.rowPriceId` | string | no | Optional id selecting the row's price at one of your price levels — the `rowPriceId` returned by the catalogue (not the price level's own id). If set, it must resolve. |
| `catalogue.productName` | string | no | Display name for the line. |
| `catalogue.productDescription` | string | no | Longer description for the line. |
| `catalogue.categoryName` | string | no | Category name for the line. |
| `catalogue.priceName` | string | no | Price name shown for the line. |
| `catalogue.params` | object[] | no | Product parameters as a JSON array of {name, value} entries (for example [{"name": "Colour", "value": "Monument"}]). The colour is taken from the "Colour" parameter and validated against the product's available colours. |
| `catalogue.attributes` | object[] | no | Additional named attributes for the line, as a JSON array of {name, value} entries (for example {name: "Size", value: "76x38mm"}). An entry may also carry flags that hide it from specific documents or views, such as the invoice PDF or the customer view. |
| `catalogue.pricing` | LinePricing | no | Pricing for this line. The catalogue does not price the line; you supply it. Pricing for a single priced line: quantity, prices, discount, cost, markup, margin, and pricing strategy. On priced lines the server validates — or, once derivation is enabled for your account, derives — the line total from the quantity, unit price, and discount; see `totalPrice` for the exact formula, the rounding rule, and what happens if it does not match. |
| `catalogue.pricing.quantity` | string | no | Quantity for this line, as a decimal string (e.g. "2" or "2.5"). Supports up to 4 decimal places. It is the first factor of the line-total formula documented on `totalPrice` — EXCEPT on measurement-priced (lineal/square) lines, where the measured length or area alone sets the priced amount and this factor is treated as 1 whenever the server derives or checks the total. Do not multiply a measurement-priced total by quantity. (Only on free-text lines on accounts WITHOUT server-side derivation does the legacy formula still multiply by it — see `totalPrice`). |
| `catalogue.pricing.unitPrice` | Money | no | Per-unit price. Required on priced lines — except on catalogue lines with server-side derivation enabled for your account, where you may omit it and supply `cost` plus `markup` instead: the server computes it as cost x (1 + markup/100) (or cost + markup for a fixed markup). If you can send the price directly, do; the derivation exists for callers whose source system stores only cost and markup. The server rounds this to 4 decimal places (half up) before pricing, so unit-price precision finer than that (micro amounts that are not a multiple of 100) is not preserved and can shift the computed line total. |
| `catalogue.pricing.totalPrice` | Money | no | The line total, as a Money amount in micros.  Server-side derivation is rolling out account by account. Once it is enabled for your account, this field is optional on most priced lines — omit it (leave the whole Money object out; an empty Money is a supplied $0.00) and the server computes it. Until then it is required on priced lines, exactly as before.  The formula is:    quantity * `unitPrice` * (1 - discount / 100)  rounded to the nearest cent — 2 decimal places, half up (0.005 rounds up). For lineal or square measurement pricing the result is then multiplied by the measured length or area the server derives from the line's measurement details before rounding — and on measurement-priced lines the quantity factor is pinned to 1 once derivation is enabled for your account, whether the server derives the total or checks one you send: the measurements alone set the priced amount. (Without derivation, free-text lines still multiply by `quantity` — match it when computing such a total yourself.) Deriving needs a non-zero quantity or measurement set (deriving with a zero quantity or an empty measurement set is rejected rather than stored as $0.00; a zero unit price — a free line — still derives). On a product kit priced as a standard kit, an omitted parent total is derived as the sum of its components and sub-kits (omitted sub-kit totals are likewise derived from their components) — priced component totals must accompany the request; a missing one is rejected rather than summed as zero. A supplied kit total, at any tier, is stored as sent.  If you DO send a value on a catalogue (once derivation is enabled for your account), on-the-fly, or labour line, it is checked against the formula and a mismatch is rejected with HTTP 400. Send the amount as a whole number of cents (`amountMicros` a multiple of 10000); a sub-cent amount is rounded to the nearest cent before the check.  Exceptions, where the total is never derived — send a correct value, because these lines are stored as sent: |
| `catalogue.pricing.discount` | string | no | Discount applied to the line, as a decimal percentage string (e.g. "10.00" means 10%). Supports up to 2 decimal places. In the line-total formula on `totalPrice` it enters as the factor (1 - discount / 100). |
| `catalogue.pricing.cost` | Money | no | Unit cost for this line, used to compute margin — and, with derivation enabled, the base the server recomputes `markup` (and an omitted `unitPrice`) from. Rounded to 4 decimal places (half up) before use, so sub-4dp cost precision is not preserved. |
| `catalogue.pricing.markup` | string | no | Markup applied to the line, as a decimal string — either a money amount or a percentage, depending on `markupIsPercentage`.  With server-side derivation enabled for your account: whenever `cost` is non-zero, the value you send here is DISCARDED and recomputed from `cost` and the unit price (as a percentage — `markupIsPercentage` reads back true), so the stored markup always agrees with the stored prices. Do not expect to read back the value you sent. With a zero or absent cost your value is kept as sent. |
| `catalogue.pricing.markupIsPercentage` | boolean | no | Whether markup is a percentage (true) or a fixed amount (false). Omit it to use the default, true; send false only for a fixed-amount markup. Always present on reads, and reads back true whenever the server recomputed the markup (see `markup`). |
| `catalogue.pricing.margin` | Money | no | Margin for the line. When supplied, it is validated against cost and quantity — and with derivation enabled it is recomputed alongside the total whenever `cost` is present, so (like `markup`) the stored value may differ from what you sent. Simplest: omit it and let the server compute. |
| `catalogue.pricing.pricingStrategy` | PricingStrategy | no | How this line is priced (per-unit quantity, lineal, or square measurement). Defaults to per-unit quantity pricing. How a quantity is interpreted for pricing — whether it means a count of each, a length, or an area.  On a catalogue product this is the product's pricing basis. On an order or quote line, measurement-based strategies (lineal or square metres/feet) require the line's measurement details to be supplied.   - PRICING_STRATEGY_UNSPECIFIED: Unset, or a legacy product with no pricing strategy recorded.  - PRICING_STRATEGY_BASIC_QUANTITIES: Quantity is a simple per-each count.  - PRICING_STRATEGY_LINEAL_METRES: Quantity is a length in lineal metres.  - PRICING_STRATEGY_CUSTOM_FORMULA: Quantity is priced by a custom formula.  - PRICING_STRATEGY_SQUARE_METRES: Quantity is an area in square metres.  - PRICING_STRATEGY_LINEAL_FEET: Quantity is a length in lineal feet.  - PRICING_STRATEGY_SQUARE_FEET: Quantity is an area in square feet. One of: PRICING_STRATEGY_UNSPECIFIED, PRICING_STRATEGY_BASIC_QUANTITIES, PRICING_STRATEGY_LINEAL_METRES, PRICING_STRATEGY_CUSTOM_FORMULA, PRICING_STRATEGY_SQUARE_METRES, PRICING_STRATEGY_LINEAL_FEET, PRICING_STRATEGY_SQUARE_FEET. |
| `catalogue.pricing.priceLevel` | string | no | Optional named price level applied to this line. |
| `catalogue.pricing.isTaxFree` | boolean | no | Whether this line is exempt from tax. |
| `catalogue.pricing.tax` | TaxDetail | no | The tax applied to this line: rate, code, and jurisdiction. Complements the `isTaxFree` flag. In v1 the server applies your account's tax settings to taxable lines; this object reserves the shape for richer per-line tax later. |
| `catalogue.pricing.measurements` | MeasurementEntry[] | no | The measurements that price this line, for the lineal and square pricing strategies. Units follow the strategy: metres for *_METRES, feet for *_FEET (see MeasurementEntry). Requires an explicit, measurement-priced `pricingStrategy` on this same object. On these strategies the measured amount is the priced quantity — `quantity` is NOT a factor (on accounts without server-side derivation, free-text lines are the one legacy exception; see `quantity`); the server sums these pieces (applying your account's minimum-length setting on lineal strategies) to derive the amount that scales the line total. One measured piece (or panel) in a measurement-priced line or kit component. Values are decimal strings in the line's strategy-native unit: metres for the *_METRES pricing strategies, feet for *_FEET. |
| `catalogue.pricing.measurements.length` | string | no | Length of this piece, as a decimal string in the strategy's unit (e.g. "2.4" metres, or "8" feet). |
| `catalogue.pricing.measurements.width` | string | no | Width of this piece, as a decimal string in the strategy's unit. Square strategies only — a width on a lineal entry is rejected, and a square entry without one is rejected. |
| `catalogue.pricing.measurements.amount` | string | no | How many pieces of this size, as a decimal string. Defaults to 1. |
| `catalogue.pricing.asBuiltMeasurements` | MeasurementEntry[] | no | As-built measurements — what production actually cut, in the same shape and units as `measurements`. These drive cost, margin, and stock consumption, never the line price. Optional: whenever omitted (create and update alike) they default to `measurements`. Send them only when your as-built figures differ from what was quoted. One measured piece (or panel) in a measurement-priced line or kit component. Values are decimal strings in the line's strategy-native unit: metres for the *_METRES pricing strategies, feet for *_FEET. |
| `catalogue.pricing.asBuiltMeasurements.length` | string | no | Length of this piece, as a decimal string in the strategy's unit (e.g. "2.4" metres, or "8" feet). |
| `catalogue.pricing.asBuiltMeasurements.width` | string | no | Width of this piece, as a decimal string in the strategy's unit. Square strategies only — a width on a lineal entry is rejected, and a square entry without one is rejected. |
| `catalogue.pricing.asBuiltMeasurements.amount` | string | no | How many pieces of this size, as a decimal string. Defaults to 1. |
| `labour` | LabourLine | no | A line charging for labour. Set exactly one of the six line-type fields. |
| `labour.labourUserId` | string | yes | The id of the worker who performed the labour. Required, and must be an active user in the company that owns the order or quote. |
| `labour.productName` | string | no | A short name for the labour. |
| `labour.productDescription` | string | no | A longer description of the labour. |
| `labour.pricing` | LinePricing | no | Quantity and pricing for this line: the hours in `quantity`, the charge rate in `unitPrice` and the cost rate in `cost`. There are no rate overrides elsewhere on the line, and the worker's own rates are not applied: an omitted `cost` is stored as zero, not taken from the user's `hourlyRateCost`. Pricing for a single priced line: quantity, prices, discount, cost, markup, margin, and pricing strategy. On priced lines the server validates — or, once derivation is enabled for your account, derives — the line total from the quantity, unit price, and discount; see `totalPrice` for the exact formula, the rounding rule, and what happens if it does not match. |
| `labour.pricing.quantity` | string | no | Quantity for this line, as a decimal string (e.g. "2" or "2.5"). Supports up to 4 decimal places. It is the first factor of the line-total formula documented on `totalPrice` — EXCEPT on measurement-priced (lineal/square) lines, where the measured length or area alone sets the priced amount and this factor is treated as 1 whenever the server derives or checks the total. Do not multiply a measurement-priced total by quantity. (Only on free-text lines on accounts WITHOUT server-side derivation does the legacy formula still multiply by it — see `totalPrice`). |
| `labour.pricing.unitPrice` | Money | no | Per-unit price. Required on priced lines — except on catalogue lines with server-side derivation enabled for your account, where you may omit it and supply `cost` plus `markup` instead: the server computes it as cost x (1 + markup/100) (or cost + markup for a fixed markup). If you can send the price directly, do; the derivation exists for callers whose source system stores only cost and markup. The server rounds this to 4 decimal places (half up) before pricing, so unit-price precision finer than that (micro amounts that are not a multiple of 100) is not preserved and can shift the computed line total. |
| `labour.pricing.totalPrice` | Money | no | The line total, as a Money amount in micros.  Server-side derivation is rolling out account by account. Once it is enabled for your account, this field is optional on most priced lines — omit it (leave the whole Money object out; an empty Money is a supplied $0.00) and the server computes it. Until then it is required on priced lines, exactly as before.  The formula is:    quantity * `unitPrice` * (1 - discount / 100)  rounded to the nearest cent — 2 decimal places, half up (0.005 rounds up). For lineal or square measurement pricing the result is then multiplied by the measured length or area the server derives from the line's measurement details before rounding — and on measurement-priced lines the quantity factor is pinned to 1 once derivation is enabled for your account, whether the server derives the total or checks one you send: the measurements alone set the priced amount. (Without derivation, free-text lines still multiply by `quantity` — match it when computing such a total yourself.) Deriving needs a non-zero quantity or measurement set (deriving with a zero quantity or an empty measurement set is rejected rather than stored as $0.00; a zero unit price — a free line — still derives). On a product kit priced as a standard kit, an omitted parent total is derived as the sum of its components and sub-kits (omitted sub-kit totals are likewise derived from their components) — priced component totals must accompany the request; a missing one is rejected rather than summed as zero. A supplied kit total, at any tier, is stored as sent.  If you DO send a value on a catalogue (once derivation is enabled for your account), on-the-fly, or labour line, it is checked against the formula and a mismatch is rejected with HTTP 400. Send the amount as a whole number of cents (`amountMicros` a multiple of 10000); a sub-cent amount is rounded to the nearest cent before the check.  Exceptions, where the total is never derived — send a correct value, because these lines are stored as sent: |
| `labour.pricing.discount` | string | no | Discount applied to the line, as a decimal percentage string (e.g. "10.00" means 10%). Supports up to 2 decimal places. In the line-total formula on `totalPrice` it enters as the factor (1 - discount / 100). |
| `labour.pricing.cost` | Money | no | Unit cost for this line, used to compute margin — and, with derivation enabled, the base the server recomputes `markup` (and an omitted `unitPrice`) from. Rounded to 4 decimal places (half up) before use, so sub-4dp cost precision is not preserved. |
| `labour.pricing.markup` | string | no | Markup applied to the line, as a decimal string — either a money amount or a percentage, depending on `markupIsPercentage`.  With server-side derivation enabled for your account: whenever `cost` is non-zero, the value you send here is DISCARDED and recomputed from `cost` and the unit price (as a percentage — `markupIsPercentage` reads back true), so the stored markup always agrees with the stored prices. Do not expect to read back the value you sent. With a zero or absent cost your value is kept as sent. |
| `labour.pricing.markupIsPercentage` | boolean | no | Whether markup is a percentage (true) or a fixed amount (false). Omit it to use the default, true; send false only for a fixed-amount markup. Always present on reads, and reads back true whenever the server recomputed the markup (see `markup`). |
| `labour.pricing.margin` | Money | no | Margin for the line. When supplied, it is validated against cost and quantity — and with derivation enabled it is recomputed alongside the total whenever `cost` is present, so (like `markup`) the stored value may differ from what you sent. Simplest: omit it and let the server compute. |
| `labour.pricing.pricingStrategy` | PricingStrategy | no | How this line is priced (per-unit quantity, lineal, or square measurement). Defaults to per-unit quantity pricing. How a quantity is interpreted for pricing — whether it means a count of each, a length, or an area.  On a catalogue product this is the product's pricing basis. On an order or quote line, measurement-based strategies (lineal or square metres/feet) require the line's measurement details to be supplied.   - PRICING_STRATEGY_UNSPECIFIED: Unset, or a legacy product with no pricing strategy recorded.  - PRICING_STRATEGY_BASIC_QUANTITIES: Quantity is a simple per-each count.  - PRICING_STRATEGY_LINEAL_METRES: Quantity is a length in lineal metres.  - PRICING_STRATEGY_CUSTOM_FORMULA: Quantity is priced by a custom formula.  - PRICING_STRATEGY_SQUARE_METRES: Quantity is an area in square metres.  - PRICING_STRATEGY_LINEAL_FEET: Quantity is a length in lineal feet.  - PRICING_STRATEGY_SQUARE_FEET: Quantity is an area in square feet. One of: PRICING_STRATEGY_UNSPECIFIED, PRICING_STRATEGY_BASIC_QUANTITIES, PRICING_STRATEGY_LINEAL_METRES, PRICING_STRATEGY_CUSTOM_FORMULA, PRICING_STRATEGY_SQUARE_METRES, PRICING_STRATEGY_LINEAL_FEET, PRICING_STRATEGY_SQUARE_FEET. |
| `labour.pricing.priceLevel` | string | no | Optional named price level applied to this line. |
| `labour.pricing.isTaxFree` | boolean | no | Whether this line is exempt from tax. |
| `labour.pricing.tax` | TaxDetail | no | The tax applied to this line: rate, code, and jurisdiction. Complements the `isTaxFree` flag. In v1 the server applies your account's tax settings to taxable lines; this object reserves the shape for richer per-line tax later. |
| `labour.pricing.measurements` | MeasurementEntry[] | no | The measurements that price this line, for the lineal and square pricing strategies. Units follow the strategy: metres for *_METRES, feet for *_FEET (see MeasurementEntry). Requires an explicit, measurement-priced `pricingStrategy` on this same object. On these strategies the measured amount is the priced quantity — `quantity` is NOT a factor (on accounts without server-side derivation, free-text lines are the one legacy exception; see `quantity`); the server sums these pieces (applying your account's minimum-length setting on lineal strategies) to derive the amount that scales the line total. One measured piece (or panel) in a measurement-priced line or kit component. Values are decimal strings in the line's strategy-native unit: metres for the *_METRES pricing strategies, feet for *_FEET. |
| `labour.pricing.measurements.length` | string | no | Length of this piece, as a decimal string in the strategy's unit (e.g. "2.4" metres, or "8" feet). |
| `labour.pricing.measurements.width` | string | no | Width of this piece, as a decimal string in the strategy's unit. Square strategies only — a width on a lineal entry is rejected, and a square entry without one is rejected. |
| `labour.pricing.measurements.amount` | string | no | How many pieces of this size, as a decimal string. Defaults to 1. |
| `labour.pricing.asBuiltMeasurements` | MeasurementEntry[] | no | As-built measurements — what production actually cut, in the same shape and units as `measurements`. These drive cost, margin, and stock consumption, never the line price. Optional: whenever omitted (create and update alike) they default to `measurements`. Send them only when your as-built figures differ from what was quoted. One measured piece (or panel) in a measurement-priced line or kit component. Values are decimal strings in the line's strategy-native unit: metres for the *_METRES pricing strategies, feet for *_FEET. |
| `labour.pricing.asBuiltMeasurements.length` | string | no | Length of this piece, as a decimal string in the strategy's unit (e.g. "2.4" metres, or "8" feet). |
| `labour.pricing.asBuiltMeasurements.width` | string | no | Width of this piece, as a decimal string in the strategy's unit. Square strategies only — a width on a lineal entry is rejected, and a square entry without one is rejected. |
| `labour.pricing.asBuiltMeasurements.amount` | string | no | How many pieces of this size, as a decimal string. Defaults to 1. |
| `notes` | NotesLine | no | A note line, with no pricing. Set exactly one of the six line-type fields. |
| `notes.notesType` | NotesType | yes | The kind of note. Required. Whether a notes line is internal-only or visible to the customer.   - NOTES_TYPE_UNSPECIFIED: Default, unset value. Not a valid choice for a notes line.  - NOTES_TYPE_INTERNAL: An internal note, not shown to the customer.  - NOTES_TYPE_EXTERNAL: An external note, visible to the customer. One of: NOTES_TYPE_UNSPECIFIED, NOTES_TYPE_INTERNAL, NOTES_TYPE_EXTERNAL. |
| `notes.notes` | string | no | The note text. |
| `notes.productName` | string | no | A short name for the note line. |
| `notes.productDescription` | string | no | A longer description for the note line. |
| `flashing` | FlashingLine | no | A flashing line, with its drawing and geometry. Set exactly one of the six line-type fields. A sheet-metal flashing line item: the flashing material, its specification, pricing, and its drawings.  A flashing line is created with its document (CreateQuote, CreateOrder) or added whole to a quote (AddQuoteLineItem); it cannot yet be added to an existing order, updated, or removed individually — those calls answer HTTP 501 (not_implemented). Its specification (`bends`, `totalGirth`, `totalLength`, `subitems`) and its prices are stored exactly as you send them: the API never derives, prices, or cross-checks a flashing, so compute them yourself from the drawing and cut list as described on each field. Lengths and girths are always millimetres (metres for `totalLength`), whatever the account's measurement system. |
| `flashing.templateId` | string | no | The id of the flashing material or template. Required when the order or quote is submitted. |
| `flashing.productName` | string | no | The display name of the flashing material. |
| `flashing.priceLevel` | string | no | The name of the price level applied to this line (for example "A"), not a price level id. Required when the order or quote is submitted; an empty value is stored as "A". |
| `flashing.colour` | string | no | The flashing colour. Required when the order or quote is submitted, and validated against the colours available for the template when `templateId` is set; without a template it is stored unchecked. |
| `flashing.thickness` | string | no | The material thickness, as a decimal string in millimetres (for example "0.55"). Required when the order or quote is submitted. Send the thickness of the selected template (`templateId`) — each thickness is a distinct template. It is stored as sent and not compared with the template, so a mismatch is saved silently. |
| `flashing.bends` | string | no | The number of bends in the flashing, as a decimal string. Count one bend for each point that joins two edges, plus the bends each finish adds (crush fold 2, open hook 2, feather 1, drip edge 1; the account's `crushFoldBendCount` setting, when set, replaces the crush-fold count). With `otherSides`, take the count from the side with the largest girth. Required when the order or quote is submitted, and must then be greater than zero. Stored as sent; not checked against the drawing. |
| `flashing.totalGirth` | string | no | The total girth of the flashing in millimetres, as a decimal string: the sum of every edge size in the drawing's `lines.values` (hidden edges excluded) plus the `size` of every finish. Edges of 110, 320 and 10 with a 10 mm crush fold give "450". With `otherSides`, use the side with the largest girth. Required when the order or quote is submitted, and must then be greater than zero. Stored as sent; not checked against the drawing. |
| `flashing.totalLength` | string | no | The total length of the flashing in metres, as a decimal string: the sum over `subitems` of amount × length ÷ 1000. Three pieces at 1200 plus two at 925 give "5.45". Stored as sent; not checked against `subitems`. |
| `flashing.unitPrice` | Money | no | The price per metre of the flashing. Required when the order or quote is submitted. |
| `flashing.unitPrice.amountMicros` | string | no | Amount in micros — millionths of the currency's major unit. 1.00 = 1_000_000 micros, so $12.34 is 12_340_000 — sent and returned over JSON as the string "12340000" (64-bit integers serialize as JSON strings). A whole number of cents (or pence, etc.) is a multiple of 10_000 micros. |
| `flashing.unitPrice.currency` | string | no | ISO 4217 currency code (3 letters, e.g. "AUD"). |
| `flashing.totalPrice` | Money | no | The total price for this line. Stored as sent and never derived or checked. Factory prices a flashing as `unitPrice` × the priced length, where each piece shorter than the account's `minimumFlashingLengthMm` is charged at that minimum, rounded to the cent. |
| `flashing.totalPrice.amountMicros` | string | no | Amount in micros — millionths of the currency's major unit. 1.00 = 1_000_000 micros, so $12.34 is 12_340_000 — sent and returned over JSON as the string "12340000" (64-bit integers serialize as JSON strings). A whole number of cents (or pence, etc.) is a multiple of 10_000 micros. |
| `flashing.totalPrice.currency` | string | no | ISO 4217 currency code (3 letters, e.g. "AUD"). |
| `flashing.customPrice` | Money | no | A custom total price for the line. When set, the document's subtotal uses it in place of `totalPrice`; `unitPrice` and `customPricePerLength` never enter the subtotal directly. |
| `flashing.customPrice.amountMicros` | string | no | Amount in micros — millionths of the currency's major unit. 1.00 = 1_000_000 micros, so $12.34 is 12_340_000 — sent and returned over JSON as the string "12340000" (64-bit integers serialize as JSON strings). A whole number of cents (or pence, etc.) is a multiple of 10_000 micros. |
| `flashing.customPrice.currency` | string | no | ISO 4217 currency code (3 letters, e.g. "AUD"). |
| `flashing.customPricePerLength` | Money | no | A custom price per metre. Factory uses it in place of `unitPrice` when computing `totalPrice`; send the resulting `totalPrice` yourself, as the API does not recompute it. |
| `flashing.customPricePerLength.amountMicros` | string | no | Amount in micros — millionths of the currency's major unit. 1.00 = 1_000_000 micros, so $12.34 is 12_340_000 — sent and returned over JSON as the string "12340000" (64-bit integers serialize as JSON strings). A whole number of cents (or pence, etc.) is a multiple of 10_000 micros. |
| `flashing.customPricePerLength.currency` | string | no | ISO 4217 currency code (3 letters, e.g. "AUD"). |
| `flashing.subitems` | object[] | no | The cut list: one entry per piece length, each an object with `amount` (the number of pieces) and `length` (the piece length in millimetres), both JSON numbers — for example `[{"amount": 3, "length": 1200}, {"amount": 2, "length": 925}]`. Stored as sent and not validated; a flashing with no lengths cannot be completed in Factory. Unlike `measurements` on other line kinds, lengths here are millimetre numbers, not metre strings. |
| `flashing.isTaxFree` | boolean | no | Whether this line is exempt from tax. |
| `flashing.drawing` | FlashingDrawing | yes | The main drawing for the flashing: the folded profile whose edge sizes give `totalGirth` and `bends`. Required — a flashing line without a drawing is rejected with HTTP 400 (validation_failure). Its `side` defaults to the far side. A flashing drawing: its identity, metadata, geometry, and the URL of its rendered SVG image. Carried only by flashing lines (`drawing` / `otherSides` on FlashingLine) — drawings describe a flashing's folded profile and are not a general-purpose image or attachment type. Geometry is sent in the same shape the drawing tool holds it: `points` are the vertices, joined by the edges listed in each point's `vectors` and `connect`; `lines.values` gives each edge's real size in millimetres; `angles.values` gives the angle at each vertex. Point coordinates only lay out the sketch — the sizes in `lines` are the dimensions. A drawing whose `points`, `lines` or `angles` exceeds about 15,000 characters of JSON is rejected with HTTP 400 (validation_failure). |
| `flashing.drawing.drawingId` | string | no | Server-assigned unique id of the drawing. Read-only output. |
| `flashing.drawing.tempId` | string | no | A client-assigned correlation id supplied when creating the drawing. The write that creates the drawing returns it paired with the assigned `drawingId` in the response's `drawings` mapping (CreateQuote, CreateOrder, AddQuoteLineItem) — use that to address UploadDrawingSvg. It must be unique across every drawing in the request, other sides included; a repeated id is rejected with HTTP 400 (validation_failure). Omit it and the server assigns unique ids for you. It is not stored, so reads do not return it. |
| `flashing.drawing.drawingNumber` | integer | no | The drawing's display number within the order or quote. Not assigned by the server: it is stored as sent (0 when omitted), and reads and printed documents order drawings by it, so number them 0, 1, 2… in line order. |
| `flashing.drawing.side` | DrawingSide | no | Which face of the flashing this drawing represents. When not specified, a line's main `drawing` is the far side and each of its `otherSides` is the near side. Which face of the flashing a drawing represents. When not specified, a flashing line's main `drawing` is the far side and each of its `otherSides` is the near side.   - DRAWING_SIDE_UNSPECIFIED: Default, unset value.  - DRAWING_SIDE_FAR: The far side of the flashing.  - DRAWING_SIDE_NEAR: The near side of the flashing. One of: DRAWING_SIDE_UNSPECIFIED, DRAWING_SIDE_FAR, DRAWING_SIDE_NEAR. |
| `flashing.drawing.isFreeDrawing` | boolean | no | Whether the edge sizes in `lines.values` are the drawing's dimensions. Send `true`: when false, Factory measures each edge from the points' canvas coordinates instead, so girth, bends and the displayed sizes come from the sketch rather than from the sizes you supplied. |
| `flashing.drawing.isLargeBoxSize` | boolean | no | Whether the drawing uses the large box size. |
| `flashing.drawing.isDeleted` | boolean | no | Whether the drawing has been deleted. |
| `flashing.drawing.points` | map<Point> | no | The vertices of the drawing, keyed by point id. Record each edge at both ends: `p1.vectors` lists `p2` exactly when `p2.connect` lists `p1`. Required when the order or quote is submitted. A vertex in the drawing. Points are connected by edges to form the flashing profile. |
| `flashing.drawing.points.*.id` | string | no | The unique id of this point within the drawing. |
| `flashing.drawing.points.*.x` | number | no | The x coordinate of the point, in canvas space. |
| `flashing.drawing.points.*.y` | number | no | The y coordinate of the point, in canvas space. |
| `flashing.drawing.points.*.vectors` | string[] | no | The ids of points reached by edges leaving this point. Every edge must also appear in the target point's `connect`. |
| `flashing.drawing.points.*.connect` | string[] | no | The ids of points connected to this point by incoming edges. Every edge must also appear in the source point's `vectors`. |
| `flashing.drawing.points.*.finish` | Finish | no | Optional end treatment at this point. An end treatment applied to a point on a flashing edge (for example a hook or fold). Optional on a point. |
| `flashing.drawing.points.*.finish.type` | FinishType | no | The kind of end treatment. The end-treatment applied to a flashing edge. Each type has a short code used in the finish's `label`, adds its `size` to the flashing's total girth, and counts a fixed number of bends.   - FINISH_TYPE_UNSPECIFIED: Unspecified end treatment.  - FINISH_TYPE_CRUSH_FOLD: A crush fold. Code "cf"; counts 2 bends (or the account's `crushFoldBendCount` when set).  - FINISH_TYPE_OPEN_HOOK: An open hook. Code "oh"; counts 2 bends.  - FINISH_TYPE_FEATHER: A feathered edge. Code "fe"; counts 1 bend.  - FINISH_TYPE_DRIP_EDGE: A drip edge. Code "de"; counts 1 bend. One of: FINISH_TYPE_UNSPECIFIED, FINISH_TYPE_CRUSH_FOLD, FINISH_TYPE_OPEN_HOOK, FINISH_TYPE_FEATHER, FINISH_TYPE_DRIP_EDGE. |
| `flashing.drawing.points.*.finish.size` | number | no | The size of the end treatment in millimetres. It counts toward the flashing's `totalGirth`. |
| `flashing.drawing.points.*.finish.label` | string | no | The display label for this finish: the type's code followed by the size, e.g. "cf10" for a 10 mm crush fold or "oh25" for a 25 mm open hook. |
| `flashing.drawing.points.*.finish.flip` | boolean | no | Which side of the edge the finish folds to. Looking from the finished end along its edge (screen coordinates, y pointing down), `false` puts the fold on the right-hand side and `true` on the left. A feathered edge is drawn mirrored relative to the other types. |
| `flashing.drawing.points.*.finish.position` | LabelPosition | no | Optional bounding box for this finish's label. A label's bounding box in canvas (SVG) coordinate space. Used for line labels, angle labels, and finish labels. |
| `flashing.drawing.points.*.finish.position.x` | number | no | The x coordinate of the label box, in canvas space. |
| `flashing.drawing.points.*.finish.position.y` | number | no | The y coordinate of the label box, in canvas space. |
| `flashing.drawing.points.*.finish.position.width` | number | no | The width of the label box, in canvas space. |
| `flashing.drawing.points.*.finish.position.height` | number | no | The height of the label box, in canvas space. |
| `flashing.drawing.lines` | LineSet | no | The edge sizes between points in millimetres, with their optional label positions. Give every edge a size — Factory counts the girth of a drawing with a missing size as 0. When omitted, the drawing is stored with an empty set and reads return `lines` with empty `values` and `positions`. The collection of edge lengths and their label positions for a drawing. |
| `flashing.drawing.lines.values` | map<LineCell> | no | The size entry for each edge, keyed by the ids of the two points it connects joined with a hyphen, source first: the edge from `p1` to `p2` is `"p1-p2"`. The length entry for a single edge between two points. |
| `flashing.drawing.lines.values.*.size` | number | no | The size of the edge in millimetres. Omitted when a size has not yet been entered — but give every edge a size, or Factory counts the girth as 0. |
| `flashing.drawing.lines.values.*.hidden` | boolean | no | Whether this edge's length label is hidden. |
| `flashing.drawing.lines.positions` | map<LabelPosition> | no | The label box for each edge's size label, keyed like `values`. Optional: Factory places any label without a box itself. A label's bounding box in canvas (SVG) coordinate space. Used for line labels, angle labels, and finish labels. |
| `flashing.drawing.lines.positions.*.x` | number | no | The x coordinate of the label box, in canvas space. |
| `flashing.drawing.lines.positions.*.y` | number | no | The y coordinate of the label box, in canvas space. |
| `flashing.drawing.lines.positions.*.width` | number | no | The width of the label box, in canvas space. |
| `flashing.drawing.lines.positions.*.height` | number | no | The height of the label box, in canvas space. |
| `flashing.drawing.angles` | AngleSet | no | The vertex angles in degrees, with their optional label positions. When omitted, the drawing is stored with an empty set and reads return `angles` with empty `values` and `positions`. The collection of vertex angles and their label positions for a drawing. |
| `flashing.drawing.angles.values` | map<AngleCell> | no | The angle entry for each vertex, keyed by point id. The angle entry for a single point (vertex) in the drawing. |
| `flashing.drawing.angles.values.*.angle` | number | no | The angle at this vertex, in degrees. Omitted when no angle is set. |
| `flashing.drawing.angles.values.*.hidden` | boolean | no | Whether this vertex's angle label is hidden. Omitted when not set. |
| `flashing.drawing.angles.positions` | map<LabelPosition> | no | The label box for each vertex's angle label, keyed by point id. Optional: Factory places any label without a box itself. A label's bounding box in canvas (SVG) coordinate space. Used for line labels, angle labels, and finish labels. |
| `flashing.drawing.angles.positions.*.x` | number | no | The x coordinate of the label box, in canvas space. |
| `flashing.drawing.angles.positions.*.y` | number | no | The y coordinate of the label box, in canvas space. |
| `flashing.drawing.angles.positions.*.width` | number | no | The width of the label box, in canvas space. |
| `flashing.drawing.angles.positions.*.height` | number | no | The height of the label box, in canvas space. |
| `flashing.drawing.annotations` | map<TextBox> | no | Free-text annotations on the drawing, keyed by annotation id. A free-text annotation placed on the drawing. |
| `flashing.drawing.annotations.*.x` | number | no | The x coordinate of the annotation, in canvas space. Omitted until placed. |
| `flashing.drawing.annotations.*.y` | number | no | The y coordinate of the annotation, in canvas space. Omitted until placed. |
| `flashing.drawing.annotations.*.width` | number | no | The width of the annotation box, in canvas space. |
| `flashing.drawing.annotations.*.height` | number | no | The height of the annotation box, in canvas space. |
| `flashing.drawing.annotations.*.value` | string | no | The annotation text as a flat string. May be present alongside the structured `text` form. |
| `flashing.drawing.annotations.*.text` | TextRow[] | no | The annotation text in structured rows. May be present alongside `value`. One row of text within a text annotation. |
| `flashing.drawing.annotations.*.text.id` | integer | no | The 0-based index of this row within the text annotation. |
| `flashing.drawing.annotations.*.text.indent` | integer | no | The indentation level of this row. |
| `flashing.drawing.annotations.*.text.value` | string[] | no | The text segments that make up this row, in order. |
| `flashing.drawing.annotations.*.rotateDeg` | number | no | Optional rotation of the annotation, in degrees. |
| `flashing.drawing.frontArrow` | Arrow | no | The arrow marking the front face of the flashing. Optional. The arrow that indicates the front-facing direction of the flashing. |
| `flashing.drawing.frontArrow.x` | number | no | The x coordinate of the arrow, in canvas space. Omitted until placed. |
| `flashing.drawing.frontArrow.y` | number | no | The y coordinate of the arrow, in canvas space. Omitted until placed. |
| `flashing.drawing.frontArrow.angle` | number | no | The direction the arrow points, in degrees, turning clockwise on screen from 0 = left: 90 points up, 180 right, 270 down. |
| `flashing.drawing.squareAngle` | SquareAngle | no | The right-angle (90°) marker placed on the drawing. |
| `flashing.drawing.squareAngle.x` | number | no | The x coordinate of the marker, in canvas space. Omitted until placed. |
| `flashing.drawing.squareAngle.y` | number | no | The y coordinate of the marker, in canvas space. Omitted until placed. |
| `flashing.drawing.svgUrl` | string | no | A presigned URL to the rendered SVG image of the drawing. Read-only output; populated after the SVG is uploaded via UploadDrawingSvg on OrderService or QuoteService. |
| `flashing.otherSides` | FlashingDrawing[] | no | Additional side drawings of the same flashing, used when the profile tapers: Factory compares each side's edge sizes with the main drawing's, edge by edge, and counts every differing edge as a taper. Their `side` defaults to the near side. When present, `totalGirth` and `bends` come from whichever side has the largest girth. A flashing drawing: its identity, metadata, geometry, and the URL of its rendered SVG image. Carried only by flashing lines (`drawing` / `otherSides` on FlashingLine) — drawings describe a flashing's folded profile and are not a general-purpose image or attachment type. Geometry is sent in the same shape the drawing tool holds it: `points` are the vertices, joined by the edges listed in each point's `vectors` and `connect`; `lines.values` gives each edge's real size in millimetres; `angles.values` gives the angle at each vertex. Point coordinates only lay out the sketch — the sizes in `lines` are the dimensions. A drawing whose `points`, `lines` or `angles` exceeds about 15,000 characters of JSON is rejected with HTTP 400 (validation_failure). |
| `flashing.otherSides.drawingId` | string | no | Server-assigned unique id of the drawing. Read-only output. |
| `flashing.otherSides.tempId` | string | no | A client-assigned correlation id supplied when creating the drawing. The write that creates the drawing returns it paired with the assigned `drawingId` in the response's `drawings` mapping (CreateQuote, CreateOrder, AddQuoteLineItem) — use that to address UploadDrawingSvg. It must be unique across every drawing in the request, other sides included; a repeated id is rejected with HTTP 400 (validation_failure). Omit it and the server assigns unique ids for you. It is not stored, so reads do not return it. |
| `flashing.otherSides.drawingNumber` | integer | no | The drawing's display number within the order or quote. Not assigned by the server: it is stored as sent (0 when omitted), and reads and printed documents order drawings by it, so number them 0, 1, 2… in line order. |
| `flashing.otherSides.side` | DrawingSide | no | Which face of the flashing this drawing represents. When not specified, a line's main `drawing` is the far side and each of its `otherSides` is the near side. Which face of the flashing a drawing represents. When not specified, a flashing line's main `drawing` is the far side and each of its `otherSides` is the near side.   - DRAWING_SIDE_UNSPECIFIED: Default, unset value.  - DRAWING_SIDE_FAR: The far side of the flashing.  - DRAWING_SIDE_NEAR: The near side of the flashing. One of: DRAWING_SIDE_UNSPECIFIED, DRAWING_SIDE_FAR, DRAWING_SIDE_NEAR. |
| `flashing.otherSides.isFreeDrawing` | boolean | no | Whether the edge sizes in `lines.values` are the drawing's dimensions. Send `true`: when false, Factory measures each edge from the points' canvas coordinates instead, so girth, bends and the displayed sizes come from the sketch rather than from the sizes you supplied. |
| `flashing.otherSides.isLargeBoxSize` | boolean | no | Whether the drawing uses the large box size. |
| `flashing.otherSides.isDeleted` | boolean | no | Whether the drawing has been deleted. |
| `flashing.otherSides.points` | map<Point> | no | The vertices of the drawing, keyed by point id. Record each edge at both ends: `p1.vectors` lists `p2` exactly when `p2.connect` lists `p1`. Required when the order or quote is submitted. A vertex in the drawing. Points are connected by edges to form the flashing profile. |
| `flashing.otherSides.points.*.id` | string | no | The unique id of this point within the drawing. |
| `flashing.otherSides.points.*.x` | number | no | The x coordinate of the point, in canvas space. |
| `flashing.otherSides.points.*.y` | number | no | The y coordinate of the point, in canvas space. |
| `flashing.otherSides.points.*.vectors` | string[] | no | The ids of points reached by edges leaving this point. Every edge must also appear in the target point's `connect`. |
| `flashing.otherSides.points.*.connect` | string[] | no | The ids of points connected to this point by incoming edges. Every edge must also appear in the source point's `vectors`. |
| `flashing.otherSides.points.*.finish` | Finish | no | Optional end treatment at this point. An end treatment applied to a point on a flashing edge (for example a hook or fold). Optional on a point. |
| `flashing.otherSides.points.*.finish.type` | FinishType | no | The kind of end treatment. The end-treatment applied to a flashing edge. Each type has a short code used in the finish's `label`, adds its `size` to the flashing's total girth, and counts a fixed number of bends.   - FINISH_TYPE_UNSPECIFIED: Unspecified end treatment.  - FINISH_TYPE_CRUSH_FOLD: A crush fold. Code "cf"; counts 2 bends (or the account's `crushFoldBendCount` when set).  - FINISH_TYPE_OPEN_HOOK: An open hook. Code "oh"; counts 2 bends.  - FINISH_TYPE_FEATHER: A feathered edge. Code "fe"; counts 1 bend.  - FINISH_TYPE_DRIP_EDGE: A drip edge. Code "de"; counts 1 bend. One of: FINISH_TYPE_UNSPECIFIED, FINISH_TYPE_CRUSH_FOLD, FINISH_TYPE_OPEN_HOOK, FINISH_TYPE_FEATHER, FINISH_TYPE_DRIP_EDGE. |
| `flashing.otherSides.points.*.finish.size` | number | no | The size of the end treatment in millimetres. It counts toward the flashing's `totalGirth`. |
| `flashing.otherSides.points.*.finish.label` | string | no | The display label for this finish: the type's code followed by the size, e.g. "cf10" for a 10 mm crush fold or "oh25" for a 25 mm open hook. |
| `flashing.otherSides.points.*.finish.flip` | boolean | no | Which side of the edge the finish folds to. Looking from the finished end along its edge (screen coordinates, y pointing down), `false` puts the fold on the right-hand side and `true` on the left. A feathered edge is drawn mirrored relative to the other types. |
| `flashing.otherSides.points.*.finish.position` | LabelPosition | no | Optional bounding box for this finish's label. A label's bounding box in canvas (SVG) coordinate space. Used for line labels, angle labels, and finish labels. |
| `flashing.otherSides.points.*.finish.position.x` | number | no | The x coordinate of the label box, in canvas space. |
| `flashing.otherSides.points.*.finish.position.y` | number | no | The y coordinate of the label box, in canvas space. |
| `flashing.otherSides.points.*.finish.position.width` | number | no | The width of the label box, in canvas space. |
| `flashing.otherSides.points.*.finish.position.height` | number | no | The height of the label box, in canvas space. |
| `flashing.otherSides.lines` | LineSet | no | The edge sizes between points in millimetres, with their optional label positions. Give every edge a size — Factory counts the girth of a drawing with a missing size as 0. When omitted, the drawing is stored with an empty set and reads return `lines` with empty `values` and `positions`. The collection of edge lengths and their label positions for a drawing. |
| `flashing.otherSides.lines.values` | map<LineCell> | no | The size entry for each edge, keyed by the ids of the two points it connects joined with a hyphen, source first: the edge from `p1` to `p2` is `"p1-p2"`. The length entry for a single edge between two points. |
| `flashing.otherSides.lines.values.*.size` | number | no | The size of the edge in millimetres. Omitted when a size has not yet been entered — but give every edge a size, or Factory counts the girth as 0. |
| `flashing.otherSides.lines.values.*.hidden` | boolean | no | Whether this edge's length label is hidden. |
| `flashing.otherSides.lines.positions` | map<LabelPosition> | no | The label box for each edge's size label, keyed like `values`. Optional: Factory places any label without a box itself. A label's bounding box in canvas (SVG) coordinate space. Used for line labels, angle labels, and finish labels. |
| `flashing.otherSides.lines.positions.*.x` | number | no | The x coordinate of the label box, in canvas space. |
| `flashing.otherSides.lines.positions.*.y` | number | no | The y coordinate of the label box, in canvas space. |
| `flashing.otherSides.lines.positions.*.width` | number | no | The width of the label box, in canvas space. |
| `flashing.otherSides.lines.positions.*.height` | number | no | The height of the label box, in canvas space. |
| `flashing.otherSides.angles` | AngleSet | no | The vertex angles in degrees, with their optional label positions. When omitted, the drawing is stored with an empty set and reads return `angles` with empty `values` and `positions`. The collection of vertex angles and their label positions for a drawing. |
| `flashing.otherSides.angles.values` | map<AngleCell> | no | The angle entry for each vertex, keyed by point id. The angle entry for a single point (vertex) in the drawing. |
| `flashing.otherSides.angles.values.*.angle` | number | no | The angle at this vertex, in degrees. Omitted when no angle is set. |
| `flashing.otherSides.angles.values.*.hidden` | boolean | no | Whether this vertex's angle label is hidden. Omitted when not set. |
| `flashing.otherSides.angles.positions` | map<LabelPosition> | no | The label box for each vertex's angle label, keyed by point id. Optional: Factory places any label without a box itself. A label's bounding box in canvas (SVG) coordinate space. Used for line labels, angle labels, and finish labels. |
| `flashing.otherSides.angles.positions.*.x` | number | no | The x coordinate of the label box, in canvas space. |
| `flashing.otherSides.angles.positions.*.y` | number | no | The y coordinate of the label box, in canvas space. |
| `flashing.otherSides.angles.positions.*.width` | number | no | The width of the label box, in canvas space. |
| `flashing.otherSides.angles.positions.*.height` | number | no | The height of the label box, in canvas space. |
| `flashing.otherSides.annotations` | map<TextBox> | no | Free-text annotations on the drawing, keyed by annotation id. A free-text annotation placed on the drawing. |
| `flashing.otherSides.annotations.*.x` | number | no | The x coordinate of the annotation, in canvas space. Omitted until placed. |
| `flashing.otherSides.annotations.*.y` | number | no | The y coordinate of the annotation, in canvas space. Omitted until placed. |
| `flashing.otherSides.annotations.*.width` | number | no | The width of the annotation box, in canvas space. |
| `flashing.otherSides.annotations.*.height` | number | no | The height of the annotation box, in canvas space. |
| `flashing.otherSides.annotations.*.value` | string | no | The annotation text as a flat string. May be present alongside the structured `text` form. |
| `flashing.otherSides.annotations.*.text` | TextRow[] | no | The annotation text in structured rows. May be present alongside `value`. One row of text within a text annotation. |
| `flashing.otherSides.annotations.*.text.id` | integer | no | The 0-based index of this row within the text annotation. |
| `flashing.otherSides.annotations.*.text.indent` | integer | no | The indentation level of this row. |
| `flashing.otherSides.annotations.*.text.value` | string[] | no | The text segments that make up this row, in order. |
| `flashing.otherSides.annotations.*.rotateDeg` | number | no | Optional rotation of the annotation, in degrees. |
| `flashing.otherSides.frontArrow` | Arrow | no | The arrow marking the front face of the flashing. Optional. The arrow that indicates the front-facing direction of the flashing. |
| `flashing.otherSides.frontArrow.x` | number | no | The x coordinate of the arrow, in canvas space. Omitted until placed. |
| `flashing.otherSides.frontArrow.y` | number | no | The y coordinate of the arrow, in canvas space. Omitted until placed. |
| `flashing.otherSides.frontArrow.angle` | number | no | The direction the arrow points, in degrees, turning clockwise on screen from 0 = left: 90 points up, 180 right, 270 down. |
| `flashing.otherSides.squareAngle` | SquareAngle | no | The right-angle (90°) marker placed on the drawing. |
| `flashing.otherSides.squareAngle.x` | number | no | The x coordinate of the marker, in canvas space. Omitted until placed. |
| `flashing.otherSides.squareAngle.y` | number | no | The y coordinate of the marker, in canvas space. Omitted until placed. |
| `flashing.otherSides.svgUrl` | string | no | A presigned URL to the rendered SVG image of the drawing. Read-only output; populated after the SVG is uploaded via UploadDrawingSvg on OrderService or QuoteService. |
| `flashing.tax` | TaxDetail | no | The tax applied to this line: rate, code, and jurisdiction. Complements the `isTaxFree` flag. In v1 the server applies your account's tax settings to taxable lines; this object reserves the shape for richer per-line tax later. |
| `flashing.tax.rate` | string | no | The tax rate applied, as a decimal fraction (e.g. "0.10" means 10%). |
| `flashing.tax.code` | string | no | The tax code, e.g. "GST", "VAT", or "SALES_TAX". Open-ended — not a fixed set. |
| `flashing.tax.jurisdiction` | string | no | The tax jurisdiction, e.g. "AU", "GB", or "US-CA-LOS_ANGELES". Open-ended. |
| `productKit` | ProductKitLine | no | A line for a predefined product kit. Set exactly one of the six line-type fields. |
| `productKit.kitId` | string | no | The kit's id (`kitId` on Kit, from the catalogue read surface). Optional: omit it to define an on-the-fly kit not linked to any catalogue kit — the kit is described entirely by this line's name, pricing, components, and sub-kits. |
| `productKit.kitRowId` | string | no | The selected kit row/variant id. Optional. |
| `productKit.productName` | string | no | Display name of the kit. |
| `productKit.customPricing` | boolean | no | Whether the kit is custom-priced (true) rather than computed from its components (false). |
| `productKit.description` | string | no | Free-text description of the kit. |
| `productKit.displayKitItems` | object[] | no | Which documents and views the kit's components are shown on, as a JSON array of display-target keys — for example "displayOnWorkOrderPdf", "displayOnInvoicePdf", or "displayOnAllViews". Optional. |
| `productKit.displaySubKits` | object[] | no | Which documents and views the kit's sub-kits are shown on, as a JSON array of display-target keys, using the same values as `displayKitItems`. Optional. |
| `productKit.pricing` | LinePricing | no | Overall pricing for the kit line. Pricing for a single priced line: quantity, prices, discount, cost, markup, margin, and pricing strategy. On priced lines the server validates — or, once derivation is enabled for your account, derives — the line total from the quantity, unit price, and discount; see `totalPrice` for the exact formula, the rounding rule, and what happens if it does not match. |
| `productKit.pricing.quantity` | string | no | Quantity for this line, as a decimal string (e.g. "2" or "2.5"). Supports up to 4 decimal places. It is the first factor of the line-total formula documented on `totalPrice` — EXCEPT on measurement-priced (lineal/square) lines, where the measured length or area alone sets the priced amount and this factor is treated as 1 whenever the server derives or checks the total. Do not multiply a measurement-priced total by quantity. (Only on free-text lines on accounts WITHOUT server-side derivation does the legacy formula still multiply by it — see `totalPrice`). |
| `productKit.pricing.unitPrice` | Money | no | Per-unit price. Required on priced lines — except on catalogue lines with server-side derivation enabled for your account, where you may omit it and supply `cost` plus `markup` instead: the server computes it as cost x (1 + markup/100) (or cost + markup for a fixed markup). If you can send the price directly, do; the derivation exists for callers whose source system stores only cost and markup. The server rounds this to 4 decimal places (half up) before pricing, so unit-price precision finer than that (micro amounts that are not a multiple of 100) is not preserved and can shift the computed line total. |
| `productKit.pricing.totalPrice` | Money | no | The line total, as a Money amount in micros.  Server-side derivation is rolling out account by account. Once it is enabled for your account, this field is optional on most priced lines — omit it (leave the whole Money object out; an empty Money is a supplied $0.00) and the server computes it. Until then it is required on priced lines, exactly as before.  The formula is:    quantity * `unitPrice` * (1 - discount / 100)  rounded to the nearest cent — 2 decimal places, half up (0.005 rounds up). For lineal or square measurement pricing the result is then multiplied by the measured length or area the server derives from the line's measurement details before rounding — and on measurement-priced lines the quantity factor is pinned to 1 once derivation is enabled for your account, whether the server derives the total or checks one you send: the measurements alone set the priced amount. (Without derivation, free-text lines still multiply by `quantity` — match it when computing such a total yourself.) Deriving needs a non-zero quantity or measurement set (deriving with a zero quantity or an empty measurement set is rejected rather than stored as $0.00; a zero unit price — a free line — still derives). On a product kit priced as a standard kit, an omitted parent total is derived as the sum of its components and sub-kits (omitted sub-kit totals are likewise derived from their components) — priced component totals must accompany the request; a missing one is rejected rather than summed as zero. A supplied kit total, at any tier, is stored as sent.  If you DO send a value on a catalogue (once derivation is enabled for your account), on-the-fly, or labour line, it is checked against the formula and a mismatch is rejected with HTTP 400. Send the amount as a whole number of cents (`amountMicros` a multiple of 10000); a sub-cent amount is rounded to the nearest cent before the check.  Exceptions, where the total is never derived — send a correct value, because these lines are stored as sent: |
| `productKit.pricing.discount` | string | no | Discount applied to the line, as a decimal percentage string (e.g. "10.00" means 10%). Supports up to 2 decimal places. In the line-total formula on `totalPrice` it enters as the factor (1 - discount / 100). |
| `productKit.pricing.cost` | Money | no | Unit cost for this line, used to compute margin — and, with derivation enabled, the base the server recomputes `markup` (and an omitted `unitPrice`) from. Rounded to 4 decimal places (half up) before use, so sub-4dp cost precision is not preserved. |
| `productKit.pricing.markup` | string | no | Markup applied to the line, as a decimal string — either a money amount or a percentage, depending on `markupIsPercentage`.  With server-side derivation enabled for your account: whenever `cost` is non-zero, the value you send here is DISCARDED and recomputed from `cost` and the unit price (as a percentage — `markupIsPercentage` reads back true), so the stored markup always agrees with the stored prices. Do not expect to read back the value you sent. With a zero or absent cost your value is kept as sent. |
| `productKit.pricing.markupIsPercentage` | boolean | no | Whether markup is a percentage (true) or a fixed amount (false). Omit it to use the default, true; send false only for a fixed-amount markup. Always present on reads, and reads back true whenever the server recomputed the markup (see `markup`). |
| `productKit.pricing.margin` | Money | no | Margin for the line. When supplied, it is validated against cost and quantity — and with derivation enabled it is recomputed alongside the total whenever `cost` is present, so (like `markup`) the stored value may differ from what you sent. Simplest: omit it and let the server compute. |
| `productKit.pricing.pricingStrategy` | PricingStrategy | no | How this line is priced (per-unit quantity, lineal, or square measurement). Defaults to per-unit quantity pricing. How a quantity is interpreted for pricing — whether it means a count of each, a length, or an area.  On a catalogue product this is the product's pricing basis. On an order or quote line, measurement-based strategies (lineal or square metres/feet) require the line's measurement details to be supplied.   - PRICING_STRATEGY_UNSPECIFIED: Unset, or a legacy product with no pricing strategy recorded.  - PRICING_STRATEGY_BASIC_QUANTITIES: Quantity is a simple per-each count.  - PRICING_STRATEGY_LINEAL_METRES: Quantity is a length in lineal metres.  - PRICING_STRATEGY_CUSTOM_FORMULA: Quantity is priced by a custom formula.  - PRICING_STRATEGY_SQUARE_METRES: Quantity is an area in square metres.  - PRICING_STRATEGY_LINEAL_FEET: Quantity is a length in lineal feet.  - PRICING_STRATEGY_SQUARE_FEET: Quantity is an area in square feet. One of: PRICING_STRATEGY_UNSPECIFIED, PRICING_STRATEGY_BASIC_QUANTITIES, PRICING_STRATEGY_LINEAL_METRES, PRICING_STRATEGY_CUSTOM_FORMULA, PRICING_STRATEGY_SQUARE_METRES, PRICING_STRATEGY_LINEAL_FEET, PRICING_STRATEGY_SQUARE_FEET. |
| `productKit.pricing.priceLevel` | string | no | Optional named price level applied to this line. |
| `productKit.pricing.isTaxFree` | boolean | no | Whether this line is exempt from tax. |
| `productKit.pricing.tax` | TaxDetail | no | The tax applied to this line: rate, code, and jurisdiction. Complements the `isTaxFree` flag. In v1 the server applies your account's tax settings to taxable lines; this object reserves the shape for richer per-line tax later. |
| `productKit.pricing.measurements` | MeasurementEntry[] | no | The measurements that price this line, for the lineal and square pricing strategies. Units follow the strategy: metres for *_METRES, feet for *_FEET (see MeasurementEntry). Requires an explicit, measurement-priced `pricingStrategy` on this same object. On these strategies the measured amount is the priced quantity — `quantity` is NOT a factor (on accounts without server-side derivation, free-text lines are the one legacy exception; see `quantity`); the server sums these pieces (applying your account's minimum-length setting on lineal strategies) to derive the amount that scales the line total. One measured piece (or panel) in a measurement-priced line or kit component. Values are decimal strings in the line's strategy-native unit: metres for the *_METRES pricing strategies, feet for *_FEET. |
| `productKit.pricing.measurements.length` | string | no | Length of this piece, as a decimal string in the strategy's unit (e.g. "2.4" metres, or "8" feet). |
| `productKit.pricing.measurements.width` | string | no | Width of this piece, as a decimal string in the strategy's unit. Square strategies only — a width on a lineal entry is rejected, and a square entry without one is rejected. |
| `productKit.pricing.measurements.amount` | string | no | How many pieces of this size, as a decimal string. Defaults to 1. |
| `productKit.pricing.asBuiltMeasurements` | MeasurementEntry[] | no | As-built measurements — what production actually cut, in the same shape and units as `measurements`. These drive cost, margin, and stock consumption, never the line price. Optional: whenever omitted (create and update alike) they default to `measurements`. Send them only when your as-built figures differ from what was quoted. One measured piece (or panel) in a measurement-priced line or kit component. Values are decimal strings in the line's strategy-native unit: metres for the *_METRES pricing strategies, feet for *_FEET. |
| `productKit.pricing.asBuiltMeasurements.length` | string | no | Length of this piece, as a decimal string in the strategy's unit (e.g. "2.4" metres, or "8" feet). |
| `productKit.pricing.asBuiltMeasurements.width` | string | no | Width of this piece, as a decimal string in the strategy's unit. Square strategies only — a width on a lineal entry is rejected, and a square entry without one is rejected. |
| `productKit.pricing.asBuiltMeasurements.amount` | string | no | How many pieces of this size, as a decimal string. Defaults to 1. |
| `productKit.attributes` | object[] | no | Additional named attributes for the kit line, as a JSON array of {name, value} entries; for measurement-priced kits they describe the measurement entries. |
| `productKit.components` | KitComponent[] | no | The kit's direct components. One component line inside a kit or sub-kit.  A component is itself typed — it may be a catalogue-product, on-the-fly, notes, labour, or kit-product line — and carries its own pricing and measurement details. |
| `productKit.components.productType` | KitComponentType | no | The component's kind: catalogue product, on-the-fly, labour, or notes. Required — it determines which of the fields below apply. The kind of a component within a product kit.   - KIT_COMPONENT_TYPE_UNSPECIFIED: Default, unset value. Not a valid choice for a kit component.  - KIT_COMPONENT_TYPE_CATALOGUE_PRODUCT: A component that is a product from your catalogue.  - KIT_COMPONENT_TYPE_ON_THE_FLY_PRODUCT: A free-form component not tied to a catalogue product. Occurs on order and quote kits only — it is not a catalogue-template component kind.  - KIT_COMPONENT_TYPE_NOTES: A note component: carries text rather than a priced product.  - KIT_COMPONENT_TYPE_LABOUR: A labour component. One of: KIT_COMPONENT_TYPE_UNSPECIFIED, KIT_COMPONENT_TYPE_CATALOGUE_PRODUCT, KIT_COMPONENT_TYPE_ON_THE_FLY_PRODUCT, KIT_COMPONENT_TYPE_NOTES, KIT_COMPONENT_TYPE_LABOUR. |
| `productKit.components.productId` | string | no | The catalogue product id for this component. Optional. |
| `productKit.components.productRowId` | string | no | The catalogue product table-row (variant) id. Optional. |
| `productKit.components.kitProductId` | string | no | The catalogue kit-product-component id this component was instantiated from. Optional. |
| `productKit.components.productName` | string | no | Display name of the component. Set it on every write: component names are stored verbatim and are NEVER derived from `productId` or `productRowId` — a component created without a name is stored nameless and every read of the document returns it with an empty name. When building this line from a catalogue kit template, echo the template component's `productName` (returned by GetKit) into this field. |
| `productKit.components.productDescription` | string | no | Free-text description of the component. |
| `productKit.components.quantity` | string | no | Quantity for this component, as a decimal string. |
| `productKit.components.baseQuantity` | string | no | Base quantity before any per-unit multipliers, as a decimal string. |
| `productKit.components.unitPrice` | Money | no | Price per unit. |
| `productKit.components.totalPrice` | Money | no | Total price for this component. With derived pricing enabled every priced component must carry it — a missing one is rejected rather than summed as zero — and it is checked against the component's own figures: unit price x quantity x (1 - discount / 100), with the measured amount replacing quantity on measurement-priced components (`quantity` is not a factor there — see `measurements`). |
| `productKit.components.customPrice` | Money | no | A manual override of the component's TOTAL price — not a unit price. When set, tax and margin are computed from this value in place of `totalPrice`, so a disagreeing pair stores an incoherent document. Send it only to deliberately override the component's total, and never echo `unitPrice` into it. With derived pricing enabled, a `customPrice` that disagrees with `totalPrice` is rejected (400). |
| `productKit.components.customPricePerLength` | Money | no | A manual override of the price per unit of measured length (for example, per lineal metre), applied instead of the unit price on measurement-priced components. Send it only to deliberately override — omit it otherwise: an explicit $0.00 is stored as an override of $0.00, not ignored. |
| `productKit.components.discount` | string | no | Discount applied to this component, as a decimal string. |
| `productKit.components.cost` | Money | no | Cost of the component. |
| `productKit.components.markup` | string | no | Markup applied to the component, as a decimal string. Interpreted as a percentage when `markupIsPercentage` is true. |
| `productKit.components.markupIsPercentage` | boolean | no | Whether markup is a percentage (true) or an absolute amount (false). Omit it to use the default, true; send false only for a fixed-amount markup. Always present on reads. |
| `productKit.components.margin` | Money | no | Margin earned on the component. |
| `productKit.components.pricingStrategy` | PricingStrategy | no | How the component is priced. How a quantity is interpreted for pricing — whether it means a count of each, a length, or an area.  On a catalogue product this is the product's pricing basis. On an order or quote line, measurement-based strategies (lineal or square metres/feet) require the line's measurement details to be supplied.   - PRICING_STRATEGY_UNSPECIFIED: Unset, or a legacy product with no pricing strategy recorded.  - PRICING_STRATEGY_BASIC_QUANTITIES: Quantity is a simple per-each count.  - PRICING_STRATEGY_LINEAL_METRES: Quantity is a length in lineal metres.  - PRICING_STRATEGY_CUSTOM_FORMULA: Quantity is priced by a custom formula.  - PRICING_STRATEGY_SQUARE_METRES: Quantity is an area in square metres.  - PRICING_STRATEGY_LINEAL_FEET: Quantity is a length in lineal feet.  - PRICING_STRATEGY_SQUARE_FEET: Quantity is an area in square feet. One of: PRICING_STRATEGY_UNSPECIFIED, PRICING_STRATEGY_BASIC_QUANTITIES, PRICING_STRATEGY_LINEAL_METRES, PRICING_STRATEGY_CUSTOM_FORMULA, PRICING_STRATEGY_SQUARE_METRES, PRICING_STRATEGY_LINEAL_FEET, PRICING_STRATEGY_SQUARE_FEET. |
| `productKit.components.isTaxFree` | boolean | no | Whether this component is exempt from tax. |
| `productKit.components.attributes` | object[] | no | Additional named attributes for the component, as a JSON array of {name, value} entries; for measurement-priced components they describe the measurement entries. |
| `productKit.components.notes` | string | no | Free-text notes — used when the component is a notes line. |
| `productKit.components.notesType` | NotesType | no | The kind of notes line, when this is a notes component. Whether a notes line is internal-only or visible to the customer.   - NOTES_TYPE_UNSPECIFIED: Default, unset value. Not a valid choice for a notes line.  - NOTES_TYPE_INTERNAL: An internal note, not shown to the customer.  - NOTES_TYPE_EXTERNAL: An external note, visible to the customer. One of: NOTES_TYPE_UNSPECIFIED, NOTES_TYPE_INTERNAL, NOTES_TYPE_EXTERNAL. |
| `productKit.components.labourUserId` | string | no | The company user assigned, when this is a labour component. |
| `productKit.components.colour` | string | no | Colour of the component, populated for catalogue components from the product row. |
| `productKit.components.material` | string | no | Material of the component, populated for catalogue components from the product row. |
| `productKit.components.colourOptions` | object[] | no | The selectable options for this component's variant attribute — most often colour, but also other attributes such as size — as a JSON array of {label, value} entries, echoed from the catalogue. Display and read only. |
| `productKit.components.tax` | TaxDetail | no | The tax applied to this component: rate, code, and jurisdiction. Complements the `isTaxFree` flag. In v1 the server applies your account's tax settings to taxable components; this object reserves the shape for richer tax later. |
| `productKit.components.measurements` | MeasurementEntry[] | no | The measurements that price this component, for the lineal and square pricing strategies. Units follow the strategy: metres for *_METRES, feet for *_FEET (see MeasurementEntry). Requires an explicit, measurement-priced `pricingStrategy` on this component. The measured amount is the priced quantity — `quantity` is NOT a factor. One measured piece (or panel) in a measurement-priced line or kit component. Values are decimal strings in the line's strategy-native unit: metres for the *_METRES pricing strategies, feet for *_FEET. |
| `productKit.components.measurements.length` | string | no | Length of this piece, as a decimal string in the strategy's unit (e.g. "2.4" metres, or "8" feet). |
| `productKit.components.measurements.width` | string | no | Width of this piece, as a decimal string in the strategy's unit. Square strategies only — a width on a lineal entry is rejected, and a square entry without one is rejected. |
| `productKit.components.measurements.amount` | string | no | How many pieces of this size, as a decimal string. Defaults to 1. |
| `productKit.components.asBuiltMeasurements` | MeasurementEntry[] | no | As-built measurements — what production actually cut, in the same shape and units as `measurements`. These drive cost, margin, and stock consumption, never the component price. Optional: whenever omitted (create and update alike) they default to `measurements`. Send them only when your as-built figures differ from what was quoted. One measured piece (or panel) in a measurement-priced line or kit component. Values are decimal strings in the line's strategy-native unit: metres for the *_METRES pricing strategies, feet for *_FEET. |
| `productKit.components.asBuiltMeasurements.length` | string | no | Length of this piece, as a decimal string in the strategy's unit (e.g. "2.4" metres, or "8" feet). |
| `productKit.components.asBuiltMeasurements.width` | string | no | Width of this piece, as a decimal string in the strategy's unit. Square strategies only — a width on a lineal entry is rejected, and a square entry without one is rejected. |
| `productKit.components.asBuiltMeasurements.amount` | string | no | How many pieces of this size, as a decimal string. Defaults to 1. |
| `productKit.subKits` | SubKit[] | no | The kit's sub-assemblies, each with its own components. A sub-assembly within a kit.  A sub-kit groups a set of components under its own title and quantity, letting a kit be organized into named sub-assemblies. |
| `productKit.subKits.title` | string | no | Display title of the sub-assembly. |
| `productKit.subKits.quantity` | string | no | Quantity of this sub-assembly, as a decimal string. |
| `productKit.subKits.actualQuantity` | string | no | Actual measured quantity, as a decimal string. |
| `productKit.subKits.unitPrice` | Money | no | Price per unit of the sub-assembly. |
| `productKit.subKits.totalPrice` | Money | no | Total price of the sub-assembly. |
| `productKit.subKits.components` | KitComponent[] | no | The components that make up this sub-assembly. One component line inside a kit or sub-kit.  A component is itself typed — it may be a catalogue-product, on-the-fly, notes, labour, or kit-product line — and carries its own pricing and measurement details. |
| `productKit.subKits.components.productType` | KitComponentType | no | The component's kind: catalogue product, on-the-fly, labour, or notes. Required — it determines which of the fields below apply. The kind of a component within a product kit.   - KIT_COMPONENT_TYPE_UNSPECIFIED: Default, unset value. Not a valid choice for a kit component.  - KIT_COMPONENT_TYPE_CATALOGUE_PRODUCT: A component that is a product from your catalogue.  - KIT_COMPONENT_TYPE_ON_THE_FLY_PRODUCT: A free-form component not tied to a catalogue product. Occurs on order and quote kits only — it is not a catalogue-template component kind.  - KIT_COMPONENT_TYPE_NOTES: A note component: carries text rather than a priced product.  - KIT_COMPONENT_TYPE_LABOUR: A labour component. One of: KIT_COMPONENT_TYPE_UNSPECIFIED, KIT_COMPONENT_TYPE_CATALOGUE_PRODUCT, KIT_COMPONENT_TYPE_ON_THE_FLY_PRODUCT, KIT_COMPONENT_TYPE_NOTES, KIT_COMPONENT_TYPE_LABOUR. |
| `productKit.subKits.components.productId` | string | no | The catalogue product id for this component. Optional. |
| `productKit.subKits.components.productRowId` | string | no | The catalogue product table-row (variant) id. Optional. |
| `productKit.subKits.components.kitProductId` | string | no | The catalogue kit-product-component id this component was instantiated from. Optional. |
| `productKit.subKits.components.productName` | string | no | Display name of the component. Set it on every write: component names are stored verbatim and are NEVER derived from `productId` or `productRowId` — a component created without a name is stored nameless and every read of the document returns it with an empty name. When building this line from a catalogue kit template, echo the template component's `productName` (returned by GetKit) into this field. |
| `productKit.subKits.components.productDescription` | string | no | Free-text description of the component. |
| `productKit.subKits.components.quantity` | string | no | Quantity for this component, as a decimal string. |
| `productKit.subKits.components.baseQuantity` | string | no | Base quantity before any per-unit multipliers, as a decimal string. |
| `productKit.subKits.components.unitPrice` | Money | no | Price per unit. |
| `productKit.subKits.components.totalPrice` | Money | no | Total price for this component. With derived pricing enabled every priced component must carry it — a missing one is rejected rather than summed as zero — and it is checked against the component's own figures: unit price x quantity x (1 - discount / 100), with the measured amount replacing quantity on measurement-priced components (`quantity` is not a factor there — see `measurements`). |
| `productKit.subKits.components.customPrice` | Money | no | A manual override of the component's TOTAL price — not a unit price. When set, tax and margin are computed from this value in place of `totalPrice`, so a disagreeing pair stores an incoherent document. Send it only to deliberately override the component's total, and never echo `unitPrice` into it. With derived pricing enabled, a `customPrice` that disagrees with `totalPrice` is rejected (400). |
| `productKit.subKits.components.customPricePerLength` | Money | no | A manual override of the price per unit of measured length (for example, per lineal metre), applied instead of the unit price on measurement-priced components. Send it only to deliberately override — omit it otherwise: an explicit $0.00 is stored as an override of $0.00, not ignored. |
| `productKit.subKits.components.discount` | string | no | Discount applied to this component, as a decimal string. |
| `productKit.subKits.components.cost` | Money | no | Cost of the component. |
| `productKit.subKits.components.markup` | string | no | Markup applied to the component, as a decimal string. Interpreted as a percentage when `markupIsPercentage` is true. |
| `productKit.subKits.components.markupIsPercentage` | boolean | no | Whether markup is a percentage (true) or an absolute amount (false). Omit it to use the default, true; send false only for a fixed-amount markup. Always present on reads. |
| `productKit.subKits.components.margin` | Money | no | Margin earned on the component. |
| `productKit.subKits.components.pricingStrategy` | PricingStrategy | no | How the component is priced. How a quantity is interpreted for pricing — whether it means a count of each, a length, or an area.  On a catalogue product this is the product's pricing basis. On an order or quote line, measurement-based strategies (lineal or square metres/feet) require the line's measurement details to be supplied.   - PRICING_STRATEGY_UNSPECIFIED: Unset, or a legacy product with no pricing strategy recorded.  - PRICING_STRATEGY_BASIC_QUANTITIES: Quantity is a simple per-each count.  - PRICING_STRATEGY_LINEAL_METRES: Quantity is a length in lineal metres.  - PRICING_STRATEGY_CUSTOM_FORMULA: Quantity is priced by a custom formula.  - PRICING_STRATEGY_SQUARE_METRES: Quantity is an area in square metres.  - PRICING_STRATEGY_LINEAL_FEET: Quantity is a length in lineal feet.  - PRICING_STRATEGY_SQUARE_FEET: Quantity is an area in square feet. One of: PRICING_STRATEGY_UNSPECIFIED, PRICING_STRATEGY_BASIC_QUANTITIES, PRICING_STRATEGY_LINEAL_METRES, PRICING_STRATEGY_CUSTOM_FORMULA, PRICING_STRATEGY_SQUARE_METRES, PRICING_STRATEGY_LINEAL_FEET, PRICING_STRATEGY_SQUARE_FEET. |
| `productKit.subKits.components.isTaxFree` | boolean | no | Whether this component is exempt from tax. |
| `productKit.subKits.components.attributes` | object[] | no | Additional named attributes for the component, as a JSON array of {name, value} entries; for measurement-priced components they describe the measurement entries. |
| `productKit.subKits.components.notes` | string | no | Free-text notes — used when the component is a notes line. |
| `productKit.subKits.components.notesType` | NotesType | no | The kind of notes line, when this is a notes component. Whether a notes line is internal-only or visible to the customer.   - NOTES_TYPE_UNSPECIFIED: Default, unset value. Not a valid choice for a notes line.  - NOTES_TYPE_INTERNAL: An internal note, not shown to the customer.  - NOTES_TYPE_EXTERNAL: An external note, visible to the customer. One of: NOTES_TYPE_UNSPECIFIED, NOTES_TYPE_INTERNAL, NOTES_TYPE_EXTERNAL. |
| `productKit.subKits.components.labourUserId` | string | no | The company user assigned, when this is a labour component. |
| `productKit.subKits.components.colour` | string | no | Colour of the component, populated for catalogue components from the product row. |
| `productKit.subKits.components.material` | string | no | Material of the component, populated for catalogue components from the product row. |
| `productKit.subKits.components.colourOptions` | object[] | no | The selectable options for this component's variant attribute — most often colour, but also other attributes such as size — as a JSON array of {label, value} entries, echoed from the catalogue. Display and read only. |
| `productKit.subKits.components.tax` | TaxDetail | no | The tax applied to this component: rate, code, and jurisdiction. Complements the `isTaxFree` flag. In v1 the server applies your account's tax settings to taxable components; this object reserves the shape for richer tax later. |
| `productKit.subKits.components.measurements` | MeasurementEntry[] | no | The measurements that price this component, for the lineal and square pricing strategies. Units follow the strategy: metres for *_METRES, feet for *_FEET (see MeasurementEntry). Requires an explicit, measurement-priced `pricingStrategy` on this component. The measured amount is the priced quantity — `quantity` is NOT a factor. One measured piece (or panel) in a measurement-priced line or kit component. Values are decimal strings in the line's strategy-native unit: metres for the *_METRES pricing strategies, feet for *_FEET. |
| `productKit.subKits.components.measurements.length` | string | no | Length of this piece, as a decimal string in the strategy's unit (e.g. "2.4" metres, or "8" feet). |
| `productKit.subKits.components.measurements.width` | string | no | Width of this piece, as a decimal string in the strategy's unit. Square strategies only — a width on a lineal entry is rejected, and a square entry without one is rejected. |
| `productKit.subKits.components.measurements.amount` | string | no | How many pieces of this size, as a decimal string. Defaults to 1. |
| `productKit.subKits.components.asBuiltMeasurements` | MeasurementEntry[] | no | As-built measurements — what production actually cut, in the same shape and units as `measurements`. These drive cost, margin, and stock consumption, never the component price. Optional: whenever omitted (create and update alike) they default to `measurements`. Send them only when your as-built figures differ from what was quoted. One measured piece (or panel) in a measurement-priced line or kit component. Values are decimal strings in the line's strategy-native unit: metres for the *_METRES pricing strategies, feet for *_FEET. |
| `productKit.subKits.components.asBuiltMeasurements.length` | string | no | Length of this piece, as a decimal string in the strategy's unit (e.g. "2.4" metres, or "8" feet). |
| `productKit.subKits.components.asBuiltMeasurements.width` | string | no | Width of this piece, as a decimal string in the strategy's unit. Square strategies only — a width on a lineal entry is rejected, and a square entry without one is rejected. |
| `productKit.subKits.components.asBuiltMeasurements.amount` | string | no | How many pieces of this size, as a decimal string. Defaults to 1. |
| `id` | string | no | The server-assigned id of this line — unique and stable for the life of the line. Returned when a quote is read; pass it to update or remove the line. Not set when creating a line (the server assigns it). This id has a different form from the quote id. |

## Responses

| Status | Schema | Description |
| --- | --- | --- |
| 200 | `UpdateOrderLineItemResponse` | A successful response. |
| 400 | `Error` | The request was rejected because it failed validation — the body is a validation-failure envelope: an overall type and message and one entry per field-level problem (each with a stable code, a message, and a param pointing at the offending field) — or because the order is not modifiable: an invoiced or accounting-locked order refuses line changes (failed_precondition). |
| 401 | `Error` | The request is missing a valid bearer token, or the token is invalid or expired. |
| 403 | `Error` | The token is valid but does not permit this action, or the resource belongs to a company the token cannot act for. The error type is permission_denied. |
| 404 | `Error` | No order with the given id exists for the authenticated company, the order is archived (archived orders are read-only), the document is still a quote — manage its lines with the QuoteService line endpoints — or the line id does not identify a line on this order. |
| 429 | `Error` | The request was throttled (rate_limited) or exceeded a size limit (resource_exhausted). When throttled, the Retry-After header says how many seconds to wait before retrying; a resource_exhausted request will fail the same way if retried unchanged. |
| default | `Error` | Any other error. The body is the same error envelope every error uses: a short stable type identifying the kind of failure (for example "rate_limited" or "internal"), a human-readable message, and the request's idempotency key echoed back when one was supplied. |

## Returns

`UpdateOrderLineItemResponse`

| Field | Type | Description |
| --- | --- | --- |
| `order` | Order | The updated order, including the recomputed totals. |
| `order.orderId` | string | The order's unique id. Read-only. |
| `order.isSubmitted` | boolean | Whether the order has been submitted (true) or is still a draft (false). |
| `order.customerId` | string | The id of the customer this order belongs to. Always present. Read-only. |
| `order.customerCompanyName` | string | The customer's company name. Read-only. |
| `order.statusId` | string | The id of the order's workflow status. Defaults to a "Submitted" status when the order is submitted without one set. |
| `order.statusName` | string | The display name of the order's workflow status. Read-only. |
| `order.subtotal` | Money | Order subtotal — the sum of line totals before tax. Derived by the server from the line items; read-only. |
| `order.subtotal.amountMicros` | string | Amount in micros — millionths of the currency's major unit. 1.00 = 1_000_000 micros, so $12.34 is 12_340_000 — sent and returned over JSON as the string "12340000" (64-bit integers serialize as JSON strings). A whole number of cents (or pence, etc.) is a multiple of 10_000 micros. |
| `order.subtotal.currency` | string | ISO 4217 currency code (3 letters, e.g. "AUD"). |
| `order.taxAmount` | Money | Total tax for the order, as an absolute money amount (the tax `amount`, not a rate). Derived by the server from your account's tax settings; read-only. See `tax` for the rate, code, and jurisdiction that produced it. |
| `order.taxAmount.amountMicros` | string | Amount in micros — millionths of the currency's major unit. 1.00 = 1_000_000 micros, so $12.34 is 12_340_000 — sent and returned over JSON as the string "12340000" (64-bit integers serialize as JSON strings). A whole number of cents (or pence, etc.) is a multiple of 10_000 micros. |
| `order.taxAmount.currency` | string | ISO 4217 currency code (3 letters, e.g. "AUD"). |
| `order.total` | Money | Order grand total. Derived by the server; read-only. |
| `order.total.amountMicros` | string | Amount in micros — millionths of the currency's major unit. 1.00 = 1_000_000 micros, so $12.34 is 12_340_000 — sent and returned over JSON as the string "12340000" (64-bit integers serialize as JSON strings). A whole number of cents (or pence, etc.) is a multiple of 10_000 micros. |
| `order.total.currency` | string | ISO 4217 currency code (3 letters, e.g. "AUD"). |
| `order.margin` | Money | Order margin, computed by the server from the line items. Read-only. |
| `order.margin.amountMicros` | string | Amount in micros — millionths of the currency's major unit. 1.00 = 1_000_000 micros, so $12.34 is 12_340_000 — sent and returned over JSON as the string "12340000" (64-bit integers serialize as JSON strings). A whole number of cents (or pence, etc.) is a multiple of 10_000 micros. |
| `order.margin.currency` | string | ISO 4217 currency code (3 letters, e.g. "AUD"). |
| `order.totalCost` | Money | Total cost of the order, computed by the server from the line items. Read-only. |
| `order.totalCost.amountMicros` | string | Amount in micros — millionths of the currency's major unit. 1.00 = 1_000_000 micros, so $12.34 is 12_340_000 — sent and returned over JSON as the string "12340000" (64-bit integers serialize as JSON strings). A whole number of cents (or pence, etc.) is a multiple of 10_000 micros. |
| `order.totalCost.currency` | string | ISO 4217 currency code (3 letters, e.g. "AUD"). |
| `order.lines` | SalesLine[] | The order's line items. |
| `order.lines.onTheFly` | OnTheFlyLine | A free-form line not tied to a catalogue product. Set exactly one of the six line-type fields. |
| `order.lines.catalogue` | CatalogueLine | A line for a product from your catalogue. Set exactly one of the six line-type fields. |
| `order.lines.labour` | LabourLine | A line charging for labour. Set exactly one of the six line-type fields. |
| `order.lines.notes` | NotesLine | A note line, with no pricing. Set exactly one of the six line-type fields. |
| `order.lines.flashing` | FlashingLine | A flashing line, with its drawing and geometry. Set exactly one of the six line-type fields. A sheet-metal flashing line item: the flashing material, its specification, pricing, and its drawings.  A flashing line is created with its document (CreateQuote, CreateOrder) or added whole to a quote (AddQuoteLineItem); it cannot yet be added to an existing order, updated, or removed individually — those calls answer HTTP 501 (not_implemented). Its specification (`bends`, `totalGirth`, `totalLength`, `subitems`) and its prices are stored exactly as you send them: the API never derives, prices, or cross-checks a flashing, so compute them yourself from the drawing and cut list as described on each field. Lengths and girths are always millimetres (metres for `totalLength`), whatever the account's measurement system. |
| `order.lines.flashing.templateId` | string | The id of the flashing material or template. Required when the order or quote is submitted. |
| `order.lines.flashing.productName` | string | The display name of the flashing material. |
| `order.lines.flashing.priceLevel` | string | The name of the price level applied to this line (for example "A"), not a price level id. Required when the order or quote is submitted; an empty value is stored as "A". |
| `order.lines.flashing.colour` | string | The flashing colour. Required when the order or quote is submitted, and validated against the colours available for the template when `templateId` is set; without a template it is stored unchecked. |
| `order.lines.flashing.thickness` | string | The material thickness, as a decimal string in millimetres (for example "0.55"). Required when the order or quote is submitted. Send the thickness of the selected template (`templateId`) — each thickness is a distinct template. It is stored as sent and not compared with the template, so a mismatch is saved silently. |
| `order.lines.flashing.bends` | string | The number of bends in the flashing, as a decimal string. Count one bend for each point that joins two edges, plus the bends each finish adds (crush fold 2, open hook 2, feather 1, drip edge 1; the account's `crushFoldBendCount` setting, when set, replaces the crush-fold count). With `otherSides`, take the count from the side with the largest girth. Required when the order or quote is submitted, and must then be greater than zero. Stored as sent; not checked against the drawing. |
| `order.lines.flashing.totalGirth` | string | The total girth of the flashing in millimetres, as a decimal string: the sum of every edge size in the drawing's `lines.values` (hidden edges excluded) plus the `size` of every finish. Edges of 110, 320 and 10 with a 10 mm crush fold give "450". With `otherSides`, use the side with the largest girth. Required when the order or quote is submitted, and must then be greater than zero. Stored as sent; not checked against the drawing. |
| `order.lines.flashing.totalLength` | string | The total length of the flashing in metres, as a decimal string: the sum over `subitems` of amount × length ÷ 1000. Three pieces at 1200 plus two at 925 give "5.45". Stored as sent; not checked against `subitems`. |
| `order.lines.flashing.unitPrice` | Money | The price per metre of the flashing. Required when the order or quote is submitted. |
| `order.lines.flashing.totalPrice` | Money | The total price for this line. Stored as sent and never derived or checked. Factory prices a flashing as `unitPrice` × the priced length, where each piece shorter than the account's `minimumFlashingLengthMm` is charged at that minimum, rounded to the cent. |
| `order.lines.flashing.customPrice` | Money | A custom total price for the line. When set, the document's subtotal uses it in place of `totalPrice`; `unitPrice` and `customPricePerLength` never enter the subtotal directly. |
| `order.lines.flashing.customPricePerLength` | Money | A custom price per metre. Factory uses it in place of `unitPrice` when computing `totalPrice`; send the resulting `totalPrice` yourself, as the API does not recompute it. |
| `order.lines.flashing.subitems` | object[] | The cut list: one entry per piece length, each an object with `amount` (the number of pieces) and `length` (the piece length in millimetres), both JSON numbers — for example `[{"amount": 3, "length": 1200}, {"amount": 2, "length": 925}]`. Stored as sent and not validated; a flashing with no lengths cannot be completed in Factory. Unlike `measurements` on other line kinds, lengths here are millimetre numbers, not metre strings. |
| `order.lines.flashing.isTaxFree` | boolean | Whether this line is exempt from tax. |
| `order.lines.flashing.drawing` | FlashingDrawing | The main drawing for the flashing: the folded profile whose edge sizes give `totalGirth` and `bends`. Required — a flashing line without a drawing is rejected with HTTP 400 (validation_failure). Its `side` defaults to the far side. A flashing drawing: its identity, metadata, geometry, and the URL of its rendered SVG image. Carried only by flashing lines (`drawing` / `otherSides` on FlashingLine) — drawings describe a flashing's folded profile and are not a general-purpose image or attachment type. Geometry is sent in the same shape the drawing tool holds it: `points` are the vertices, joined by the edges listed in each point's `vectors` and `connect`; `lines.values` gives each edge's real size in millimetres; `angles.values` gives the angle at each vertex. Point coordinates only lay out the sketch — the sizes in `lines` are the dimensions. A drawing whose `points`, `lines` or `angles` exceeds about 15,000 characters of JSON is rejected with HTTP 400 (validation_failure). |
| `order.lines.flashing.drawing.drawingId` | string | Server-assigned unique id of the drawing. Read-only output. |
| `order.lines.flashing.drawing.tempId` | string | A client-assigned correlation id supplied when creating the drawing. The write that creates the drawing returns it paired with the assigned `drawingId` in the response's `drawings` mapping (CreateQuote, CreateOrder, AddQuoteLineItem) — use that to address UploadDrawingSvg. It must be unique across every drawing in the request, other sides included; a repeated id is rejected with HTTP 400 (validation_failure). Omit it and the server assigns unique ids for you. It is not stored, so reads do not return it. |
| `order.lines.flashing.drawing.drawingNumber` | integer | The drawing's display number within the order or quote. Not assigned by the server: it is stored as sent (0 when omitted), and reads and printed documents order drawings by it, so number them 0, 1, 2… in line order. |
| `order.lines.flashing.drawing.side` | DrawingSide | Which face of the flashing this drawing represents. When not specified, a line's main `drawing` is the far side and each of its `otherSides` is the near side. Which face of the flashing a drawing represents. When not specified, a flashing line's main `drawing` is the far side and each of its `otherSides` is the near side.   - DRAWING_SIDE_UNSPECIFIED: Default, unset value.  - DRAWING_SIDE_FAR: The far side of the flashing.  - DRAWING_SIDE_NEAR: The near side of the flashing. One of: DRAWING_SIDE_UNSPECIFIED, DRAWING_SIDE_FAR, DRAWING_SIDE_NEAR. |
| `order.lines.flashing.drawing.isFreeDrawing` | boolean | Whether the edge sizes in `lines.values` are the drawing's dimensions. Send `true`: when false, Factory measures each edge from the points' canvas coordinates instead, so girth, bends and the displayed sizes come from the sketch rather than from the sizes you supplied. |
| `order.lines.flashing.drawing.isLargeBoxSize` | boolean | Whether the drawing uses the large box size. |
| `order.lines.flashing.drawing.isDeleted` | boolean | Whether the drawing has been deleted. |
| `order.lines.flashing.drawing.points` | map<Point> | The vertices of the drawing, keyed by point id. Record each edge at both ends: `p1.vectors` lists `p2` exactly when `p2.connect` lists `p1`. Required when the order or quote is submitted. A vertex in the drawing. Points are connected by edges to form the flashing profile. |
| `order.lines.flashing.drawing.points.*.id` | string | The unique id of this point within the drawing. |
| `order.lines.flashing.drawing.points.*.x` | number | The x coordinate of the point, in canvas space. |
| `order.lines.flashing.drawing.points.*.y` | number | The y coordinate of the point, in canvas space. |
| `order.lines.flashing.drawing.points.*.vectors` | string[] | The ids of points reached by edges leaving this point. Every edge must also appear in the target point's `connect`. |
| `order.lines.flashing.drawing.points.*.connect` | string[] | The ids of points connected to this point by incoming edges. Every edge must also appear in the source point's `vectors`. |
| `order.lines.flashing.drawing.points.*.finish` | Finish | Optional end treatment at this point. An end treatment applied to a point on a flashing edge (for example a hook or fold). Optional on a point. |
| `order.lines.flashing.drawing.points.*.finish.type` | FinishType | The kind of end treatment. The end-treatment applied to a flashing edge. Each type has a short code used in the finish's `label`, adds its `size` to the flashing's total girth, and counts a fixed number of bends.   - FINISH_TYPE_UNSPECIFIED: Unspecified end treatment.  - FINISH_TYPE_CRUSH_FOLD: A crush fold. Code "cf"; counts 2 bends (or the account's `crushFoldBendCount` when set).  - FINISH_TYPE_OPEN_HOOK: An open hook. Code "oh"; counts 2 bends.  - FINISH_TYPE_FEATHER: A feathered edge. Code "fe"; counts 1 bend.  - FINISH_TYPE_DRIP_EDGE: A drip edge. Code "de"; counts 1 bend. One of: FINISH_TYPE_UNSPECIFIED, FINISH_TYPE_CRUSH_FOLD, FINISH_TYPE_OPEN_HOOK, FINISH_TYPE_FEATHER, FINISH_TYPE_DRIP_EDGE. |
| `order.lines.flashing.drawing.points.*.finish.size` | number | The size of the end treatment in millimetres. It counts toward the flashing's `totalGirth`. |
| `order.lines.flashing.drawing.points.*.finish.label` | string | The display label for this finish: the type's code followed by the size, e.g. "cf10" for a 10 mm crush fold or "oh25" for a 25 mm open hook. |
| `order.lines.flashing.drawing.points.*.finish.flip` | boolean | Which side of the edge the finish folds to. Looking from the finished end along its edge (screen coordinates, y pointing down), `false` puts the fold on the right-hand side and `true` on the left. A feathered edge is drawn mirrored relative to the other types. |
| `order.lines.flashing.drawing.points.*.finish.position` | LabelPosition | Optional bounding box for this finish's label. A label's bounding box in canvas (SVG) coordinate space. Used for line labels, angle labels, and finish labels. |
| `order.lines.flashing.drawing.points.*.finish.position.x` | number | The x coordinate of the label box, in canvas space. |
| `order.lines.flashing.drawing.points.*.finish.position.y` | number | The y coordinate of the label box, in canvas space. |
| `order.lines.flashing.drawing.points.*.finish.position.width` | number | The width of the label box, in canvas space. |
| `order.lines.flashing.drawing.points.*.finish.position.height` | number | The height of the label box, in canvas space. |
| `order.lines.flashing.drawing.lines` | LineSet | The edge sizes between points in millimetres, with their optional label positions. Give every edge a size — Factory counts the girth of a drawing with a missing size as 0. When omitted, the drawing is stored with an empty set and reads return `lines` with empty `values` and `positions`. The collection of edge lengths and their label positions for a drawing. |
| `order.lines.flashing.drawing.lines.values` | map<LineCell> | The size entry for each edge, keyed by the ids of the two points it connects joined with a hyphen, source first: the edge from `p1` to `p2` is `"p1-p2"`. The length entry for a single edge between two points. |
| `order.lines.flashing.drawing.lines.values.*.size` | number | The size of the edge in millimetres. Omitted when a size has not yet been entered — but give every edge a size, or Factory counts the girth as 0. |
| `order.lines.flashing.drawing.lines.values.*.hidden` | boolean | Whether this edge's length label is hidden. |
| `order.lines.flashing.drawing.lines.positions` | map<LabelPosition> | The label box for each edge's size label, keyed like `values`. Optional: Factory places any label without a box itself. A label's bounding box in canvas (SVG) coordinate space. Used for line labels, angle labels, and finish labels. |
| `order.lines.flashing.drawing.lines.positions.*.x` | number | The x coordinate of the label box, in canvas space. |
| `order.lines.flashing.drawing.lines.positions.*.y` | number | The y coordinate of the label box, in canvas space. |
| `order.lines.flashing.drawing.lines.positions.*.width` | number | The width of the label box, in canvas space. |
| `order.lines.flashing.drawing.lines.positions.*.height` | number | The height of the label box, in canvas space. |
| `order.lines.flashing.drawing.angles` | AngleSet | The vertex angles in degrees, with their optional label positions. When omitted, the drawing is stored with an empty set and reads return `angles` with empty `values` and `positions`. The collection of vertex angles and their label positions for a drawing. |
| `order.lines.flashing.drawing.angles.values` | map<AngleCell> | The angle entry for each vertex, keyed by point id. The angle entry for a single point (vertex) in the drawing. |
| `order.lines.flashing.drawing.angles.values.*.angle` | number | The angle at this vertex, in degrees. Omitted when no angle is set. |
| `order.lines.flashing.drawing.angles.values.*.hidden` | boolean | Whether this vertex's angle label is hidden. Omitted when not set. |
| `order.lines.flashing.drawing.angles.positions` | map<LabelPosition> | The label box for each vertex's angle label, keyed by point id. Optional: Factory places any label without a box itself. A label's bounding box in canvas (SVG) coordinate space. Used for line labels, angle labels, and finish labels. |
| `order.lines.flashing.drawing.angles.positions.*.x` | number | The x coordinate of the label box, in canvas space. |
| `order.lines.flashing.drawing.angles.positions.*.y` | number | The y coordinate of the label box, in canvas space. |
| `order.lines.flashing.drawing.angles.positions.*.width` | number | The width of the label box, in canvas space. |
| `order.lines.flashing.drawing.angles.positions.*.height` | number | The height of the label box, in canvas space. |
| `order.lines.flashing.drawing.annotations` | map<TextBox> | Free-text annotations on the drawing, keyed by annotation id. A free-text annotation placed on the drawing. |
| `order.lines.flashing.drawing.annotations.*.x` | number | The x coordinate of the annotation, in canvas space. Omitted until placed. |
| `order.lines.flashing.drawing.annotations.*.y` | number | The y coordinate of the annotation, in canvas space. Omitted until placed. |
| `order.lines.flashing.drawing.annotations.*.width` | number | The width of the annotation box, in canvas space. |
| `order.lines.flashing.drawing.annotations.*.height` | number | The height of the annotation box, in canvas space. |
| `order.lines.flashing.drawing.annotations.*.value` | string | The annotation text as a flat string. May be present alongside the structured `text` form. |
| `order.lines.flashing.drawing.annotations.*.text` | TextRow[] | The annotation text in structured rows. May be present alongside `value`. One row of text within a text annotation. |
| `order.lines.flashing.drawing.annotations.*.text.id` | integer | The 0-based index of this row within the text annotation. |
| `order.lines.flashing.drawing.annotations.*.text.indent` | integer | The indentation level of this row. |
| `order.lines.flashing.drawing.annotations.*.text.value` | string[] | The text segments that make up this row, in order. |
| `order.lines.flashing.drawing.annotations.*.rotateDeg` | number | Optional rotation of the annotation, in degrees. |
| `order.lines.flashing.drawing.frontArrow` | Arrow | The arrow marking the front face of the flashing. Optional. The arrow that indicates the front-facing direction of the flashing. |
| `order.lines.flashing.drawing.frontArrow.x` | number | The x coordinate of the arrow, in canvas space. Omitted until placed. |
| `order.lines.flashing.drawing.frontArrow.y` | number | The y coordinate of the arrow, in canvas space. Omitted until placed. |
| `order.lines.flashing.drawing.frontArrow.angle` | number | The direction the arrow points, in degrees, turning clockwise on screen from 0 = left: 90 points up, 180 right, 270 down. |
| `order.lines.flashing.drawing.squareAngle` | SquareAngle | The right-angle (90°) marker placed on the drawing. |
| `order.lines.flashing.drawing.squareAngle.x` | number | The x coordinate of the marker, in canvas space. Omitted until placed. |
| `order.lines.flashing.drawing.squareAngle.y` | number | The y coordinate of the marker, in canvas space. Omitted until placed. |
| `order.lines.flashing.drawing.svgUrl` | string | A presigned URL to the rendered SVG image of the drawing. Read-only output; populated after the SVG is uploaded via UploadDrawingSvg on OrderService or QuoteService. |
| `order.lines.flashing.otherSides` | FlashingDrawing[] | Additional side drawings of the same flashing, used when the profile tapers: Factory compares each side's edge sizes with the main drawing's, edge by edge, and counts every differing edge as a taper. Their `side` defaults to the near side. When present, `totalGirth` and `bends` come from whichever side has the largest girth. A flashing drawing: its identity, metadata, geometry, and the URL of its rendered SVG image. Carried only by flashing lines (`drawing` / `otherSides` on FlashingLine) — drawings describe a flashing's folded profile and are not a general-purpose image or attachment type. Geometry is sent in the same shape the drawing tool holds it: `points` are the vertices, joined by the edges listed in each point's `vectors` and `connect`; `lines.values` gives each edge's real size in millimetres; `angles.values` gives the angle at each vertex. Point coordinates only lay out the sketch — the sizes in `lines` are the dimensions. A drawing whose `points`, `lines` or `angles` exceeds about 15,000 characters of JSON is rejected with HTTP 400 (validation_failure). |
| `order.lines.flashing.otherSides.drawingId` | string | Server-assigned unique id of the drawing. Read-only output. |
| `order.lines.flashing.otherSides.tempId` | string | A client-assigned correlation id supplied when creating the drawing. The write that creates the drawing returns it paired with the assigned `drawingId` in the response's `drawings` mapping (CreateQuote, CreateOrder, AddQuoteLineItem) — use that to address UploadDrawingSvg. It must be unique across every drawing in the request, other sides included; a repeated id is rejected with HTTP 400 (validation_failure). Omit it and the server assigns unique ids for you. It is not stored, so reads do not return it. |
| `order.lines.flashing.otherSides.drawingNumber` | integer | The drawing's display number within the order or quote. Not assigned by the server: it is stored as sent (0 when omitted), and reads and printed documents order drawings by it, so number them 0, 1, 2… in line order. |
| `order.lines.flashing.otherSides.side` | DrawingSide | Which face of the flashing this drawing represents. When not specified, a line's main `drawing` is the far side and each of its `otherSides` is the near side. Which face of the flashing a drawing represents. When not specified, a flashing line's main `drawing` is the far side and each of its `otherSides` is the near side.   - DRAWING_SIDE_UNSPECIFIED: Default, unset value.  - DRAWING_SIDE_FAR: The far side of the flashing.  - DRAWING_SIDE_NEAR: The near side of the flashing. One of: DRAWING_SIDE_UNSPECIFIED, DRAWING_SIDE_FAR, DRAWING_SIDE_NEAR. |
| `order.lines.flashing.otherSides.isFreeDrawing` | boolean | Whether the edge sizes in `lines.values` are the drawing's dimensions. Send `true`: when false, Factory measures each edge from the points' canvas coordinates instead, so girth, bends and the displayed sizes come from the sketch rather than from the sizes you supplied. |
| `order.lines.flashing.otherSides.isLargeBoxSize` | boolean | Whether the drawing uses the large box size. |
| `order.lines.flashing.otherSides.isDeleted` | boolean | Whether the drawing has been deleted. |
| `order.lines.flashing.otherSides.points` | map<Point> | The vertices of the drawing, keyed by point id. Record each edge at both ends: `p1.vectors` lists `p2` exactly when `p2.connect` lists `p1`. Required when the order or quote is submitted. A vertex in the drawing. Points are connected by edges to form the flashing profile. |
| `order.lines.flashing.otherSides.points.*.id` | string | The unique id of this point within the drawing. |
| `order.lines.flashing.otherSides.points.*.x` | number | The x coordinate of the point, in canvas space. |
| `order.lines.flashing.otherSides.points.*.y` | number | The y coordinate of the point, in canvas space. |
| `order.lines.flashing.otherSides.points.*.vectors` | string[] | The ids of points reached by edges leaving this point. Every edge must also appear in the target point's `connect`. |
| `order.lines.flashing.otherSides.points.*.connect` | string[] | The ids of points connected to this point by incoming edges. Every edge must also appear in the source point's `vectors`. |
| `order.lines.flashing.otherSides.points.*.finish` | Finish | Optional end treatment at this point. An end treatment applied to a point on a flashing edge (for example a hook or fold). Optional on a point. |
| `order.lines.flashing.otherSides.points.*.finish.type` | FinishType | The kind of end treatment. The end-treatment applied to a flashing edge. Each type has a short code used in the finish's `label`, adds its `size` to the flashing's total girth, and counts a fixed number of bends.   - FINISH_TYPE_UNSPECIFIED: Unspecified end treatment.  - FINISH_TYPE_CRUSH_FOLD: A crush fold. Code "cf"; counts 2 bends (or the account's `crushFoldBendCount` when set).  - FINISH_TYPE_OPEN_HOOK: An open hook. Code "oh"; counts 2 bends.  - FINISH_TYPE_FEATHER: A feathered edge. Code "fe"; counts 1 bend.  - FINISH_TYPE_DRIP_EDGE: A drip edge. Code "de"; counts 1 bend. One of: FINISH_TYPE_UNSPECIFIED, FINISH_TYPE_CRUSH_FOLD, FINISH_TYPE_OPEN_HOOK, FINISH_TYPE_FEATHER, FINISH_TYPE_DRIP_EDGE. |
| `order.lines.flashing.otherSides.points.*.finish.size` | number | The size of the end treatment in millimetres. It counts toward the flashing's `totalGirth`. |
| `order.lines.flashing.otherSides.points.*.finish.label` | string | The display label for this finish: the type's code followed by the size, e.g. "cf10" for a 10 mm crush fold or "oh25" for a 25 mm open hook. |
| `order.lines.flashing.otherSides.points.*.finish.flip` | boolean | Which side of the edge the finish folds to. Looking from the finished end along its edge (screen coordinates, y pointing down), `false` puts the fold on the right-hand side and `true` on the left. A feathered edge is drawn mirrored relative to the other types. |
| `order.lines.flashing.otherSides.points.*.finish.position` | LabelPosition | Optional bounding box for this finish's label. A label's bounding box in canvas (SVG) coordinate space. Used for line labels, angle labels, and finish labels. |
| `order.lines.flashing.otherSides.points.*.finish.position.x` | number | The x coordinate of the label box, in canvas space. |
| `order.lines.flashing.otherSides.points.*.finish.position.y` | number | The y coordinate of the label box, in canvas space. |
| `order.lines.flashing.otherSides.points.*.finish.position.width` | number | The width of the label box, in canvas space. |
| `order.lines.flashing.otherSides.points.*.finish.position.height` | number | The height of the label box, in canvas space. |
| `order.lines.flashing.otherSides.lines` | LineSet | The edge sizes between points in millimetres, with their optional label positions. Give every edge a size — Factory counts the girth of a drawing with a missing size as 0. When omitted, the drawing is stored with an empty set and reads return `lines` with empty `values` and `positions`. The collection of edge lengths and their label positions for a drawing. |
| `order.lines.flashing.otherSides.lines.values` | map<LineCell> | The size entry for each edge, keyed by the ids of the two points it connects joined with a hyphen, source first: the edge from `p1` to `p2` is `"p1-p2"`. The length entry for a single edge between two points. |
| `order.lines.flashing.otherSides.lines.values.*.size` | number | The size of the edge in millimetres. Omitted when a size has not yet been entered — but give every edge a size, or Factory counts the girth as 0. |
| `order.lines.flashing.otherSides.lines.values.*.hidden` | boolean | Whether this edge's length label is hidden. |
| `order.lines.flashing.otherSides.lines.positions` | map<LabelPosition> | The label box for each edge's size label, keyed like `values`. Optional: Factory places any label without a box itself. A label's bounding box in canvas (SVG) coordinate space. Used for line labels, angle labels, and finish labels. |
| `order.lines.flashing.otherSides.lines.positions.*.x` | number | The x coordinate of the label box, in canvas space. |
| `order.lines.flashing.otherSides.lines.positions.*.y` | number | The y coordinate of the label box, in canvas space. |
| `order.lines.flashing.otherSides.lines.positions.*.width` | number | The width of the label box, in canvas space. |
| `order.lines.flashing.otherSides.lines.positions.*.height` | number | The height of the label box, in canvas space. |
| `order.lines.flashing.otherSides.angles` | AngleSet | The vertex angles in degrees, with their optional label positions. When omitted, the drawing is stored with an empty set and reads return `angles` with empty `values` and `positions`. The collection of vertex angles and their label positions for a drawing. |
| `order.lines.flashing.otherSides.angles.values` | map<AngleCell> | The angle entry for each vertex, keyed by point id. The angle entry for a single point (vertex) in the drawing. |
| `order.lines.flashing.otherSides.angles.values.*.angle` | number | The angle at this vertex, in degrees. Omitted when no angle is set. |
| `order.lines.flashing.otherSides.angles.values.*.hidden` | boolean | Whether this vertex's angle label is hidden. Omitted when not set. |
| `order.lines.flashing.otherSides.angles.positions` | map<LabelPosition> | The label box for each vertex's angle label, keyed by point id. Optional: Factory places any label without a box itself. A label's bounding box in canvas (SVG) coordinate space. Used for line labels, angle labels, and finish labels. |
| `order.lines.flashing.otherSides.angles.positions.*.x` | number | The x coordinate of the label box, in canvas space. |
| `order.lines.flashing.otherSides.angles.positions.*.y` | number | The y coordinate of the label box, in canvas space. |
| `order.lines.flashing.otherSides.angles.positions.*.width` | number | The width of the label box, in canvas space. |
| `order.lines.flashing.otherSides.angles.positions.*.height` | number | The height of the label box, in canvas space. |
| `order.lines.flashing.otherSides.annotations` | map<TextBox> | Free-text annotations on the drawing, keyed by annotation id. A free-text annotation placed on the drawing. |
| `order.lines.flashing.otherSides.annotations.*.x` | number | The x coordinate of the annotation, in canvas space. Omitted until placed. |
| `order.lines.flashing.otherSides.annotations.*.y` | number | The y coordinate of the annotation, in canvas space. Omitted until placed. |
| `order.lines.flashing.otherSides.annotations.*.width` | number | The width of the annotation box, in canvas space. |
| `order.lines.flashing.otherSides.annotations.*.height` | number | The height of the annotation box, in canvas space. |
| `order.lines.flashing.otherSides.annotations.*.value` | string | The annotation text as a flat string. May be present alongside the structured `text` form. |
| `order.lines.flashing.otherSides.annotations.*.text` | TextRow[] | The annotation text in structured rows. May be present alongside `value`. One row of text within a text annotation. |
| `order.lines.flashing.otherSides.annotations.*.text.id` | integer | The 0-based index of this row within the text annotation. |
| `order.lines.flashing.otherSides.annotations.*.text.indent` | integer | The indentation level of this row. |
| `order.lines.flashing.otherSides.annotations.*.text.value` | string[] | The text segments that make up this row, in order. |
| `order.lines.flashing.otherSides.annotations.*.rotateDeg` | number | Optional rotation of the annotation, in degrees. |
| `order.lines.flashing.otherSides.frontArrow` | Arrow | The arrow marking the front face of the flashing. Optional. The arrow that indicates the front-facing direction of the flashing. |
| `order.lines.flashing.otherSides.frontArrow.x` | number | The x coordinate of the arrow, in canvas space. Omitted until placed. |
| `order.lines.flashing.otherSides.frontArrow.y` | number | The y coordinate of the arrow, in canvas space. Omitted until placed. |
| `order.lines.flashing.otherSides.frontArrow.angle` | number | The direction the arrow points, in degrees, turning clockwise on screen from 0 = left: 90 points up, 180 right, 270 down. |
| `order.lines.flashing.otherSides.squareAngle` | SquareAngle | The right-angle (90°) marker placed on the drawing. |
| `order.lines.flashing.otherSides.squareAngle.x` | number | The x coordinate of the marker, in canvas space. Omitted until placed. |
| `order.lines.flashing.otherSides.squareAngle.y` | number | The y coordinate of the marker, in canvas space. Omitted until placed. |
| `order.lines.flashing.otherSides.svgUrl` | string | A presigned URL to the rendered SVG image of the drawing. Read-only output; populated after the SVG is uploaded via UploadDrawingSvg on OrderService or QuoteService. |
| `order.lines.flashing.tax` | TaxDetail | The tax applied to this line: rate, code, and jurisdiction. Complements the `isTaxFree` flag. In v1 the server applies your account's tax settings to taxable lines; this object reserves the shape for richer per-line tax later. |
| `order.lines.productKit` | ProductKitLine | A line for a predefined product kit. Set exactly one of the six line-type fields. |
| `order.lines.id` | string | The server-assigned id of this line — unique and stable for the life of the line. Returned when a quote is read; pass it to update or remove the line. Not set when creating a line (the server assigns it). This id has a different form from the quote id. |
| `order.adjustments` | Adjustment[] | Order-level fees, discounts, and markups. At most one fee per order is allowed. |
| `order.adjustments.type` | AdjustmentType | The kind of adjustment: a fee, discount, or markup. Required. The kind of order- or quote-level adjustment: a fee, a discount, or a markup. Only fees and discounts change the document's totals.   - ADJUSTMENT_TYPE_UNSPECIFIED: Default, unset value. Not a valid choice when setting an adjustment.  - ADJUSTMENT_TYPE_FEE: A fee added to the order or quote after any discounts, and taxed at the account's rate. It must be a fixed `amount`, not a `percent`, and at most one fee is allowed per order or quote.  - ADJUSTMENT_TYPE_DISCOUNT: A discount subtracted from the lines' subtotal before tax and before any fee. A `percent` discount is taken of the lines' subtotal as it stands when the discount is applied; with several discounts, each applies to the subtotal left by the earlier ones, in the order they were added.  - ADJUSTMENT_TYPE_MARKUP: A markup recorded against the order or quote. It is stored and returned on reads but changes no total: to mark up a document, raise its line prices. Any number of markups may be recorded. One of: ADJUSTMENT_TYPE_UNSPECIFIED, ADJUSTMENT_TYPE_FEE, ADJUSTMENT_TYPE_DISCOUNT, ADJUSTMENT_TYPE_MARKUP. |
| `order.adjustments.title` | string | A label describing the adjustment. |
| `order.adjustments.amount` | Money | The adjustment as a fixed money amount. Exactly one of `amount` or `percent` must be set. A fee must use this form. |
| `order.adjustments.percent` | string | The adjustment as a percentage (for example, "10.00"). Exactly one of `amount` or `percent` must be set. For a discount, the percentage is taken of the lines' subtotal (see AdjustmentType); a fee given as a percent is rejected with HTTP 400 (validation_failure). |
| `order.fulfilmentMethod` | FulfilmentMethod | How the customer receives the order: pickup, delivery, or installation. How the customer receives the goods on an order or quote. Determines which address is used: delivery uses the delivery address, installation uses the install address.   - FULFILMENT_METHOD_UNSPECIFIED: Default, unset value.  - FULFILMENT_METHOD_PICKUP: The customer collects the goods themselves.  - FULFILMENT_METHOD_DELIVERY: The goods are delivered to the delivery address.  - FULFILMENT_METHOD_INSTALL: The goods are installed at the install address. One of: FULFILMENT_METHOD_UNSPECIFIED, FULFILMENT_METHOD_PICKUP, FULFILMENT_METHOD_DELIVERY, FULFILMENT_METHOD_INSTALL. |
| `order.billingAddress` | Address | Billing address for the order. |
| `order.billingAddress.address1` | string | First address line (street number and name). |
| `order.billingAddress.address2` | string | Second address line (unit, suite, or similar). |
| `order.billingAddress.city` | string | City or suburb. |
| `order.billingAddress.state` | string | State, province, or region. |
| `order.billingAddress.postalCode` | string | Postal code (ZIP code, postcode). |
| `order.billingAddress.countryCode` | string | Country, as an uppercase ISO 3166-1 alpha-2 code (e.g. "AU"). Optional; when supplied, any other form is rejected. |
| `order.deliveryAddress` | Address | Delivery address. Applies when `fulfilmentMethod` is DELIVERY. |
| `order.deliveryAddress.address1` | string | First address line (street number and name). |
| `order.deliveryAddress.address2` | string | Second address line (unit, suite, or similar). |
| `order.deliveryAddress.city` | string | City or suburb. |
| `order.deliveryAddress.state` | string | State, province, or region. |
| `order.deliveryAddress.postalCode` | string | Postal code (ZIP code, postcode). |
| `order.deliveryAddress.countryCode` | string | Country, as an uppercase ISO 3166-1 alpha-2 code (e.g. "AU"). Optional; when supplied, any other form is rejected. |
| `order.installAddress` | Address | Installation address. Applies when `fulfilmentMethod` is INSTALL. |
| `order.installAddress.address1` | string | First address line (street number and name). |
| `order.installAddress.address2` | string | Second address line (unit, suite, or similar). |
| `order.installAddress.city` | string | City or suburb. |
| `order.installAddress.state` | string | State, province, or region. |
| `order.installAddress.postalCode` | string | Postal code (ZIP code, postcode). |
| `order.installAddress.countryCode` | string | Country, as an uppercase ISO 3166-1 alpha-2 code (e.g. "AU"). Optional; when supplied, any other form is rejected. |
| `order.reference` | string | Free-text external reference, e.g. the order id or purchase order (PO) number from your own system. Shown as "PO #" in the Factory app and as "PO" on the order documents. |
| `order.orderNumber` | string | Factory's number for this order. Assigned by the server when the document was created (a quote keeps its number when it becomes an order), sequential within your company, and never changed. Shown as "Order #" in the Factory app (order list, order page, workflow board) and on the order confirmation, invoice, work order, and delivery docket, and used as the document reference in the accounting integrations. Read-only. |
| `order.receivedStatus` | ReceivedStatus | Whether the order has been received. Read-only. Whether and how the order has reached the customer. Read-only.   - RECEIVED_STATUS_UNSPECIFIED: Default, unset value.  - RECEIVED_STATUS_DELIVERED: The order was delivered.  - RECEIVED_STATUS_PICKED_UP: The order was picked up by the customer.  - RECEIVED_STATUS_NOT_RECEIVED: The order has not yet reached the customer.  - RECEIVED_STATUS_INSTALLED: The order was installed. One of: RECEIVED_STATUS_UNSPECIFIED, RECEIVED_STATUS_DELIVERED, RECEIVED_STATUS_PICKED_UP, RECEIVED_STATUS_NOT_RECEIVED, RECEIVED_STATUS_INSTALLED. |
| `order.paymentStatus` | PaymentStatus | The order's payment status. Read-only. Whether the order has been paid for. Read-only.   - PAYMENT_STATUS_UNSPECIFIED: Default, unset value.  - PAYMENT_STATUS_UNPAID: No payment has been received.  - PAYMENT_STATUS_PARTIALLY_PAID: Part of the order total has been paid.  - PAYMENT_STATUS_PAID: The order has been paid in full. One of: PAYMENT_STATUS_UNSPECIFIED, PAYMENT_STATUS_UNPAID, PAYMENT_STATUS_PARTIALLY_PAID, PAYMENT_STATUS_PAID. |
| `order.customFields` | object | The document's custom-field values, keyed by each field's configured key. |
| `order.createdAt` | string | When the order was created. Read-only. |
| `order.submittedAt` | string | When the order was submitted. Read-only. |
| `order.lastUpdatedAt` | string | When the order was last updated. Read-only. |
| `order.requiredAt` | string | The date the order is required or needed by. |
| `order.contact` | Contact | The order's point-of-contact person. |
| `order.contact.name` | string | The contact person's name. |
| `order.contact.email` | string | The contact's email address. Optional; when provided, it must be a valid email address. |
| `order.contact.phone` | string | The contact's landline phone number. |
| `order.contact.mobile` | string | The contact's mobile number, normalized to E.164 format (e.g. +61400000000). |
| `order.notes` | string | Free-text notes about the order. |
| `order.pickupNotes` | string | Free-text notes shown when the order is picked up. |
| `order.deliveryFee` | Money | The delivery fee charged on the order. Read-only. |
| `order.deliveryFee.amountMicros` | string | Amount in micros — millionths of the currency's major unit. 1.00 = 1_000_000 micros, so $12.34 is 12_340_000 — sent and returned over JSON as the string "12340000" (64-bit integers serialize as JSON strings). A whole number of cents (or pence, etc.) is a multiple of 10_000 micros. |
| `order.deliveryFee.currency` | string | ISO 4217 currency code (3 letters, e.g. "AUD"). |
| `order.createdByUserId` | string | The id of the user who created the order, empty when unset. Resolve the user via the Users API (which can return users who have since left). Read-only. |
| `order.submittedByUserId` | string | The id of the user who submitted the order, empty when unset. Resolve the user via the Users API (which can return users who have since left). Read-only. |
| `order.discountAmount` | Money | The order-level discount total, rolled up from the per-line discounts and the discount entries in `adjustments`. Read-only. |
| `order.discountAmount.amountMicros` | string | Amount in micros — millionths of the currency's major unit. 1.00 = 1_000_000 micros, so $12.34 is 12_340_000 — sent and returned over JSON as the string "12340000" (64-bit integers serialize as JSON strings). A whole number of cents (or pence, etc.) is a multiple of 10_000 micros. |
| `order.discountAmount.currency` | string | ISO 4217 currency code (3 letters, e.g. "AUD"). |
| `order.invoiceNumber` | string | The order's invoice number as displayed: the order's own number, or the linked accounting system's number when synced. Empty until the order is invoiced. Read-only. |
| `order.invoicedAt` | string | When the order was invoiced. Unset until the order is invoiced. Read-only. |
| `order.statusColour` | string | The colour of the order's workflow status, for display (defaults to "transparent"). The display companion to `statusName`. Read-only. |
| `order.tax` | TaxDetail | The tax applied to the order: rate, code, and jurisdiction. Reflects your account's tax settings — the values actually applied — and is the companion descriptor to the `taxAmount` amount. Read-only. |
| `order.tax.rate` | string | The tax rate applied, as a decimal fraction (e.g. "0.10" means 10%). |
| `order.tax.code` | string | The tax code, e.g. "GST", "VAT", or "SALES_TAX". Open-ended — not a fixed set. |
| `order.tax.jurisdiction` | string | The tax jurisdiction, e.g. "AU", "GB", or "US-CA-LOS_ANGELES". Open-ended. |
| `order.labels` | Label[] | The labels attached to this order, oldest attachment first. Present on create responses when `labelIds` are supplied; absent from line-write responses. |
| `order.labels.labelId` | string | The label's id. |
| `order.labels.name` | string | Display name of the label. Unique within your company. |
| `order.labels.colour` | string | Display colour of the label, as a hex string (for example "#FF69B4"). |
| `order.isArchived` | boolean | Whether the order is archived. Archived orders are hidden from every read by default: reach them with GetOrder's `includeArchived`, ListOrders' archived, or QueryOrders' `includeArchived`. Always false on default reads. Read-only. |
| `order.labourTotal` | Money | The total charged for labour on the order: the sum of the labour line totals, including labour components inside product kits. Derived by the server from the line items on every write; read-only. |
| `order.labourTotal.amountMicros` | string | Amount in micros — millionths of the currency's major unit. 1.00 = 1_000_000 micros, so $12.34 is 12_340_000 — sent and returned over JSON as the string "12340000" (64-bit integers serialize as JSON strings). A whole number of cents (or pence, etc.) is a multiple of 10_000 micros. |
| `order.labourTotal.currency` | string | ISO 4217 currency code (3 letters, e.g. "AUD"). |

---

Source: https://developer.factory.app/reference/orders/update-order-line-item · Factory Sales API v1
