The AI Feature API allows you to retrieve a small Area of Interest (AOI) from our " Open World " style vector map that exists for our Gen3+ AI content. You can use your Nearmap AI export credits to extract a single building at a specific location to the  AOI enclosed by a property, or even a small neighbourhood. All you need to provide is a polygon for your Query AOI, an optional date range, and your Nearmap API Key.

Why AI Feature API? 

The AI Feature API allows programmatic access to Nearmap AI for Gen 3 content and beyond. You can use the AI Feature API for:

  • Distributed AOIs: If you have a number of small areas of interest that are distributed broadly rather than clustered in a contiguous region. For example, assessment of property parcels for an insurance carrier.
  • Large data sets: If your AOI crosses multiple regions, it is best to use the date query in the AI Feature API. This allows you to extract the latest result available for each property regardless of the survey regions to which you require access.
  • Regular updates: For customers who continuously update their data set in a transactional way, the API can be used to automated this rather than relying on a user to frequently export via MapBrowser.
  • Real-time access: Customer-facing applications that require real-time retrieval of Nearmap AI content are well suited to API access. Because all our AI content is pre-processed, the time taken to retrieve the results is typically faster than on-the-fly AI processing systems.

Illustration of defining a Query AOI (outlined in red) on our vector map, and returning some of the features and attributes. The data necessary to visualise the shapes and metadata within the Query AOI is all included in a single API payload.

Getting Started

Accessing the API

If you already have access to the relevant AI Packs, and an appropriate number of Nearmap AI export credits, all you need to do is ask your account manager to add the "AI Feature API" product to your subscription. This leverages the shared Nearmap AI credit balance and AI Pack configuration - just think of it as an additional way to access the data to which you have already subscribed.

If you do not yet have Nearmap AI, learn how to get started in this article: Access AI Content . Note that each user must be enabled separately by your Nearmap account administrator to use the AI Feature API, and each API user will also need AI Export. Permissions. Find out more here:  Manage a User's 3D or AI Export Permissions

To use any of our Nearmap APIs, you need an API key. Learn how to get an API key here: API Key Authentication.

Getting Started Guide

The Getting Started Guide is a Jupyter Notebook containing python code and informal documentation to help you get up and running as quickly as possible. It explores a range of common tasks, and provides a useful base of algorithms and 3rd party packages that may help software developers who do not have a geospatial background to get started quickly with simple tasks such as calculating areas and distances between objects.

API Specification

The formal API Specification has been made available as a Swagger Spec. This is the best place to go for precise details on permitted query parameters, available endpoints, response formats and error codes once you have access to the API.

Here, we provide a quick overview of each endpoint in the AI Feature API. An endpoint is a particular base URL which allows you to perform a certain type of query, and receive the relevant response.

features.json

https://api.nearmap.com/ai/features/v4/features.json


This API endpoint of the AI Feature API takes the Query AOI as a polygon, and returns the results contained within it.

Usage patterns

The most common usage pattern is to retrieve a property boundary as the Query AOI, either from a locally stored database of property boundaries, or daisy-chained with a 3rd party API (where a latitude/longitude or address is used to retrieve a parcel boundary, and that parcel boundary is then used with the features.json endpoint). A variety of these parcel data sets and APIs is available in each of the coverage areas in which we operate.

Other uses include:

  • Individual feature retrieval from a small Query AOI: Requesting a very small Query AOI at a location where a building or other object is expected. The API returns any features that intersect with your AOI, so a small Query AOI including a building will return the entire building.
  • Assembling a map of a larger area from tiled Query AOIs: Because each feature has a unique ID, features intersecting the boundary of your Query AOIs can be successfully deduplicated, and a full seamless map assembled. The most efficient way to do this is to create a set of tiled Query AOIs that are at the larger end of our performance limits. Note that this approach may consume a large number of credits per query (but the total number of credits will be equivalent to the number consumed on the same AOI with a MapBrowser export).
  • Real-time retrieval of an end user's Query AOI: Some of our customers have online tools where their end-user can dynamically define an AOI. This AOI can be used as a Query AOI, and the results will be returned quickly to provide a seamless real-time experience.

This endpoint provides the most flexibility and precision to ensure there is no ambiguity around what is being returned.

What happens to features intersected by the AOI polygon?

In general, all feature polygons (and their associated attribute metadata) that intersect with the query polygon are returned in full, without being truncated. This allows you to deal with potential parcel boundary errors as you see fit, by excluding or including whole buildings, for example, or cutting them at the location of your choice. The only exception to this rule is the potentially unbounded features in the Vegetation and Surfaces packs, which are cropped to the Query AOI. This is to prevent a single query from inadvertently returning an entire ocean or forest in a single payload.

Data Structure

The data structure is designed to be approximately the REST API equivalent of what can be exported from MapBrowser – the spreadsheet file of parcel "roll-ups", and the rich geospatial file of the feature polygons. The features.json endpoint seeks to return the fullest, richest set of data possible, and as a result, is not designed to plug instantly into any particular software package or platform. The necessary information is, however, included in each payload, such that a variety of wrappers could be constructed to perform more specific tasks.

The data structure is best described by the Swagger Spec here.

Sample Queries

The simplest sample query to get you started is:

https://api.nearmap.com/ai/features/v4/features.json?polygon={lon1,lat1,lon2,lat2,...}&apikey={your_nearmap_api_key}

This will return the latest available Nearmap AI data from the provided polygon.


A slightly more complex query would be:

https://api.nearmap.com/ai/features/v4/features.json?polygon={lon1,lat1,lon2,lat2,...}&since=2020-01-01&until=2020-12-31&packs=building&apikey={your_nearmap_api_key}

This will return the latest result within the date window (the year 2020), and strip the response payload back to the data enabled by "AI Pack: Building Footprints" only (even if you have other AI Packs attached to your subscription).

You can also use a survey ID directly from our coverage API to select the survey, rather than a date range:

https://api.nearmap.com/ai/features/v4/features.json?polygon={lon1,lat1,lon2,lat2,...}&surveyResourceId={survey_resource_id_from_coverage}&apikey={your_nearmap_api_key}

classes.json

https://api.nearmap.com/ai/features/v4/classes.json?apikey={your_nearmap_api_key}

The classes.json endpoint is used to retrieve information about all the Feature Classes you have access to with your AI Packs. All the features (polygons) returned by the features.json endpoint have both an individual uuid for unique identification, and a feature class, which also has a uuid. The feature class (such as "Building") allows you to code specific patterns of behaviour in your application when features of that specific type are returned – whether to control z order and styling for visualisation purposes, or to inspect and use the metadata as part of your workflow.

Note that human-readable descriptions of Feature Classes should NOT be used in application code, as we reserve the right to adjusts them. The uuid of each feature class is immutable, and will always be associated with that semantic definition. It can therefore be mapped to your preferred description for exposure in your application or used internally for mapping the right application behaviour.

packs.json

https://api.nearmap.com/ai/features/v4/packs.json?apikey={your_nearmap_api_key}


The packs.json endpoint is used to show which packs are available on the user's subscription and provides a richer and more complex data structure than the more simple classes.json endpoint.

coverage.json

https://api.nearmap.com/ai/features/v4/coverage.json?point={lon},{lat}apikey={your_nearmap_api_key}

The coverage.json endpoint is used to find what surveys (dates and survey resource IDs) have had AI data processed. The response not only provides the surveys that have AI data, but the precise version of the data (systemVersion), and which feature and attribute class IDs are available on it.

Limits

The current limits imposed on the API for general customers are Query AOIs up to 1km2 and a limit of 20 requests per second. These may be adjusted over time. The 1km2 limit is designed to permit any reasonable individual property parcel to be requested (e.g. an airport or golf course). The easiest way to deal with larger or multipolygon areas is to break into multiple API requests.

The limit of 20 requests per second equates to about 1.7 million requests per 24-hour period. This is roughly what is achievable with a single desktop machine maxing out CPU usage with multiple parallel requests on a fast internet connection. If higher rates are required (such as large enterprise bulk requests using cloud infrastructure), please talk to your account manager.

Swagger Spec


openapi: 3.0.0 info: title: AI Feature API description: > Serves Nearmap AI Features. **NOTE:** - Fields with the `x-internal` property set to `true` are available to internal users only. - Fields with the `x-beta` property set to `true` are currently under development and beta prototype, and may be changed without increasing the API major version number. version: "4.0.0" contact: email: apiteam@nearmap.com servers: - description: Production url: https://api.nearmap.com/ai/features/v4 security: - APIKeyQuery: [] - APIKeyHeader: [] tags: - name: features paths: /features.json: get: tags: - features summary: Returns AI features with their attributes. description: > Returns features and their attributes within the given polygon and date range. Either the polygon or all geocoding address related query parameters (but not both) must be provided. operationId: getFeaturesByDate parameters: - $ref: '#/components/parameters/optionalPolygon' - $ref: '#/components/parameters/since' - $ref: '#/components/parameters/until' - $ref: "#/components/parameters/bulk" - $ref: "#/components/parameters/packs" - $ref: "#/components/parameters/classes" - $ref: "#/components/parameters/streetAddress" - $ref: "#/components/parameters/city" - $ref: "#/components/parameters/state" - $ref: "#/components/parameters/zip" - $ref: "#/components/parameters/reference" responses: '200': $ref: '#/components/responses/features_ok' '400': $ref: '#/components/responses/features_bad_request' '401': $ref: '#/components/responses/generic_unauthorized' '403': $ref: '#/components/responses/generic_forbidden' '404': $ref: '#/components/responses/features_not_found' /surveyresources/{surveyResourceId}/features.json: get: tags: - features summary: Returns AI features with their attributes. description: > Returns features and their attributes within the given survey resource and polygon. Either the polygon or all geocoding address related query parameters (but not both) must be provided. operationId: getFeaturesBySurveyResourceId parameters: - $ref: '#/components/parameters/polygon' - $ref: "#/components/parameters/bulk" - $ref: "#/components/parameters/packs" - $ref: "#/components/parameters/surveyResourceId" - $ref: "#/components/parameters/streetAddress" - $ref: "#/components/parameters/city" - $ref: "#/components/parameters/state" - $ref: "#/components/parameters/zip" - $ref: "#/components/parameters/reference" responses: '200': $ref: '#/components/responses/features_ok' '400': $ref: '#/components/responses/features_bad_request' '401': $ref: '#/components/responses/generic_unauthorized' '403': $ref: '#/components/responses/generic_forbidden' '404': $ref: '#/components/responses/features_not_found' /coverage.json: get: tags: - coverage summary: Searches for the survey resources available in a particular area. description: Returns survey resources at a particular location, filtered by date. operationId: getCoverage parameters: - name: polygon in: query description: | The polygon to check for coverage, as a set of points where the first and last point must be the same. Either the polygon or point parameter must be specified. required: false example: '-96.15764446556568,41.22445342518808,-96.15716367959976,41.22444989477328,-96.1571603268385,41.22461027628211,-96.15764245390892,41.224611789313336,-96.15764446556568,41.22445342518808' schema: type: string - name: point in: query description: | The point to check for coverage, as a comma separate longitude and latitude. Either the polygon or point parameter must be specified. required: false example: '-96.15764446556568,41.22445342518808' schema: type: string - name: since in: query description: | Since is a date (`YYYY-MM-DD`) specifying the capture date of the earlist resource to include in the response. If none is specified, then all historic resources are included. required: false schema: type: string - name: until in: query description: | Until is a date (`YYYY-MM-DD`) specifying the capture date of the latest resource to include in the response. If none is specified, resources are included up to and including the latest resource. required: false schema: type: string responses: '200': description: OK content: application/json: schema: type: object required: ["result"] properties: result: type: array items: type: object required: - id - captureDate - systemVersion - classes properties: id: type: string description: The ID of the survey resource. example: ae6f93cc-befc-4538-b87b-4733909c5cc1 captureDate: type: string description: The capture date of the survey associated with the survey resource. format: date example: "2019-09-27" systemVersion: type: string description: The system version of the survey resource. example: gen3-winter_sunrise-1.1 classes: type: array description: The list of classes available in the survey resource. This includes both feature classes and attribute classes. items: type: object required: ["id"] properties: id: type: string description: The class ID. Details about the class are available via the `classes.json` endpoint. example: 2a29365e-e1c9-4be6-b5c2-233f2de6d845 taskId: x-internal: true type: string description: The task ID associated with the survey resource. Only available to internal users. example: 8bdb1651-3e32-4985-8c55-790e4cf36c76 '400': description: Bad request. There was a problem with the request parameters. content: application/json: schema: $ref: '#/components/schemas/Error' examples: No geometry provided: value: code: NO_GEOMETRY_PROVIDED message: Polygon or point query parameter missing. Invalid polygon: value: code: INVALID_POLYGON message: Input polygon must be a valid sequence of x,y coordinates. Invalid since date: value: code: INVALID_SINCE message: Date must be in YYYY-MM-DD format. Invalid until date: value: code: INVALID_UNTIL message: Date must be in YYYY-MM-DD format. Invalid date range: value: code: INVALID_DATE_RANGE message: Since date must be before until date. '401': $ref: '#/components/responses/generic_unauthorized' '403': $ref: '#/components/responses/generic_forbidden' /packs.json: get: tags: - features summary: Returns packs available to the user. description: Returns detailed information about the packs available to the user calling the API. Details include which feature and attribute classes are available as part of each pack. parameters: [] responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/PacksReport' '401': $ref: '#/components/responses/generic_unauthorized' '403': $ref: '#/components/responses/generic_forbidden' /classes.json: get: tags: - features summary: Returns all the feature and attribute classes available to the user. description: Returns detailed information about the feature and attribute classes available to the user calling the API. parameters: [] responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/ClassesReport' '401': $ref: '#/components/responses/generic_unauthorized' '403': $ref: '#/components/responses/generic_forbidden' components: securitySchemes: APIKeyQuery: name: apikey type: apiKey in: query APIKeyHeader: name: Authorization type: apiKey in: header description: Header value in the format 'Apikey <api_key>' schemas: FeatureResult: type: object properties: systemVersion: type: string description: The version of the system used to generate the AI data. credits: type: integer example: 1 description: The number of credits used for this request. link: type: string example: "https://apps.nearmap.com/maps/#/@-33.7251728,151.2955012,20.00z,0d/V/20190927" description: The MapBrowser link to the location that was requested. features: type: array description: The AI features at the location requested. items: $ref: '#/components/schemas/Feature' reference: type: string example: "123456" description: > The reference passed in via the X-Nearmap-Ext-Reference request header value, if it is present. It is up to the user to track the semantics of this field. E.g. they may wish to interpret it as an insurance policy ID. required: - systemVersion - credits - link - features Feature: type: object required: - id - classId - description - confidence - parentId - geometry - areaSqm - areaSqft - surveyDate - attributes properties: id: type: string description: The Unique ID of this feature. example: "1e88ed3a-abc7-5c34-963e-06df354d39fb" classId: type: string description: The unique ID for the class of this feature. example: "5a5cb214-eee3-4fdd-bfce-d21e9793cf6a" description: type: string description: A description of the class of this feature. example: "Roof" confidence: type: number description: The confidence level for this feature. format: double example: 0.94140625 parentId: type: string description: The feature ID of immediate parent of this feature. geometry: $ref: '#/components/schemas/Geometry' areaSqm: type: number description: The area of the feature geometry in square meters, rounded to 1 decimal place. example: 12.8 areaSqft: type: number description: The area of the feature geometry in square feet, rounded to the nearest integer. example: 138.0 unclippedAreaSqm: type: number description: The unclipped area of the feature geometry in square meters, rounded to 1 decimal place. example: 15.8 unclippedAreaSqft: type: number description: The unclipped area of the feature geometry in square feet, rounded to the nearest integer. example: 150.0 surveyDate: type: string description: The date of the survey capture. format: date example: "2019-09-27" meshDate: type: string description: The date of the 3D mesh used to generate the resource (if applicable). format: date example: "2019-09-27" attributes: type: array description: The list of attributes related to this feature. items: $ref: '#/components/schemas/Attribute' Attribute: type: object description: Additional attribute data for a feature. An attribute will contain many additional fields that are specific to each attribute class. The full schemas for each attribute class are available via the `classes.json` endpoint. required: - classId - description properties: classId: type: string description: The unique ID that identifies the class of this attribute. example: "9357faf9-ea45-4787-8e9c-967b9819de9e" description: type: string description: A description of this class of this attribute. example: "Roof Material" Geometry: type: object description: 'GeoJSON encoding of the feature geometry.' properties: type: type: string description: GeoJSON geometry type. enum: - Point - Polygon - MultiPolygon coordinates: type: array description: Coordinates of the GeoJSON geometry. items: type: object Error: title: Error response type: object description: Error response. properties: code: type: string description: Error code message: type: string description: Error message PacksReport: title: Packs report. type: object description: Packs available to the user. properties: packs: type: array description: The available packs. items: $ref: '#/components/schemas/PackReport' required: - packs PackReport: title: Pack report. type: object description: Details of an available pack. properties: code: type: string example: 'roof_char' description: "The pack code, as appears in the 'packs' query parameter of the features.json endpoint" featureClasses: type: array description: The feature classes available in the pack. items: $ref: '#/components/schemas/PacksEndpointClass' attributeClasses: type: array description: The attribute classes available in the pack. items: $ref: '#/components/schemas/PacksEndpointClass' required: - code - featureClasses - attributeClasses PacksEndpointClass: title: Class report. type: object description: Details of a class available within a pack. The class can either be a feature class or an attribute class. properties: id: type: string description: A unique identifier that can be used to refer to the class. example: 1344cc38-cf6f-42fd-a2ca-6e7e1dd854c4 internalId: x-internal: true type: integer description: A unique internal identifier that can be used to refer to the class. Only available for internal users. example: 1001 description: type: string description: The user friendly human description of the class. example: Shingle roof supportedVersions: type: array description: The system versions that this class is available in. example: [ "gen3-winter_sunrise-1.1" ] items: type: string supportedVersionsInternal: x-internal: true type: array description: The internal system versions that this class is available in. items: type: string required: - id - description - supportedVersions ClassesReport: title: Classes report. type: object description: Classes available to the user. properties: packs: type: array description: The available feature and attribute classes. items: $ref: '#/components/schemas/ClassesEndpointClass' required: - classes ClassesEndpointClass: title: Feature Attribute Class report. type: object description: Details of a class. The class can either be a feature class or an attribute class. properties: type: type: string description: The class type. enum: - Attribute - Feature example: Attribute id: type: string description: A unique identifier that can be used to refer to the class. example: 1344cc38-cf6f-42fd-a2ca-6e7e1dd854c4 internalId: x-internal: true type: integer description: A unique internal identifier that can be used to refer to the class. Only available for internal users. example: 1001 description: type: string description: The user friendly human description of the class. example: Shingle roof schema: type: object description: A JSON Schema object that represents the schema of attributes with this attribute class ID. More details of JSON Schema can be found at https://json-schema.org/. This field is only applicable for attribute classes. parameters: since: name: since in: query description: | Since is a date (`YYYY-MM-DD`) specifying that the capture must be on or after the given date (if not provided then the first available survey date in the location is assumed). required: false schema: type: string example: "2018-08-18" until: name: until in: query description: | Until is a date (`YYYY-MM-DD`) specifying that the capture date must be on or before the given date (if not provided then the current date is assumed). required: false schema: type: string example: "2021-08-18" bulk: x-beta: true name: bulk in: query description: | Bulk determines whether if the request is part of a large batch of requests, meaning requests will not be rate-limited. Valid parameter values: 1, t, T, TRUE, true, True, 0, f, F, FALSE, false, False. required: false schema: type: string example: "true" packs: name: packs in: query description: | Packs accepts a list of comma separated product packs. This returns specific features and attributes under the pack. The response will return all features and attributes that the user is entitled to if no packs are provided. It cannot be used with the `classes` query paremeter. required: false schema: type: string example: "solar,pool,roof_char" classes: name: classes in: query description: | Classes accepts a list of comma separated feature class IDs. Features classes not requested will be filtered out of the response. The full list of available feature classes can be obtained by using the `classes.json` endpoint (Feature class IDs are in the `id` field for classes of type `Feature`). The response will include all feature classes that the user is entitled to if the query parameter is not specified. It cannot be used with the `packs` query parameter. required: false schema: type: string example: 2e0bd9e3-3b67-4990-84dc-1b4812fdd02b,0339726f-081e-5a6e-b9a9-42d95c1b5c8a polygon: name: polygon in: query description: | Represents the Area Of Interest (AOI) to query against. It is depicted by a set of points (longitude/latitude pairs) where the first and last point must be the same. The polygon must not self-intersect. required: true example: '-96.15764446556568,41.22445342518808,-96.15716367959976,41.22444989477328,-96.1571603268385,41.22461027628211,-96.15764245390892,41.224611789313336,-96.15764446556568,41.22445342518808' schema: type: string optionalPolygon: name: polygon in: query description: | Represents the Area Of Interest (AOI) to query against. It is depicted by a set of points (longitude/latitude pairs) where the first and last point must be the same. The polygon must not self-intersect. Must be omitted if address geocoding parameters are supplied. required: false example: '-96.15764446556568,41.22445342518808,-96.15716367959976,41.22444989477328,-96.1571603268385,41.22461027628211,-96.15764245390892,41.224611789313336,-96.15764446556568,41.22445342518808' schema: type: string streetAddress: x-beta: true name: streetAddress in: query description: | The street address for a geocoded request. Should consist of the street number, street name, and street type. Must be omitted if the polygon query parameter is provided. required: false example: '5201 California Ave' schema: type: string city: x-beta: true name: city in: query description: | The city, suburb, or locality for a geocoded request. Must be omitted if the polygon query parameter is provided. required: false example: Irvine schema: type: string state: x-beta: true name: state in: query description: | The two letter state code for a geocoded request. Must be omitted if the polygon query parameter is provided. required: false example: CA schema: type: string zip: x-beta: true name: zip in: query description: | The five digit zip code for a geocoded request. Must be omitted if the polygon query parameter is provided. required: false example: 92602 schema: type: string surveyResourceId: name: surveyResourceId in: path description: | The ID of the survey resource to fetcha AI data from. required: true example: 6c6abf86-1727-4472-8e91-7defb3c7ae3c schema: type: string reference: name: X-Nearmap-Ext-Reference in: header description: Allows a reference string to be echoed back opaquely in the body of the response. required: false example: "123456" schema: type: string responses: features_ok: description: OK content: application/json: schema: $ref: '#/components/schemas/FeatureResult' features_bad_request: description: Bad Request. There was a problem with the request parameters. content: application/json: schema: $ref: '#/components/schemas/Error' examples: Invalid polygon: value: code: INVALID_POLYGON message: Input polygon must be a valid sequence of x,y coordinates. Invalid since date: value: code: INVALID_SINCE message: Date must be in YYYY-MM-DD format. Invalid until date: value: code: INVALID_UNTIL message: Date must be in YYYY-MM-DD format. Invalid date range: value: code: INVALID_DATE_RANGE message: Since date must be before until date. Both polygon and address set: value: code: BOTH_POLYGON_AND_ADDRESS_SET message: Only one of either polygon or address parameters can be provided. Neither polygon nor address set: value: code: NEITHER_POLYGON_NOR_ADDRESS_SET message: One of either polygon or address parameters must be provided. Invalid address: value: code: INVALID_ADDRESS message: All address fields must be set to valid non-empty values. Unknown pack: value: code: UNKNOWN_PACK message: foo is an unknown product pack Packs and classes: value: code: PACKS_AND_CLASSES message: Request includes both packs and classes AOI exceeds maximum size: value: code: AOI_EXCEEDS_MAX_SIZE message: AOI exceeds maximum size. Unknown feature class: value: code: UNKNOWN_CLASS message: Unknown class foo. Packs And Classes Queried: value: code: PACKS_AND_CLASSES message: Both Packs and FeatureClasses included in query. generic_unauthorized: description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/Error' generic_forbidden: description: Forbidden content: application/json: schema: $ref: '#/components/schemas/Error' features_not_found: description: Not Found. No data is available matching the request criteria. content: application/json: schema: $ref: '#/components/schemas/Error'



FAQs