EFC Rest API v1.7.0

This API is in active development and is subject to change.

Unless otherwise specified, return type is always application/json. Requests with incompatible Accept headers will receive a 406 Not Acceptable error.

GUIDs must be lowercase and dash delimited (e.g. 01234567-89ab-cdef-0123-456789abcdef).

Table of Contents

Authentication

Authentication is currently only available for server-to-server communications. Direct client-to-server authentication (e.g. directly from a website frontend or a desktop or mobile application) is not yet supported, but a proxy strategy for these use cases is outlined below.

API partner registration is currently a manual process on the EFC side. New API partners are given an api_partner_guid and a private_key hash to prove their identity. This key is stored only on the API partner's server.

You authenticate by providing both of these items. We hash the api_partner_guid with two salts (a partner-specific salt and an internal application salt) to produce what we expect the private_key to be. If it matches the one you supplied, you are authenticated and provided with a time-limited session to use in subsequent requests.

Your private key should never be transmitted directly from client-side software. If at any time you believe your private key has been compromised, we will change your salt value and provide you with a new private_key.

Authentication can be performed either via the dedicated authentication endpoint or ad hoc on any other request. A method for client authentication is discussed below.

Endpoint authentication

A dedicated authentication endpoint is available at GET /auth, with query parameters api_partner_guid and private_key. This will return a JSON object containing your API partner information. The session cookie will be returned via the set-cookie response header, and should be sent via the Cookie request header in subsequent requests.

Ad hoc authentication

The API also supports ad hoc authentication to simplify one-off requests. For any endpoint, the API partner can supply their api_partner_guid and private_key in addition to the normal request data. If authentication passes, this will return the expected response for that endpoint. As with endpoint authentication, a session cookie is returned via the set-cookie response header.

Client-based authentication

The API does not currently support direct client-based authentication, such as from a browser, desktop, or mobile application. In these use cases, the client must proxy the request through the API partner's server, asking the server to perform the requests on its behalf. This is to prevent transmission of the private key over the client's network, which compromises the key.

For example:

$.ajax({
    url: 'http://api-partner-server.com/efc-proxy-handler',
    data: {
        method: 'GET',
        endpoint: '/profile',
        request_data: {
            lat:  40.833262,
            lon: -77.842598,
        }
    },
    success: /* success handler */,
    error: /* error handler */
})

In this example, efc-proxy-handler is a script or service acting as a secure proxy that accepts requests only from expected sources. It forwards the client's request on to the EFC API after appending the api_partner_guid and private_key for ad hoc authentication, and sends the result back to the client.

Version

GET /version

Returns a JSON object with a semver version string and its major, minor, and patch components.

Profiles

GET /profile/top

Returns a JSON array of the top-level profiles the account has access to.

GET /profile/{guid}

Returns a JSON profile object.

GET /profile/{guid}/children

Returns a JSON array of profiles directly under the given profile.

GET /profile/{guid}/crop_areas

Returns a JSON array of the crop areas for the specified profile. Descending order on crop year.

Crop Area Object:

{
    "crop_area_guid": string guid,
    "field_guid": string guid,
    "code": string cdms crop code,
    "year": number,
    "billable_acres": string,
    "cdms_seed_id": string,
    "harvest_date": string date -example "2021-11-01T04:00:00.000Z" or null,
    "planting_date": string date -example "2021-11-01T04:00:00.000Z" or null,
    "active": boolean,
    "created_date": string date -example "2021-11-01T04:00:00.000Z",
    "modified_date": string date -example "2021-11-01T04:00:00.000Z" or null,
    "acres": string,
    "wkt": string,
    "crop": {
        "code": string cdms crop code,
        "name": string,
        "crop_guid": string guid,
        "lbs_per_bushel": number
    },
    "variety": {
        "name": string,
        "seed_guid": string guid,
        "cdms_seed_id": string,
        "sub_crop_name": string,
        "commodity_guid": string guid,
        "commodity_name": string
    } or null
}

GET /profile/{guid}/crop_areas/current

Returns a JSON array of the crop areas for the specified profile. Limited to the latest year.

GET /profile?location_guid={location_guid}&lon={lon}&lat={lat}[&srid={srid}]

Returns a JSON array of profiles (type=field) under the given location that contain the specified point. SRID defaults to 4326.

GET /profile?location_guid={location_guid}&grower={grower}&farm={farm}&field={field}

Returns a JSON array of up to five profiles that most closely match the specified grower/farm/field using a fuzzy search algorithm.

Each result includes four additional values for verification:

GET /profile/modified?after=...

Returns a JSON array of the most recent 250 profiles added or modified since the "after" parameter (required: UNIX Timestamp)

Boundaries

GET /boundary/{guid}[?format={format}][&srid={srid}]

Retrieves the boundary in one of three formats: text (default, WKT), shapefile, or geojson. SRID is optional and defaults to 4326.

PUT /boundary/{guid}

Inserts/Updates a boundary geometry for the given boundary guid profile. Returns the boundary's geometry record.

Request must have Content-Type set to multipart/form-data with the following form data:

POST /boundary/{guid}

No longer used. Entry left for backwards compatibility. Will return a 405 WRONG-VERB error.

Units

GET /units

Returns a JSON array of units.

Field data

GET /field/{field-guid}/sample/{event-guid}[?format={format}]

Retrieves the field sample data in one of two formats: json (default) or xml.

GET /field/{field-guid}/{logged-data-type}/{event-guid}[?format={format}]

Retrieves logged data (asapplied|asplanted|yield) in one of two formats: geojson (default) or zip.

Work orders

GET /workorder/{guid}

Retrieves the work order as a JSON object.

GET /workorder?grower_guid={grower_guid}

Returns matching work orders as a JSON array.

Available Criteria

GET /v2/workorder

Returns a list of workorders as a JSON object

Deprecated

Jobs

GET /job/{guid}

Retrieves the job as a JSON object.

GET /job?{criteria}

Returns matching jobs as a JSON array.

Available Criteria

GET /job/{guid}/lab/checkin/report/{layer_id}

Returns a presigned-link to a Lab Checking Report

Query Params

{
    layer_id: sample layer string -- required in the url path
    guid: guid string  -- required in the url path
}

200 Response

{
    url: string
}

400 Responses

    400 Bad Request - "layer_id" must be supplied in the url
    400 Bad Request - "guid" is required as a query param

403 Response

    403 Forbidden

PUT /job/{guid}/status/{new_status}

Sets job to specified status.

Job Statuses: "Entered", "Accepted", "Assigned", "Prepared", "In-Process", "Completed", "Finalized", "Invoiced", "On-Hold", "Rejected", "Canceled", "Archived"

Query Params

{
    guid: job guid string -- required in the url path
    new: string  -- required in the url path
}

200 Response

{}

400 Responses

    400 Bad Request - Unrecognized "status". Valid status are: "Entered", "Accepted", "Assigned", "Prepared", "In-Process", "Completed", "Finalized", "Invoiced", "On-Hold", "Rejected", "Canceled", "Archived"
    400 Bad Request - No job exists with supplied "guid"
    400 Bad Request - "Archived" jobs can not have their status updated.
    400 Bad Request - Job with status: <jobs current status> can only be updated to the following statuses: <list of allowed statuses>

403 Response

    403 Forbidden

GET /lab-data/{layer_id}

Returns a JSON array of field sample and lab data information that matches the Field Alytics Layer ID

PUT /lab-data/{layer_id}/points

Uploads/Sets the points for the designated sample layer.

Query Params ``` { layer_id: sample layer string -- required in the url path }


Request Body

{ points: [ "sample_id": integer point id "wkt": wkt string geom POINT(lon lat) ] }


200 Response

{}


400 Responses
400 Bad Request - "layer_id" must be supplied in the url
400 Bad Request - "points" body item required
400 Bad Request - One or more point wkts not valid. Reason: <missing sample_id, not a valid point wkt, etc>

403 Response ```
    403 Forbidden

Contact

Please contact fa-support-api@efcsystems.com with any questions.