FlashlineFlashlineDevelopers
DocsDashboard
Guides
Getting startedConnect accountsVersioningErrors
Reference
AuthenticationGET /oauth/authorizePOST /oauth/tokenPOST /oauth/revoke
Account
GET /me
Measurements
POST /measurementsGET /measurements/{id}
Reference

Measurements

Lifecycle
pending → in_progress → complete↘ canceled

Create a measurement, share the returned link so it can be measured in Flashline, then read it back when you need the numbers. result is filled in once the status reaches complete.

POST/measurements

Creates a measurement for the connected team and returns it in pending state, with the link the contractor opens to measure it in Flashline. Store the returned id; it is how you read the result later.

Returns 201 Created, or 200 OK with the original measurement, unchanged, when the same external.id was seen before from your app. Other fields in the duplicate request are ignored, so a double-clicked button never creates two and never edits one.

Body

FieldTypeDescription
addressrequiredobjectWhere to measure. Geocoded on our side; the contractor confirms the rooftop in Flashline.
address.line1requiredstringStreet address. Max 200.
address.line2optionalstringUnit or suite.
address.cityrequiredstring
address.regionrequiredstringProvince or state code, e.g. ON, NY.
address.postal_coderequiredstring
address.countryoptionalstringISO 3166-1 alpha-2, CA or US. Defaults to the team's country.
customerrequiredobjectThe homeowner, as the contractor will see them.
customer.namerequiredstringMax 120.
customer.emailone of twostringOne of email or phone is required.
customer.phoneone of twostringAny format; stored as given.
notesoptionalstringFree text for the contractor: access, timing, what the customer said. Max 2000. Never shown to the customer.
externaloptionalobjectYour side of the link. Recommended.
external.idoptionalstringYour own id for this proposal. Max 128. Unique per app; drives idempotency.
external.urloptionalstringHTTPS link back into your product, shown to the contractor in Flashline as "Open {label}".
external.labeloptionalstringWhat the contractor sees, e.g. Proposal #88213. Max 80. Defaults to the app name.

A missing or malformed field answers 422 validation_failed; error.errors lists { "field": "customer", "message": "email or phone is required" } entries.

Request
POST /api/measurements
Authorization: Bearer flt_…
Flashline-Version: 2026-09-02
Content-Type: application/json

{
"address": {
"line1": "412 Maple Crescent",
"city": "Oakville",
"region": "ON",
"postal_code": "L6H 2K4",
"country": "CA"
},
"customer": {
"name": "Dana Whitfield",
"email": "dana@example.com",
"phone": "+1 905 555 0142"
},
"notes": "Rear eaves overflow; customer home after 4pm.",
"external": {
"id": "prop_88213",
"url": "https://crm.example.com/proposals/88213",
"label": "Proposal #88213"
}
}
Response
// 201 Created
{
"id": "msr_7Hx2Kd9mQ4",
"status": "pending",
"created_at": "2026-09-03T14:12:09Z",
"updated_at": "2026-09-03T14:12:09Z",
"completed_at": null,
"address": {
"line1": "412 Maple Crescent",
"line2": null,
"city": "Oakville",
"region": "ON",
"postal_code": "L6H 2K4",
"country": "CA",
"formatted": "412 Maple Crescent, Oakville, ON L6H 2K4, Canada",
"lat": 43.4675,
"lng": -79.6877
},
"request": {
"id": "req_Q4nT8b",
"created_at": "2026-09-03T14:12:09Z",
"customer": {
"name": "Dana Whitfield",
"email": "dana@example.com",
"phone": "+1 905 555 0142"
},
"notes": "Rear eaves overflow; customer home after 4pm.",
"external": {
"id": "prop_88213",
"url": "https://crm.example.com/proposals/88213",
"label": "Proposal #88213"
},
"url": "https://www.flashlinegutters.com/dashboard/requests/req_Q4nT8b"
},
"result": null
}
GET/measurements/{id}

Returns the measurement as it stands: the same object the create call returned, with result filled in once the contractor completes it. There are no webhooks yet: read it when your user asks for the result, or poll on a schedule you choose; a measurement that reached complete stays complete. 404 not_found for an id that does not belong to the connected team.

The measurement object

FieldTypeDescription
idstringmsr_-prefixed, stable for life. Store this.
statusenumpending: nobody has started. in_progress: a contractor opened it. complete: the measurement is done and result is present. canceled: withdrawn by the contractor in Flashline. There is no API call to cancel.
created_at, updated_attimeRFC 3339 UTC. updated_at moves on any change.
completed_attime | nullWhen the contractor completed the measurement.
addressobjectThe property. The components are what you sent, normalized, and never change after creation. formatted, lat and lng come from geocoding at creation and are refined to the measured rooftop when the contractor confirms it.
requestobjectFlashline's request record, the inbox item your call created.
request.idstringreq_-prefixed; the id the contractor sees in Flashline.
request.customerobjectname, email, phone as stored; the contractor may correct them.
request.notesstring | nullThe notes you sent, as the contractor sees them.
request.externalobject | nullid, url, label: your side of the link.
request.urlurlOpens the request in Flashline. Needs a signed-in member of the team. This is what a "Measure in Flashline" button opens.
resultobject | nullPresent when status is complete.
result.gutter_length_ftnumberTotal gutter run in decimal feet, including the contractor's override if set.
result.gutter_size_innumber | nullThe size the contractor picked, e.g. 5 or 6.
result.corner_countintegerInside and outside corners on the traced runs.
result.downspout_countinteger
result.downspout_length_ftnumberTotal, elbows included.
result.downspouts[]arrayOne entry per downspout: length_ft, floors (storeys it drops, 1 to 3), size_in (null until assigned).
result.installer_messagestring | nullThe contractor's message to the homeowner about this property. Plain text.
result.asset_pack[]arrayEvery visual Flashline produced, in presentation order: kind, url, content_type. URLs are public, stable and do not expire: embed them directly in your proposals, or copy them to your own storage. Kinds: aerial, aerial_annotated, intro, measurements, risk_analysis, hangers, certification. New kinds may be added; ignore unknown ones. Empty until generated.

result is null until the contractor completes the measurement. That is a state, not an error.

Response
// 200 OK
{
"id": "msr_7Hx2Kd9mQ4",
"status": "complete",
"created_at": "2026-09-03T14:12:09Z",
"updated_at": "2026-09-04T15:02:10Z",
"completed_at": "2026-09-04T15:02:10Z",
"address": {
"line1": "412 Maple Crescent",
"line2": null,
"city": "Oakville",
"region": "ON",
"postal_code": "L6H 2K4",
"country": "CA",
"formatted": "412 Maple Crescent, Oakville, ON L6H 2K4, Canada",
"lat": 43.46752,
"lng": -79.68771
},
"request": {
"id": "req_Q4nT8b",
"created_at": "2026-09-03T14:12:09Z",
"customer": { "name": "Dana Whitfield", "email": "dana@example.com", "phone": "+1 905 555 0142" },
"notes": "Rear eaves overflow; customer home after 4pm.",
"external": { "id": "prop_88213", "url": "https://crm.example.com/proposals/88213", "label": "Proposal #88213" },
"url": "https://www.flashlinegutters.com/dashboard/requests/req_Q4nT8b"
},
"result": {
"gutter_length_ft": 186.5,
"gutter_size_in": 5,
"corner_count": 9,
"downspout_count": 6,
"downspout_length_ft": 118,
"downspouts": [
{ "length_ft": 22, "floors": 2, "size_in": 3 },
{ "length_ft": 22, "floors": 2, "size_in": 3 },
{ "length_ft": 12, "floors": 1, "size_in": 3 },
{ "length_ft": 12, "floors": 1, "size_in": 3 },
{ "length_ft": 25, "floors": 2, "size_in": 3 },
{ "length_ft": 25, "floors": 2, "size_in": 3 }
],
"installer_message": "Dana, the rear eaves are undersized for the roof area feeding them…",
"asset_pack": [
{ "kind": "aerial", "url": "https://…/aerial.png", "content_type": "image/png" },
{ "kind": "aerial_annotated", "url": "https://…/aerial-annotated.jpg", "content_type": "image/jpeg" },
{ "kind": "intro", "url": "https://…/intro.png", "content_type": "image/png" },
{ "kind": "measurements", "url": "https://…/measurements.png", "content_type": "image/png" },
{ "kind": "risk_analysis", "url": "https://…/risk-analysis.png", "content_type": "image/png" },
{ "kind": "hangers", "url": "https://…/hangers.png", "content_type": "image/png" },
{ "kind": "certification", "url": "https://…/certification.png", "content_type": "image/png" }
]
}
}
Terms•Privacy