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, and images fields will all be null 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

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 time
  • updatedAt: ISO formatted time of the last update
  • featuresUrl: the URL to list the Features for this Project
  • name: 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

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 time
  • updatedAt: ISO formatted time of the last update
  • name: the name displayed for this Feature in the dashboard
  • id: the primary key in the Upstream System. This can be used to uniquely identify Features with the same name
  • dashboardUrl: the URL to view this Feature in the dashboard
  • notesUrl: the URL to retrieve changes to Notes (see below)
  • __app: properties that are used by the Lens app, set by users in the browser
    • tags: 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 
  • 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/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"],
      "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

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 time
  • updatedAt: ISO formatted time of the last update
  • featuresUrl: the URL to list the Features for this Project
  • name: 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

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 time
  • updatedAt: ISO formatted time of the last update
  • name: the name displayed for this Feature in the dashboard
  • id: the primary key in the Upstream System. This can be used to uniquely identify Features with the same name
  • dashboardUrl: the URL to view this Feature in the dashboard
  • notesUrl: 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 browser
    • tags: 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

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  textgeometrycentroid, 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": ""
    }
  ]
}