Documentation

Sandbox

GET /api/v1/reports/sandbox/scenarios: the test addresses, the timeline each one runs, and how failures are simulated.

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.

GET /api/v1/reports/sandbox/scenarios

The canonical test addresses, published in-band so you can discover them without leaving the API. Order one of these with a rq_test_sk_* key to trigger a specific timeline. Matching is case-insensitive, and coordinates within ~110m match too. Any address not on this list runs the cancelled timeline — there is no address that turns a sandbox order into a real one.

curl -H "Authorization: Bearer rq_test_sk_..." \
  "https://api.roofquery.com/api/v1/reports/sandbox/scenarios"
{
  "note": "Sandbox keys (rq_test_sk_*) only. The address you order is what picks the scenario — exactly, or by coordinates within ~110m. Any address not listed here runs the `cancelled` timeline.",
  "revisions": "Any sandbox order that reaches `completed` can be revised. The request emits `revisions_requested`, then the report is re-delivered and `revision_completed` fires about 15s later.",
  "scenarios": [
    {
      "scenario": "happy_path",
      "address": "6515 Turnbridge Pl, Prospect, KY 40059, USA",
      "latitude": 38.3526391,
      "longitude": -85.6208045,
      "timeline": [
        { "status": "processing",  "atSeconds": 0 },
        { "status": "in-progress", "atSeconds": 10 },
        { "status": "completed",   "atSeconds": 20 }
      ],
      "synchronousFailure": false
    },
    {
      "scenario": "payment_failed",
      "address": "400 5th Ave, New York, NY 10018, USA",
      "latitude": 40.751,
      "longitude": -73.985,
      "timeline": [],
      "synchronousFailure": true
    }
  ]
}

synchronousFailure: true means the order call itself fails — no order row is created and no webhook ever fires, because in production that failure comes back before an order exists. Every other scenario returns 201 and then works through its timeline. Webhooks are held back about 5 seconds after each transition, so the HTTP response to the call that caused a change always beats the webhook announcing it.

Each address delivers a genuinely different roof — recorded from a real property and run through the same parser and PDF path a live order uses. The Sandbox page lists them with the PDF, the XML and the ESX for each, so you can see what an address returns without ordering it. The XML is the one to pull if you're writing a parser — it's the same document a live order delivers.