Developer Documentation

Subsections of Developer Documentation

Get started

gSuite is the bundle of APIs GEOSPAN offers for fast, detailed geospatial information on structures, such as building roofs. These geospatial APIs allow the user to geoprocess a location: enabling the location to be accurately described and analyzed within a geographic information system (GIS).

The GEOSPAN API allows you to transmit that geospatial information from GEOSPAN to your data sources and users.

Before you begin: Account, API key, and Quota

Before you can successfully call the GEOSPAN API, you need an account, an API key, and some quota. As an individual GEOSPAN user, the process is familiar. If you are part of an organization, account, key, and quota are provisioned differently than if you are a sole GEOSPAN user. For more information on GEOSPAN accounts, see Your Account in the Support Knowledge Base.

Step Individual GEOSPAN User Part of an Organization
Get an account Sign up for an account. At geospan.com, select the Sign-Up button. Request an invite from the GEOSPAN account owner in your organization.
Get an API key After you have an account, generate an API key. Request an API Key from the GEOSPAN account owner in your organization.
Get quota Add to your quota with a credit card or promotional code. Confirm with your organization’s GEOSPAN account owner that quota exists for API calls.

Overview of GEOSPAN tools for end-users

While you are getting started on the APIs, it may be helpful to understand how the end-user interacts with GEOSPAN technology. End-users have the following interfaces:

  • To order a gSquare instant estimate, the user enters an address and selects the structure from the interactive map.
  • To order a gPro drawing, the user enters an address, selects the building, and provides additional information.
  • View the detailed gPro drawing of a previous order. The user can select from Orders>Complete and be directed to a URL https://apps.geospan.com/gsuite/orders/<order number>/job/<job number>.

Overview of developer interfaces

As a developer, you have access to the following gSuite APIs:

  • gSquare: GEOSPAN’s instant estimation API
  • gPro: GEOSPAN’s modeling APIs for ordering and retrieving structural drawings
  • Spatial: GIS APIs to assist building apps with gSquare and gPro
  • Webhooks: Get real-time notifications of events occurring in the GEOSPAN system

Authorization: Api-Key

GEOSPAN REST API is designed to work with API keys in the Authorization header. When calling any GEOSPAN APIs use that API key in the Authorization header with a bearer string of Api-key.

headers = {
    "Authorization": f"Api-key {GEOSPAN_API_KEY}",
}

res = requests.get(..., headers=headers)
fetch(..., {
    headers: {
        "Authorization": `Api-key ${GEOSPAN_API_KEY}`,
    },
});
curl -X 'GET' \
  'https://api.geospan.com/remote4d/v1/api/...' \
  -H 'accept: application/json' \
  -H 'Authorization: Api-key <geospanapikeystring>'

Additional concepts

You should be all set to work with the GEOSPAN API. Additional concepts, especially around Geospatial and geoprocessing specifications and conventions can be found at Concepts.

gSquare

gSquare is GEOSPAN’s “instant” roof area estimation APIs. gSquare supplies area and predominant pitch in seconds.

Use these APIs to:

Before you begin

Before starting with the gSquare APIs, take time to review the following resources:

  • Get Started — set up the right account, API key, and quota
  • gSquare examples — review the Python and JavaScript code examples
  • Concepts — familiarize yourself with geoprocessing concepts and review the gSquare Lifecycle diagram. This asynchronous approach allows for efficient handling of potentially time-consuming estimation tasks without blocking your application:
    1. Request: You initiate the lifecycle with a request to the /estimate/ endpoint to create an estimate.
    2. Get query key: The API returns a query key immediately.
    3. Poll: You then need to poll the /query/:queryKey endpoint to monitor the status of the estimate.
    4. Monitor status: You check the response from the API, which indicates one of these statuses:
      • PENDING: The estimate is still being processed.
      • FAILURE: The estimation process encountered an error.
      • SUCCESS: The estimate is complete and results are available.
    5. Act on result:
      • If FAILURE, an error report is generated.
      • If SUCCESS, read and utilize the results.
Note

While you can use the gSquare APIs to get an instant estimate, it is not required when generating an order. This step can be skipped. For information about ordering, see gPro.

Estimating roof areas

The following sections provide an example of the HTTP REST method for each API endpoint, along with explanations of request parameters and an example result that GEOSPAN returns.

POST /estimate

HTTP method

Create a new area estimation task by providing a roof footprint in Well-Known Text (WKT) format.

curl -X 'POST' \
  'https://api.geospan.com/remote4d/v1/gsquare/estimate' \
  -H 'accept: application/json' \
  -H 'Authorization: Api-Key <geospanapikeystring>' \
  -H 'Content-Type: application/json' \
  -d '{
  "wkt": "POINT ( -93.18739 44.71353 )",
  "includeImagery": true,
  "includeWeather": true
}'
{
    "queryKey": "sqm-if_plI1MRIasdf1234lkjh"
}

Parameters

wkt

[required] [type: string] Well-Known Text representation of a roof footprint. Can be a POLYGON or POINT.

includeImagery

[optional] [type: boolean] Toggle whether to include oblique views. Default is false.

includeWeather

[optional] [type: boolean] Toggle whether to include weather data. Default is false.

model

[optional] [type: string] Specify the model to use for estimation. Default is “default”.

GET /query/{query_key}

HTTP method

Retrieve the status and results of a specific estimation task using the query key returned by the POST /estimate endpoint.

curl -X 'GET' \
  'https://api.geospan.com/remote4d/v1/gsquare/query/abcd1234-5678-90ef-ghij-klmnopqrstuv' \
  -H 'accept: application/json' \
  -H 'Authorization: Api-Key <geospanapikeystring>'
{
    "computedFootprint": "POLYGON ((-93.187349 44.713629, -93.187347 44.713569, -93.187328 44.713569, -93.187322 44.71344, -93.187381 44.713439, -93.187381 44.713425, -93.187413 44.713425, -93.187414 44.713441, -93.187441 44.713441, -93.18745 44.713627, -93.187349 44.713629))",
    "totalArea": {
        "area": 197.8059923890073,
        "units": "sqm"
    },
    "pitchResult": {
        "primaryPitch": 3,
        "deviation": 1
    },
    "confidence": 6,
    "imagery": [
        {
            "orientation": "nadir",
            "image": "/9j/4AAQSkZJRgABAgAAAQABAAD/4QjKaHR0cDov
            .
            .
            .
            61TvbxGcBRkY5OakkJkyJGI+lVZoUGQG604os//2Q=="
        },
        {
            "orientation": "north",
            "image": "/9j/4AAQSkZJRgABAgAAAQABAAD/4QiwaHR0cDov
            .
            .
            .
            WzZUQnbvPeolBsGrn/2Q=="
        },
        {
            "orientation": "east",
            "image": "/9j/4AAQSkZJRgABAgAAAQABAAD/4Qi9aHR0cDov
            .
            .
            .
            ZP/AIql9al0gwVFPqf/2Q=="
        },
        {
            "orientation": "south",
            "image": "/9j/4AAQSkZJRgABAgAAAQABAAD/4QiuaHR0cDov
            .
            .
            .
            /+tWcqji9hXR//9k="
        },
        {
            "orientation": "west",
            "image": "/9j/4AAQSkZJRgABAgAAAQABAAD/4Qi+aHR0cDov
            .
            .
            .
            pnMBiIeNTuZcEdQf5UquF5WjOULM//2Q=="
        }
    ],
    "weather": [
        {
            "datecode": "231024",
            "hailSize": 1,
            "distance": 9.760984757545051
        },
        {
            "datecode": "240803",
            "hailSize": 1,
            "distance": 7.845437799202324
        }
    ]
}

Parameters

query_key

[required] [type: string] The unique identifier for the gSquare query.

Subsections of gSquare

API Specification

Before getting started

Before starting with the gSquare API, take time to review Get Started and familiarize yourself with the Concepts.

Examples

Review the Python and JavaScript examples here to see gSquare in action.

Python

Download Python

"""
Create and monitor a gSquare estimate using a point
"""
import json
import os
import sys
import requests
import time

GEOSPAN_API_KEY = os.getenv("GEOSPAN_API_KEY") or input("Please enter your API key: ")
API_HOME = os.getenv("GEOSPAN_API_HOME", "https://api.geospan.com/remote4d/v1/api/")

# Ensure this point is on a rooftop!
LOCATION = [-93.18736857022286, 44.713507124491315]


def create_estimate(lon: float, lat: float) -> dict:
    """
    Use a longitude and latitude to create a request for a
    gSquare estimate.

    The longitude and latitude should be on a roof top.

    """

    url = f"{API_HOME}/gsquare/estimate"
    headers = {
        "Authorization": f"Api-Key {GEOSPAN_API_KEY}",
    }

    data = {
        "wkt": f"POINT({lon} {lat})",
        "includeImagery": False,
        "includeWeather": True,
    }

    res = requests.post(url, headers=headers, json=data)

    # Accept both 200 (OK) and 201 (Created) as valid responses
    if res.status_code not in (200, 201):
        raise ValueError(f"Failed to create estimate. Status code: {res.status_code}, Response: {res.text}")
    
    try:
        return res.json()
    except json.JSONDecodeError:
        raise ValueError(f"Response is not valid JSON. Status code: {res.status_code}, Response: {res.text}")


def check_estimate(query_key: str):
    """
    Check the query status

    Expected reuslts:

    {
        "queryKey": "sqm-abcdef12345"
    }

    """

    url = f"{API_HOME}/gsquare/query/{query_key}"
    headers = {
        "Authorization": f"Api-Key {GEOSPAN_API_KEY}",
    }

    res = requests.get(url, headers=headers)
    return res.json()


def run_example(silent=False):
    """
    Execute a gSquare query with a point.

    Expected results:

    {
      "state": "SUCCESS",
      "results": {
        "computedFootprint": "POLYGON ((-93.187349 44.713629, -93.187347 44.713569, -93.187328 44.713569, -93.187322 44.71344, -93.187381 44.713439, -93.187381 44.713425, -93.187413 44.713425, -93.187414 44.713441, -93.187441 44.713441, -93.18745 44.713627, -93.187349 44.713629))",
        "totalArea": {
          "area": 197.8059923890073,
          "units": "sqm"
        },
        "pitchResult": {
          "primaryPitch": 3,
          "deviation": 1
        },
        "confidence": 6,
        "imagery": [],
        "weather": [
          {
            "datecode": "231024",
            "hailSize": 1.0,
            "distance": 9.760984757545051
          },
          {
            "datecode": "240803",
            "hailSize": 1.0,
            "distance": 7.845437799202324
          }
        ]
      }
    }
    """

    # get the lon-lat for the address
    # start the gsquare estimate
    query_key = create_estimate(LOCATION[0], LOCATION[1])["queryKey"]

    # monitor the estimate until it is ready then pretty-print the results
    max_polls = 20
    while True:
        estimate = check_estimate(query_key)
        if estimate["state"] != "PENDING":
            if not silent:
                print(json.dumps(estimate, indent=2))
            if estimate["state"] != "SUCCESS":
                return 1
            return 0
        max_polls -= 1
        if max_polls == 0:
            return 1
        time.sleep(2)


if __name__ == "__main__":
    if not GEOSPAN_API_KEY:
        print("API key is required.")
        sys.exit(1)  # Exit with non-zero exit code for failure

    sys.exit(run_example())

Javascript

An example of using Mapbox and Geospan APIs to replicate gSquare functionality.

Creates a Mapbox GL JS map with building outlines. When buildings are clicked, it produces a gSquare estimate.

Note

The API keys and tokens in index.js are for demonstration only. In a real application, secure them using appropriate methods, such as environment variables, backend proxies, and IAM services with temporary credentials.

Download Zip

// Config
const MAPBOX_ACCESS_TOKEN = "";
const GEOSPAN_API_TOKEN = "";

// Constants
const MARKETPLACE_API_HOME = "https://api.geospan.com/remote4d/v1/api";
const FOOTPRINTS_URL = `${MARKETPLACE_API_HOME}/spatial/footprints`;
const ESTIMATE_URL = `${MARKETPLACE_API_HOME}/gsquare/estimate`;
const ESTIMATE_RESULT_URL = `${MARKETPLACE_API_HOME}/gsquare/query`;
const AUTH_HEADER = { Authorization: `Api-Key ${GEOSPAN_API_TOKEN}` };
const RESULTS_MAX_ATTEMPTS = 20;
const RESULTS_CHECK_DELAY = 2000;
const SQ_FT_PER_SQ_M = 10.7639;

mapboxgl.accessToken = MAPBOX_ACCESS_TOKEN;

// Initialize our map
const map = new mapboxgl.Map({
  container: "map", // container ID
  center: [-74.568, 39.983], // starting position [lng, lat]
  zoom: 19, // starting zoom
  style: "mapbox://styles/mapbox/satellite-v9",
});

// Once the map loads, set up our datasources and layers
map.on("load", () => {
  // Create a new data source with an empty feature collection
  map.addSource("building-footprints", {
    type: "geojson",
    data: {
      type: "FeatureCollection",
      features: [],
    },
    // Make sure all features have a unique ID
    generateId: true,
  });

  // Add a new layer that uses our new data source to create features visible in
  // the map
  map.addLayer({
    id: "building-footprints-layer",
    type: "fill",
    source: "building-footprints",
    layout: {},
    paint: {
      // Conditional fill-color formatting for highlighting when clicked
      "fill-color": [
        "case",
        ["boolean", ["feature-state", "click"], false],
        "#FFFF00",
        "#0080ff",
      ],
      "fill-opacity": 0.5,
    },
  });

  // Load our footprint data for the first time
  loadNewFootprints();
});

// takes a polygon feature and returns its center coordinate as a WKT string
const getCenterWKT = (feature) => {
  const bounds = new mapboxgl.LngLatBounds();
  feature.geometry.coordinates[0].forEach((coordinate) => {
    bounds.extend(coordinate);
  });
  const center = bounds.getCenter();
  return `POINT (${center.lng} ${center.lat})`;
};

// Given the current bounds of the map, load building footprints for that area
// and add them into our building-footprints datasource
const loadNewFootprints = async () => {
  const bounds = map.getBounds().toArray().flat();
  const params = new URLSearchParams({
    bounds,
  }).toString();

  const footprints = await fetch(`${FOOTPRINTS_URL}?${params}`, {
    headers: AUTH_HEADER,
  })
    .then((data) => data.json())
    .catch((e) => displayResults("Could not load footprints"));

  if (footprints) {
    map.getSource("building-footprints").setData(footprints);
  }
};

// Submits and retrieves the results of the estimate
const requestEstimate = async (wkt) => {
  // Submit estimate request
  const { queryKey } = await fetch(ESTIMATE_URL, {
    method: "POST",
    headers: {
      ...AUTH_HEADER,
      Accept: "application/json",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      wkt,
      includeImagery: true,
      includeWeather: true,
    }),
  }).then((data) => data.json());

  // Poll Geospan for results
  let counter = RESULTS_MAX_ATTEMPTS;
  return new Promise((resolve, reject) => {
    const loadResults = () => {
      fetch(`${ESTIMATE_RESULT_URL}/${queryKey}`, {
        headers: AUTH_HEADER,
      })
        .then((data) => data.json())
        .then(({ state, results }) => {
          if (state === "SUCCESS") {
            resolve(results);
          } else if (state === "PENDING" && counter > 0) {
            setTimeout(() => {
              loadResults(queryKey);
            }, RESULTS_CHECK_DELAY);
          } else if (state === "FAILURE") {
            reject("There was an error in processing this request.");
          } else {
            reject("Your request has timed out.");
          }
          counter--;
        })
        .catch((e) => reject(e));
    };

    if (queryKey) {
      loadResults(queryKey);
    } else {
      reject(
        "There was an error creating the request. Please select another location or try again in a moment."
      );
    }
  });
};

// Displays the results in the sidebar
const displayResults = (results) => {
  document.querySelector("#results").innerHTML = results;
};

let highlightedBuildingId = null;

// Remove highlight from a building and clear results in the sidebar
const clearResults = () => {
  if (highlightedBuildingId !== null) {
    map.setFeatureState(
      { source: "building-footprints", id: highlightedBuildingId },
      { click: false }
    );
  }
  highlightedBuildingId = null;
  displayResults("");
};

// Adds a highlight to a clicked building
const highlightClickedBuilding = (mapboxFeature) => {
  clearResults();

  map.setFeatureState(
    { source: "building-footprints", id: mapboxFeature.id },
    { click: true }
  );

  highlightedBuildingId = mapboxFeature.id;
};

// Make sure that every time we pan / zoom the map, we update our building
// footprints
map.on("moveend", () => {
  clearResults();
  loadNewFootprints();
});

// When we click on a building, highlight the building and request an estimate
map.on("click", "building-footprints-layer", (e) => {
  highlightClickedBuilding(e.features[0]);

  displayResults("Loading gSquare Estimate...");

  // Get the center coordinate of the building and convert it to a WKT string
  // that we can use to submit our estimate request
  const wkt = getCenterWKT(e.features[0]);
  requestEstimate(wkt)
    .then((data) =>
      displayResults(`
            <div><b>Total Area</b>: ${(
              data.totalArea.area * SQ_FT_PER_SQ_M
            ).toFixed(2)} sq ft</div>
            <div><b>Primary Pitch</b>: ${data.pitchResult.primaryPitch}</div>
        `)
    )
    .catch((e) => displayResults("Unable to load estimate"));
});
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>gSquare Lite</title>
    <link
      href="https://api.mapbox.com/mapbox-gl-js/v3.6.0/mapbox-gl.css"
      rel="stylesheet"
    />
    <link rel="stylesheet" href="style.css" />
  </head>
  <body>
    <div id="map"></div>
    <div id="sidebar">
        <h1>Click a building to get a gSquare Estimate</h1>
        <div id="results"></div>
    </div>
    <script src="https://api.mapbox.com/mapbox-gl-js/v3.6.0/mapbox-gl.js"></script>
    <script src="index.js"></script>
  </body>
</html>
html, body {
    height: 100%;
    width: 100%;
    font-family: sans-serif;
}

body {
    padding: 0;
    margin: 0;
    display: flex;
    align-content: stretch;
}

#map {
    width: 80%;
}

#sidebar {
    width: 20%;
    padding: 20px;
}

gPro & xPress

gPro is GEOSPAN’s modeling APIs. Use these APIs to order and recall models — geoprocessed structural drawings. Use the gPro APIs to:

The gPro API now supports both the standard gPro roof_model product and the xPress roof_model_express product. For more information about the xPress model and API implementation, see the xPress Model overview.

The following sections provide an example of the HTTP REST method for each API group, along with explanations of request parameters and an example result that GEOSPAN returns:

The gPro API specification is available, complete with Authorization and a “Try it out” feature for each API call.

Note

This document covers gPro APIs. For information about webhooks, see Webhooks.

Create and get status on orders

Call the /order/* endpoints to create orders and get the status. Orders can include multiple jobs.

GET /order/

HTTP method

Call the /order endpoint to retrieve a paginated list of orders, with an option to sort by the order status field.

curl -X 'GET' \
  'https://api.geospan.com/remote4d/v1/api/gpro/order/?limit=2&offset=1000&ordering=number' \
  -H 'accept: application/json' \
  -H 'Authorization: Api-Key <geospanapikeystring>'
{
    "count": 4826,
    "next": "http://api.geospan.com/shop/api/gpro/order/?limit=2&offset=1002&ordering=number",
    "previous": "http://api.geospan.com/shop/api/gpro/order/?limit=2&offset=998&ordering=number",
    "results": [
        {
            "number": "101073",
            "status": "In Process",
            "orderedBy": "contact@yourcompany.com",
            "referenceId": "141MPBNYHDS",
            "customerName": "141MPBNYHDS",
            "jobs": [
                {
                    "id": 1057,
                    "status": "Completed",
                    "address": "141 Mckinley Parkway, Buffalo, New York 14220",
                    "buildingInfo": "",
                    "wkt": "POINT (-78.81471170897164 42.83583933068422)"
                }
            ]
        },
        {
            "number": "101074",
            "status": "New",
            "orderedBy": "contact@yourcompany.com",
            "referenceId": "145MPBNYHDS",
            "customerName": "145MPBNYHDS",
            "jobs": [
                {
                    "id": 1058,
                    "status": "Ready",
                    "address": "145 Mckinley Parkway, Buffalo, New York 14220",
                    "buildingInfo": "",
                    "wkt": "POINT (-78.81472199599162 42.83598846524143)"
                }
            ]
        }
    ]
}

Parameters

The GET /order API requires at least one of the following query parameter fields.

limit

[optional] [type: integer] Number of results to return per page.

offset

[optional] [type: integer] The initial index from which to return the results.

ordering

[optional] [type: string] Which field to use when ordering the results.

GET /order/{number}

HTTP method
curl -X 'GET' \
  'https://api.geospan.com/remote4d/v1/api/gpro/order/103153' \
  -H 'accept: application/json' \
  -H 'Authorization: Api-Key <geospanapikeystring>'
{
    "number": "103153",
    "orderedBy": "contact@yourcompany.com",
    "referenceId": "idprovidedbytheorderer",
    "customerName": "Contact AtYourCompany",
    "jobs": [
        {
        "id": 3109,
        "address": "",
        "buildingInfo": "Building number 1",
        "wkt": "POINT (-93.18739 44.71353)"
        },
        {
        "id": 3110,
        "address": "",
        "buildingInfo": "Building number 2",
        "wkt": "POINT (-93.1874566 44.7134632)"
        }
    ]
}

Parameters

number

[required] [type: string] The unique order number used to identify and retrieve the order.

POST /order/create

HTTP method
curl -X 'POST' \
  'https://api.geospan.com/remote4d/v1/api/gpro/order/create' \
  -H 'accept: application/json' \
  -H 'Authorization: Api-Key <geospanapikeystring>' \
  -H 'Content-Type: application/json' \
  -d '{
        "products": [
            "roof_model_express"
        ],
        "clientName": "Optional Textname",
        "referenceId": "Optional Ref ID or Policy Number",
        "associatedAddress": "Optional 16288 Fairgreen Ave, Rosemount, MN 55068",
        "buildings": [
            {
            "location": "POINT ( -93.18739 44.71353 )",
            "customerNotes":"Optional Building 1 Notes to production...",
            "buildingInfo":"Optional Building number 1"
            }
        ],
        "customerNotes": "Optional notes to production"
        }'
{
    "orderNumber": 103156,
    "jobIds": [
        3113
    ]
}
curl -X 'POST' \
  'https://api.geospan.com/remote4d/v1/api/gpro/order/create' \
  -H 'accept: application/json' \
  -H 'Authorization: Api-Key <geospanapikeystring>' \
  -H 'Content-Type: application/json' \
  -d '{
        "products": [
            "roof_model"
        ],
        "clientName": "Optional Textname",
        "referenceId": "Optional Ref ID or Policy Number",
        "associatedAddress": "Optional 16288 Fairgreen Ave, Rosemount, MN 55068",
        "buildings": [
            {
            "location": "POINT ( -93.18739 44.71353 )",
            "customerNotes":"Optional Building 1 Notes to production...",
            "buildingInfo":"Optional Building number 1"
            }
        ],
        "customerNotes": "Optional notes to production"
        }'
{
    "orderNumber": 103156,
    "jobIds": [
        3113
    ]
}

Parameters

None.

Order schemas and required fields

The POST /order/create API requires a geometry provided either in the buildings > location field or a parcel field, as well as the products field set to roof_model or roof_model_express.

The POST /order/create API expects the ExpressCheckout schema with the ExpressCheckoutBuilding schema. The following is the schema with descriptions for each field.

{
  "products": [
    "roof_model"
  ],
  "basketId": "Optional string",
  "voucherCode": "Optional string",
  "clientName": "Optional Textname",
  "referenceId": "Optional Ref ID or Policy Number",
  "associatedAddress": "Optional address",
  "buildings": [
    {
        "location": "POINT ( <number_for_longitude> <number_for_latitude> )",
        "customerNotes": "Optional notes to production for location 1",
        "buildingInfo": "Optional description of building_1"
    },
    {
        "location": "Optional second location",
        "customerNotes": "Optional notes to production for location 2",
        "buildingInfo": "Optional description of building_2"
    }
  ],
  "parcel": {
    "wkt": "Required conditionally: if buildings location field not provided"
  },
  "paymentMethodId": "string"
}

Export order and download

Call the order/{number}/export/ endpoint to export an order to a popular file format. This is a three-step process of initiating an export to a specific file format, waiting for the export to complete, and then downloading it, as in the following pseudocode routine:

  1. Create Export Task

    taskId = POST /order/{number}/export/?outputFormat={format}

  2. Poll Status

    WHILE true: status = GET /order/{number}/export/{taskId}/ IF status == "finished" THEN break SLEEP 5 seconds

  3. Download File

    file = GET /order/{number}/export/{taskId}/download/ SAVE file as "order-download.{format}"

POST /order/{number}/export/

HTTP method

The API to export an order.

The roof_model_express product has one possible value for the outputFormat: docx.
Possible values for the outputFormat are: docx, dxf, esx, geojson-lines, geojson-polygons, symbility-xml, verisk-xml, or xml.

This call responds with a taskId and a status with the possible value of: pending, finished, or error.

curl -X 'POST' \
  'https://api.geospan.com/remote4d/v1/api/gpro/order/103618/export/?outputFormat=xml' \
  -H 'accept: application/json' \
  -H 'Authorization: Api-Key <geospanapikeystring>'
{
    "taskId": "1ot3gqxj4q5a2gwz1u3jm1px5",
    "status": "pending"
}
curl -X 'POST' \
  'https://api.geospan.com/remote4d/v1/api/gpro/order/103618/export/?outputFormat=dfx' \
  -H 'accept: application/json' \
  -H 'Authorization: Api-Key <geospanapikeystring>'
{
    "taskId": "1ot3gqxj4q5a2gwz1u3jm1px5",
    "status": "pending"
}

Parameters

outputFormat

[required] [type: string]

The file format of the data to export. Possible values are:

  • docx: Word document format
  • xml: Standard XML format

The file format of the data to export. Possible values are:

  • docx: Word document format
  • dxf: AutoCAD DXF format
  • esx: ESX format
  • geojson-lines: GeoJSON lines format
  • geojson-polygons: GeoJSON polygons format
  • symbility-xml: Symbility XML format
  • verisk-xml: Verisk XML format
  • xml: Standard XML format

Export schemas and required fields

number

[required] [type: string] The order number to export.

GET /order/{number}/export/{taskId}/

HTTP method

The API to get the status of an export task. Possible values are: pending, finished, and error.

curl -X 'GET' \
--location 'https://api.geospan.com/remote4d/v1/api/gpro/order/103689/export/1ot3gqxj4q5a2gwz1u3jm1px5/' \
  -H 'Authorization: Api-Key <geospanapikeystring>'
{
    "taskId": "1ot3gqxj4q5a2gwz1u3jm1px5",
    "status": "finished"
}

Parameters

None.

Export schemas and required fields

number

[required] [type: string] Order number to export.

taskId

[required] [type: string] Export task ID provided by in the result of a call to POST /order/{number}/export/.

GET /order/{number}/export/{taskId}/download/

HTTP method
curl -X 'GET' \
--location 'https://api.geospan.com/remote4d/v1/api/gpro/order/103689/export/1ot3gqxj4q5a2gwz1u3jm1px5/download/' \
  -H 'Authorization: Api-Key <geospanapikeystring>'  \
  --output order-103689-download.xml

The output is saved to a file named order-103689-download.xml in the same directory where the cURL call was made.

Parameters

None.

Download export schemas and required fields

Accept header for downloading

[optional] [type: string] Depending on the type of export you requested, the following are acceptable media types:

  • text/xml
  • application/vnd.openxmlformats-officedocument.wordprocessingml.document
  • application/octet-stream

Providing no accept header type, or providing a type of --header 'accept: */*' also succeeds.

number

[required] [type: string] Order number to export.

taskId

[required] [type: string] Export task ID provided by in the result of a call to POST /order/{number}/export/.

output

[optional] [type: string] Depending on the call, provide a location to save the resulting file.

POST /order/{number}/structures/

HTTP method

The API to export an order projection of the structures JSON data. Available projection values are crs84, ecef, planar. The default value is crs84.

Structure coordinates will be flattened to 2D for all xPpress models.
curl -X 'GET' \
  'https://api.geospan.com/remote4d/v1/api/gpro/order/104294/export/?outputFormat=xml' \
  -H 'accept: application/json' \
  -H 'Authorization: Api-Key <geospanapikeystring>'
{
    "kind": "structurecollection",
    "structures": [
        {
            "kind": "structure",
            "projection": "crs84",
            "points": {
                "c101": {
                    "kind": "corner",
                    "coordinates": [
                        -93.38278656215714,
                        45.01580360496024,
                        298.0300107039511
                    ]
                },
                "c102": {
                    "kind": "corner",
                    "coordinates": [
                        -93.3828421751554,
                        45.01575494707009,
                        299.70632887631655
                    ]
                },
                "c103": {
                    "kind": "corner",
                    "coordinates": [
                        -93.38290127794981,
                        45.01575103014567,
                        299.70632887631655
                    ]
                },
                "c104": {
                    "kind": "corner",
                    "coordinates": [
                        -93.38296863682278,
                        45.01579153831072,
                        298.03001070581377
                    ]
                },
                "c105": {
                    "kind": "corner",
                    "coordinates": [
                        -93.38277481641455,
                        45.0157144388302,
                        298.03001070581377
                    ]
                },
                "c106": {
                    "kind": "corner",
                    "coordinates": [
                        -93.38295689080012,
                        45.015702372199215,
                        298.0300107030198
                    ]
                },
                "c107": {
                    "kind": "corner",
                    "coordinates": [
                        -93.38295821479416,
                        45.015734282841514,
                        298.1078387647867
                    ]
                },
                "c108": {
                    "kind": "corner",
                    "coordinates": [
                        -93.38295050971219,
                        45.01573479344404,
                        298.31790600530803
                    ]
                },
                "c109": {
                    "kind": "corner",
                    "coordinates": [
                        -93.38294871302814,
                        45.015721154472956,
                        298.31790652964264
                    ]
                },
                "c110": {
                    "kind": "corner",
                    "coordinates": [
                        -93.38295641906878,
                        45.01572064380766,
                        298.1078131068498
                    ]
                },
                "ground": {
                    "kind": "ground",
                    "coordinates": [
                        -93.38296863682278,
                        45.015702372199215,
                        295.1345520019531
                    ]
                }
            },
            "edges": {
                "e101": {
                    "kind": "hip",
                    "points": [
                        "c101",
                        "c102"
                    ],
                    "properties": {
                        "length": 7.16
                    }
                },
                "e108": {
                    "kind": "eave",
                    "points": [
                        "c101",
                        "c105"
                    ],
                    "properties": {
                        "attachments": [
                            "gutter"
                        ],
                        "length": 9.953
                    }
                },
                "e102": {
                    "kind": "ridge",
                    "points": [
                        "c103",
                        "c102"
                    ],
                    "properties": {
                        "length": 4.679
                    }
                },
                "e103": {
                    "kind": "hip",
                    "points": [
                        "c103",
                        "c104"
                    ],
                    "properties": {
                        "length": 7.16
                    }
                },
                "e106": {
                    "kind": "hip",
                    "points": [
                        "c103",
                        "c106"
                    ],
                    "properties": {
                        "length": 7.16
                    }
                },
                "e104": {
                    "kind": "eave",
                    "points": [
                        "c104",
                        "c101"
                    ],
                    "properties": {
                        "attachments": [
                            "gutter"
                        ],
                        "length": 14.415
                    }
                },
                "e109": {
                    "kind": "eave",
                    "points": [
                        "c104",
                        "c106"
                    ],
                    "properties": {
                        "attachments": [
                            "gutter"
                        ],
                        "length": 9.953
                    }
                },
                "e105": {
                    "kind": "eave",
                    "points": [
                        "c105",
                        "c106"
                    ],
                    "properties": {
                        "attachments": [
                            "gutter"
                        ],
                        "length": 14.415
                    }
                },
                "e107": {
                    "kind": "hip",
                    "points": [
                        "c105",
                        "c102"
                    ],
                    "properties": {
                        "length": 7.16
                    }
                },
                "e110": {
                    "kind": "chimney",
                    "points": [
                        "c108",
                        "c107"
                    ],
                    "properties": {
                        "length": 0.645
                    }
                },
                "e111": {
                    "kind": "chimney",
                    "points": [
                        "c108",
                        "c109"
                    ],
                    "properties": {
                        "length": 1.522
                    }
                },
                "e112": {
                    "kind": "chimney",
                    "points": [
                        "c109",
                        "c110"
                    ],
                    "properties": {
                        "length": 0.645
                    }
                },
                "e113": {
                    "kind": "chimney",
                    "points": [
                        "c107",
                        "c110"
                    ],
                    "properties": {
                        "length": 1.522
                    }
                }
            },
            "surfaces": {
                "surface1": {
                    "kind": "roof",
                    "edges": [
                        [
                            "e101",
                            "e102",
                            "e103",
                            "e104"
                        ]
                    ],
                    "properties": {
                        "material": "asphalt",
                        "pitch": 4,
                        "area": 50.135
                    }
                },
                "surface2": {
                    "kind": "roof",
                    "edges": [
                        [
                            "e105",
                            "e106",
                            "e107",
                            "e102"
                        ]
                    ],
                    "properties": {
                        "material": "asphalt",
                        "pitch": 4,
                        "area": 50.134
                    }
                },
                "surface3": {
                    "kind": "roof",
                    "edges": [
                        [
                            "e107",
                            "e101",
                            "e108"
                        ]
                    ],
                    "properties": {
                        "material": "asphalt",
                        "pitch": 4,
                        "area": 25.621
                    }
                },
                "surface4": {
                    "kind": "roof",
                    "edges": [
                        [
                            "e109",
                            "e106",
                            "e103"
                        ],
                        [
                            "e110",
                            "e111",
                            "e112",
                            "e113"
                        ]
                    ],
                    "properties": {
                        "material": "asphalt",
                        "pitch": 4,
                        "area": 24.638
                    }
                }
            },
            "components": {
                "roof": {
                    "surfaces": [
                        "surface1",
                        "surface2",
                        "surface3",
                        "surface4"
                    ]
                }
            }
        },
        {
            "kind": "structure",
            "projection": "crs84",
            "points": {
                "c111": {
                    "kind": "corner",
                    "coordinates": [
                        -93.38296654357835,
                        45.01588232625001,
                        297.4300534883514
                    ]
                },
                "c112": {
                    "kind": "corner",
                    "coordinates": [
                        -93.38296520261137,
                        45.01580529784941,
                        297.4300534874201
                    ]
                },
                "c113": {
                    "kind": "corner",
                    "coordinates": [
                        -93.38301710992096,
                        45.01584010318367,
                        298.87778268940747
                    ]
                },
                "c114": {
                    "kind": "corner",
                    "coordinates": [
                        -93.383017220818,
                        45.01584647305375,
                        298.87778268847615
                    ]
                },
                "c115": {
                    "kind": "corner",
                    "coordinates": [
                        -93.38306778969215,
                        45.01580439932028,
                        297.4300534874201
                    ]
                },
                "c116": {
                    "kind": "corner",
                    "coordinates": [
                        -93.38306913079664,
                        45.015881427719684,
                        297.4300534883514
                    ]
                },
                "ground": {
                    "kind": "ground",
                    "coordinates": [
                        -93.38306913079664,
                        45.01580439932029,
                        295.1345520019531
                    ]
                }
            },
            "edges": {
                "e114": {
                    "kind": "eave",
                    "points": [
                        "c111",
                        "c112"
                    ],
                    "properties": {
                        "attachments": [
                            "gutter"
                        ],
                        "length": 8.561
                    }
                },
                "e115": {
                    "kind": "hip",
                    "points": [
                        "c112",
                        "c113"
                    ],
                    "properties": {
                        "length": 5.814
                    }
                },
                "e122": {
                    "kind": "eave",
                    "points": [
                        "c112",
                        "c115"
                    ],
                    "properties": {
                        "attachments": [
                            "gutter"
                        ],
                        "length": 8.087
                    }
                },
                "e116": {
                    "kind": "ridge",
                    "points": [
                        "c113",
                        "c114"
                    ],
                    "properties": {
                        "length": 0.708
                    }
                },
                "e117": {
                    "kind": "hip",
                    "points": [
                        "c114",
                        "c111"
                    ],
                    "properties": {
                        "length": 5.825
                    }
                },
                "e119": {
                    "kind": "hip",
                    "points": [
                        "c114",
                        "c116"
                    ],
                    "properties": {
                        "length": 5.825
                    }
                },
                "e118": {
                    "kind": "eave",
                    "points": [
                        "c115",
                        "c116"
                    ],
                    "properties": {
                        "attachments": [
                            "gutter"
                        ],
                        "length": 8.561
                    }
                },
                "e120": {
                    "kind": "hip",
                    "points": [
                        "c115",
                        "c113"
                    ],
                    "properties": {
                        "length": 5.814
                    }
                },
                "e121": {
                    "kind": "eave",
                    "points": [
                        "c116",
                        "c111"
                    ],
                    "properties": {
                        "attachments": [
                            "gutter"
                        ],
                        "length": 8.087
                    }
                }
            },
            "surfaces": {
                "surface5": {
                    "kind": "roof",
                    "edges": [
                        [
                            "e114",
                            "e115",
                            "e116",
                            "e117"
                        ]
                    ],
                    "properties": {
                        "material": "asphalt",
                        "pitch": 4,
                        "area": 19.906
                    }
                },
                "surface6": {
                    "kind": "roof",
                    "edges": [
                        [
                            "e118",
                            "e119",
                            "e116",
                            "e120"
                        ]
                    ],
                    "properties": {
                        "material": "asphalt",
                        "pitch": 4,
                        "area": 19.906
                    }
                },
                "surface7": {
                    "kind": "roof",
                    "edges": [
                        [
                            "e121",
                            "e117",
                            "e119"
                        ]
                    ],
                    "properties": {
                        "material": "asphalt",
                        "pitch": 4,
                        "area": 16.955
                    }
                },
                "surface8": {
                    "kind": "roof",
                    "edges": [
                        [
                            "e120",
                            "e115",
                            "e122"
                        ]
                    ],
                    "properties": {
                        "material": "asphalt",
                        "pitch": 4,
                        "area": 16.892
                    }
                }
            },
            "components": {
                "roof": {
                    "surfaces": [
                        "surface5",
                        "surface6",
                        "surface7",
                        "surface8"
                    ]
                }
            }
        }
    ]
}

Parameters

projection

[optional] [type: string] Available projection values are crs84, ecef, planar, as in order/104294/structures/?projection=planar. crs84 is the default value.

POST /order/preview/

HTTP method

The POST /order/preview/ endpoint takes the same fields as the POST /order/create endpoint, but provides information about the order basketId, including total, discountApplied, lines, price, isComplex, and voucherCode.

curl -X 'POST' \
--location 'https://api.geospan.com/remote4d/v1/api/gpro/order/preview' \
    -H 'Authorization: Api-Key <geospanapikeystring>' \
    -H 'Content-Type: application/json' \
    -H 'Accept: application/json' \
    --data '{
    "products": [
        "roof_model"
    ],
    "buildings": [
        {
        "location": "POINT ( -93.18739 44.71353 )"
        }
    ]
    }'
{
    "basketId": 3658,
    "total": 49.0,
    "discountApplied": 0.0,
    "lines": [
        {
            "price": 49.0,
            "isComplex": false
        }
    ],
    "voucherCode": ""
}

Parameters

None.

Order schemas and required fields

The POST /order/preview API requires the same fields as the POST /order/create endpoint and the same ExpressCheckout schema with the ExpressCheckoutBuilding schema.

Get information about jobs

Call the /jobs endpoint to get the details of modeling jobs and to share them.

Note

Construction jobs are often based on parcels. But parcels can contain multiple buildings. So Geospan jobs are based on individual buildings, not parcels.

GET /jobs/

HTTP method
curl -X 'GET' \
'https://api.geospan.com/remote4d/v1/api/gpro/jobs/?limit=2' \
    -H 'accept: application/json' \
    -H 'Authorization: Api-Key <geospanapikeystring>'
{
    "count": 3002,
    "next": "http://api.geospan.com/shop/api/gpro/jobs/?limit=2&offset=2",
    "previous": null,
    "results": [
            {
                "status": "Publish",
                "product": {
                        "upc": "ROOF-S"
                    },
                "url": "http://api.geospan.com/shop/api/jobs/3002/",
                "order": {
                        "url": "http://api.geospan.com/shop/api/orders/2905/",
                        "id": 2905,
                        "number": "103041",
                        "status": "Completed",
                        "basket": {
                                "customer_name": "Contact AtYourCompany",
                                "reference_id": ""
                            },
                        "email": "contact@yourcompany.com"
                    },
                "location": {
                        "type": "Point",
                        "coordinates": [
                                -93.18739,
                                44.71353
                            ]
                    },
                "location_description": "",
                "attachments": [],
                "date_created": "2024-08-16T14:58:13.230552Z",
                "date_updated": "2024-08-16T16:02:22.250881Z",
                "status_reason": null,
                "id": 3002,
                "extra": null,
                "production_user": null,
                "production_team": "HDS-1",
                "customer_notes": "",
                "address": "16288 Fairgreen Ave, Rosemount, MN 55068",
                "building_info": "",
                "siblings": "http://api.geospan.com/shop/api/jobs/3002/siblings/",
                "history": "http://api.geospan.com/shop/api/jobs/3002/history/",
                "share_key": "0123a45678b9cdef0123a45678b9cdef",
                "priority": 5,
                "result_type": "geoid",
                "result": "{\"geoid\":\"xyz54321-5776-4591-9820-e69994a8bf93\",\"id\":5206}"
            },
            {
                "status": "Publish",
                "product": {
                        "upc": "ROOF-S"
                    },
                "url": "http://api.geospan.com/shop/api/jobs/3001/",
                "order": {
                        "url": "http://api.geospan.com/shop/api/orders/2904/",
                        "id": 2904,
                        "number": "103040",
                        "status": "Completed",
                        "basket": {
                                "customer_name": "Contact AtYourCompany",
                                "reference_id": ""
                            },
                        "email": "contact@yourcompany.com"
                    },
                "location": {
                        "type": "Point",
                        "coordinates": [
                                -93.1874566,
                                44.7134632
                            ]
                    },
                "location_description": "",
                "attachments": [],
                "date_created": "2024-08-16T13:52:21.766780Z",
                "date_updated": "2024-08-16T14:48:23.015383Z",
                "status_reason": null,
                "id": 3001,
                "extra": null,
                "production_user": null,
                "production_team": "HDS-1",
                "customer_notes": "",
                "address": "16306 Fairgreen Ave, Rosemount, MN 55068",
                "building_info": "",
                "siblings": "http://api.geospan.com/shop/api/jobs/3001/siblings/",
                "history": "http://api.geospan.com/shop/api/jobs/3001/history/",
                "share_key": "3210a45678b9cdef0123a45678b9cdef",
                "priority": 5,
                "result_type": "geoid",
                "result": "{\"geoid\":\"abc12345-e3c1-475f-b82e-237c828f7a32\",\"id\":5205}"
            }
        ]
    }

Parameters

address

[optional] [type: string] Filters jobs by the provided address. This is a partial match filter where the provided address string should be contained within the job’s address field.

address__icontains

[optional] [type: string] Filters jobs where the address contains the provided substring. This is case-insensitive.

address__istartswith

[optional] [type: string] Filters jobs where the address starts with the provided substring. This is case-insensitive.

category

[optional] [type: string enum] Filters jobs based on category. Possible values are as follows.

Value Description
gsquare List only gSquare estimates
gpro List only gPro models
express List only xPress models

This is case-sensitive and must be one of the specified values.

date_created

[optional] [type: string($date-time)] Filters jobs by the exact creation date.

date_created__gt

[optional] [type: string($date-time)] Filters jobs created after the provided date.

date_created__lt

[optional] [type: string($date-time)] Filters jobs created before the provided date.

job_id

[optional] [type: string] Filters jobs by the exact job ID.

job_id__icontains

[optional] [type: string] Filters jobs where the job ID contains the provided substring. This is case-insensitive.

job_id__istartswith

[optional] [type: string] Filters jobs where the job ID starts with the provided substring. This is case-insensitive.

limit

[optional] [type: integer] Number of results to return per page. This parameter controls pagination and helps manage the size of the response. Default is 50.

offset

[optional] [type: integer] The initial index from which to return the results. This parameter is used in pagination to skip a certain number of results before returning the response.

order__basket__customer_name

[optional] [type: string] Filters jobs by customer name within the order’s basket.

order__basket__customer_name__contains

[optional] [type: string] Filters jobs where the customer’s name in the basket contains the provided substring. This is case-insensitive.

order__basket__customer_name__icontains

[optional] [type: string] Filters jobs where the customer’s name in the basket contains the provided substring, case-insensitive.

order__basket__customer_name__startswith

[optional] [type: string] Filters jobs where the customer’s name in the basket starts with the provided substring, case-insensitive.

order__basket__reference_id

[optional] [type: string] Filters jobs by the reference ID within the order’s basket.

ordering

[optional] [type: string] Determines the field by which to order the results. See the table below for possible values.

Value Description
date_created Orders by the date the job was created
-date_created Orders by the date the job was created (descending)
date_updated Orders by the date the job was last updated
-date_updated Orders by the date the job was last updated (descending)
job_id Orders by the unique job ID
-job_id Orders by the unique job ID (descending)
order__basket__customer_name Orders by the customer’s name in the basket
-order__basket__customer_name Orders by the customer’s name in the basket (descending)
order__basket__reference_id Orders by the reference ID of the basket
-order__basket__reference_id Orders by the reference ID of the basket (descending)
order__number Orders by the order number
-order__number Orders by the order number (descending)
priority Orders by the job priority
-priority Orders by the job priority (descending)
production_team__name Orders by the production team’s name
-production_team__name Orders by the production team’s name (descending)
production_user__email Orders by the production user’s email
-production_user__email Orders by the production user’s email (descending)
status Orders by the job status
-status Orders by the job status (descending)
priority

[optional] [type: integer] Priority level for the job. See the table below for possible values.

Value Description
1 Lowest Priority
5 Standard Priority
10 Rush Priority
priority__isnot

[optional] [type: string] Filter jobs where the priority is not the specified value.

production_team

[optional] [type: string] Name of the production team assigned to the job.

production_user

[optional] [type: integer] ID of the production user assigned to the job.

production_user__email

[optional] [type: string] Email of the production user assigned to the job.

production_user__email__contains

[optional] [type: string] Filters jobs where the production user’s email contains the specified substring.

production_user__email__icontains

[optional] [type: string] Case-insensitive version of production_user__email__contains.

production_user__email__startswith

[optional] [type: string] Filters jobs where the production user’s email starts with the specified string.

production_user__in

[optional] [type: array[integer]] Filter jobs for a list of production user IDs.

production_user__isnull

[optional] [type: boolean] Filters jobs where the production user is either null or not.

progress

[optional] [type: string] Status of job progress. This parameter might be defined elsewhere.

q

[optional] [type: string] A general search query string.

result__isnull

[optional] [type: boolean] Filters jobs where the result is either null or not.

sort

[optional] [type: array[string]] Fields by which to sort the results. See the table below for possible values.

Value Description
date_created Orders by the date the job was created
-date_created Orders by the date the job was created (descending)
date_updated Orders by the date the job was last updated
-date_updated Orders by the date the job was last updated (descending)
job_id Orders by the unique job ID
-job_id Orders by the unique job ID (descending)
order__basket__customer_name Orders by the customer’s name in the basket
-order__basket__customer_name Orders by the customer’s name in the basket (descending)
order__basket__reference_id Orders by the reference ID of the basket
-order__basket__reference_id Orders by the reference ID of the basket (descending)
order__number Orders by the order number
-order__number Orders by the order number (descending)
priority Orders by the job priority
-priority Orders by the job priority (descending)
production_team__name Orders by the production team’s name
-production_team__name Orders by the production team’s name (descending)
production_user__email Orders by the production user’s email
-production_user__email Orders by the production user’s email (descending)
status Orders by the job status
-status Orders by the job status (descending)
status

[optional] [type: string enum] Status of the job. Possible values are as follows.

Value Description
New The order is new.
Pre-Model The job is being prepared for modeling.
Ready The job is ready for modeling.
Modeling The job is being modeled.
QA1 The model is ready to be reviewed at the first stage.
QA1 In Process The model is being reviewed at the first stage.
QA2 The model is ready to be reviewed at the second stage.
QA2 In Process The model is being reviewed at the second stage.
Completed The model is complete.
Publish The model is live.
Canceled A job may be canceled due to customer request, imagery issues (quality, availability, or obstructions), technical limitations, ambiguous location, or excessive building size.
Rejected The job was rejected for additional modeling if the design does not meet quality standards or specifications.
Hold The job is awaiting necessary action or information from either the customer or internal team members before it can proceed further.
Failed QA The model could not pass QA.
status__in

[optional] [type: array[string]] Filters jobs for a list of statuses. See the table below for possible values. Multiple values may be separated by commas.

Value Description
New The order is new.
Pre-Model The job is being prepared for modeling.
Ready The job is ready for modeling.
Modeling The job is being modeled.
QA1 The model is ready to be reviewed at the first stage.
QA1 In Process The model is being reviewed at the first stage.
QA2 The model is ready to be reviewed at the second stage.
QA2 In Process The model is being reviewed at the second stage.
Completed The model is complete.
Publish The model is live.
Canceled A job may be canceled due to customer request, imagery issues (quality, availability, or obstructions), technical limitations, ambiguous location, or excessive building size.
Rejected The job was rejected for additional modeling if the design does not meet quality standards or specifications.
Hold The job is awaiting necessary action or information from either the customer or internal team members before it can proceed further.
Failed QA The model could not pass QA.

GET /jobs/{id}/

HTTP method
curl -X 'GET' \
'https://api.geospan.com/remote4d/v1/api/gpro/jobs/2971/' \
    -H 'accept: application/json' \
    -H 'Authorization: Api-Key <geospanapikeystring>'
{
        "status": "Publish",
        "product": {
                "upc": "ROOF-S"
            },
        "url": "http://api.geospan.com/shop/api/jobs/2971/",
        "order": {
                "url": "http://api.geospan.com/shop/api/orders/2874/",
                "id": 2874,
                "number": "103010",
                "status": "Completed",
                "basket": {
                        "customer_name": "Contact AtYourCompany",
                        "reference_id": ""
                    },
                "email": "contact@yourcompany.com"
            },
        "location": {
                "type": "Point",
                "coordinates": [
                        -93.18739,
                        44.71353
                    ]
            },
        "location_description": "",
        "attachments": [],
        "date_created": "2024-07-25T15:35:13.078159Z",
        "date_updated": "2024-07-26T16:34:03.126315Z",
        "status_reason": null,
        "id": 2971,
        "extra": null,
        "production_user": null,
        "production_team": "HDS-1",
        "customer_notes": "note here",
        "address": "16288 Fairgreen Ave, Rosemount, MN 55068",
        "building_info": "",
        "siblings": "http://api.geospan.com/shop/api/jobs/2971/siblings/",
        "history": "http://api.geospan.com/shop/api/jobs/2971/history/",
        "share_key": "0123a45678b9cdef0123a45678b9cdef",
        "priority": 5,
        "result_type": "geoid",
        "result": "{\"geoid\":\"abc12345-c7df-4e84-ab88-1e758a5c7b88\",\"id\":5191}"
    }

Parameters

id

[required] [type: integer] A unique integer value identifying this job. It is needed to specify the exact job you want to retrieve information about. The id value can be obtained from the result of other API calls, such as listing jobs with GET /jobs/, or through end-user interfaces.

GET /jobs/{id}/structures/

HTTP method

DRAFT CONTENT Return a Structures JSON structurecollection of all structures on the order.

Structure coordinates will be flattened to 2D for all xPress models.
curl -X 'GET' \
'https://api.geospan.com/remote4d/v1/api/gpro/jobs/2971/structures/?projection=crs84' \
    -H 'accept: application/json' \
    -H 'Authorization: Api-Key <geospanapikeystring>'
{
    "kind": "structurecollection",
    "structures": [
        {
            "kind": "structure",
            "projection": "crs84",
            "points": {
                "c101": {
                    "kind": "corner",
                    "coordinates": [
                        -93.36791861497224,
                        45.02530878213521,
                        278.8077878113836
                    ]
                },
                "c102": {
                    "kind": "corner",
                    "coordinates": [
                        -93.36786325029368,
                        45.025347735448214,
                        280.56030232738703
                    ]
                },
                "c103": {
                    "kind": "corner",
                    "coordinates": [
                        -93.36780383374325,
                        45.025347735451795,
                        280.56030232366174
                    ]
                },
                "c104": {
                    "kind": "corner",
                    "coordinates": [
                        -93.36774825953246,
                        45.02530878214529,
                        278.8077878113836
                    ]
                },
                "c105": {
                    "kind": "corner",
                    "coordinates": [
                        -93.36791861509695,
                        45.02538668869866,
                        278.8077878104523
                    ]
                },
                "c106": {
                    "kind": "corner",
                    "coordinates": [
                        -93.36782082017419,
                        45.0253866887355,
                        278.8077843617648
                    ]
                },
                "c107": {
                    "kind": "corner",
                    "coordinates": [
                        -93.3677845326412,
                        45.02536126402634,
                        279.95164851192385
                    ]
                },
                "c108": {
                    "kind": "corner",
                    "coordinates": [
                        -93.36778453263756,
                        45.025366213704366,
                        279.95164866466075
                    ]
                },
                "c109": {
                    "kind": "corner",
                    "coordinates": [
                        -93.36774825941929,
                        45.02539168008893,
                        278.80778821278363
                    ]
                },
                "c110": {
                    "kind": "corner",
                    "coordinates": [
                        -93.36782082017369,
                        45.02539167919033,
                        278.8077878113836
                    ]
                },
                "ground": {
                    "kind": "ground",
                    "coordinates": [
                        -93.36791861509695,
                        45.02530878213523,
                        275.9885253915563
                    ]
                }
            },
            "edges": {
                "e101": {
                    "kind": "hip",
                    "points": [
                        "c101",
                        "c102"
                    ],
                    "properties": {
                        "length": 6.392
                    }
                },
                "e112": {
                    "kind": "eave",
                    "points": [
                        "c101",
                        "c105"
                    ],
                    "properties": {
                        "attachments": [
                            "gutter"
                        ],
                        "length": 8.658
                    }
                },
                "e102": {
                    "kind": "ridge",
                    "points": [
                        "c102",
                        "c103"
                    ],
                    "properties": {
                        "length": 4.683
                    }
                },
                "e103": {
                    "kind": "hip",
                    "points": [
                        "c103",
                        "c104"
                    ],
                    "properties": {
                        "length": 6.403
                    }
                },
                "e107": {
                    "kind": "hip",
                    "points": [
                        "c103",
                        "c107"
                    ],
                    "properties": {
                        "length": 2.224
                    }
                },
                "e104": {
                    "kind": "eave",
                    "points": [
                        "c104",
                        "c101"
                    ],
                    "properties": {
                        "attachments": [
                            "gutter"
                        ],
                        "length": 13.427
                    }
                },
                "e105": {
                    "kind": "eave",
                    "points": [
                        "c105",
                        "c106"
                    ],
                    "properties": {
                        "attachments": [
                            "gutter"
                        ],
                        "length": 7.708
                    }
                },
                "e108": {
                    "kind": "hip",
                    "points": [
                        "c105",
                        "c102"
                    ],
                    "properties": {
                        "length": 6.392
                    }
                },
                "e106": {
                    "kind": "valley",
                    "points": [
                        "c107",
                        "c106"
                    ],
                    "properties": {
                        "length": 4.18
                    }
                },
                "e109": {
                    "kind": "ridge",
                    "points": [
                        "c107",
                        "c108"
                    ],
                    "properties": {
                        "length": 0.55
                    }
                },
                "e110": {
                    "kind": "hip",
                    "points": [
                        "c108",
                        "c109"
                    ],
                    "properties": {
                        "length": 4.182
                    }
                },
                "e113": {
                    "kind": "hip",
                    "points": [
                        "c108",
                        "c110"
                    ],
                    "properties": {
                        "length": 4.183
                    }
                },
                "e111": {
                    "kind": "eave",
                    "points": [
                        "c109",
                        "c104"
                    ],
                    "properties": {
                        "attachments": [
                            "gutter"
                        ],
                        "length": 9.213
                    }
                },
                "e114": {
                    "kind": "eave",
                    "points": [
                        "c110",
                        "c109"
                    ],
                    "properties": {
                        "attachments": [
                            "gutter"
                        ],
                        "length": 5.719
                    }
                },
                "e115": {
                    "kind": "eave",
                    "points": [
                        "c106",
                        "c110"
                    ],
                    "properties": {
                        "attachments": [
                            "gutter"
                        ],
                        "length": 0.555
                    }
                }
            },
            "surfaces": {
                "surface1": {
                    "kind": "roof",
                    "edges": [
                        [
                            "e101",
                            "e102",
                            "e103",
                            "e104"
                        ]
                    ],
                    "properties": {
                        "material": "asphalt",
                        "pitch": 5,
                        "area": 42.29
                    }
                },
                "surface2": {
                    "kind": "roof",
                    "edges": [
                        [
                            "e105",
                            "e106",
                            "e107",
                            "e102",
                            "e108"
                        ]
                    ],
                    "properties": {
                        "material": "asphalt",
                        "pitch": 5,
                        "area": 33.573
                    }
                },
                "surface3": {
                    "kind": "roof",
                    "edges": [
                        [
                            "e107",
                            "e109",
                            "e110",
                            "e111",
                            "e103"
                        ]
                    ],
                    "properties": {
                        "material": "asphalt",
                        "pitch": 5,
                        "area": 22.125
                    }
                },
                "surface4": {
                    "kind": "roof",
                    "edges": [
                        [
                            "e108",
                            "e101",
                            "e112"
                        ]
                    ],
                    "properties": {
                        "material": "asphalt",
                        "pitch": 5,
                        "area": 20.358
                    }
                },
                "surface5": {
                    "kind": "roof",
                    "edges": [
                        [
                            "e110",
                            "e113",
                            "e114"
                        ]
                    ],
                    "properties": {
                        "material": "asphalt",
                        "pitch": 5,
                        "area": 8.729
                    }
                },
                "surface6": {
                    "kind": "roof",
                    "edges": [
                        [
                            "e109",
                            "e106",
                            "e115",
                            "e113"
                        ]
                    ],
                    "properties": {
                        "material": "asphalt",
                        "pitch": 5,
                        "area": 1.702
                    }
                }
            },
            "components": {
                "roof": {
                    "surfaces": [
                        "surface1",
                        "surface2",
                        "surface3",
                        "surface4",
                        "surface5",
                        "surface6"
                    ]
                }
            }
        }
    ]
}

Parameters

id

[required] [type: integer] A unique integer value identifying this job. It is needed to specify the exact job you want to retrieve structure information about. The id value can be obtained from the result of other API calls, such as listing jobs with GET /jobs/, or through end-user interfaces.

GET /jobs/{id}/oblique/

HTTP method
curl -X 'GET' \
  'https://api.geospan.com/remote4d/v1/api/gpro/jobs/2971/oblique/?orientation=n' \
  -H 'Authorization: Api-Key <geospanapikeystring>' \
  --output 2971_oblique_orientation-n.jpg

The output is saved to a file named 2971_oblique_orientation-n.jpg in the same directory where the cURL call was made.

Parameters

id

[required] [type: integer] A unique integer value identifying the job. It is needed to specify the exact job for which you want to retrieve oblique imagery. The id value can be obtained from the result of other API calls, such as listing jobs with GET /jobs/, or from the user interfaces.

orientation

[required] [type: string] Specifies the camera direction relative to the structure for the oblique image. This parameter controls the perspective of the image (e.g., from the north, south, east, or west).

Value Description
n North orientation
e East orientation
s South orientation
w West orientation

GET /jobs/{id}/ortho/{layer}/{z}/{x}/{y}/

HTTP method
curl -X 'GET' \
  'https://api.geospan.com/remote4d/v1/api/gpro/jobs/2971/ortho/base/12/2048/2048/' \
  -H 'Authorization: Api-Key <geospanapikeystring>' \
  --output 2971_ortho_base-12-2048-2048.jpg

The output is saved to a file named 2971_ortho_base-12-2048-2048.jpg in the same directory where the cURL call was made.

Parameters

id

[required] [type: integer] A unique integer value identifying the job. It is needed to specify the exact job for which you want to retrieve ortho imagery tiles. The id can be obtained from the result of other API calls, such as listing jobs with GET /jobs/, or from user interfaces.

layer

[required] [type: string] The layer to retrieve the ortho imagery from. This could represent different data layers such as different map styles, resolutions, or other types of data layers relevant to the job.

z

[required] [type: string] The tile zoom level. This parameter controls how much detail the tile contains, with higher zoom levels representing more detailed imagery.

x

[required] [type: string] The x-coordinate of the tile in the tile grid. This is used to locate the specific tile in the grid at the given zoom level.

y

[required] [type: string] The y-coordinate of the tile in the tile grid. This, along with the x-coordinate, identifies the specific tile at the given zoom level.

Share jobs

Job sharing is not supported for the xPress roof_model_express product.

When a job is shared, it receives a share_key that can be used to access job data through the shared-jobs endpoints without requiring an API key or authentication token. This endpoint is particularly useful for creating shared access to job data, enabling collaboration or viewing by external parties without the need for full access.

When you share a job, the URL is in the form https://apps.geospan.com/gsuite/shared/<shared_key>.

Note

If you unshare and then share again, the share key changes. Get the updated share key to forward to individuals.

Security Considerations: The share_key is a critical security element. Anyone with this key can access the job details, so it should be shared cautiously and only with trusted parties. This key should be kept secure, as it provides direct access to job information. Consider implementing expiration mechanisms or other security controls depending on your application’s requirements.

Rate Limiting and Quota: As with other API endpoints, be mindful of potential limits when accessing shared jobs, especially if automating requests or sharing with multiple users.

GET /jobs/{id}/share/

HTTP method

curl -X 'GET' \
  'https://api.geospan.com/remote4d/v1/api/gpro/jobs/2971/share/' \
  -H 'accept: application/json' \
  -H 'Authorization: Api-Key <geospanapikeystring>'
{"share_key":"12345ab67890cd12345ab67890cd"}

Parameters

id

[required] [type: integer] A unique integer value identifying the job. It is needed to specify the exact job for which you want to retrieve the share key. The id can be obtained from the result of other API calls, such as listing jobs with GET /jobs/, or from user interfaces.

POST /jobs/{id}/share/

HTTP method

curl -X 'POST' \
  'https://api.geospan.com/remote4d/v1/api/gpro/jobs/3002/share/' \
  -H 'accept: application/json' \
  -H 'Authorization: Api-Key <geospanapikeystring>'
{"share_key":"0987z8765y6543w0987z8765y6543w"}

Parameters

id

[required] [type: integer] A unique integer value identifying the job. It is needed to specify the exact job for which you want to create a share key. The id can be obtained from the result of other API calls, such as listing jobs with GET /jobs/, or from user interfaces.

PATCH /jobs/{id}/share/

This PATCH jobs/{id}/share call toggles the share_key between a new share key and an empty string.

The share key can be set as a call to POST /jobs/{id}/share/ or through the Share button on the user interface for the job. If a share key has not been set through these other means, calling PATCH on the jobs/{id}/share endpoint for the first time sets an initial value of the share key. Its function, however, is to toggle the share state.

HTTP method

curl -X 'PATCH' \
  'https://api.geospan.com/remote4d/v1/api/gpro/jobs/3002/share/' \
  -H 'accept: application/json' \
  -H 'Authorization: Api-Key <geospanapikeystring>' \
  -H 'Content-Type: application/json' \
  -d '{"share_key": "8765lkj4321oiuy0m9n8n9876grd32"}'
{"share_key":"8765lkj4321oiuy0m9n8n9876grd32"}

Parameters

id

[required] [type: integer] A unique integer value identifying the job. It is needed to specify the exact job for which you want to update the share key value. The id can be obtained from the result of other API calls, such as listing jobs with GET /jobs/, or from user interfaces.

  1. DELETE /jobs/{id}/share/
curl -X 'DELETE' \
  'https://api.geospan.com/remote4d/v1/api/gpro/jobs/2971/share/' \
  -H 'accept: application/json' \
  -H 'Authorization: Api-Key <geospanapikeystring>'

No message returned.

Parameters

id

[required] [type: integer] A unique integer value identifying the job. It is needed to specify the exact job for which you want to delete the share key value. The id can be obtained from the result of other API calls, such as listing jobs with GET /jobs/, or from user interfaces.

Get information about shared jobs

The /shared-jobs/{share_key}/ endpoint provides access to the details of a shared job using a share_key. This endpoint is useful for retrieving job information without requiring full authentication, making it ideal for sharing job details with external parties or collaborators. The share_key serves as a secure, unique identifier that provides access to the specific job data.

The share_key is a unique string generated when a job is shared. It acts as a secure token that allows access to job details without requiring standard API authentication. This key should be kept secure, as it provides direct access to job information.

Retrieve the share_key from the response of a POST /jobs/{id}/share/ or PATCH /jobs/{id}/share/ request, where it is created or updated. You can also get the share_key from GET /jobs/{id}/share/, and from the end-user interface.

GET /shared-jobs/{share_key}/

HTTP method

curl -X 'GET' \
  'https://api.geospan.com/remote4d/v1/api/gpro/shared-jobs/0123a45678b9cdef0123a45678b9cdef/' \
  -H 'accept: application/json' \
  -H 'Authorization: Api-Key <geospanapikeystring>'
{
    "status": "Publish",
    "product": {
        "upc": "ROOF-S"
    },
    "url": "http://api.geospan.com/shop/api/jobs/2856/",
    "order": {
        "url": "http://api.geospan.com/shop/api/orders/2761/",
        "id": 2761,
        "number": "102895",
        "status": "Completed",
        "basket": {
            "customer_name": "Your company orderer",
            "reference_id": "E2E100"
        },
        "email": "orderer@yourcompany.com"
    },
    "location": {
        "type": "Point",
        "coordinates": [
            -93.18739,
            44.71516
        ]
    },
    "location_description": "",
    "attachments": [],
    "date_created": "2024-03-18T19:44:07.583350Z",
    "date_updated": "2024-08-26T20:27:11.414115Z",
    "status_reason": null,
    "id": 2856,
    "extra": {
        "origin": "verisk",
        "origin_id": "1234abcd-0987-5678-xyz1-1234asdf9876"
    },
    "production_user": null,
    "production_team": "QAE-1",
    "customer_notes": "",
    "address": "16162 Fairgreen Ave, Rosemount, MN 55068",
    "building_info": "",
    "siblings": "http://api.geospan.com/shop/api/jobs/2856/siblings/",
    "history": "http://api.geospan.com/shop/api/jobs/2856/history/",
    "share_key": "03ec238cb2a9b193ecda1b497c83871a",
    "priority": 5,
    "result_type": "geoid",
    "result": "{\"geoid\":\"9876zyxw-098z-123a-456b-78901234asdf\",\"id\":5089}"
}
share_key

[Required][type:string] Any valid share_key string (for example, 0123a45678b9cdef0123a45678b9cdef). A unique identifier used to access a shared job, this key is generated when a job is shared.

GET /shared-jobs/{share_key}/geoid/

HTTP method

curl -X 'GET' \
  'https://api.geospan.com/remote4d/v1/api/gpro/shared-jobs/0123a45678b9cdef0123a45678b9cdef/geoid/' \
  -H 'accept: application/json' \
  -H 'Authorization: Api-Key <geospanapikeystring>'
{
    "id": 5089,
    "status": "D",
    "geoid": "537cd2a5-a311-41ec-b4f5-43aa0c36e6d0",
    "roof_model": "{\"content\":[{\"ParcelID\":\"job2856\",\"BldgNum\":\"1\",\"ComponNum\":\"1\",\"GraphicJson\":\"{\\\"groundElev\\\":284.2817687988281,\\\"hingePt\\\":null,\\\"corners\\\":{\\\"53fc4d11-d6d0-6694-b304-4cb43e7c03c9\\\":{\\\"x\\\":-252433.40573928275,\\\"y\\\":-4533102.750433343,\\\"z\\\":4465112.13824828},\\\"ca432e78-4c47-309d-03bf-0055b18aaf14\\\":{\\\"x\\\":-252433.4697731101,\\\"y\\\":-4533104.741977499,\\\"z\\\":4465108.06719631},\\\"a83e254a-8d0b-2844-e519-f2be5f4df9ca\\\":{\\\"x\\\":-252445.1894685201,\\\"y\\\":-4533104.17409267,\\\"z\\\":4465107.981158005},\\\"98caebe7-f52d-de0e-89fa-adbdd3dc0af6\\\":{\\\"x\\\":-252445.1251123508,\\\"y\\\":-4533102.182634073,\\\"z\\\":4465112.052281542}},\\\"walls\\\":[{\\\"corner1\\\":\\\"ca432e78-4c47-309d-03bf-0055b18aaf14\\\",\\\"corner2\\\":\\\"53fc4d11-d6d0-6694-b304-4cb43e7c03c9\\\",\\\"wallType\\\":\\\"r\\\"},{\\\"corner1\\\":\\\"a83e254a-8d0b-2844-e519-f2be5f4df9ca\\\",\\\"corner2\\\":\\\"ca432e78-4c47-309d-03bf-0055b18aaf14\\\",\\\"wallType\\\":\\\"e\\\"},{\\\"corner1\\\":\\\"98caebe7-f52d-de0e-89fa-adbdd3dc0af6\\\",\\\"corner2\\\":\\\"a83e254a-8d0b-2844-e519-f2be5f4df9ca\\\",\\\"wallType\\\":\\\"r\\\"},{\\\"corner1\\\":\\\"53fc4d11-d6d0-6694-b304-4cb43e7c03c9\\\",\\\"corner2\\\":\\\"98caebe7-f52d-de0e-89fa-adbdd3dc0af6\\\",\\\"wallType\\\":\\\"d\\\"}],\\\"cornersOrder\\\":[[-252433.40573928275,-4533102.750433343,4465112.13824828],[-252433.4697731101,-4533104.741977499,4465108.06719631],[-252445.1894685201,-4533104.17409267,4465107.981158005],[-252445.1251123508,-4533102.182634073,4465112.052281542]],\\\"roomCtrlPts\\\":[{\\\"roomName\\\":\\\"job2856&1&1&dn2qi\\\",\\\"myCtrl\\\":[\\\"a83e254a-8...,ca432e78-4c...\\\",\\\"98caebe...\\\"],\\\"ctrl2Pt\\\":true,\\\"materialType\\\":null,\\\"poiObjs\\\":[]}],\\\"cutoutParent\\\":null,\\\"cutoutType\\\":null}\",\"LevelNum\":1,\"tempID\":\"job2856@1@1@dn2qi\"},{\"ParcelID\":\"job2856\",\"BldgNum\":\"1\",\"ComponNum\":\"2\",\"GraphicJson\":\"{\\\"groundElev\\\":284.2817687988281,\\\"hingePt\\\":null,\\\"corners\\\":{\\\"53fc4d11-d6d0-6694-b304-4cb43e7c03c9\\\":{\\\"x\\\":-252433.40573928275,\\\"y\\\":-4533102.750433343,\\\"z\\\":4465112.13824828},\\\"98caebe7-f52d-de0e-89fa-adbdd3dc0af6\\\":{\\\"x\\\":-252445.1251123508,\\\"y\\\":-4533102.182634073,\\\"z\\\":4465112.052281542},\\\"f45af621-70c9-b273-0003-cf034d661d04\\\":{\\\"x\\\":-252444.946114973,\\\"y\\\":-4533098.129825465,\\\"z\\\":4465114.088580731},\\\"b7952dc3-7255-df15-3b6c-295637d75241\\\":{\\\"x\\\":-252438.85690594575,\\\"y\\\":-4533098.424884663,\\\"z\\\":4465114.133286617},\\\"4e441b32-91a9-f41d-c4c4-1595c8f07df8\\\":{\\\"x\\\":-252438.2768597194,\\\"y\\\":-4533099.027264776,\\\"z\\\":4465113.84981524},\\\"efd601d1-5983-20c1-30e9-3bcf8d201988\\\":{\\\"x\\\":-252437.6433304065,\\\"y\\\":-4533098.481918708,\\\"z\\\":4465114.143109792},\\\"9037c3cf-e7ca-ff7b-2001-25e16b15608c\\\":{\\\"x\\\":-252433.22314167113,\\\"y\\\":-4533098.696102111,\\\"z\\\":4465114.17556043}},\\\"walls\\\":[{\\\"corner1\\\":\\\"53fc4d11-d6d0-6694-b304-4cb43e7c03c9\\\",\\\"corner2\\\":\\\"98caebe7-f52d-de0e-89fa-adbdd3dc0af6\\\",\\\"wallType\\\":\\\"d\\\"},{\\\"corner1\\\":\\\"f45af621-70c9-b273-0003-cf034d661d04\\\",\\\"corner2\\\":\\\"98caebe7-f52d-de0e-89fa-adbdd3dc0af6\\\",\\\"wallType\\\":\\\"r\\\"},{\\\"corner1\\\":\\\"b7952dc3-7255-df15-3b6c-295637d75241\\\",\\\"corner2\\\":\\\"f45af621-70c9-b273-0003-cf034d661d04\\\",\\\"wallType\\\":\\\"g\\\"},{\\\"corner1\\\":\\\"b7952dc3-7255-df15-3b6c-295637d75241\\\",\\\"corner2\\\":\\\"4e441b32-91a9-f41d-c4c4-1595c8f07df8\\\",\\\"wallType\\\":\\\"n\\\"},{\\\"corner1\\\":\\\"efd601d1-5983-20c1-30e9-3bcf8d201988\\\",\\\"corner2\\\":\\\"4e441b32-91a9-f41d-c4c4-1595c8f07df8\\\",\\\"wallType\\\":\\\"n\\\"},{\\\"corner1\\\":\\\"efd601d1-5983-20c1-30e9-3bcf8d201988\\\",\\\"corner2\\\":\\\"9037c3cf-e7ca-ff7b-2001-25e16b15608c\\\",\\\"wallType\\\":\\\"e\\\"},{\\\"corner1\\\":\\\"9037c3cf-e7ca-ff7b-2001-25e16b15608c\\\",\\\"corner2\\\":\\\"53fc4d11-d6d0-6694-b304-4cb43e7c03c9\\\",\\\"wallType\\\":\\\"r\\\"}],\\\"cornersOrder\\\":[[-252433.40573928275,-4533102.750433343,4465112.13824828],[-252445.1251123508,-4533102.182634073,4465112.052281542],[-252444.946114973,-4533098.129825465,4465114.088580731],[-252438.85690594575,-4533098.424884663,4465114.133286617],[-252438.2768597194,-4533099.027264776,4465113.84981524],[-252437.6433304065,-4533098.481918708,4465114.143109792],[-252433.22314167113,-4533098.696102111,4465114.17556043]],\\\"roomCtrlPts\\\":[{\\\"roomName\\\":\\\"job2856&1&2&dbz95\\\",\\\"myCtrl\\\":[\\\"53fc4d11-d...,98caeb...\\\",\\\"efd601...\\\"],\\\"ctrl2Pt\\\":true,\\\"materialType\\\":null,\\\"poiObjs\\\":[]}],\\\"cutoutParent\\\":null,\\\"cutoutType\\\":null}\",\"LevelNum\":1,\"tempID\":\"job2856@1@2@dbz95\"},{\"ParcelID\":\"job2856\",\"BldgNum\":\"1\",\"ComponNum\":\"3\",\"GraphicJson\":\"{\\\"groundElev\\\":284.2817687988281,\\\"hingePt\\\":null,\\\"corners\\\":{\\\"072c321f-bb19-9243-492a-07856554145b\\\":{\\\"x\\\":-252438.00459117617,\\\"y\\\":-4533092.392307089,\\\"z\\\":4465120.555984414},\\\"c7f1a239-2039-3b40-e5b7-0ed5a7d2ea47\\\":{\\\"x\\\":-252432.98290329005,\\\"y\\\":-4533091.44294743,\\\"z\\\":4465119.412825007},\\\"0310919c-e265-d9eb-799b-9dc732ab6e21\\\":{\\\"x\\\":-252433.25517203115,\\\"y\\\":-4533098.0779082095,\\\"z\\\":4465112.706662344},\\\"0b882747-9416-8002-169f-c7576f446814\\\":{\\\"x\\\":-252433.56301924028,\\\"y\\\":-4533098.13588638,\\\"z\\\":4465112.776968592},\\\"8dbf0af3-1452-4518-dd70-0fff099da0de\\\":{\\\"x\\\":-252437.66080003206,\\\"y\\\":-4533098.907638827,\\\"z\\\":4465113.712821135},\\\"e21a7927-bd73-72b2-fc09-feec565e7bc6\\\":{\\\"x\\\":-252437.64333040648,\\\"y\\\":-4533098.481918709,\\\"z\\\":4465114.143109792},\\\"cb4688dd-85c0-da55-999a-f27e95dbf79f\\\":{\\\"x\\\":-252438.27685971936,\\\"y\\\":-4533099.027264776,\\\"z\\\":4465113.849815241}},\\\"walls\\\":[{\\\"corner1\\\":\\\"072c321f-bb19-9243-492a-07856554145b\\\",\\\"corner2\\\":\\\"c7f1a239-2039-3b40-e5b7-0ed5a7d2ea47\\\",\\\"wallType\\\":\\\"r\\\"},{\\\"corner1\\\":\\\"c7f1a239-2039-3b40-e5b7-0ed5a7d2ea47\\\",\\\"corner2\\\":\\\"0310919c-e265-d9eb-799b-9dc732ab6e21\\\",\\\"wallType\\\":\\\"e\\\"},{\\\"corner1\\\":\\\"0b882747-9416-8002-169f-c7576f446814\\\",\\\"corner2\\\":\\\"0310919c-e265-d9eb-799b-9dc732ab6e21\\\",\\\"wallType\\\":\\\"r\\\"},{\\\"corner1\\\":\\\"8dbf0af3-1452-4518-dd70-0fff099da0de\\\",\\\"corner2\\\":\\\"0b882747-9416-8002-169f-c7576f446814\\\",\\\"wallType\\\":\\\"s\\\"},{\\\"corner1\\\":\\\"e21a7927-bd73-72b2-fc09-feec565e7bc6\\\",\\\"corner2\\\":\\\"8dbf0af3-1452-4518-dd70-0fff099da0de\\\",\\\"wallType\\\":\\\"n\\\"},{\\\"corner1\\\":\\\"e21a7927-bd73-72b2-fc09-feec565e7bc6\\\",\\\"corner2\\\":\\\"cb4688dd-85c0-da55-999a-f27e95dbf79f\\\",\\\"wallType\\\":\\\"v\\\"},{\\\"corner1\\\":\\\"cb4688dd-85c0-da55-999a-f27e95dbf79f\\\",\\\"corner2\\\":\\\"072c321f-bb19-9243-492a-07856554145b\\\",\\\"wallType\\\":\\\"d\\\"}],\\\"cornersOrder\\\":[[-252438.00459117617,-4533092.392307089,4465120.555984414],[-252432.98290329005,-4533091.44294743,4465119.412825007],[-252433.25517203115,-4533098.0779082095,4465112.706662344],[-252433.56301924028,-4533098.13588638,4465112.776968592],[-252437.66080003206,-4533098.907638827,4465113.712821135],[-252437.64333040648,-4533098.481918709,4465114.143109792],[-252438.27685971936,-4533099.027264776,4465113.849815241]],\\\"roomCtrlPts\\\":[{\\\"roomName\\\":\\\"job2856&1&3&pipxg4\\\",\\\"myCtrl\\\":[\\\"cb4688dd-8...,072c321f-bb...\\\",\\\"c7f1a2...\\\"],\\\"ctrl2Pt\\\":true,\\\"materialType\\\":null,\\\"poiObjs\\\":[]}],\\\"cutoutParent\\\":null,\\\"cutoutType\\\":null}\",\"LevelNum\":1,\"tempID\":\"job2856@1@3@pipxg4\"},{\"ParcelID\":\"job2856\",\"BldgNum\":\"1\",\"ComponNum\":\"4\",\"GraphicJson\":\"{\\\"groundElev\\\":284.2817687988281,\\\"hingePt\\\":null,\\\"corners\\\":{\\\"6dc7bdf0-2542-c997-a614-cdb8d952c323\\\":{\\\"x\\\":-252442.8902726021,\\\"y\\\":-4533090.963113398,\\\"z\\\":4465119.3403225895},\\\"072c321f-bb19-9243-492a-07856554145b\\\":{\\\"x\\\":-252438.00459117617,\\\"y\\\":-4533092.392307089,\\\"z\\\":4465120.555984414},\\\"cb4688dd-85c0-da55-999a-f27e95dbf79f\\\":{\\\"x\\\":-252438.27685971936,\\\"y\\\":-4533099.027264776,\\\"z\\\":4465113.849815241},\\\"e594d0d7-a6c3-edc3-28e4-21a546b67f16\\\":{\\\"x\\\":-252438.85690594578,\\\"y\\\":-4533098.424884664,\\\"z\\\":4465114.133286617},\\\"a91f98ce-f98b-b86f-5858-4a3d646ea22b\\\":{\\\"x\\\":-252438.87446771425,\\\"y\\\":-4533098.852850227,\\\"z\\\":4465113.700728418},\\\"3c917bde-4a92-0593-7e14-3abeea730ff4\\\":{\\\"x\\\":-252443.16254134322,\\\"y\\\":-4533097.598074179,\\\"z\\\":4465112.634159926}},\\\"walls\\\":[{\\\"corner1\\\":\\\"6dc7bdf0-2542-c997-a614-cdb8d952c323\\\",\\\"corner2\\\":\\\"072c321f-bb19-9243-492a-07856554145b\\\",\\\"wallType\\\":\\\"r\\\"},{\\\"corner1\\\":\\\"cb4688dd-85c0-da55-999a-f27e95dbf79f\\\",\\\"corner2\\\":\\\"072c321f-bb19-9243-492a-07856554145b\\\",\\\"wallType\\\":\\\"d\\\"},{\\\"corner1\\\":\\\"e594d0d7-a6c3-edc3-28e4-21a546b67f16\\\",\\\"corner2\\\":\\\"cb4688dd-85c0-da55-999a-f27e95dbf79f\\\",\\\"wallType\\\":\\\"v\\\"},{\\\"corner1\\\":\\\"e594d0d7-a6c3-edc3-28e4-21a546b67f16\\\",\\\"corner2\\\":\\\"a91f98ce-f98b-b86f-5858-4a3d646ea22b\\\",\\\"wallType\\\":\\\"n\\\"},{\\\"corner1\\\":\\\"a91f98ce-f98b-b86f-5858-4a3d646ea22b\\\",\\\"corner2\\\":\\\"3c917bde-4a92-0593-7e14-3abeea730ff4\\\",\\\"wallType\\\":\\\"s\\\"},{\\\"corner1\\\":\\\"3c917bde-4a92-0593-7e14-3abeea730ff4\\\",\\\"corner2\\\":\\\"6dc7bdf0-2542-c997-a614-cdb8d952c323\\\",\\\"wallType\\\":\\\"g\\\"}],\\\"cornersOrder\\\":[[-252442.8902726021,-4533090.963113398,4465119.3403225895],[-252438.00459117617,-4533092.392307089,4465120.555984414],[-252438.27685971936,-4533099.027264776,4465113.849815241],[-252438.85690594578,-4533098.424884664,4465114.133286617],[-252438.87446771425,-4533098.852850227,4465113.700728418],[-252443.16254134322,-4533097.598074179,4465112.634159926]],\\\"roomCtrlPts\\\":[{\\\"roomName\\\":\\\"job2856&1&4&n3eky\\\",\\\"myCtrl\\\":[\\\"cb4688dd-85...,072c321f-b...\\\",\\\"6dc7bdf0...\\\"],\\\"ctrl2Pt\\\":true,\\\"materialType\\\":null,\\\"poiObjs\\\":[]}],\\\"cutoutParent\\\":null,\\\"cutoutType\\\":null}\",\"LevelNum\":1,\"tempID\":\"job2856@1@4@n3eky\"},{\"ParcelID\":\"job2856\",\"BldgNum\":\"1\",\"ComponNum\":\"5\",\"GraphicJson\":\"{\\\"groundElev\\\":284.2817687988281,\\\"hingePt\\\":null,\\\"corners\\\":{\\\"1018641d-cfff-fd9e-d412-fe75d9d2bc09\\\":{\\\"x\\\":-252432.97829072867,\\\"y\\\":-4533100.061761592,\\\"z\\\":4465112.813912762},\\\"12594dcc-490d-6190-94b0-e834b5010509\\\":{\\\"x\\\":-252433.02205957274,\\\"y\\\":-4533101.12837228,\\\"z\\\":4465111.735852042},\\\"29c99044-628a-2d59-ec7e-377e17172b1e\\\":{\\\"x\\\":-252433.64878013442,\\\"y\\\":-4533101.423264464,\\\"z\\\":4465112.053056732},\\\"272af71e-b902-8e79-4005-bd3cfae7999b\\\":{\\\"x\\\":-252433.60276756957,\\\"y\\\":-4533100.356762353,\\\"z\\\":4465113.131133937}},\\\"walls\\\":[{\\\"corner1\\\":\\\"12594dcc-490d-6190-94b0-e834b5010509\\\",\\\"corner2\\\":\\\"1018641d-cfff-fd9e-d412-fe75d9d2bc09\\\",\\\"wallType\\\":\\\"e\\\"},{\\\"corner1\\\":\\\"12594dcc-490d-6190-94b0-e834b5010509\\\",\\\"corner2\\\":\\\"29c99044-628a-2d59-ec7e-377e17172b1e\\\",\\\"wallType\\\":\\\"h\\\"},{\\\"corner1\\\":\\\"29c99044-628a-2d59-ec7e-377e17172b1e\\\",\\\"corner2\\\":\\\"272af71e-b902-8e79-4005-bd3cfae7999b\\\",\\\"wallType\\\":\\\"f\\\"},{\\\"corner1\\\":\\\"1018641d-cfff-fd9e-d412-fe75d9d2bc09\\\",\\\"corner2\\\":\\\"272af71e-b902-8e79-4005-bd3cfae7999b\\\",\\\"wallType\\\":\\\"h\\\"}],\\\"cornersOrder\\\":[[-252432.97829072867,-4533100.061761592,4465112.813912762],[-252433.02205957274,-4533101.12837228,4465111.735852042],[-252433.64878013442,-4533101.423264464,4465112.053056732],[-252433.60276756957,-4533100.356762353,4465113.131133937]],\\\"roomCtrlPts\\\":[{\\\"roomName\\\":\\\"job2856&1&5&x7t8uw\\\",\\\"myCtrl\\\":[\\\"29c99044-6...,272af7...\\\",\\\"12594dcc-490...\\\"],\\\"ctrl2Pt\\\":true,\\\"materialType\\\":null,\\\"poiObjs\\\":[]}],\\\"cutoutParent\\\":null,\\\"cutoutType\\\":null}\",\"LevelNum\":1,\"tempID\":\"job2856@1@5@x7t8uw\"},{\"ParcelID\":\"job2856\",\"BldgNum\":\"1\",\"ComponNum\":\"6\",\"GraphicJson\":\"{\\\"groundElev\\\":284.2817687988281,\\\"hingePt\\\":null,\\\"corners\\\":{\\\"12594dcc-490d-6190-94b0-e834b5010509\\\":{\\\"x\\\":-252433.02205957274,\\\"y\\\":-4533101.12837228,\\\"z\\\":4465111.735852042},\\\"53567ce9-4aa7-16b7-54e8-45b49315f120\\\":{\\\"x\\\":-252433.64517179123,\\\"y\\\":-4533101.523473014,\\\"z\\\":4465111.299505856},\\\"29c99044-628a-2d59-ec7e-377e17172b1e\\\":{\\\"x\\\":-252433.64878013442,\\\"y\\\":-4533101.423264464,\\\"z\\\":4465112.053056732}},\\\"walls\\\":[{\\\"corner1\\\":\\\"12594dcc-490d-6190-94b0-e834b5010509\\\",\\\"corner2\\\":\\\"53567ce9-4aa7-16b7-54e8-45b49315f120\\\",\\\"wallType\\\":\\\"e\\\"},{\\\"corner1\\\":\\\"53567ce9-4aa7-16b7-54e8-45b49315f120\\\",\\\"corner2\\\":\\\"29c99044-628a-2d59-ec7e-377e17172b1e\\\",\\\"wallType\\\":\\\"s\\\"},{\\\"corner1\\\":\\\"12594dcc-490d-6190-94b0-e834b5010509\\\",\\\"corner2\\\":\\\"29c99044-628a-2d59-ec7e-377e17172b1e\\\",\\\"wallType\\\":\\\"h\\\"}],\\\"cornersOrder\\\":[[-252433.02205957274,-4533101.12837228,4465111.735852042],[-252433.64517179123,-4533101.523473014,4465111.299505856],[-252433.64878013442,-4533101.423264464,4465112.053056732]],\\\"roomCtrlPts\\\":[{\\\"roomName\\\":\\\"job2856&1&6&dfroal\\\",\\\"myCtrl\\\":[\\\"12594dcc-4...,53567ce9-4aa...\\\",\\\"29c99044-628a-2d...\\\"],\\\"ctrl2Pt\\\":true,\\\"materialType\\\":null,\\\"poiObjs\\\":[]}],\\\"cutoutParent\\\":null,\\\"cutoutType\\\":null}\",\"LevelNum\":1,\"tempID\":\"job2856@1@6@dfroal\"},{\"ParcelID\":\"job2856\",\"BldgNum\":\"1\",\"ComponNum\":\"7\",\"GraphicJson\":\"{\\\"groundElev\\\":284.2817687988281,\\\"hingePt\\\":null,\\\"corners\\\":{\\\"1018641d-cfff-fd9e-d412-fe75d9d2bc09\\\":{\\\"x\\\":-252432.97829072867,\\\"y\\\":-4533100.061761592,\\\"z\\\":4465112.813912762},\\\"272af71e-b902-8e79-4005-bd3cfae7999b\\\":{\\\"x\\\":-252433.60276756957,\\\"y\\\":-4533100.356762353,\\\"z\\\":4465113.131133937},\\\"82f17acc-70e8-8ebe-e834-8b23d1b396cb\\\":{\\\"x\\\":-252433.55693677737,\\\"y\\\":-4533099.613036891,\\\"z\\\":4465113.2339232275}},\\\"walls\\\":[{\\\"corner1\\\":\\\"1018641d-cfff-fd9e-d412-fe75d9d2bc09\\\",\\\"corner2\\\":\\\"272af71e-b902-8e79-4005-bd3cfae7999b\\\",\\\"wallType\\\":\\\"h\\\"},{\\\"corner1\\\":\\\"82f17acc-70e8-8ebe-e834-8b23d1b396cb\\\",\\\"corner2\\\":\\\"272af71e-b902-8e79-4005-bd3cfae7999b\\\",\\\"wallType\\\":\\\"s\\\"},{\\\"corner1\\\":\\\"1018641d-cfff-fd9e-d412-fe75d9d2bc09\\\",\\\"corner2\\\":\\\"82f17acc-70e8-8ebe-e834-8b23d1b396cb\\\",\\\"wallType\\\":\\\"e\\\"}],\\\"cornersOrder\\\":[[-252432.97829072867,-4533100.061761592,4465112.813912762],[-252433.60276756957,-4533100.356762353,4465113.131133937],[-252433.55693677737,-4533099.613036891,4465113.2339232275]],\\\"roomCtrlPts\\\":[{\\\"roomName\\\":\\\"job2856&1&7&b2wktb\\\",\\\"myCtrl\\\":[\\\"101864...,82f17acc-70e...\\\",\\\"272af71...\\\"],\\\"ctrl2Pt\\\":true,\\\"materialType\\\":null,\\\"poiObjs\\\":[]}],\\\"cutoutParent\\\":null,\\\"cutoutType\\\":null}\",\"LevelNum\":1,\"tempID\":\"job2856@1@7@b2wktb\"}]}",
    "wall_model": null,
    "cropped_image": null,
    "parent": null
}
share_key

[Required][type:string] Any valid share_key string (for example, 0123a45678b9cdef0123a45678b9cdef). A unique identifier used to access a shared job, this key is generated when a job is shared.

GET /shared-jobs/{share_key}/oblique/

HTTP method

curl -X 'GET' \
  'https://api.geospan.com/remote4d/v1/api/gpro/shared-jobs/0123a45678b9cdef0123a45678b9cdef/oblique/?orientation=n' \
  -H 'Authorization: Api-Key <geospanapikeystring>' \
  --output shared-jobs_b9cdef_oblique_orientation-n.jpg

The output is saved to a file named shared-jobs_b9cdef_oblique_orientation-n.jpg in the same directory where the cURL call was made.

share_key

[Required][type:string] Any valid share_key string (for example, 0123a45678b9cdef0123a45678b9cdef). A unique identifier used to access a shared job, this key is generated when a job is shared.

GET /shared-jobs/{share_key}/ortho/{layer}/{z}/{x}/{y}/

HTTP method

curl -X 'GET' \
  'https://api.geospan.com/remote4d/v1/api/gpro/shared-jobs/0123a45678b9cdef0123a45678b9cdef/ortho/base/12/2048/2048/' \
  -H 'Authorization: Api-Key <geospanapikeystring>' \
  --output shared-jobs_8b9cdef_ortho_base-12-2048-2048.jpg

The output is saved to a file named shared-jobs_8b9cdef_ortho_base-12-2048-2048.jpg in the same directory where the cURL call was made.

Parameters

share_key

[Required][type:string] Any valid share_key string (for example, 0123a45678b9cdef0123a45678b9cdef). A unique identifier used to access a shared job, this key is generated when a job is shared.

Subsections of gPro & xPress

xPress Model

The GEOSPAN xPress model is designed as a subset of the existing gPro tier. No new API calls or endpoints are introduced, while others are limited in the xPress model tier. This approach simplifies integration for integrators who require fast models with the basic functionality, while maintaining compatibility with the broader gPro API.

For an overview of why and when to order an xPress model, see Introducing xPress. Here, learn how to order an xPress model, and read about the technical details and differences between the xPress model and the gPro model.

Choose the roof_model_express product

To get an xPress model, use the products value roof_model_express when creating an order.

Check in real time for gPro API support of the xPress model: when you have ordered the roof_model_express product, any gPro API that does not support the xPress product—for example model sharing—returns a 415.

Note

The gPro overview has a dropdown in the upper right corner of the screen that toggles between gPro and xPress models for easy filtering.

gPro and xPress model versions dropdown gPro and xPress model versions dropdown

The same endpoints and underlying infrastructure mean you can easily transition to the full gPro tier without additional integration, as the foundational API structure and calls remain consistent.

What’s different in the xPress model?

  • Order the xPress model: Use roof_model_express for your products value when you make a call to the /order API to get faster computations and reduced processing costs without sacrificing accuracy for basic requirements.
  • DOCX-Only file export: xPress exports only the DOCX format.
  • No Job sharing support: You cannot share the xPress model through the API or the Geospan gSuite user interface.
  • 2D-Only structure coordinates: Structure coordinates in the xPress API are flattened to 2D, optimizing data processing and storage for applications that do not require 3D representations.

API Specification

Before getting started

Before starting with the gPro API, take time to review Get Started and familiarize yourself with the Concepts.

Working with Webhooks

Webhooks allow real-time notifications of events occurring in the GEOSPAN system. They are enabled on a per-account basis and can be configured to send notifications for various events related to orders and jobs.

Note

Webhooks need to be enabled by a GEOSPAN admin. Please contact your GEOSPAN sales representative to have them enabled.

GEOSPAN Webhooks Workflow

The following workflow shows how to enable webhooks. Work with your GEOSPAN sales rep on this early release of webhooks.

Note

Webhook events are configured and triggered on an account-wide basis, rather than a per-user basis. When a webhook is set up, it listens for and returns events for all users associated with that account, not just the user who configured the webhook.

This allows for centralized event handling across your entire organization’s GEOSPAN activities, as the webhook returns events for all users under the account, regardless of which user originally set up the webhook.

  1. Enable Webhooks with your GEOSPAN sales rep:
  • Contact your GEOSPAN sales rep to enable webhooks.
  • Provide your callback URL, desired events (e.g., orderCreated, jobCompleted), and optional custom header for security.
  1. Prepare Your Server:
  • Set up an endpoint to receive POST requests at the callback URL.
  • Implement logic to handle and process webhook payloads.
  1. Secure Your Endpoint:
  • Validate the custom header if provided.
  • Implement error handling and logging.
  1. Process Webhook Events:
  • Parse JSON payloads.
  • Handle each event type (e.g., orderCreated, jobCompleted) with specific logic.
  1. Test and Monitor:
  • Work with GEOSPAN to test the integration.
  • Set up monitoring and error alerts.
  1. Scale and Optimize:
  • Ensure handling can scale with event volume.
  • Implement retry logic or queueing if needed.
  1. Maintain and Update:
  • Stay in touch with GEOSPAN for updates.
  • Adjust handling for new event types as needed.

Available Events

orderCreated

Triggered each time an order is created on the account.

Example event:

{
    "eventType": "orderCreated",
    "target": {
        "order": 100999,
        "jobs": [
            123,
            456,
        ]
    }
}

orderCompleted

Triggered each time an order is completed for the account.

Example event:

{
    "eventType": "orderCompleted",
    "target": {
        "order": 100999,
        "jobs": [
            123,
            456,
        ]
    }
}

orderCanceled

Triggered each time an order is canceled on the account. This means that all jobs on the order have been canceled as well.

Example event:

{
    "eventType": "orderCanceled",
    "target": {
        "order": 100999,
        "jobs": [
            123,
            456,
        ]
    }
}

jobCompleted

Triggered when an individual job on an order has been completed.

Example event:

{
    "eventType": "jobCompleted",
    "target": {
        "order": 100999,
        "jobs": [
            123
        ]
    }
}

jobCanceled

Triggered when an individual job on an order has been completed.

Example event:

{
    "eventType": "jobCanceled",
    "target": {
        "order": 100999,
        "jobs": [
            123
        ]
    }
}

exportReady

Triggered when a file type (e.g., dxf, xml ) for an order has finished exporting.

Example event:

{
    "eventType": "exportReady",
    "target": {
        "order": 100999,
        "jobs": [
            123
        ]
    }
}

Introducing xPress

The GEOSPAN xPress API tier is for businesses and developers who need reliable roof assessments with speed, efficiency, and cost-effectiveness. This tier offers streamlined functionality while maintaining the essential features needed to handle orders effectively, such as overhead and oblique images, line drawings, measurement outputs, pitch detection, and total area calculations.

Order an xPress model and use the same gPro API. For the technical details on how to order an xPress model, see xPress Model.

Why choose xPress API?

The xPress API maximizes efficiency without compromising on essential capabilities.

  • Speed: Reduced complexity in models and data formats.
  • Cost-Efficiency: Streamlined features translate to lower operational costs.
  • Simplicity: Focuses on essential features that drive progress.

What’s different in the xPress model?

While gPro includes additional features (such as advanced roof features, 3D modeling, and insurance format support), gPro Xpress streamlines the process for quicker results with a focus on accuracy and efficiency, making it a great choice for users who need a rapid yet detailed analysis.

The xPress model offers a streamlined roofing calculation service through the /order API endpoint, providing faster processing at reduced costs while maintaining accuracy for basic needs. It exports exclusively to DOCX format and operates with 2D structure coordinates rather than 3D representations. The model does not support job sharing functionality either through the API or the Geospan gSuite interface.

When to choose xPress API

The xPress API tier is a streamlined, cost-effective solution for specific use cases. It offers simplified functionality, faster processing, and reduced data complexity, making it a practical choice for focused applications, such as retail roofing.

xPress is particularly suited for use cases where simplicity and rapid processing are key. xPress is not suitable for use cases that require high-accuracy confidences, such as insurance workflows that may require 95-99% accuracy. Below are scenarios where the xPress API tier is the best fit.

1. Simplified data models

  • When you need: quick, lightweight models for single-property assessments or simplified mapping applications.
  • Uses roof_model_express: Ideal for projects that require basic modeling without the computational overhead of more complex models.
  • 2D Coordinates: If your application doesn’t require 3D structural data, the xPress API’s flattened 2D structure coordinates provide a straightforward solution that simplifies integration and data handling.

2. The DOCX file format

  • When you need: measurements in a standard business format.

    Supports export calls only to the DOCX format, a widely used document type.

3. No job sharing

  • When you need: automated order pipelines or systems with a single job or user account per process.

    The xPress API does not support job sharing, making it ideal for single-user operations or environments where collaboration features are unnecessary. Reduces potential complexities in API calls and simplifies security management.

4. Prioritizing speed and cost efficiency

  • When you need: Batch-processed orders with minimal overhead.

    This makes it a great choice for high-volume, cost-sensitive applications.

Try the xPress model today

Read the xPress Model overview. Then review gPro & xPress Models APIs with the model toggle set to “xPress”.

gPro and xPress model versions dropdown gPro and xPress model versions dropdown

Spatial

Geospan’s Spatial APIs provide Geographic Information System (GIS) functionality that integrates with GEOSPAN services. These geospatial helper APIs are useful to assist with both gSquare and gPro applications.

The Spatial APIs allow you to retrieve spatial data, such as roof footprints, within a specified bounding box. Use these APIs, combined with data from other Geospan API, to analyze and visualize geospatial information.

Authentication

Authentication for the Spatial APIs uses the same API-Key as the gPro API. Include your API key in the Authorization header of your requests:

Authorization: Api-Key YOUR_API_KEY

Base URL

The base URL for the Spatial APIs is:

https://api.geospan.com/remote4d/v1/api/spatial/

Using the Spatial APIs with gPro Data

One way to use the Spatial APIs in conjunction with the gPro APIs is by:

  1. Retrieving GeoJSON data for a specific job from the gPro API
  2. Calculating a bounding box based on the coordinates in the GeoJSON data
  3. Using the calculated bounding box to query the Spatial API for footprints data

By following this process, you can combine the detailed structure information from the gPro APIs with the broader spatial context provided by the Spatial APIs.

Review the following Python and JavaScript examples to see gSquare in action.

Review and download example code

Note

The API keys and tokens in index.js are for demonstration only. In a real application, secure them using appropriate methods, such as environment variables, backend proxies, and IAM services with temporary credentials.

// Footprints API interaction script for browser environments

// Function to create and append a pre element with the given content
function appendPre(content, parent = document.getElementById('results')) {
    const pre = document.createElement('pre');
    pre.textContent = JSON.stringify(content, null, 2);
    parent.appendChild(pre);
}

// Main function to execute the API call
async function fetchFootprints(apiKey) {
    if (!apiKey) {
        console.error("API key is required");
        appendPre("Error: API key is required");
        return;
    }

    // Hardcoded bounding box coordinates
    const minLon = -93.18814705349445;
    const minLat = 44.71487409726919;
    const maxLon = -93.18663294650553;
    const maxLat = 44.715445901318304;

    const bounds = `${minLon},${minLat},${maxLon},${maxLat}`;

    // Query the Spatial API using the hardcoded bounding box
    const url = 'https://api.geospan.com/remote4d/v1/api/spatial/footprints';
    const params = new URLSearchParams({ bounds });
    const headers = {
        'Authorization': `Api-Key ${apiKey}`,
        'accept': 'application/json'
    };

    try {
        const response = await fetch(`${url}?${params}`, { headers });
        if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
        }
        const footprintsData = await response.json();

        console.log("Footprints data:", footprintsData);
        appendPre("Footprints data:");
        appendPre(footprintsData);

    } catch (error) {
        console.error("An error occurred:", error);
        appendPre(`An error occurred: ${error.message}`);
    }
}

// Set up event listener for form submission
document.addEventListener('DOMContentLoaded', () => {
    const form = document.getElementById('apiKeyForm');
    const resultsDiv = document.getElementById('results');

    form.addEventListener('submit', (e) => {
        e.preventDefault();
        resultsDiv.innerHTML = ''; // Clear previous results
        const apiKey = document.getElementById('apiKey').value;
        fetchFootprints(apiKey);
    });
});
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Footprints API Demo</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            line-height: 1.6;
            margin: 0;
            padding: 20px;
            max-width: 800px;
            margin: 0 auto;
        }

        h1 {
            color: #333;
        }

        form {
            margin-bottom: 20px;
        }

        input[type="text"] {
            width: 300px;
            padding: 5px;
        }

        button {
            padding: 5px 10px;
            background-color: #4CAF50;
            color: white;
            border: none;
            cursor: pointer;
        }

        button:hover {
            background-color: #45a049;
        }

        pre {
            background-color: #f4f4f4;
            border: 1px solid #ddd;
            border-radius: 4px;
            padding: 10px;
            white-space: pre-wrap;
            word-wrap: break-word;
        }
    </style>
</head>

<body>
    <h1>Footprints API Demo</h1>
    <form id="apiKeyForm">
        <label for="apiKey">Enter your API Key:</label>
        <input type="text" id="apiKey" name="apiKey" required>
        <button type="submit">Fetch Footprints</button>
    </form>
    <div id="results"></div>

    <script src="index.js"></script>
</body>

</html>
"""
Get GeoJSON from gPro API and query the Spatial API using a calculated bounding box
"""
import requests
import json
import os
import sys

GEOSPAN_API_KEY = os.getenv("GEOSPAN_API_KEY") or input("Please enter your API key: ")
API_HOME = os.getenv("GEOSPAN_API_HOME", "https://api.geospan.com/remote4d/v1/api/")

# Define the run_example function
def run_example(silent=False):
    min_lon, min_lat, max_lon, max_lat = [
        -93.18814705349445,
        44.71487409726919,
        -93.18663294650553,
        44.715445901318304,
    ]
    bounds = f"{min_lon},{min_lat},{max_lon},{max_lat}"

    # Step 3: Query the Spatial API using the calculated bounding box
    url = f"{API_HOME}/spatial/footprints"
    params = {"bounds": bounds}
    headers = {
        "Authorization": f"Api-Key {GEOSPAN_API_KEY}",
    }
    response = requests.get(url, params=params, headers=headers)
    response.raise_for_status()
    footprints_data = response.json()

    if not silent:
        # Output the footprints data
        print("Footprints data:")
        print(json.dumps(footprints_data, indent=2))

    return 0  # Return 0 to indicate success


if __name__ == "__main__":
    if not GEOSPAN_API_KEY:
        print("API key is required.")
        sys.exit(1)  # Exit with non-zero exit code for failure

    sys.exit(run_example())

Download JavaScript

Download Python

Subsections of Spatial

API Specification

Before starting with the Spatial API, take time to review Get Started and familiarize yourself with the Concepts.

Concepts

After you have reviewed the steps to Get Started with GEOSPAN, review the following topics to become familiar with geospatial and geoprocessing topics within the GEOSPAN ecosystem.

Well-Known-Text (WKT)

What is WKT?

WKT is a simplified geometry encoding that is quick to parse and emit. The Wikipedia page for WKT has a nice write-up and examples of the format in use.

Why not GeoJSON?

GeoJSON is great! But there are some advantages that WKT can provide:

  • Typing for WKT is much simpler. GeoJSON is an object-type with very specific property values and sub-objects. While this can be done it requires additional overhead and the type (object) on initial glance is not descriptive. WKT is a string. The input property is named wkt in GEOSPAN APIs to provide consistency and clarity that this is a WKT-String and those familiar with common GIS geometry-types will recognize it immediately.
  • WKT parsing can be deferred. When embedding a GeoJSON object into a request body, the entire body of the request, including the GeoJSON will be parsed by most frameworks. If an API does not actually need the geometry information this can slow down request parsing especially as the GeoJSON grows larger in size.

Helpful utilities for WKT

WGS84 Decimal Degrees

GEOSPAN APIs expect incoming geometries to use WGS84 Decimal Degrees. This is the same as the GeoJSON specification.

gSquare Lifecycle

Estimates are generated asynchronously. A request is made to create an estimate, a query key is returned, and then the query should be monitored for success or failure.

flowchart LR
    A[Call /estimate/] -->|Get queryKey| B(Poll /query/:queryKey)
    B --> C{Check status}
    C -->|PENDING| C
    C -->|FAILURE| E[Report error]
    C -->|SUCCESS| F[Read results]

gPro Lifecycle

Requests for the gPro API go through a multi-stage lifecycle. A new request can either enter the “Pre-Model” stage or be immediately canceled. From “Pre-Model”, the request moves to “Ready” and then “Modeling”. During “Modeling”, the request goes through a series of QA steps, during which the request can be progressed, rejected, or canceled. The final outcome is either the request being completed or rejected.

flowchart TD
   A[New] --> B[Pre-Model]
   A[New] --> N((Canceled))
   B[Pre-Model] --> C[Ready]
   B[Pre-Model] --> N((Canceled))
   C[Ready] --> D[Modeling]
   D[Modeling] --> E[QA1]
   E[QA1] --> F[QA1 In Process]
   E[QA1] --> I[Rejected]
   E[QA1] --> N((Canceled))
   F[QA1 In Process] --> G[QA2]
   F[QA1 In Process] --> I[Rejected]
   F[QA1 In Process] --> N((Canceled))
   G[QA2] --> H[QA2 In Process]
   G[QA2] --> J[Failed QA]
   G[QA2] --> I[Rejected]
   H[QA2 In Process] ----> L((Completed))
   H[QA2 In Process] --> J[Failed QA]
   H[QA2 In Process] --> N((Canceled))
   H[QA2 In Process] --> G[QA2]
   I[Rejected] --> D[Modeling]
   I[Rejected] --> N((Canceled))
   J[Failed QA] --> F[QA1 In Process]
   J[Failed QA] --> I[Rejected]
   J[Failed QA] --> N((Canceled))

style L fill:#6fac5d
style N fill:#b94663
style F fill:#bc7d39
style H fill:#bc7d39
style D fill:#bc7d39
style B fill:#bc7d39