# GET /v1/quotes:query

**Service:** Quotes  
**Operation:** `QuoteService_QueryQuotes`

Like ListQuotes, but ordered by when each quote last changed (oldest first) and filterable by an `updatedSince` / `updatedBefore` time window — so a poller fetches only what changed since its last run and checkpoints on the most recent quote it saw. Use ListQuotes for simple lookups; use this to keep an external system (CRM, reporting) in sync. Paginated via `pageSize` / `pageToken`.

Quotes have no workflow or payment status. Available filters: `customerId`, reference (substring), `isSubmitted` (draft/sent), `labelIds`, `fulfilmentMethod`, `createdAfter`/`createdBefore` (creation window), `requiredAfter`/`requiredBefore` (required-by window), and `includeArchived`.

One migration to expect while syncing: a quote accepted in the Factory app becomes an order. It leaves this feed without a tombstone entry — there is no final "deleted" record — and reappears in QueryOrders as an order id. The two ids share their 26-character suffix and differ only in prefix: a quote "quote_<suffix>" becomes the order "order_<suffix>". Reconcile a quote that stops updating here by swapping the prefix and checking the order feed for that id.

## Parameters

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `updatedSince` | query | string | no | Return only quotes updated at or after this time. Pass your last sync time here to fetch just what changed since then; omit to start from the beginning. This is the primary filter for incremental sync. |
| `updatedBefore` | query | string | no | Optional upper bound: return only quotes updated strictly before this time. Combine with `updatedSince` to page through a bounded window; omit for "up to now". |
| `pageSize` | query | integer | no | Maximum number of quotes to return per page. 0 uses the server default; the server may cap the value. |
| `pageToken` | query | string | no | Opaque page token from a previous response, used to fetch the next page. |
| `customerId` | query | string | no | Optional: only return quotes for this customer id. |
| `reference` | query | string | no | Optional: only return quotes whose external reference contains this text, compared case-insensitively (a substring match, not exact-equals). |
| `isSubmitted` | query | boolean | no | Optional: filter by whether the quote has been sent. Leave unset to return all quotes; set to false to return only drafts; set to true to return only sent quotes. |
| `createdAfter` | query | string | no | Only quotes created at or after this time (inclusive). Optional; filters on the quote's creation time, independent of the updated window — combine the two windows to sync recent changes for quotes created in a period. Note: this parameter is named `createdAfter`, not `createdSince` — it is a range filter, not a sync checkpoint. |
| `createdBefore` | query | string | no | Only quotes created strictly before this time (exclusive). Optional; combine with `createdAfter` to bound a creation window. |
| `fulfilmentMethod` | query | string | no | Optional: only return quotes with this fulfilment method. Leave unset to include all. One of: FULFILMENT_METHOD_UNSPECIFIED, FULFILMENT_METHOD_PICKUP, FULFILMENT_METHOD_DELIVERY, FULFILMENT_METHOD_INSTALL. |
| `requiredAfter` | query | string | no | Only quotes required at or after this time. Optional; filters on the quote's required-by date, independent of the other filters. |
| `requiredBefore` | query | string | no | Only quotes required strictly before this time. Optional; combine with `requiredAfter` to bound a required-by window. |
| `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. |

## Responses

| Status | Schema | Description |
| --- | --- | --- |
| 200 | `QueryQuotesResponse` | A successful response. |
| 400 | `Error` | The request was rejected because it was malformed — for example an unusable page token or an invalid filter value. The body is a validation-failure envelope: an overall type and message and one entry per problem (each with a stable code, a message, and a param pointing at the offending parameter). |
| 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. |
| 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

`QueryQuotesResponse`

| Field | Type | Description |
| --- | --- | --- |
| `quotes` | Quote[] | The quotes in this page, oldest change first. Use the last quote's update time as the `updatedSince` for your next call. |
| `quotes.quoteId` | string | The quote's unique id. Read-only. |
| `quotes.isSubmitted` | boolean | Whether the quote has been finalised and sent (true) or is still a draft (false). |
| `quotes.customerId` | string | The id of the customer this quote belongs to. Always present. Read-only. |
| `quotes.customerCompanyName` | string | The customer's company name. Read-only. |
| `quotes.subtotal` | Money | Quote subtotal — the sum of line totals before tax. Derived by the server from the line items; read-only. |
| `quotes.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. |
| `quotes.subtotal.currency` | string | ISO 4217 currency code (3 letters, e.g. "AUD"). |
| `quotes.taxAmount` | Money | Total tax for the quote, 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. |
| `quotes.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. |
| `quotes.taxAmount.currency` | string | ISO 4217 currency code (3 letters, e.g. "AUD"). |
| `quotes.total` | Money | Quote grand total. Derived by the server; read-only. |
| `quotes.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. |
| `quotes.total.currency` | string | ISO 4217 currency code (3 letters, e.g. "AUD"). |
| `quotes.margin` | Money | Quote margin, computed by the server from the line items. Read-only. |
| `quotes.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. |
| `quotes.margin.currency` | string | ISO 4217 currency code (3 letters, e.g. "AUD"). |
| `quotes.totalCost` | Money | Total cost of the quote, computed by the server from the line items. Read-only. |
| `quotes.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. |
| `quotes.totalCost.currency` | string | ISO 4217 currency code (3 letters, e.g. "AUD"). |
| `quotes.discountAmount` | Money | The quote-level discount total, rolled up from the per-line discounts and the discount entries in `adjustments`. Read-only. |
| `quotes.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. |
| `quotes.discountAmount.currency` | string | ISO 4217 currency code (3 letters, e.g. "AUD"). |
| `quotes.lines` | SalesLine[] | The quote's line items. |
| `quotes.lines.onTheFly` | OnTheFlyLine | A free-form line not tied to a catalogue product. Set exactly one of the six line-type fields. |
| `quotes.lines.catalogue` | CatalogueLine | A line for a product from your catalogue. Set exactly one of the six line-type fields. |
| `quotes.lines.labour` | LabourLine | A line charging for labour. Set exactly one of the six line-type fields. |
| `quotes.lines.notes` | NotesLine | A note line, with no pricing. Set exactly one of the six line-type fields. |
| `quotes.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. |
| `quotes.lines.flashing.templateId` | string | The id of the flashing material or template. Required when the order or quote is submitted. |
| `quotes.lines.flashing.productName` | string | The display name of the flashing material. |
| `quotes.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". |
| `quotes.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. |
| `quotes.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. |
| `quotes.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. |
| `quotes.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. |
| `quotes.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`. |
| `quotes.lines.flashing.unitPrice` | Money | The price per metre of the flashing. Required when the order or quote is submitted. |
| `quotes.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. |
| `quotes.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. |
| `quotes.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. |
| `quotes.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. |
| `quotes.lines.flashing.isTaxFree` | boolean | Whether this line is exempt from tax. |
| `quotes.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). |
| `quotes.lines.flashing.drawing.drawingId` | string | Server-assigned unique id of the drawing. Read-only output. |
| `quotes.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. |
| `quotes.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. |
| `quotes.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. |
| `quotes.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. |
| `quotes.lines.flashing.drawing.isLargeBoxSize` | boolean | Whether the drawing uses the large box size. |
| `quotes.lines.flashing.drawing.isDeleted` | boolean | Whether the drawing has been deleted. |
| `quotes.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. |
| `quotes.lines.flashing.drawing.points.*.id` | string | The unique id of this point within the drawing. |
| `quotes.lines.flashing.drawing.points.*.x` | number | The x coordinate of the point, in canvas space. |
| `quotes.lines.flashing.drawing.points.*.y` | number | The y coordinate of the point, in canvas space. |
| `quotes.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`. |
| `quotes.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`. |
| `quotes.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. |
| `quotes.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. |
| `quotes.lines.flashing.drawing.points.*.finish.size` | number | The size of the end treatment in millimetres. It counts toward the flashing's `totalGirth`. |
| `quotes.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. |
| `quotes.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. |
| `quotes.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. |
| `quotes.lines.flashing.drawing.points.*.finish.position.x` | number | The x coordinate of the label box, in canvas space. |
| `quotes.lines.flashing.drawing.points.*.finish.position.y` | number | The y coordinate of the label box, in canvas space. |
| `quotes.lines.flashing.drawing.points.*.finish.position.width` | number | The width of the label box, in canvas space. |
| `quotes.lines.flashing.drawing.points.*.finish.position.height` | number | The height of the label box, in canvas space. |
| `quotes.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. |
| `quotes.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. |
| `quotes.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. |
| `quotes.lines.flashing.drawing.lines.values.*.hidden` | boolean | Whether this edge's length label is hidden. |
| `quotes.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. |
| `quotes.lines.flashing.drawing.lines.positions.*.x` | number | The x coordinate of the label box, in canvas space. |
| `quotes.lines.flashing.drawing.lines.positions.*.y` | number | The y coordinate of the label box, in canvas space. |
| `quotes.lines.flashing.drawing.lines.positions.*.width` | number | The width of the label box, in canvas space. |
| `quotes.lines.flashing.drawing.lines.positions.*.height` | number | The height of the label box, in canvas space. |
| `quotes.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. |
| `quotes.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. |
| `quotes.lines.flashing.drawing.angles.values.*.angle` | number | The angle at this vertex, in degrees. Omitted when no angle is set. |
| `quotes.lines.flashing.drawing.angles.values.*.hidden` | boolean | Whether this vertex's angle label is hidden. Omitted when not set. |
| `quotes.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. |
| `quotes.lines.flashing.drawing.angles.positions.*.x` | number | The x coordinate of the label box, in canvas space. |
| `quotes.lines.flashing.drawing.angles.positions.*.y` | number | The y coordinate of the label box, in canvas space. |
| `quotes.lines.flashing.drawing.angles.positions.*.width` | number | The width of the label box, in canvas space. |
| `quotes.lines.flashing.drawing.angles.positions.*.height` | number | The height of the label box, in canvas space. |
| `quotes.lines.flashing.drawing.annotations` | map<TextBox> | Free-text annotations on the drawing, keyed by annotation id. A free-text annotation placed on the drawing. |
| `quotes.lines.flashing.drawing.annotations.*.x` | number | The x coordinate of the annotation, in canvas space. Omitted until placed. |
| `quotes.lines.flashing.drawing.annotations.*.y` | number | The y coordinate of the annotation, in canvas space. Omitted until placed. |
| `quotes.lines.flashing.drawing.annotations.*.width` | number | The width of the annotation box, in canvas space. |
| `quotes.lines.flashing.drawing.annotations.*.height` | number | The height of the annotation box, in canvas space. |
| `quotes.lines.flashing.drawing.annotations.*.value` | string | The annotation text as a flat string. May be present alongside the structured `text` form. |
| `quotes.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. |
| `quotes.lines.flashing.drawing.annotations.*.text.id` | integer | The 0-based index of this row within the text annotation. |
| `quotes.lines.flashing.drawing.annotations.*.text.indent` | integer | The indentation level of this row. |
| `quotes.lines.flashing.drawing.annotations.*.text.value` | string[] | The text segments that make up this row, in order. |
| `quotes.lines.flashing.drawing.annotations.*.rotateDeg` | number | Optional rotation of the annotation, in degrees. |
| `quotes.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. |
| `quotes.lines.flashing.drawing.frontArrow.x` | number | The x coordinate of the arrow, in canvas space. Omitted until placed. |
| `quotes.lines.flashing.drawing.frontArrow.y` | number | The y coordinate of the arrow, in canvas space. Omitted until placed. |
| `quotes.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. |
| `quotes.lines.flashing.drawing.squareAngle` | SquareAngle | The right-angle (90°) marker placed on the drawing. |
| `quotes.lines.flashing.drawing.squareAngle.x` | number | The x coordinate of the marker, in canvas space. Omitted until placed. |
| `quotes.lines.flashing.drawing.squareAngle.y` | number | The y coordinate of the marker, in canvas space. Omitted until placed. |
| `quotes.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. |
| `quotes.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). |
| `quotes.lines.flashing.otherSides.drawingId` | string | Server-assigned unique id of the drawing. Read-only output. |
| `quotes.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. |
| `quotes.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. |
| `quotes.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. |
| `quotes.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. |
| `quotes.lines.flashing.otherSides.isLargeBoxSize` | boolean | Whether the drawing uses the large box size. |
| `quotes.lines.flashing.otherSides.isDeleted` | boolean | Whether the drawing has been deleted. |
| `quotes.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. |
| `quotes.lines.flashing.otherSides.points.*.id` | string | The unique id of this point within the drawing. |
| `quotes.lines.flashing.otherSides.points.*.x` | number | The x coordinate of the point, in canvas space. |
| `quotes.lines.flashing.otherSides.points.*.y` | number | The y coordinate of the point, in canvas space. |
| `quotes.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`. |
| `quotes.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`. |
| `quotes.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. |
| `quotes.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. |
| `quotes.lines.flashing.otherSides.points.*.finish.size` | number | The size of the end treatment in millimetres. It counts toward the flashing's `totalGirth`. |
| `quotes.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. |
| `quotes.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. |
| `quotes.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. |
| `quotes.lines.flashing.otherSides.points.*.finish.position.x` | number | The x coordinate of the label box, in canvas space. |
| `quotes.lines.flashing.otherSides.points.*.finish.position.y` | number | The y coordinate of the label box, in canvas space. |
| `quotes.lines.flashing.otherSides.points.*.finish.position.width` | number | The width of the label box, in canvas space. |
| `quotes.lines.flashing.otherSides.points.*.finish.position.height` | number | The height of the label box, in canvas space. |
| `quotes.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. |
| `quotes.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. |
| `quotes.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. |
| `quotes.lines.flashing.otherSides.lines.values.*.hidden` | boolean | Whether this edge's length label is hidden. |
| `quotes.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. |
| `quotes.lines.flashing.otherSides.lines.positions.*.x` | number | The x coordinate of the label box, in canvas space. |
| `quotes.lines.flashing.otherSides.lines.positions.*.y` | number | The y coordinate of the label box, in canvas space. |
| `quotes.lines.flashing.otherSides.lines.positions.*.width` | number | The width of the label box, in canvas space. |
| `quotes.lines.flashing.otherSides.lines.positions.*.height` | number | The height of the label box, in canvas space. |
| `quotes.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. |
| `quotes.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. |
| `quotes.lines.flashing.otherSides.angles.values.*.angle` | number | The angle at this vertex, in degrees. Omitted when no angle is set. |
| `quotes.lines.flashing.otherSides.angles.values.*.hidden` | boolean | Whether this vertex's angle label is hidden. Omitted when not set. |
| `quotes.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. |
| `quotes.lines.flashing.otherSides.angles.positions.*.x` | number | The x coordinate of the label box, in canvas space. |
| `quotes.lines.flashing.otherSides.angles.positions.*.y` | number | The y coordinate of the label box, in canvas space. |
| `quotes.lines.flashing.otherSides.angles.positions.*.width` | number | The width of the label box, in canvas space. |
| `quotes.lines.flashing.otherSides.angles.positions.*.height` | number | The height of the label box, in canvas space. |
| `quotes.lines.flashing.otherSides.annotations` | map<TextBox> | Free-text annotations on the drawing, keyed by annotation id. A free-text annotation placed on the drawing. |
| `quotes.lines.flashing.otherSides.annotations.*.x` | number | The x coordinate of the annotation, in canvas space. Omitted until placed. |
| `quotes.lines.flashing.otherSides.annotations.*.y` | number | The y coordinate of the annotation, in canvas space. Omitted until placed. |
| `quotes.lines.flashing.otherSides.annotations.*.width` | number | The width of the annotation box, in canvas space. |
| `quotes.lines.flashing.otherSides.annotations.*.height` | number | The height of the annotation box, in canvas space. |
| `quotes.lines.flashing.otherSides.annotations.*.value` | string | The annotation text as a flat string. May be present alongside the structured `text` form. |
| `quotes.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. |
| `quotes.lines.flashing.otherSides.annotations.*.text.id` | integer | The 0-based index of this row within the text annotation. |
| `quotes.lines.flashing.otherSides.annotations.*.text.indent` | integer | The indentation level of this row. |
| `quotes.lines.flashing.otherSides.annotations.*.text.value` | string[] | The text segments that make up this row, in order. |
| `quotes.lines.flashing.otherSides.annotations.*.rotateDeg` | number | Optional rotation of the annotation, in degrees. |
| `quotes.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. |
| `quotes.lines.flashing.otherSides.frontArrow.x` | number | The x coordinate of the arrow, in canvas space. Omitted until placed. |
| `quotes.lines.flashing.otherSides.frontArrow.y` | number | The y coordinate of the arrow, in canvas space. Omitted until placed. |
| `quotes.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. |
| `quotes.lines.flashing.otherSides.squareAngle` | SquareAngle | The right-angle (90°) marker placed on the drawing. |
| `quotes.lines.flashing.otherSides.squareAngle.x` | number | The x coordinate of the marker, in canvas space. Omitted until placed. |
| `quotes.lines.flashing.otherSides.squareAngle.y` | number | The y coordinate of the marker, in canvas space. Omitted until placed. |
| `quotes.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. |
| `quotes.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. |
| `quotes.lines.productKit` | ProductKitLine | A line for a predefined product kit. Set exactly one of the six line-type fields. |
| `quotes.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. |
| `quotes.adjustments` | Adjustment[] | Quote-level fees, discounts, and markups. At most one fee per quote is allowed. |
| `quotes.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. |
| `quotes.adjustments.title` | string | A label describing the adjustment. |
| `quotes.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. |
| `quotes.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). |
| `quotes.fulfilmentMethod` | FulfilmentMethod | How the customer would receive the order if the quote is accepted: 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. |
| `quotes.billingAddress` | Address | Billing address for the quote. |
| `quotes.billingAddress.address1` | string | First address line (street number and name). |
| `quotes.billingAddress.address2` | string | Second address line (unit, suite, or similar). |
| `quotes.billingAddress.city` | string | City or suburb. |
| `quotes.billingAddress.state` | string | State, province, or region. |
| `quotes.billingAddress.postalCode` | string | Postal code (ZIP code, postcode). |
| `quotes.billingAddress.countryCode` | string | Country, as an uppercase ISO 3166-1 alpha-2 code (e.g. "AU"). Optional; when supplied, any other form is rejected. |
| `quotes.deliveryAddress` | Address | Delivery address. Applies when `fulfilmentMethod` is DELIVERY. |
| `quotes.deliveryAddress.address1` | string | First address line (street number and name). |
| `quotes.deliveryAddress.address2` | string | Second address line (unit, suite, or similar). |
| `quotes.deliveryAddress.city` | string | City or suburb. |
| `quotes.deliveryAddress.state` | string | State, province, or region. |
| `quotes.deliveryAddress.postalCode` | string | Postal code (ZIP code, postcode). |
| `quotes.deliveryAddress.countryCode` | string | Country, as an uppercase ISO 3166-1 alpha-2 code (e.g. "AU"). Optional; when supplied, any other form is rejected. |
| `quotes.installAddress` | Address | Installation address. Applies when `fulfilmentMethod` is INSTALL. |
| `quotes.installAddress.address1` | string | First address line (street number and name). |
| `quotes.installAddress.address2` | string | Second address line (unit, suite, or similar). |
| `quotes.installAddress.city` | string | City or suburb. |
| `quotes.installAddress.state` | string | State, province, or region. |
| `quotes.installAddress.postalCode` | string | Postal code (ZIP code, postcode). |
| `quotes.installAddress.countryCode` | string | Country, as an uppercase ISO 3166-1 alpha-2 code (e.g. "AU"). Optional; when supplied, any other form is rejected. |
| `quotes.deliveryFee` | Money | The delivery fee quoted on the order. Read-only. |
| `quotes.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. |
| `quotes.deliveryFee.currency` | string | ISO 4217 currency code (3 letters, e.g. "AUD"). |
| `quotes.reference` | string | Free-text external reference, e.g. the quote id or purchase order (PO) number from your own system. Shown as "PO #" in the Factory app and as "PO" on the quote and order documents. |
| `quotes.orderNumber` | string | Factory's number for this quote. Assigned by the server when the quote is created, sequential within your company, and never changed — the quote keeps this number if it becomes an order. Shown as "Quote #" on the quote PDF and email, as "Order #" in the Factory app (order list, order page, workflow board) and on invoices and delivery documents, and used as the document reference in the accounting integrations. Read-only. |
| `quotes.customFields` | object | The document's custom-field values, keyed by each field's configured key. |
| `quotes.contact` | Contact | The quote's point-of-contact person. |
| `quotes.contact.name` | string | The contact person's name. |
| `quotes.contact.email` | string | The contact's email address. Optional; when provided, it must be a valid email address. |
| `quotes.contact.phone` | string | The contact's landline phone number. |
| `quotes.contact.mobile` | string | The contact's mobile number, normalized to E.164 format (e.g. +61400000000). |
| `quotes.notes` | string | Free-text notes about the quote. |
| `quotes.requiredAt` | string | The date the customer needs the order by, if the quote is accepted. |
| `quotes.quotedAt` | string | The date the quote was issued. |
| `quotes.createdAt` | string | When the quote was created. Read-only. |
| `quotes.submittedAt` | string | When the quote was sent (finalised). Read-only. |
| `quotes.lastUpdatedAt` | string | When the quote was last updated. Read-only. |
| `quotes.createdByUserId` | string | The id of the user who created the quote, empty when unset. Resolve the user via the Users API (which can return users who have since left). Read-only. |
| `quotes.submittedByUserId` | string | The id of the user who sent the quote, empty when unset. Resolve the user via the Users API (which can return users who have since left). Read-only. |
| `quotes.tax` | TaxDetail | The tax applied to the quote: 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. |
| `quotes.tax.rate` | string | The tax rate applied, as a decimal fraction (e.g. "0.10" means 10%). |
| `quotes.tax.code` | string | The tax code, e.g. "GST", "VAT", or "SALES_TAX". Open-ended — not a fixed set. |
| `quotes.tax.jurisdiction` | string | The tax jurisdiction, e.g. "AU", "GB", or "US-CA-LOS_ANGELES". Open-ended. |
| `quotes.labels` | Label[] | The labels attached to this quote, oldest attachment first. Present on create responses when `labelIds` are supplied; absent from line-write responses. |
| `quotes.labels.labelId` | string | The label's id. |
| `quotes.labels.name` | string | Display name of the label. Unique within your company. |
| `quotes.labels.colour` | string | Display colour of the label, as a hex string (for example "#FF69B4"). |
| `quotes.labourTotal` | Money | The total charged for labour on the quote: 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. |
| `quotes.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. |
| `quotes.labourTotal.currency` | string | ISO 4217 currency code (3 letters, e.g. "AUD"). |
| `nextPageToken` | string | Token to pass as `pageToken` to fetch the next page; empty when there are no more results. |

---

Source: https://developer.factory.app/reference/quotes/query-quotes · Factory Sales API v1
