Documentation

Brand profiles

Saved brands for your own customers: name, contact block, colours and logo, referenced on a PDF link as ?brand=. Create, update, upload a logo, delete.

API reference

Base URL: https://api.roofquery.com. Authenticate with Authorization: Bearer <your key> — except the four file routes, which take no key.

Copies this whole page as Markdown, so you can paste it into an assistant and have it write the integration. Nothing secret goes on the clipboard — your keys aren't included.

Brand profiles

A profile is one saved brand for the PDF: a company name, a contact block, two colours and a logo. Keep one per customer you resell reports to, and name it on a download link as ?brand=<profileId>. The report renders with that customer's brand, logo included, on an order you placed. Nothing about your own account defaults changes.

MethodPathDoes
GET/api/v1/branding/profilesEvery profile on the account, newest first
POST/api/v1/branding/profilesCreate. Returns 201 with the profile and its id
GET/api/v1/branding/profiles/:idOne profile
PATCH/api/v1/branding/profiles/:idChange any text or colour field. Omitted fields are left alone
DELETE/api/v1/branding/profiles/:idDelete the profile and its logo file. Links that name it fall back to your defaults
PUT/api/v1/branding/profiles/:id/logoUpload the logo: raw image bytes as the body, with an image Content-Type
DELETE/api/v1/branding/profiles/:id/logoRemove the logo. The profile's name and colours stay
FieldRequiredRules
nameTo createYour own label — usually the customer's name. Never printed. 80 chars
companyNameTo createPrints on the header band, footer and cover attribution. 80 chars
addressNoContact block. 160 chars
publicPhoneNoContact block. 32 chars. A 10-digit number is formatted (502) 555-0100
publicEmailNoContact block. 160 chars
brandColorNoHex. Defaults to RoofQuery blue
brandTextColorNoHex. Picked for contrast when omitted
curl -X POST "https://api.roofquery.com/api/v1/branding/profiles" \
  -H "Authorization: Bearer rq_live_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Acme Roofing — Louisville",
    "companyName": "Acme Roofing",
    "address": "900 Bardstown Rd, Louisville, KY 40204",
    "publicPhone": "5025559876",
    "publicEmail": "[email protected]",
    "brandColor": "#0F7A4D"
  }'
HTTP/1.1 201 Created

{
  "profile": {
    "profileId": "rq_brand_7f3a21c9d4e07b16",
    "name": "Acme Roofing — Louisville",
    "companyName": "Acme Roofing",
    "address": "900 Bardstown Rd, Louisville, KY 40204",
    "publicPhone": "5025559876",
    "publicEmail": "[email protected]",
    "brandColor": "#0F7A4D",
    "brandTextColor": null,
    "hasLogo": false,
    "createdAt": "2026-09-09T14:02:11.000Z",
    "updatedAt": "2026-09-09T14:02:11.000Z"
  }
}

Then the logo, as bytes. No multipart, no JSON wrapper — the file is the body:

curl -X PUT "https://api.roofquery.com/api/v1/branding/profiles/rq_brand_7f3a21c9d4e07b16/logo" \
  -H "Authorization: Bearer rq_live_sk_..." \
  -H "Content-Type: image/png" \
  --data-binary @acme-logo.png

And any PDF link for that customer:

https://api.roofquery.com/api/v1/reports/orders/rq_ord_8f3a21c9/pdf?brand=rq_brand_7f3a21c9d4e07b16

A profile is complete. When a link names one, every printed field comes from the profile and nothing falls through to your account defaults — a profile with no phone number prints no phone number, rather than yours under the customer's name. Explicit query params on the same link still win over the profile, field by field.

Ownership. The PDF route takes no key, so a profile is checked against the company that placed the order. A profile from another account, or an id that doesn't exist, returns 404 not_found — the same answer as an unknown order id, so the route can't be used to discover which ids exist. Ids are rq_brand_ plus 64 random bits.

Logos go through the same pipeline as your account logo: PNG, JPEG, WebP, GIF, AVIF or SVG, under 5MB, squared to a 512×512 PNG with transparent padding. There is no URL field, on purpose — see White labeling. Up to 500 profiles per account; past that, 409 profile_limit. Profiles can also be created and edited by hand in the portal under Branding → Profiles, which shows each one's id and a test PDF.