NAV Navbar
shell
  • Introduction
  • Authentication
  • Users
  • Attaching custom metadata
  • Farms
  • Fields
  • Projects
  • Plant Counts
  • Zonal Statistics
  • Introduction

    Solvi API is organized around REST and allows for programmatic access to resources like users and projects. Below you will find detailed information on how to access the API and which operations are currently supported.

    In Solvi, a Project represents a single upload of multiple images. Projects can be grouped under Fields, which in turn are grouped into Farms to make it easier to organize and share data. Current API implementation allows to create and fetch projects for the specific user, as well as upload and stitch images into maps. Once processed, the outputs such as orthomosaics and elevation maps can either be accessed through the API or the user can be redirected to Solvi to view and analyze the processed imagery.

    Authentication

    Example API key request:

    curl "api_endpoint_here"
      -H "X-Api-Key: <your-api-key>"
    

    Make sure to replace <your-api-key> with your API key.

    To use Solvi API you first need an API key. You will get an API key from Solvi, contact us to get your key. If you for some reason need to revoke a key, you can also contact us.

    Please note that the API key should be kept secret and not be exposed to end-users: for example, never send the API key to a web browser.

    With the API key, you can access general API methods, for example, to register new users in Solvi, and create user-specific tokens.

    Requests requiring an API key should add the X-Api-Key header:

    X-Api-Key: <your-api-key>

    Example user-specific request:

    curl "api_endpoint_here"
      -H "Authorization: Bearer <user-specific-token>"
    

    Make sure to replace <user-specific-token> with your token.

    Instead of using the API key, requests that act on behalf of a specific user, like creating or getting projects, should use a user-specific token to authenticate as the user. When using a user-specific token, do not include the API key in the same request. A user-specific token has a limited lifetime and is less security sensitive compared to the API key. For example, a user token can be sent to and used directly from for example a browser, or for passwordless authentication when the user is redirected from your portal to Solvi. A user-specific token can be used for a limited amount of time (currently 24 hours) before it expires. A user-specific token is created by using the endpoint to create a user-specific token.

    User specific requests should use the Authorization header instead of the X-Api-Key header:

    Authorization: Bearer <user-specific-token>

    Users

    Register new user

    Example request:

    curl -X POST
      -H "X-Api-Key: <your-api-key>"
      -H "Content-Type: application/json"
      -d '{ "user": { "email": "john@example.com", "password": "password", "first_name": "John", "last_name": "Doe"}}'
      "https://solvi.ag/api/v1/users"
    

    Example response:

      {
        "status": "success",
        "user_id": 182
      }
    

    This endpoint registers a new user. If successful, the response will return user_id that you would use later to generate user-specific tokens.

    HTTP Request

    POST https://solvi.ag/api/v1/users

    Parameters

    Parameter Description
    email required Email
    password required Password
    first_name required First name
    last_name required Last name

    Generate user-specific token

    Example request:

    curl -X GET
      -H "X-Api-Key: <your-api-key>"
      "https://solvi.ag/api/v1/users/<user_id>/token"
    

    Example response:

      {
        "status": "success",
        "user_id": 26,
        "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoyNiwiZXhwIjo0OCwiZXhwIjoxNTAxMjU2NzAyfQ.cu5zIye7ubBhv7YsFIxXkO0E_W0hG0VrlOTQx6L3b3c"
      }
    

    This endpoint gives a token for the specific user that should be used to create and retrieve user projects. Every request will generate na ew token. The token is valid for 24 hours.

    HTTP Request

    GET https://solvi.ag/api/v1/users/<user_id>/token

    Parameters

    Parameter Description
    user_id required User ID given when user is created

    Attaching custom metadata

    When using the API, it is common that the farms, fields and projects in Solvi also exist in your own systems, and you need information to track which entity in your system a Solvi entity maps to. There are many ways to accomplish this, but one way is to attach metadata to the Solvi entities. Farms, fields and projects created through the API all support attaching arbitrary data to them. Solvi does not use this data, so you can put anything here, as long as it can be encoded in JSON.

    Endpoints to create or update farms, fields and projects all accept an optional parameter metadata for this purpose.

    Endpoints that return farms, fields and projects also return the metadata under the metadata property if set, or null otherwise.

    Farms

    Create farm

    Example request:

    curl -X POST
      -H "Authorization: Bearer <user-jwt-token>"
      -H "Content-Type: application/json"
      -d '{"farm": {"name": "My second farm"}}'
      "https://solvi.ag/api/v1/farms"
    

    Example response:

      {
        "status": "success",
        "farm_id": 793
      }
    

    Creates a new farm.

    HTTP Request

    POST https://solvi.ag/api/v1/farms

    Parameters

    Parameter Description
    name required Name of the the farm
    metadata optional Optional arbitrary metadata

    Get farms

    Example request:

    curl -X GET
      -H "Authorization: Bearer <user-jwt-token>"
      -H "Content-Type: application/json"
      "https://solvi.ag/api/v1/farms"
    

    Example response:

        [
          {
            "name": "My farm",
            "created_at": "2019-02-08T09:18:37.655Z",
            "fields": [
              {
                "id": 2657,
                "name": "Veddige",
                "created_at": "2019-03-08T04:05:38.628Z",
                "metadata": null
              }
            ],
            "metadata": null
          }
        ]
    

    Gets all user farms and a list of fields related to each farm.

    HTTP Request

    GET https://solvi.ag/api/v1/farms

    Fields

    Create field

    Example request:

    curl -X POST
      -H "Authorization: Bearer <user-jwt-token>"
      -H "Content-Type: application/json"
      -d '{"field": { "name": "Winter Wheat", "geom": "{\"type\":\"Polygon\",\"coordinates\":[[[100.0, 0.0],[101.0, 0.0],[101.0, 1.0],[100.0, 1.0],[100.0, 0.0]]]}"}}'
      "https://solvi.ag/api/v1/fields"
    

    Example response:

      {
        "status": "success",
        "field_id": 793
      }
    

    Creates a new field. Field boundaries can be provided as Polygon or MultiPolygon in GeoJSON format. The farm to organize the field under can also be provided. The response contains field_id which can be later used to relate projects to the specific field.

    HTTP Request

    POST https://solvi.ag/api/v1/fields

    Parameters

    Parameter Description
    name required Name of the the field
    geom optional Boundaries of the field as a Polygon or Multipolygon in GeoJSON format and EPSG:4326 coordinate system(lonlat)
    farm_id optional The id of the farm to put the field under; if not specified, the user's last created farm is used
    metadata optional Optional arbitrary metadata

    Get fields

    Example request:

    curl -X GET
      -H "Authorization: Bearer <user-jwt-token>"
      -H "Content-Type: application/json"
      "https://solvi.ag/api/v1/fields"
    

    Example response:

        [
          {
              "id": 199,
              "name": "wheat field",
              "created_at": "2018-02-27T12:45:05.550Z",
              "projects": [
                  {
                      "project_id": 1291,
                      "status": "processed",
                      "name": "27-FEB-2018",
                      "field_name": "Wheat field",
                      "survey_date": "2018-02-26T14:19:36.000Z",
                      "upload_date": "2018-02-27T12:45:05.556Z",
                      "url": "https://solvi.ag/projects/1291",
                      "thumbnail_url": "https://solvi.ag/projects/1291/thumbnail.png",
                      "metadata": null
                  }
              ],
              "metadata": null
          }
        ]
    

    Gets all user fields and a list of projects related to each field.

    HTTP Request

    GET https://solvi.ag/api/v1/fields

    Projects

    Create project

    Example request:

    curl -X POST
      -H "Authorization: Bearer <user-jwt-token>"
      -H "Content-Type: application/json"
      -d '{ "type": "overlapping", "field_id": "field_1", "field_name": "Wheat Field", "field_geom": "{\"type\":\"Polygon\",\"coordinates\":[[[100.0, 0.0],[101.0, 0.0],[101.0, 1.0],[100.0, 1.0],[100.0, 0.0]]]}" }'
      "https://solvi.ag/api/v1/projects"
    

    Example response:

      {
        "status": "success",
        "project_id": 142,
        "project_url": "https://solvi.ag/projects/142/photos/upload",
        "imagery_upload_data": {
          "url":"https://solvi-projects-dev.s3.eu-west-1.amazonaws.com",
          "fields": {
            [...]
          },
          "key_prefix":"uploads/26c1ce11-c9bf-4825-821c-72e9f600a6cf/originals/"
        },
      }
    

    This endpoint creates a new project which is required before imagery upload. In response, you will receive URL to upload-page for the newly created project where the user can be redirected.

    There are multiple types of projects: overlapping (the default), stitched and scouting:

    Projects can be connected to a Field. When multiple projects are related to the same Field, they appear in the same map view when data is processed. This allows for easier navigation between imagery over the same Field and over the time data comparison.

    Fields can be either be:

    Optionally, a project can be created with a so-called webhook that will be called every time the status of the project changes. This makes it possible for integration to for example react when a project finishes processing, without having to use polling to check the project's status. To add a webhook, specify the URL to be called with the status_webhook parameter. See the section on webhooks for details.

    The project's crop, survey date and altitude, data which will be displayed in Solvi's UI, can also be submitted.

    HTTP Request

    POST https://solvi.ag/api/v1/projects

    Parameters

    Parameter Description
    type optional The type of imagery for this project: overlapping, stitched or scouting; default is overlapping
    field_id Solvi field id as returned from Fields API
    field_name Name of the the field
    field_geom optional Boundaries of the field as a polygon in GeoJSON format and EPSG:4326 coordinate system(lonlat)
    status_webhook optional A URL to be called when the project's status changes
    webhook_secret optional A token to use to sign webhook requests, see webhooks for details
    survey_date optional Date survey was conducted, formatted as YYYY-MM-DD
    crop optional The documented crop; free form string
    altitude optional Altitude the imagery was taken from in meters
    metadata optional Optional arbitrary metadata

    Update project data

    Example request:

    curl -X PUT
      -H "Authorization: Bearer <user-jwt-token>"
      -H "Content-Type: application/json"
      -d '{
        "survey_date": "2022-08-18"
      }'
    

    Example response:

    {
        "status": "ok"
    }
    

    HTTP Request

    PUT https://solvi.ag/api/v1/projects/<project_id>

    Parameters

    Parameter Description
    survey_date optional Date survey was conducted, formatted as YYYY-MM-DD
    crop optional The documented crop; free form string
    altitude optional Altitude the imagery was taken from in meters
    metadata optional Optional arbitrary metadata

    This endpoint allows updating survey date, crop, altitude and metadata for a project.

    Upload local imagery

    Example request:

    curl -X POST
      -H "Authorization: Bearer <user-jwt-token>"
      -H "Content-Type: application/json"
      "https://solvi.ag/api/v1/projects/<project_id>/begin_upload"
    

    Example response:

    {
      "status": "ok",
      "imagery_upload_data": {
        "url": "https://solvi-projects.s3.eu-west-1.amazonaws.com",
        "fields": {
          "x-amz-storage-class": "STANDARD_IA",
          "policy": "eyJleHBpcmF0aW9uIjoiMjAyMC0wOC0wN1QwNzozMjo1MVoiLCJjb25kaXRpb25zIjpbeyJidWNrZXQiOiJzb2x2aS1wcm9qZWN0cy1kZXYifSxbInN0YXJ0cy13aXRoIiwiJGtleSIsInVwbG9hZHMvMjZjMWNlMTEtYzliZi00ODI1LTgyMWMtNzJlOWY2MDBhNmNmL29yaWdpbmFscy8iXSxbInN0YXJ0cy13aXRoIiwiJENvbnRlbnQtVHlwZSIsIiJdLHsieC1hbXotc3RvcmFnZS1jbGFzcyI6IlNUQU5EQVJEX0lBIn0seyJ4LWFtei1jcmVkZW50aWFsIjoiQUtJQVVWTUhLR1RRRldMTlkyTUgvMjAyMDA4MDUvZXUtd2VzdC0xL3MzL2F3czRfcmVxdWVzdCJ9LHsieC1hbXotYWxnb3JpdGhtIjoiQVdTNC1ITUFDLVNIQTI1NiJ9LHsieC1hbXotZGF0ZSI6IjIwMjAwODA1VDA3MzI1MVoifV18",
          "x-amz-credential": "AKIAUVMHKGTQFWLNY2MX/20200805/eu-west-1/s3/aws4_request",
          "x-amz-algorithm": "AWS4-HMAC-SHA256",
          "x-amz-date": "20200805T073251Z",
          "x-amz-signature": "5494b8f7ca5c78c45daf7d8099f3c4b93e141567d3691dbec3dcc0f6fd2e0181"
        },
        "key_prefix": "uploads/26c1ce11-c9bf-4825-821c-72e9f600a6cf/originals/"
      }
    }
    

    After a project has been created, imagery can be uploaded to it by sending the begin_upload request. The response includes information required to upload imagery for the project.

    Example JavaScript function to POST an image using imagery_upload_data retrieved from the example above:

    function uploadFile (imagery_upload_data, f) {
      const form = new FormData()
      Object.keys(imagery_upload_data.fields).forEach(field => form.append(field, imagery_upload_data.fields[field]))
      const key = imagery_upload_data.key_prefix + f.name
      form.append('key', key)
      form.append('Content-Type', 'image/jpeg')
      form.append('file', f)
    
      return fetch(imagery_upload_data.url, { method: 'POST', body: form })
        .then(response => {
          if (!response.ok) {
            throw new Error(`Unexpected response HTTP ${response.status} ${response.statusText}`)
          }
        })
    }
    

    Example JavaScript function to post an array of files using the uploadFile function above, using imagery_upload_data retrieved from the example above:

    function uploadFiles (imagery_upload_data, files) {
      return uploadNext()
    
      function uploadNext () {
        return new Promise(function (resolve, reject) {
          const file = files.shift()
          if (file) {
            uploadFile(imagery_upload_data, file)
              .then(uploadNext)
              .catch(reject)
          } else {
            resolve()
          }
        })
      }
    }
    

    The required parameters are included in the imagery_upload_data object: this object has a url property indicating the URL to POST imagery to, and a fields object, listing the HTTP form data fields required for the POST request. In addition to these fields, the form must also include a key field, this is the destination path for the uploaded file: the key must start with specified key_prefix and its value must be unique for each image, usually the key is set from the key_prefix and the uploaded file's filename. Note that subdirectories are not allowed and the filename can't contain special characters like /, \ and :.

    HTTP Request

    POST https://solvi.ag/api/v1/projects/<project_id>/begin_upload

    Parameters

    Parameter Description
    project_id required Project ID given when project is created

    Upload remote imagery

    Example request:

    curl -X POST
      -H "Authorization: Bearer <user-jwt-token>"
      -H "Content-Type: application/json"
      "https://solvi.ag/api/v1/projects/<project_id>/process_external_ortho"
      -d '{
        "ortho_url": "https://example.com/my_ortho.tiff"
      }'
    

    Example response:

    {
      "status": "ok"
    }
    

    This will start processing a prestitched ortho photo located at the URL provided in the ortho_url parameter. Note that the ortho must be possible to download through a simple HTTP GET request without any other authentication than is present in the URL itself. For example a presigned S3 URL is suitable.

    You should not use the complete_upload endpoint in combination with this endpoint, processing will start immediately when using this endpoint.

    Note that this operation is only valid for projects of prestitched type.

    HTTP Request

    POST https://solvi.ag/api/v1/projects/<project_id>/process_external_ortho

    Parameters

    Parameter Description
    project_id required Project ID given when project is created
    ortho_url required The URL to download the prestitched ortho from

    Processing uploaded imagery

    Example request:

    curl -X POST
      -H "Authorization: Bearer <user-jwt-token>"
      -H "Content-Type: application/json"
      "https://solvi.ag/api/v1/projects/<project_id>/complete_upload"
    

    Example response:

    {
      "status": "ok",
    }
    

    When project imagery has been uploaded, the upload must be completed, which will start the processing of the imagery.

    If processing was successfully started, the HTTP response code will be 200. In addition, a response of 402 (Payment required) can also be returned, if the upload or credit quota for the user is not sufficient for processing the upload.

    HTTP Request

    POST https://solvi.ag/api/v1/projects/<project_id>/complete_upload

    Parameters

    Parameter Description
    project_id required Project ID given when project is created

    Get projects

    Example request:

    curl -X GET
      -H "Authorization: Bearer <user-jwt-token>"
      'https://solvi.ag/api/v1/projects?field_geom={"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[100.0, 0.0],[101.0, 0.0],[101.0, 1.0],[100.0, 1.0],[100.0, 0.0]]]}]}'
    

    Example response:

      [
        {
          "project_id": 9999,
          "status": "processed",
          "name": "25-JUN-2018",
          "plant_counts": "published",
          "field": {
              "id": 9999,
              "name": "Winter Wheat",
              "identfier": "WW-01",
              "farm": {
                  "id": 656,
                  "name": "Borgeby Farm"
              }
          },
          "survey_date": "2018-06-25T19:19:27.000Z",
          "upload_date": "2018-06-25T20:50:14.870Z",
          "url": "https://solvi.ag/projects/9999",
          "thumbnail_url": "https://solvi.ag/projects/9999/thumbnail.png",
          "metadata": null
        },
        {
          "name": "New project",
          "url": "https://solvi.ag/projects/new",
          "metadata": null
        }
      ]
    

    This endpoint retrieves all projects created by the user or shared with user by others. If field boundaries are provided, only projects whose extent overlaps boundaries are returned.

    HTTP Request

    GET https://solvi.ag/api/v1/projects

    Parameters

    Parameter Description
    field_geom optional Boundaries of the field as a polygon in GeoJSON format and EPSG:4326 coordinate system(lonlat).

    Project outputs

    Example request:

    curl -X GET
      -H "Authorization: Bearer <user-jwt-token>"
      'https://solvi.ag/api/v1/projects/<project-id>
    

    Example response:

      {
        "project_id": 9999,
        "status": "processed",
        "name": "25-JUN-2018",
        "plant_counts": "published",
        "field": {
            "id": 9999,
            "name": "Winter Wheat",
            "identfier": "WW-01",
            "farm": {
                "id": 656,
                "name": "Borgeby Farm"
            }
        },
        "survey_date": "2018-06-25T19:19:27.000Z",
        "upload_date": "2018-06-25T20:50:14.870Z",
        "url": "https://solvi.ag/projects/9999",
        "thumbnail_url": "https://solvi.ag/projects/9999/thumbnail.png",
        "resources": {
          "thumbnail": "https://solvi.ag/projects/9999/thumbnail.png",
          "ortho": "https://solvi-projects.s3.eu-west-1.amazonaws.com/uploads/ed12e5f6-b6c9-4df8-9522-1dbc29be854b/results/ortho.tiff?...",
          "dem": "https://solvi-projects-dev.s3.eu-west-1.amazonaws.com/uploads/ed12e5f6-b6c9-4df8-9522-1dbc29be854b/results/dem.tiff?..."
        },
        "metadata": null
      },
    

    This endpoint retrieves projects created by the user or shared with the user by others.

    The included resources are URLs that can be used to fetch the project outputs. These resource URLs are temporary, with a lifetime of 15 minutes before they expire.

    HTTP Request

    GET https://solvi.ag/api/v1/projects/<project_id>

    Parameters

    Parameter Description
    project_id required Project ID given when project is created

    Project tiled imagery

    Example request:

    curl -X GET
      -H "Authorization: Bearer <user-jwt-token>"
      'https://solvi.ag/api/v1/projects/<project-id>/tiles/<type>
    

    Example response:

    {
      "url": "https://ts2.solvi.nu/.../results/ortho.tiff/rgb/rgb/tile/{z}/{x}/{y}.png?token=...",
      "type": "tileset/orthomosaic",
      "resolution": 0.15961538646165616,
      "bounds": {
        "value": [
          -115.407127627406,
          33.13991737241373,
          -115.39728408213948,
          33.144345906954
        ],
        "crs": "EPSG:4326"
      }
    }
    

    This endpoint retrieves a tile template URL, suitable for use with popular map clients like OpenLayers or Leaflet. The URLs are temporary, with a lifetime of at least 48 hours.

    Note that all types are not necessarily available for all projects. Requesting a tile type that is not available will give a HTTP 404 response.

    For ortho and dem tiles (when response type is "tileset/orthomosaic), geographic bounds are returned in the bounds property, and the native resolution (meters/pixel) is given by resolution.

    For plant_counts (when response type is "tileset/plant_counts), number_plants and number_missing give totals for the detected plants.

    HTTP Request

    GET https://solvi.ag/api/v1/projects/<project-id>/tiles/<type>

    Parameters

    Parameter Description
    project_id required Project ID given when project is created
    type required Type of tiles to fetch; currently one of ortho for RGB orthomosaic, dem for colored elevation model or plant_counts for plant counts

    Webhooks

    Webhooks allow setting up integrations that subscribe to certain events from Solvi. When one of those events is triggered, an HTTP POST payload is sent to the webhook's configured URL. Currently, project status (event type status_changed) and plant counts published (event type plant_counts_published) are the three available events in Solvi.

    Example webhook request payload

    {
      "project_id": 8993,
      "event_type": "status_changed",
      "old_status": "not_processed",
      "new_status": "processed"
    }
    

    The webhook is configured when creating a project or when creating a plant count by specifing the webhook parameter, which should contain the URL of the webhook.

    Webhook events

    The type of event that occured is determined by the event_type parameter of the request body. Currently, there are two supported event types:

    Status changes

    The status change messages contains old_status, the status of the project before this change, as well as new_status, the project's updated status.

    There are three different project statuses:

    Plant Counts Published

    Notifies that plant counts data has been published for this project. The results can be fetched using the tiles endpoint with plant_counts as type.

    Securing webhooks

    To ensure that Solvi is the sender of the webhook requests, you can optionally also specify a secret token when registering the webhook, by using the webhook_secret parameter: the secret can be any string of your choosing.

    Example signature header

    X-Solvi-Signature: sha1=494e5dbdd1afbe4d44091bf86872b5eb4b9133e5
    

    When a secret token has been specified, Solvi will include the HTTP header X-Solvi-Signature, which will contain an HMAC-SHA1 signature of the body.

    This follows the same pattern as securing webhooks on GitHub, except for using the header X-Solvi-Signature instead.

    Plant Counts

    The plant counts API is under development and currently only supports a limited number of use cases:

    Create Plant Counts

    Example request:

    curl 
      -X POST 
      -H "Authorization: Bearer <user-jwt-token>" 
      -H 'Content-Type: application/json'
      -d '{"model": "base-models/shape"}'
      https://solvi.ag/api/v1/projects/<project-id>/plant_counts
    

    Example response:

      {
        "status": "Created",
        "job_id": "88a2af8601cf2b7c4e14979f8df73bca7352ccce",
      }
    

    This initiates a plant count for the specified project. A plant count can either be:

    When using the API, automatic plant counts are currently only supported for scouting projects.

    To create a supervised "done for you" plant count, set the request_done_for_you parameter to true.

    Creating a plant count is an asynchronous process, after creation the plant count will be processing, and the results can not be accessed until it has completed. This asynchronous process is called a job. To check the job's status, it can either be polled (see below) or a webhook URL can be submitted when starting the plant count; this webhook will be called when the job's status changes. Plant count webhooks only work in automatic mode, "done for you" plant counts can either use polling, or add a project webhook and listen to when the project's plant count is published. See webhooks for more details. Note that "done for you" type plant counts can take up to 24 hours to complete.

    The detection is performed using a detection model. By default, two different models are available:

    In addition, more models might be available on a per-user basis.

    HTTP Request

    POST https://solvi.ag/api/v1/projects/<project-id>/plant_counts

    Parameters

    Parameter Description
    model required The detection model to be used
    detect_rows optional true if row detection should be performed; only supported in automatic scouting plant counts
    request_done_for_you optional true if detection should be done for you by Solvi personel
    webhook optional URL of the webhook to send status updates to

    Plant Count data

    Example request:

    curl 
      -X GET
      -H "Authorization: Bearer <user-jwt-token>" 
      https://solvi.ag/api/v1/projects/<project-id>/plant_counts/<job-id>
    

    Example response:

      {
        "status": "completed",
        "results": [
          "https://solvi-staging-production.s3.eu-west-1.amazonaws.com/uploads/..."
        ]
      }
    

    Gets the status of a previously started plant count, or overview information about a processed plant count.

    Depending on status of the detection job, different HTTP status codes will be used for the response:

    When processing has completed, the response will contain a results property which lists URLs that can be used to get the detection results. These URLs are valid for at least 24 hours. For scouting projects, a detection results in a JSON file containing a summary of the detection, as well as one GeoJSON file per image in the project.

    The results of a detection are kept in storage for one week. After this time, the results are removed from storage and requesting the results will return a 404 code. If a detection is published, the results will be kept in storage.

    Note that "done for you" plant counts in legacy projects, processed before 2023-01-01, the returned result may be a single ZIP archive file containing a Shapefile. In newer projects, the returned data will always be uncompressed data in multiple files.

    Plant Count Webhook

    In addition to polling a plant count for data, you can also register a webhook that will be notified when the plant count has been processed. The webhook URL is specified when you create the plant count. The webhook will sign requests using the project's webhook secret if it is set.

    The webhook will currently only receive a single type of event: job_status_changed. This event triggers when the plant detection job's status changes. It contains:

    There are three different statuses:

    Publishing Plant Counts

    Example request:

    curl 
      -X POST
      -H "Authorization: Bearer <user-jwt-token>" 
      https://solvi.ag/api/v1/projects/<project-id>/plant_counts/<job-id>/publish
    

    Example response:

      {
        "status": "Success",
      }
    

    After a plant count job has completed succesfully, its results can be published. This will achieve two things:

    Listing a Project's Plant Counts

    Example request:

    curl 
      -X GET
      -H "Authorization: Bearer <user-jwt-token>" 
      https://solvi.ag/api/v1/projects/<project-id>/plant_counts
    

    Example response:

      [
        {
          "id": "88a2af8601cf2b7c4e14979f8df73bca7352ccce",
          "status": "completed",
          "created_at": "2019-02-08T09:18:37.655Z",
        },
        {
          "id": "34a2af8601cf2b7c4e14979f8df73bca7352aef43",
          "status": "published",
          "created_at": "2021-03-12T14:33:31.241Z",
        }
      ]
    

    Lists all created plant counts for a project with their id and status. Status is one of:

    Deleting a Plant Count

    Example request:

    curl 
      -X DELETE
      -H "Authorization: Bearer <user-jwt-token>" 
      https://solvi.ag/api/v1/projects/<project-id>/plant_counts/<job-id>
    

    Example response:

      {
        "status": "deleted",
      }
    

    Removes the results of a plant count. Please note that "done for you" plant counts can't be deleted.

    Zonal Statistics

    The Zonal Statistics API lets you create zones in a project and create various statistics for them: primarily various vegetation indices as well as plant count statistics for projects where plant counts have been published.

    Creating and calculating statistics for zones

    Example request:

    curl -X POST
      -H "Authorization: Bearer <user-jwt-token>" 
      -H "Content-Type: application/json"
      -d '{
        "indices": ["vari"],
        "extra_data": {"plant_counts": true},
        "geojson": {
          "type": "FeatureCollection",
          "features": [
            {
              "type": "Feature",
              "properties": {},
              "geometry": {
                "type": "Polygon"
                "coordinates": [
                  [
                    [
                      -115.40068410376747,
                      33.14301501895726
                    ],
                    [
                      -115.40068410376747,
                      33.142561119287876
                    ],
                    [
                      -115.4001781509446,
                      33.142561119287876
                    ],
                    [
                      -115.4001781509446,
                      33.14301501895726
                    ],
                    [
                      -115.40068410376747,
                      33.14301501895726
                    ]
                  ]
                ],
              }
            }
          ]
        }
      }'
      https://solvi.ag/api/v1/projects/<project-id>/zonal_statistics'
    

    Example response:

    {
        "type": "FeatureCollection",
        "features": [
            {
                "type": "Feature",
                "properties": {
                    "vari_p25": -0.12272727489471436,
                    "vari_p75": -0.051350148394703865,
                    "vari_mean": -0.08275701161977407,
                    "vari_median": -0.11009174585342407,
                    "vari_stdev": 0.05680577057554646,
                    "vari_min": -0.1606217622756958,
                    "vari_max": 0.1172839477658
                    [...]
    

    Sets the zones for a project and calculates the provided statistics. The zones should be provided through the geojson parameter: it should contain a GeoJSON FeatureCollection with Polygon features. Other GeoJSON objects or invalid GeoJSON will result in a 400 Bad request response.

    In addition to the zone features, the indices parameter lists the vegetation indices that should be calculated for the zones. The indices should be listed as lowercase abbreviations, for example VARI index should be listed as "vari". Note that the available indices vary depending on the project's bands: for example, NDVI is only available if the project's orthophoto has red and near-infrared (NIR) bands. Listing unknown indices or indices that can't be calculated will also result in a 400 Bad request response.

    For projects with published plant counts, plant count statistics can also be calculated by the optional parameter extra_data, which in this case should be set to {"plant_counts": true}.

    The endpoint responds with a GeoJSON FeatureCollection with the same geometries that were provided, but with properties added for the calculated statistics. This response is also saved with the project, and can be viewed on Solvi's web site, and also later fetched with the GET endpoint below.

    HTTP Request

    POST https://solvi.ag/api/v1/projects/<project-id>/zonal_statistics

    Parameters

    Parameter Description
    indices required List in vegetation indices to calculate; index names should be lower case strings
    geojson required GeoJSON FeatureCollection representing the zone features
    extra_data optional Extra data layers to calculate statistics for, expressed as an object with string layer names as keys and boolean values to indicate if layer should be used

    Getting Zonal Statistics for a project

    Example request:

    curl 
      -X GET
      -H "Authorization: Bearer <user-jwt-token>" 
      https://solvi.ag/api/v1/projects/<project-id>/zonal_statistics
    

    Example response:

    {
        "type": "FeatureCollection",
        "features": [
            {
                "type": "Feature",
                "properties": {
                    "vari_p25": -0.12272727489471436,
                    "vari_p75": -0.051350148394703865,
                    "vari_mean": -0.08275701161977407,
                    "vari_median": -0.11009174585342407,
                    "vari_stdev": 0.05680577057554646,
                    "vari_min": -0.1606217622756958,
                    "vari_max": 0.1172839477658
                    [...]
    

    Fetches any saved zonal statistics for a project. The zones are returned as a GeoJSON FeatureCollection with statistics in each feature's properties. If no zones are defined for this project, a 404 Not found is returned.