NAV Navbar
php csharp

Introduction

Welcome to the Companion API! You can use our REST API to access Companion API endpoints, which can get information on observations in our database.

You can view code examples in PHP and C# in the dark area to the right.

Replace {{SERVER_PREFIX}} in the described webservices by the right value (depending on the server you are requesting):

Please refer to your point of contact if you have any problem.

Authentication

Companion uses JSON Web Token (JWT) authentication. Companion expects for a JWT to be included in all API requests to the server in a header that looks like the following.

Authorization: Bearer myjwttoken

See how you can generate your JWT below.

Please note that the algorithm used to sign the token is HMAC-SHA256.

Generate JWT

// package NuGet jose-jwt is used here

string payload = JsonConvert.SerializeObject(
    new {
        iss = "your_api_key", // TODO replace value with your credentials
        iat = DateTimeOffset.ToUnixTimeSeconds() // current timestamp
    }
);

string jwt = Jose.JWT.Encode(
    payload,
    System.Text.UTF8Encoding.Default.GetBytes(
        "PleaseKeepItSecret!" // TODO replace value with your credentials
    ),
    JwsAlgorithm.HS256
);

// In this example,
// jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ5b3VyX2FwaV9rZXkiLCJpYXQiOjE1MTYyMzkwMjJ9.hBBy96qEfmEW9OJyaOU5Lcbahszst8KEXFaxlbcvrJk"
<?php
use \Firebase\JWT\JWT; // The following code works with firebase/php-jwt

$payload = [
    'iss' => 'your_api_key', // TODO replace value with your credentials
    'iat' => time() // current timestamp
];

$jwt = JWT::encode(
    $payload,
    'PleaseKeepItSecret!', // TODO replace value with your credentials
    'HS256'
);

// In this example,
// $jwt = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJ5b3VyX2FwaV9rZXkiLCJpYXQiOjE1MTYyMzkwMjJ9.81E1KKRWJk92Qxo6o5sqPk-b583QSfKcbhE0cxsgzy8"
?>

There are three parameters you will need to define to generate a JWT.

The two following data have to be put in what is called the payload, it enables Companion API to identify the access rights for the JWT.

Parameter Description
iss "Issuer": Your api key provided by your point of contact
iat "Issued at": Timestamp (unix time) identifying the time at which the JWT was issued (you should set it to current timestamp when generating JWT)

Then you need to use your secret key provided by your point of contact.

Following the previous indications, you can follow the example on the dark area to generate your JWT.

Your JWT should look like the following: xxxxx.yyyyy.zzzzz

Observations

Get All Observations

The request returns JSON structured like this:

[
    {
        "id": 57174,
        "observation_date": "2019-05-15T10:10:56",
        "latitude": 45.6885045,
        "longitude": 4.7677997,
        "user_id": 10053,
        "username": "AnonUser10053",
        "user_profession": "GROWER",
        "user_photo_path": null,
        "crop_code": "1112",
        "crop_name": "BTH",
        "crop_picture_path": "https://companion.basf.com/images/crops/sww.jpg",
        "seed_id": null,
        "seed_name": null,
        "growthstage_code": 4,
        "growthstage_name": "3 feuilles",
        "growthstage_picture_path": "https://companion.basf.com/images/images/growthstages/sww_3leaves_out.jpg",
        "pest_code": "BASF16",
        "pest_name": "Cicadelles",
        "pest_picture_path": "https://companion.basf.com/images/pests/sww_cicadelle_icon.jpg",
        "meto_code": 14,
        "meto_name": "Quel est le nombre dans vos pièges ?",
        "meto_unit": "Individu(s) dans les pièges.",
        "nota_code": 19,
        "nota_name": "1 à 29",
        "risk_level": 1,
        "comment": null,
        "photo_path": null
    },
    {
        "id": 57175,
        "observation_date": "2019-05-16T15:10:56",
        "latitude": 45.6885045,
        "longitude": 4.7677997,
        "user_id": 10053,
        "username": "AnonUser10053",
        "user_profession": "GROWER",
        "user_photo_path": null,
        "crop_code": "1112",
        "crop_name": "BTH",
        "crop_picture_path": "https://companion.basf.com/images/crops/sww.jpg",
        "seed_id": null,
        "seed_name": null,
        "growthstage_code": 4,
        "growthstage_name": "3 feuilles",
        "growthstage_picture_path": "https://companion.basf.com/images/growthstages/sww_3leaves_out.jpg",
        "pest_code": "BASF16",
        "pest_name": "Cicadelles",
        "pest_picture_path": "https://companion.basf.com/images/pests/sww_cicadelle_icon.jpg",
        "meto_code": 14,
        "meto_name": "Quel est le nombre dans vos pièges ?",
        "meto_unit": "Individu(s) dans les pièges.",
        "nota_code": 19,
        "nota_name": "1 à 29",
        "risk_level": 1,
        "comment": null,
        "photo_path": null
    }
]

This endpoint retrieves all observations that you can access.

HTTP Request

GET {{SERVER_PREFIX}}/api/v1/observations

Headers

Key Prefix Format Description
Authorization Bearer Authorization: Bearer myjwttoken myjwttoken should be replaced by the JWT generated previously.

Query Parameters

All parameters are optional.

Parameter Description
fromDate Format: yyyyMMdd. If defined, observations made before the fromDate won't be returned.
toDate Format: yyyyMMdd. If defined, observations made after the toDate won't be returned.

Response

Name Description
id
observation_date Date when observation was made
Format: yyyy-MM-dd'T'HH:mm:ss
latitude Location's latitude of the observation
longitude Location's longitude of the observation
user_id User ID who made the observation
username Username in Companion
user_profession User's profession
Possible values: GROWER, CROP_ADVISOR, OTHER.
user_photo_path Absolute URL to user profile photo
Can be null if user does not have a profile photo.
crop_code Crop code in Companion
Example: 1112
crop_name Crop name
Example: Wheat
crop_picture_path Absolute URL to crop picture
seed_id ID of the seed related to the pest
Can be null.
seed_name Name of the seed related to the pest
Example: ALIGATOR
Can be null.
growthstage_code Crop's growth stage code in Companion
Can be null.
growthstage_name Crop's growth stage name
Example: 1 node
Can be null.
growthstage_picture_path Absolute URL to growth stage picture
Can be null.
pest_code Pest code in Companion
Example: BASF39
pest_name Pest name
Example: Oidium (Leaves)
pest_picture_path Absolute URL to pest picture
meto_code Methodology code in Companion
Example: 4
Can be null.
meto_name Methodology (usually a question).
Example: Out of 20 stalks, how many are affected ?
Can be null.
meto_unit Methodology unit.
Example: Affected plant base(s) out of 20 observed bases.
Can be null.
nota_code Nota code in Companion
Example: 14
Can be null.
nota_name Notation value (according to methodology).
Example: 1 to 9
Can be null.
risk_level Value from 0 to 3 (lowest to highest).
Example: 2
Can be null.
comment Comment made by the user
Can be null if user has not posted any comment.
photo_path Absolute URL to the observation picture
Can be null if user has not taken any photo.

Errors

Companion API uses conventional HTTP response codes to indicate the success or failure of an API request. In general: Codes in the 2xx range indicate success. Codes in the 4xx range indicate an error that failed given the information provided (e.g., a required parameter was omitted, a charge failed, etc.). Codes in the 5xx range indicate an error with Stripe's servers (these are rare).

Error Code Meaning
400 Bad Request -- Your request is invalid.
This error has different reasons:
- Token could not be read
- Wrong api key in token (which means your api key is not found in Companion database)
- Bad token (which means your JWT generated seems not good, please ensure you use the right secret key)
- Expired token
- fromDate does not conform to expected format : "yyyyMMdd"
- toDate does not conform to expected format : "yyyyMMdd"
401 Unauthorized -- Your authorization key is wrong.
403 Forbidden -- The access to the endpoint requires specific rights.
You can also have this error the case you have tried to call our API at least 10 times during the last hour.
429 Too Many Requests -- You're requesting the server too many times! Slow down!
500 Internal Server Error -- We had a problem with our server. Try again later or refer to your point of access.
503 Service Unavailable -- We're temporarily offline for maintenance. Please try again later.