Getting started
Connect a contractor's Flashline account and make your first call. Four steps; the code is everything you need on your side.
Get an organization, then create an app
Access is by request: email support@flashlinegutters.com with your company name and the developer who will own it. They get an invite to the organization's test account, which signs them in to the dashboard. Use an email not already on a Flashline team; an account has one team.
In the developer dashboard, create an app, add your callback URL as a redirect URI, and generate a client secret (shown once; keep it server-side). Redirect URIs must be https; http://localhost and http://127.0.0.1 (any port) work for local testing.
client_id flc_9Hx2Kd
client_secret fls_… # shown once, keep it on your server
redirect_uri https://app.example.com/flashline/callback
Send the contractor to Flashline
A link or button to the authorize URL; nothing in it is secret. The contractor signs in and clicks Allow. Any team member can; the connection belongs to the team.
state comes back unchanged; use it to pass metadata or verify the callback is yours.
PKCE (S256) is required: code_challenge on the link, code_verifier at the exchange. Most OAuth libraries handle it.
<a href="https://www.flashlinegutters.com/api/oauth/authorize?client_id=flc_9Hx2Kd&redirect_uri=https%3A%2F%2Fapp.example.com%2Fflashline%2Fcallback&response_type=code&state=7f3a9c1e&code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM&code_challenge_method=S256">
Connect Flashline
</a>
Connect request
Acme CRM wants to connect to Acme Gutters
Acme CRM by Acme Software will be able to:
- See your team's name and this connection
- Create measurement requests for your team
- Read the results of the measurements it created
It cannot see your quotes, customers or pricing, or change anything already in Flashline. Disconnect it any time in Settings > Integrations.
Handle the callback
The callback carries a one-time code (10 minutes) and your state. Exchange it at the token endpoint with your client credentials, server-side.
Store the access_token per connected account. It never expires and has no refresh token; reconnecting replaces it, disconnecting from either side revokes it. The response names the team. On Deny you get error=access_denied instead of a code; send the contractor back to your app.
// https://app.example.com/flashline/callback
app.get("/flashline/callback", async (req, res) => {
const { code, error } = req.query;
if (error || typeof code !== "string") {
// The contractor clicked Deny, or the request did not come from Flashline.
return res.redirect("/settings/integrations");
}
const response = await fetch("https://www.flashlinegutters.com/api/oauth/token", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: new URLSearchParams({
grant_type: "authorization_code",
code,
redirect_uri: "https://app.example.com/flashline/callback",
client_id: process.env.FLASHLINE_CLIENT_ID,
client_secret: process.env.FLASHLINE_CLIENT_SECRET,
code_verifier: verifier, // the value your code_challenge was derived from
}),
});
if (!response.ok) {
return res.status(502).send(`Flashline token exchange failed (${response.status})`);
}
const { access_token } = await response.json();
await saveFlashlineToken(access_token);
// Return the contractor to your app.
res.redirect("/settings/integrations");
});
{
"access_token": "flt_Zt8m…",
"token_type": "bearer",
"team": { "id": "7c1e5a0e-…", "name": "Acme Gutters" },
"connected_at": "2026-09-02T13:58:02Z"
}
Make your first call
GET /api/me returns the connected team. Show its name so the contractor knows it worked.
Next: Connect accounts (reconnect, disconnect), Versioning (the header), Errors (codes, rate limit, retries).
ReferenceGET /meconst r = await fetch("https://www.flashlinegutters.com/api/me", {
headers: {
Authorization: `Bearer ${access_token}`,
"Flashline-Version": "2026-09-02",
},
});
const { team } = await r.json(); // team.name is "Acme Gutters"
{
"team": { "id": "7c1e5a0e-…", "name": "Acme Gutters" },
"app": { "client_id": "flc_9Hx2Kd", "name": "Acme CRM" },
"connected_at": "2026-09-02T13:58:02Z"
}
Good to know
Cost. No charge for the API or for connecting. Contractors' Flashline accounts cover what they measure.
No app review. An app works as soon as it has a client secret and a redirect URI; nothing waits on an approval.
SDKs. No SDK, OpenAPI spec or Postman collection yet. The API is three resource endpoints plus OAuth; the samples on these pages are complete.
Changelog. The Versions table on Versioning is the changelog; breaking changes get a dated version.
Questions. support@flashlinegutters.com