Using the Note Sync APIs
These APIs allow you to build a system to replicate changes from Lens to storage you control (e.g. Salesforce, a database, etc). They're meant to be used for unidirectional sync to other systems (i.e. Lens is the source of truth for notes made in Lens). Changes made to synced notes in other systems cannot be replicated back to Lens.
Changes
- 2023/6/23: Add feature by id endpoint, explicitly mark API V1 as deprecated.
- 2021/11/10: Add draft API V2 endpoints
- 2021/1/11: Add endpoint to list Note changes by Project
- 2020/1/11: The
text
,geometry
,centroid
, andimages
fields will all benull
if the Note is deleted (even if they were present before the note was deleted). Previously those fields would still be present.
Versioning
- The API version is part of the URL, e.g. https://api.upstream.tech/api/v1/
- We won't remove fields or change types without prior notice, or changing the major version
- We may add new fields without changing the version
- The order of the fields is unspecified and may change
Authentication
Every Organization has a Read Only API Token. This token functions as a shared secret.
Contact Upstream support to get your API Token, or to rotate it.
API tokens should be included in every request in the Authorization header.
Rate Limits
Each endpoint has a defined rate limit. If the request rate to this endpoint is exceeded then HTTP status 429 will be returned. The rate limit is tracked over a sliding window.
Rate limits are tracked per-endpoint, per-organization. If multiple requests use different API keys for the same Organization they’ll all count against the same limit.
API V1
API V1 is deprecated and shouldn't be used.
List Projects
- Rate Limit: 25 / min
- URL: https://api.upstream.tech/api/v1/projects
- Method: GET
- Query Params:
page
: for pagination
Properties in Lens are grouped into Projects (also called Portfolios in the app). This endpoint returns a list of all Projects for the current Organization.
Pagination
The page
query parameter can be used to request different pages of data (starting at 1).
The number of results returned in a page is unspecified and may change at Upstream’s discretion. To retrieve all Projects, consumers should continue fetching subsequent pages of data until hasNextPage
is false.
Response Format
createdAt
: ISO formatted creation timeupdatedAt
: ISO formatted time of the last updatefeaturesUrl
: the URL to list the Features for this Projectname
: the display name for this Project in the app
{ "data": [ { "createdAt": "2019-01-01T00:00:00+00:00", "featuresUrl": "https://api.upstream.tech/api/v1/projects/8fbb22e0-2cb7-4fde-8eb1-111111111111/features", "id": "8fbb22e0-2cb7-4fde-8eb1-111111111111", "isArchived": false, "name": "Project Name", "organizationId": "org-id", "updatedAt": "2019-01-01T00:00:00+00:00" } ], "hasNextPage": false, "page": 1 }
List Features for Project
- Rate Limit: 25 / min
- URL: https://api.upstream.tech/api/v1/projects/project_id
/features - Method: GET
- Query Params:
page
: for pagination
Each Property in the Lens dashboard is represented as a GeoJSON Feature in this API. For Properties with multiple locations, each location will be a distinct Feature (with a unique id).
The project_id
can be found by using the List Projects endpoint.
Results are sorted by creation time in descending order (newest Features first).
Pagination
The page
query parameter can be used to request different pages of data (starting at 1).
The number of results returned in a page is unspecified and may change at Upstream’s discretion. To retrieve all Features, consumers should continue fetching subsequent pages of data until hasNextPage
is false.
Response Format
Entries in the data array are GeoJSON Features. The Feature properties are taken from the shapefiles uploaded when setting up your Upstream dashboard.
There are also several system properties that will always be present:
createdAt
: ISO formatted creation timeupdatedAt
: ISO formatted time of the last updatename
: the name displayed for this Feature in the dashboardid
: the primary key in the Upstream System. This can be used to uniquely identify Features with the same namedashboardUrl
: the URL to view this Feature in the dashboardnotesUrl
: the URL to retrieve changes to Notes (see below)__app
: properties that are used by the Lens app, set by users in the browsertags
: a list of tag names applied to this Feature
{ "page": 1, "hasNextPage": true, "data": [ { "geometry": { "coordinates": [ [ [-113.51932525634766, 37.110503028109626], [-113.5323715209961, 37.081749544018415], [-113.52447509765625, 37.060382750228186], [-113.49700927734375, 37.06202656346916], [-113.49014282226562, 37.09900294387622], [-113.5000991821289, 37.112967104709234], [-113.51932525634766, 37.110503028109626] ] ], "type": "Polygon" }, "id": 0, "properties": { "createdAt": "2019-01-01T00:00:00+00:00", "name": "", "updatedAt": "2019-01-02T00:00:00+00:00", "notesUrl": "https://api.upstream.tech/api/v1/...", "dashboardUrl": "https://app.upstream.tech/projects/....", "idV2": "UUID (used in V2 of the API)", "lensId": "UUID - same as idV2" }, "type": "Feature" } ] }
Listing Changes to Notes
Notes are created for Features. These endpoints return Notes ordered by when they were created or changed. You can either retrieve Notes for a specific Feature, or for all Features in a Project. The response format is the same for both endpoints.
Show Note Changes for Feature
- Rate Limit: 120 / min
- URL: https://api.upstream.tech/api/v1/projects/project_id
/features/ feature_id /notes -
- Query Params:
- after: the pagination token (see below) after which results should be returned. If omitted, the earliest results will be returned.
Show Note Changes for all Features in a Project
- Rate Limit: 240 / min
- URL: https://api.upstream.tech/api/v1/projects/project_id/
notes - Method: GET
- Query Params:
after
: the pagination token (see below) after which results should be returned. If omitted, the earliest results will be returned.
Pagination
Each Note in the data array has a paginationToken
field. This opaque token can be used to retrieve another page of results after the last item in the current page using the after query parameter. If no paginationToken
is provided in the after query parameter, the earliest results will be returned.
The paginationToken
of the last item processed can be stored to resume synchronization after a known point in the future. However, tokens are specific to the Feature on which the Note was made, and should not be used for different Features.
If more results are available, the hasNextPage
field will be true. The number of results returned per page is unspecified and may be changed at Upstream’s discretion. To retrieve all changes, consumers should continue fetching subsequent pages of data until hasNextPage
is false.
Date filtering
Each note in the data array has an updatedAt
field, which can be used to filter results based on when a note was last updated. Dates can be filtered by an updatedAtBefore
or updatedAtAfter
query parameter. The date field follows a YYYY-MM-DDTHH:MMZ
format. For example, to represent May 1, 2021 you would use: 2021-05-01T00:00Z.
Response Format
The full Note record will be returned, not just the fields that have changed. It is the consumer’s responsibility to identify the delta between what’s stored in their system and the latest changes (or to overwrite what’s stored with the latest data from the response).
Data will be returned in chronological order (oldest then newest), by the updatedAt
time.
geometry
is a GeoJSON geometry for the point or polygon of the note (if present).
Notes are “soft deleted” in Lens; deleted notes will have their isArchived field set to true in the response. The text
, geometry
, centroid
, and images
fields will all be null
if the Note is deleted (even if they were present before the note was deleted).
If the note is attached to a specific date (or range of dates for a comparison), a specific imagery layer (e.g. truecolor or vegetation), and includes geometry, then the images
array will be populated. There may be multiple entries (if the note refers to a date range). Each entry in the array includes metadata about the image (e.g. source and resolution) and a URL to retrieve the image itself.
{ "hasNextPage": true, "data": [ { "id": 123908, "displayNumber": 1, "featureId": 123, "featureIdV2": "eef6bf98-03c6-4bd5-b3c9-4c3a7e38cf89", "createdAt": "2019-01-01T00:00:00+00:00", "updatedAt": "2019-01-01T00:00:00+00:00", "isArchived": false, "text": "note content", "userId": "email@address.com", "userName": "User Name", "attachments": ["https://url/to/attachment"], "tags": [ "Vegetation" ], "geometry": { "coordinates": [ [ [-113.51932525634766, 37.110503028109626], [-113.5323715209961, 37.081749544018415], [-113.52447509765625, 37.060382750228186], [-113.49700927734375, 37.06202656346916], [-113.49014282226562, 37.09900294387622], [-113.5000991821289, 37.112967104709234], [-113.51932525634766, 37.110503028109626] ] ], "type": "Polygon" }, "centroid": [-113.49700927734375, 37.06202656346916], "images": [ { "source": "Source Name (resolution)", "type": "truecolor", "capturedAt": "2018-12-31T00:00:00+00:00", "copyright": "2018, Imagery Vendor", "url": "https://url/to/image", "output_resolution_meters": 0.75 } ], "dashboardUrl": "https://app.upstream.tech/projects/....", "paginationToken": "" } ] }
API V2
Below is a summary of differences between API V1 and V2:
- Feature IDs have changed from integers to UUID strings
- In both URL paths, and JSON responses
- The V2 Feature IDs are now present on V1 responses to aid in migrating
List Projects
- Rate Limit: 25 / min
- URL: https://api.upstream.tech/api/v2/projects
- Method: GET
- Query Params:
page
: for pagination
Properties in Lens are grouped into Projects (also called Portfolios in the app). This endpoint returns a list of all Projects for the current Organization.
Pagination
The page
query parameter can be used to request different pages of data (starting at 1).
The number of results returned in a page is unspecified and may change at Upstream’s discretion. To retrieve all Projects, consumers should continue fetching subsequent pages of data until hasNextPage
is false.
Response Format
createdAt
: ISO formatted creation timeupdatedAt
: ISO formatted time of the last updatefeaturesUrl
: the URL to list the Features for this Projectname
: the display name for this Project in the app
{ "data": [ { "createdAt": "2019-01-01T00:00:00+00:00", "featuresUrl": "https://api.upstream.tech/api/v2/projects/8fbb22e0-2cb7-4fde-8eb1-111111111111/features", "noteChangesUrl": "https://api.upstream.tech/api/v2/projects/8fbb22e0-2cb7-4fde-8eb1-111111111111/notes", "id": "8fbb22e0-2cb7-4fde-8eb1-111111111111", "isArchived": false, "name": "Project Name", "organizationId": "org-id", "updatedAt": "2019-01-01T00:00:00+00:00" } ], "hasNextPage": false, "page": 1 }
List Features for Project
- Rate Limit: 25 / min
- URL: https://api.upstream.tech/api/v2/projects/project_id
/features - Method: GET
- Query Params:
page
: for pagination
Each Property in the Lens dashboard is represented as a GeoJSON Feature in this API. For Properties with multiple locations, each location will be a distinct Feature (with a unique id).
The project_id
can be found by using the List Projects endpoint.
Results are sorted by creation time in descending order (newest Features first).
Pagination
The page
query parameter can be used to request different pages of data (starting at 1).
The number of results returned in a page is unspecified and may change at Upstream’s discretion. To retrieve all Features, consumers should continue fetching subsequent pages of data until hasNextPage
is false.
Response Format
Entries in the data array are GeoJSON Features. The Feature properties are taken from the shapefiles uploaded when setting up your Upstream dashboard.
There are also several system properties that will always be present:
createdAt
: ISO formatted creation timeupdatedAt
: ISO formatted time of the last updatename
: the name displayed for this Feature in the dashboardid
: the primary key in the Upstream System. This can be used to uniquely identify Features with the same namedashboardUrl
: the URL to view this Feature in the dashboardnotesUrl
: the URL to retrieve changes to Notes (see below)selfUrl
: the URL to retrieve this Feature again__app
: properties that are used by the Lens app, set by users in the browsertags
: a list of tag names applied to this Feature
{ "page": 1, "hasNextPage": true, "data": [ { "geometry": { "coordinates": [ [ [ -113.51932525634766, 37.110503028109626 ], [ -113.5323715209961, 37.081749544018415 ], [ -113.52447509765625, 37.060382750228186 ], [ -113.49700927734375, 37.06202656346916 ], [ -113.49014282226562, 37.09900294387622 ], [ -113.5000991821289, 37.112967104709234 ], [ -113.51932525634766, 37.110503028109626 ] ] ], "type": "Polygon" }, "id": "eef6bf98-03c6-4bd5-b3c9-4c3a7e38cf89", "properties": { "createdAt": "2019-01-01T00:00:00+00:00", "name": "Area Name", "updatedAt": "2019-01-02T00:00:00+00:00", "notesUrl": "https://api.upstream.tech/api/v2/...", "selfUrl": "https://api.upstream.tech/api/v2/...", "dashboardUrl": "https://app.upstream.tech/projects/....", "lensId": "eef6bf98-03c6-4bd5-b3c9-4c3a7e38cf89", "__app": { "tags": [ "Needs Review" ] } }, "type": "Feature" } ] }
Get Feature By ID
- Rate limit: 120 / min
- URL: https://api.upstream.tech/api/v2/features/feature_id
- Method: GET
Response Format
The same as for an individual Feature in the List Features for Project endpoint.
{"data": { "geometry": { "coordinates": [ [ [ -113.51932525634766, 37.110503028109626 ], [ -113.5323715209961, 37.081749544018415 ], [ -113.52447509765625, 37.060382750228186 ], [ -113.49700927734375, 37.06202656346916 ], [ -113.49014282226562, 37.09900294387622 ], [ -113.5000991821289, 37.112967104709234 ], [ -113.51932525634766, 37.110503028109626 ] ] ], "type": "Polygon" }, "id": "eef6bf98-03c6-4bd5-b3c9-4c3a7e38cf89", "properties": { "createdAt": "2019-01-01T00:00:00+00:00", "name": "Area Name", "updatedAt": "2019-01-02T00:00:00+00:00", "notesUrl": "https://api.upstream.tech/api/v2/...", "selfUrl": "https://api.upstream.tech/api/v2/...", "dashboardUrl": "https://app.upstream.tech/projects/....", "lensId": "eef6bf98-03c6-4bd5-b3c9-4c3a7e38cf89", "__app": { "tags": [ "Needs Review" ] } }, "type": "Feature" } }
Listing Changes to Notes
Notes are created for Features. These endpoints return Notes ordered by when they were created or changed. You can either retrieve Notes for a specific Feature, or for all Features in a Project. The response format is the same for both endpoints.
Show Note Changes for Feature
- Rate Limit: 120 / min
- URL: https://api.upstream.tech/api/v2/projects/project_id
/features/ feature_id /notes - Method: GET
- Query Params:
- after: the pagination token (see below) after which results should be returned. If omitted, the earliest results will be returned.
Show Note Changes for all Features in a Project
- Rate Limit: 240 / min
- URL: https://api.upstream.tech/api/v2/projects/project_id
/notes - Method: GET
- Query Params:
after
: the pagination token (see below) after which results should be returned. If omitted, the earliest results will be returned.
Pagination
Each Note in the data array has a paginationToken
field. This opaque token can be used to retrieve another page of results after the last item in the current page using the after query parameter. If no paginationToken
is provided in the after query parameter, the earliest results will be returned.
The paginationToken
of the last item processed can be stored to resume synchronization after a known point in the future. However, tokens are specific to the Feature on which the Note was made, and should not be used for different Features.
If more results are available, the hasNextPage
field will be true. The number of results returned per page is unspecified and may be changed at Upstream’s discretion. To retrieve all changes, consumers should continue fetching subsequent pages of data until hasNextPage
is false.
Date filtering
Each note in the data array has an updatedAt
field, which can be used to filter results based on when a note was last updated. Dates can be filtered by an updatedAtBefore
or updatedAtAfter
query parameter. The date field follows a YYYY-MM-DDTHH:MMZ
format. For example, to represent May 1, 2021 you would use: 2021-05-01T00:00Z.
Response Format
The full Note record will be returned, not just the fields that have changed. It is the consumer’s responsibility to identify the delta between what’s stored in their system and the latest changes (or to overwrite what’s stored with the latest data from the response).
Data will be returned in chronological order (oldest then newest), by the updatedAt
time.
geometry
is a GeoJSON geometry for the point or polygon of the note (if present).
Notes are “soft deleted” in Lens; deleted notes will have their isArchived field set to true in the response. The text
, geometry
, centroid
, and images
fields will all be null
if the Note is deleted (even if they were present before the note was deleted).
If the note is attached to a specific date (or range of dates for a comparison), a specific imagery layer (e.g. truecolor or vegetation), and includes geometry, then the images
array will be populated. There may be multiple entries (if the note refers to a date range). Each entry in the array includes metadata about the image (e.g. source and resolution) and a URL to retrieve the image itself.
{ "hasNextPage": true, "data": [ { "id": 123908, "displayNumber": 1, "feature": { "id": "eef6bf98-03c6-4bd5-b3c9-4c3a7e38cf89", "properties': { "fieldName": "fieldValue" } }, "createdAt": "2019-01-01T00:00:00+00:00", "updatedAt": "2019-01-01T00:00:00+00:00", "isArchived": false, "text": "note content", "userId": "email@address.com", "userName": "User Name", "attachments": [ "https://url/to/attachment" ], "geometry": { "coordinates": [ [ [ -113.51932525634766, 37.110503028109626 ], [ -113.5323715209961, 37.081749544018415 ], [ -113.52447509765625, 37.060382750228186 ], [ -113.49700927734375, 37.06202656346916 ], [ -113.49014282226562, 37.09900294387622 ], [ -113.5000991821289, 37.112967104709234 ], [ -113.51932525634766, 37.110503028109626 ] ] ], "type": "Polygon" }, "centroid": [ -113.49700927734375, 37.06202656346916 ], "images": [ { "source": "Source Name (resolution)", "type": "truecolor", "capturedAt": "2018-12-31T00:00:00+00:00", "copyright": "2018, Imagery Vendor", "url": "https://url/to/image", "output_resolution_meters": 0.75 } ], "dashboardUrl": "https://app.upstream.tech/projects/....", "paginationToken": "" } ] }