All Forerunner REST endpoints are served from the following domains:
https://app.staging.withforerunner.com
for staginghttps://app.withforerunner.com
for production
Unless otherwise specified, we expect all requests that POST / PUT data to be of Content-Type: application/json
.
Unless otherwise specified, all fields in a request are required.
In order to successfully authenticate against the Forerunner API, integrating parties should send an Authorization: Bearer ${AUTH_TOKEN}
header with each request. This AUTH_TOKEN
will be provided by Forerunner to the integrating party upon request and will be used to associate any API request with the integrating party’s account in Forerunner. AUTH_TOKEN
s are long-lived, although Forerunner reserves the right to rotate these keys with prior notice if we believe they have been compromised or are affected by any other security-related concerns.
This endpoint is used to submit a file to the Forerunner platform. Since this endpoint accepts a file, data submitted to it must be posted as multi-part form data (i.e. Content-Type: multipart/form-data
).
Route: /api/v1/files
Method: POST
Form Data:
fileUpload
- the file. Only a single document should be sent at a time.
fileType
- the string “Elevation Certificate” (other file types may be forthcoming)
Response:
{
file: {
id: string
},
errors: [{
message: string,
field: "fileUpload"
|
"fileType"
}]
}
Below is an explanation of each of the response’s field:
file
id
: A UUID that uniquely identifies the file in Forerunner.url
: The URL that points to the document in Forerunner. Requires authentication.errors
: A list of errors identified in the request, if any.message
: A human-readable description of the error encounteredfield
: The field the error pertains to.This endpoint is used to fetch a paginated list of files. Note that files can either be public or non-public, so please correctly set the hiddenFromPublic
query parameter to fit your use-case. For instance, if displaying Forerunner data on a publicly-accessible website, please set hiddenFromPublic=false
.
Route: /api/v1/files
Method: GET
Request: No request body is required, but the following query parameters can be used to filter the paginated list:
fileType
: Required string. The possible values here vary depending on how the community is configured in Forerunner, but one common value is Elevation Certificate
, which will return all processed elevation certificates.hiddenFromPublic
: Optional string enum. Acceptable values are true
or false
. If omitted, both public and non-public files are returned. If set to false
, only public files will be returned - conversely, if set to true
, only non-public files will be returned.page
: Optional non-zero, positive number. Used for getting the next page in the sequence. See the pageInfo
response object for details about how many pages of records are available.
Response:
{
files: [{
id: string,
publicURL: string,
filename: string,
mimeType: string,
property: {
id: string,
address: string,
publicURL: string,
coordinates: [number, number],
parcel: {
id: string,
address: string,
parcelId: string
},
}
}],
pageInfo: {
page: number,
pageSize: number,
totalCount: number,
totalPages: number
},
errors: [{
message: string,
field: string
}]
};
Below is an explanation of each of the response’s fields:
files
: The array of files that match the filter criteria. 25 per page.id
: A UUID that uniquely identifies the file in Forerunner's systems.publicURL
: The URL for the file's public download page. Absent if the file is hidden from public.filename
: The file's original filename when it was uploaded to Forerunner.mimeType
: The file's mime type.property
: The property the file is associated with.id
: A UUID that uniquely identifies the property in Forerunner’s systems.address
: The property's fully qualified address. Some properties may not have addresses.publicURL
: The URL for the property's public profile page. Absent if the property is hidden from the public.coordinates
: A two-element array containing the property’s numeric latitude and longitude in EPSG:4326, in that order.parcel
: The parcel the property is associated with. Some properties don't have parcels.id
: A UUID that uniquely identifies the parcel in Forerunner's systemsparcelId
: The parcel's id - often times used to uniquely identify parcels within external, non-Forerunner systems. Also known as parcel number.address
: The parcel's fully qualified address. Some parcels may not have addresses.pageInfo
: An object containing pagination details.page
: The current page being retrieved.pageSize
: The number of records per page.totalCount
: The total number of records across all pages.totalPages
: The total number of pages.errors
: An array of errors encountered when processing the request. If errors
is non-empty, the properties
array will be absent.message
: A human-readable explanation of what the error was. For instance, this could be “page must be a number” if an page
query parameter is given.field
: The field that caused the error. For instance, this could be page
in the case of an invalid page.Forerunner supports the creation / updating / deletion of substantial damage / substantial improvement (i.e. SI/SD) data.
This endpoint is used to submit an SI/SD entry to Forerunner.
Route: /api/v1/sisd
Method: POST
Request:
{
type: "improvement" | "damage",
value: number,
date: "MM/DD/YYYY",
description: string,
propertyMarketValue: number,
address: string,
parcelId: string,
coordinates: [number, number]
};
Below is an explanation of each of the request’s fields:
type
: Whether the SI/SD is an improvement to the property or damage sustained by the property. Acceptable values are the strings improvement
and damage
.value
: The total value of the improvement or damage, provided as dollars. For instance, if a porch renovation cost $3,451.23, provide 3451.23
. This value should be non-negative.date
: The date at which the improvement or damage occurred. This should be formatted as “MM/DD/YYYY” (so, a string with 2 digits for the month, 2 digits for the day, 4 digits for the year). For instance, if a porch renovation was done on August 18, 2023, this should be 08/18/2023
.description
: Optional. A human-readable description of the improvement or damage.propertyMarketValue
: Optional. The total property market value of the property impacted by the improvement or damage. Similar to value, this should be provided in dollars.address
: Optional if parcelId
or coordinates
is provided. This is the fully qualified address of the property impacted by the improvement or damage formatted as ${streetNumber} ${streetName} ${streetPostfix}, ${city}, ${state} ${zip}
. For instance, you’d provide “2 15th St NW, Washington, DC 20024” for the Washington Monument.parcelId
: Optional if address
or coordinates
is provided. This is the parcel id associated with the property impacted by the improvement or damage. This is often times also referred to as the “parcel number” in GIS systems.coordinates
: Optional if parcelId
or address
is provided. This should be a two-element array containing the property’s numeric latitude and longitude in EPSG:4326, in that order. So, if a property is located at “38.8895° N, 77.0353 W”, provide [38.8895,-77.0353]
.
If your account has a unique identifier configured for SI/SD, it will be required as an additional parameter. For example, if a Permit ID is required for an SI/SD, permitId: xyz
should be included in the request body.
Special note: One of address
, parcelId
, or coordinates
is required in order for Forerunner to properly geolocate the SI/SD.
Response:
{
sisd: {
id: string,
},
property: {
warnings: [{
message: string,
}]
},
errors: [{
message: string,
field: string
}]
};
Below is an explanation of each of the response’s fields:
sisd
: The created SI/SD object. Absent if errors
is non-empty.id
: A UUID that uniquely identifies the SI/SD in Forerunner’s systemsproperty
: The property the SI/SD was associated with in Forerunner.warnings
: An array of warnings related to the state of the property’s SI/SD threshold.message
: A string describing the warning. For instance, if a property’s total SI/SD value exceeds a critical percentage of the property’s market value during the SI/SD cumulative tracking period, this would read: “The improvement costs recorded for this property meet or exceed your community’s Substantial Improvement threshold. Further action might be necessary to ensure compliance.”errors
: An array of errors encountered when processing the request. If errors
is non-empty, the sisd
object will be absent.message
: A human-readable explanation of what the error was. For instance, this could be “unable to geocode address” if an invalid address is given.field
: The field that caused the error. For instance, this could be address
in the case of an invalid address or value
in the case of a negative value.permitId: xyz
should be included in the request body.
Special note: Forerunner will do its level best to adequately both geocode the property and also identify that property’s market value if not enough information is provided in the incoming request. If Forerunner cannot do either of these things with confidence, the request will be rejected with all applicable errors
. For instance, if the address provide is poorly formatted and no coordinates are provided, the errors
array would look like [{ field: "address", message: "Could not standardize address" }]
. Similar errors may occur if the coordinates are not within the community’s geographic boundaries within Forerunner or if the parcelId
provided does not exist within Forerunner.
This endpoint is used to update an existing SI/SD entry within Forerunner.
Route: /api/v1/sisd/:id
, where :id
is the id of the SI/SD to update.
Method: PATCH
Request:
{
type: "improvement" | "damage",
value: number,
date: "MM/DD/YYYY",
description: string | null,
propertyMarketValue: number,
};
All fields are optional, but at least one field should be present.
If your account has a unique identifier configured for SI/SD, and it needs to be updated on the already-created SI/SD, it can be included as an additional parameter. For example, if the unique identifier is Permit ID, permitId: xyz
can be included in the request body.
You cannot change the geospatial information of an already-created SI/SD. If an SI/SD was geocoded to the wrong property or if the coordinates on the SI/SD changed for whatever reason, please delete and re-submit the SI/SD instead.
Response: Same as the submit response.
This endpoint is used to delete an existing SI/SD entry from Forerunner.
Route: /api/v1/sisd/:id
, where :id
is the id of the SI/SD
to delete.
Method: DELETE
Request: No request body.
Response:
{
property: {
warnings: [{
message: string,
}]
}
};
Please see the property
field on the “Submit SI/SD” response for more information.
If the SI/SD did not exist, a bodiless HTTP response with a 404
status code will be returned.
Forerunner will eventually support the creation / updating / deletion of log data. What follows is the proposed specification for this API.
This endpoint is used to submit a log entry to Forerunner.
Route: /api/v1/logs
Method: POST
Request:
{
type: "web" | "walk_in" | "phone" | "written_or_email_request",
date: "MM/DD/YYYY",
status: "open" | "complete" | "in_progress",
contactInformation: {
name: string,
email: string,
phone: string
},
discussion: {
insuranceInfoGiven: "verbally" | "handout" | "email",
siteVisit: boolean,
propertyProtectionAdviceGiven: boolean,
financialAdviceGiven: boolean,
requestedHelpWith: string,
internalNotes: string
},
address: string,
parcelId: string,
coordinates: [number, number]
};
Below is an explanation of each of the request’s fields:
type
: How the incoming log was received. Acceptable values are "web"
, "walk_in"
, "phone"
, and "written_or_email_request"
. date
: The date at which the log was received. This should be formatted as “MM/DD/YYYY” (so, a string with 2 digits for the month, 2 digits for the day, 4 digits for the year). For instance, if a porch renovation was done on August 18, 2023, this should be 08/18/2023
.status
: The current status of the log. Acceptable values are "open"
, "complete"
, and "in_progress"
.contactInformation
: Optional. This object contains details about the resident's contact information. All of this object's fields are also optional.name
: The resident's name.email
: The resident's email.phone
: The resident's phone.discussion
: Optional. This object contains details about the discussion had while the log was being filled. All of this object's fields are also optional.siteVisit
: boolean
indicating whether or not an on-site visit happened.insuranceInfoGiven
: boolean
indicating whether or not insurance information was given during the discussion.propertyProtectionAdviceGiven
: boolean
indicating whether or not property protection advice was given during the discussion.financialAdviceGiven
: boolean
indicating whether or not financial advice was given during the discussion.requestedHelpWith
: free-form text containing details about what the resident requested help with.internalNotes
: free-form text containing any notes internal to the community about this specific log.address
: Optional if parcelId
or coordinates
is provided. This is the fully qualified address of the property impacted by the improvement or damage formatted as ${streetNumber} ${streetName} ${streetPostfix}, ${city}, ${state} ${zip}
. For instance, you’d provide “2 15th St NW, Washington, DC 20024” for the Washington Monument.parcelId
: Optional if address
or coordinates
is provided. This is the parcel id associated with the property impacted by the improvement or damage. This is often times also referred to as the “parcel number” in GIS systems.coordinates
: Optional if parcelId
or address
is provided. This should be a two-element array containing the property’s numeric latitude and longitude in EPSG:4326, in that order. So, if a property is located at “38.8895° N, 77.0353 W”, provide [38.8895,-77.0353]
.
Special note: One of address
, parcelId
, or coordinates
is required in order for Forerunner to properly geolocate the Log.
Response:
{
log: {
id: string,
},
errors: [{
message: string,
field: string
}]
};
Below is an explanation of each of the response’s fields:
log
: The created log object. Absent if errors
is non-empty.id
: A UUID that uniquely identifies the log in Forerunner’s systems.errors
: An array of errors encountered when processing the request. If errors
is non-empty, the log
object will be absent.message
: A human-readable explanation of what the error was. For instance, this could be “unable to geocode address” if an invalid address is given.field
: The field that caused the error. For instance, this could be date
in the case of an invalid date.
Forerunner will do its level best to adequately geocode the property. If Forerunner cannot do this with confidence, the request will be rejected with all applicable errors
. For instance, if the address provide is poorly formatted and no coordinates are provided, the errors
array would look like [{ field: "address", message: "Could not standardize address" }]
. Similar errors may occur if the coordinates are not within the community’s geographic boundaries within Forerunner or if the parcelId
provided does not exist within Forerunner.
This endpoint is used to update an existing log entry within Forerunner.
Route: /api/v1/logs/:id,
where :id
is the id of the log to update.
Method: PATCH
Request: Identical to the submit request body, except that all fields are optional and the geospatial fields (i.e. address
, coordinates
, and parcelId
) are not accepted. If a log was geocoded to the wrong property or if the coordinates on log changed for whatever reason, please delete the log and re-submit it instead.
Response: Same as the submit response.
This endpoint is used to delete a log entry within Forerunner.
Route: /api/v1/logs/:id
, where :id
is the id of the log to delete.
Method: DELETE
Request: No request body.
Response: No response body.
If the log did not exist, a bodiless HTTP response with a 404
status code will be returned.
These endpoints provide access to Forerunner's property data. In Forerunner's parlance, a "property" is a geographic point that represents, most often, a structure or building. Properties often have addresses, but not always. A property belongs to zero or one parcels, and a parcel can have zero or more properties. For instance, a parcel with address "123 Main Street" can have two different properties - "123 Main Street Main Building" and "123 Main Street Annex".
Properties in Forerunner can be either public or private, so please be careful to always specify hiddenFromPublic=false
in all requests to these endpoints if the data being fetched from the API is to be displayed to members of the public.
This endpoint is used to fetch a paginated list of properties.
Route: /api/v1/properties
Method: GET
Request: No request body is required, but the following query parameters can be used to filter the paginated list:
parcelId
: Optional string. Restricts the resulting properties to those associated with the parcel with the given parcelId
. Note that this parcelId
is sometimes known as "parcel number" in other GIS systems.hiddenFromPublic
: Optional string enum. Acceptable values are true
or false
. If omitted, both public and non-public properties are returned. If set to false
, only public properties will be returned - conversely, if set to true
, only non-public properties will be returned.page
: Optional non-zero, positive number. Used for getting the next page in the sequence. See the pageInfo
response object for details about how many pages of records are available.geometry
: Optional URI encoded JSON string. Acceptable values are the geometry
fragment of geojson Polygon features. If provided, only properties whose coordinates intersect with this geometry will be returned. As an example, the following JSON blob, after being URI encoded, is a valid geometry: { "type": "Polygon", "coordinates": [ [ [ -73.98836883114409, 40.67402149000125 ], [ -73.98836883114409, 40.66928110727923 ], [ -73.98070752927185, 40.66928110727923 ], [ -73.98070752927185, 40.67402149000125 ], [ -73.98836883114409, 40.67402149000125 ] ] ] }
Response:
{
properties: [{
id: string,
address: string,
publicURL: string,
coordinates: [number, number],
parcel: {
id: string,
address: string,
parcelId: string
}
}],
pageInfo: {
page: number,
pageSize: number,
totalCount: number,
totalPages: number
},
errors: [{
message: string,
field: string
}]
};
Below is an explanation of each of the response’s fields:
properties
: The array of properties that match the filter criteria. 25 per page.id
: A UUID that uniquely identifies the property in Forerunner’s systems.address
: The property's fully qualified address. Some properties may not have addresses.publicURL
: The URL for the property's public profile page. Absent if the property is hidden from the public.coordinates
: A two-element array containing the property’s numeric latitude and longitude in EPSG:4326, in that order.parcel
: The parcel the property is associated with. Some properties don't have parcels.id
: A UUID that uniquely identifies the parcel in Forerunner's systemsparcelId
: The parcel's id - often times used to uniquely identify parcels within external, non-Forerunner systems. Also known as parcel number.address
: The parcel's fully qualified address. Some parcels may not have addresses.pageInfo
: An object containing pagination details.page
: The current page being retrieved.pageSize
: The number of records per page.totalCount
: The total number of records across all pages.totalPages
: The total number of pages.errors
: An array of errors encountered when processing the request. If errors
is non-empty, the properties
array will be absent.message
: A human-readable explanation of what the error was. For instance, this could be “page must be a number” if an page
query parameter is given.field
: The field that caused the error. For instance, this could be page
in the case of an invalid page.Although not required, integrating with Forerunner’s webhooks allows the integrating party to receive different lifecycle events from Forerunner as things change within Forerunner’s systems.
Every webhook request from Forerunner will include at least the headers listed below. Additional headers (for authentication purposes, for example) can be added upon request.
Content-Type: application/json
User-Agent: ${RELEVANT_USER_AGENT}
Forerunner will retry any failed webhook request 3 times using an exponential backoff algorithm to avoid overwhelming the target server.
A response is considered a failure if the target server returns a non-2XX response.
This webhook is sent out whenever a submitted file has fully finished processing and has been vetted for issues. The webhook payload is as follows:
{
file: {
id: string,
status: "canceled" | "completed",
url: string,
validationIssues: [
{
type: "error" | "warning",
errorCode: string,
fieldText: string,
issue: string,
},
],
},
};
Below is an explanation of each of the webhook’s fields:
id
: A UUID that uniquely identifies the file in Forerunner.status
: One of either canceled
or completed
. A document’s processing can be canceled due to a variety of different reasons, such as the contents of the file not matching up with the file type.validationIssues
: Any issues with how the document was filled out. These issues do not relate to transcribing or processing the document - rather, they relate to the actual semantic content of the document, such as whether or not a surveyor filled out a require field on an elevation certificate or if a surveyor input a value with the wrong format. For this reason, a canceled
document will not have any validationIssues
.errorCode
: A machine-readable code that uniquely identifies the issue.type
: The type of the issue. A type of error
indicates that the document was filled out incorrectly in one or more places and requires immediate attention, while a warning
type indicates that something looks amiss but not critically so.fieldText
: The field / input in the document the issue pertains to. For instance, if the error is about an elevation certificate’s building diagram number, this would read “A7. Building Diagram Number”.issue
: A string describing the actual issue. For instance, this would read “Can't be blank” for fields that should not have been left empty when the file was filled out. Combined with fieldText
, integrating parties can use issue
to compose a human-readable message to show to their users.Please do not hesitate to reach out to engineering@withforerunner.com with any questions or concerns about the above API.
You can unsubscribe at any time. View our Privacy Policy.
Best practice FP&A templates and models come pre-loaded, so essential reports are available from the moment you connect.
Best practice FP&A templates and models come pre-loaded, so essential reports are available from the moment you connect.
Best practice FP&A templates and models come pre-loaded, so essential reports are available from the moment you connect.
Best practice FP&A templates and models come pre-loaded, so essential reports are available from the moment you connect.