SoilSense API (beta)

Download OpenAPI specification:

⚠️ Beta Notice

This API is currently in beta. Features, endpoints, and schemas are subject to change before the final release. We appreciate your feedback during this period and recommend pinning to specific behavior only after GA.

API documentation for SoilSense soil monitoring services.

Introduction

To use the SoilSense API, you'll need to create an API key:

  1. Log in to your SoilSense account at app.soilsense.io
  2. Navigate to Settings (cog icon next to the farm name) → Farm
  3. Scroll down to the API KEYS section
  4. Click "Create API Key"
  5. Give your key a name (e.g., "My Integration", "Weather App")
  6. Copy the generated key - you won't be able to see it again!
  7. Store it securely - treat it like a secret password
curl -H "x-api-key: YOUR_API_KEY_HERE" \
     https://api.app.soilsense.io/api/farm

You can try the endpoints out in our Swagger interface at https://api.app.soilsense.io/swagger.

Authentication

All API endpoints require authentication using an API key in the request header:

x-api-key: your_api_key_here

⚠️ Security: Never expose your API key in client-side code or public repositories.

Rate Limits

The API implements universal rate limiting that applies consistently across all endpoints:

All limits are applied per API key (or IP address if no API key is provided):

  • Per second: 20 requests per second
  • Per minute: 600 requests per minute
  • Per hour: 10,000 requests per hour

All three rate limits are enforced simultaneously.

Any single limit can block your request. The rate limit headers in the response show information from the most recently applied rate limiter.

Every response includes rate limit information:

RateLimit-Limit: 600
RateLimit-Remaining: 287
RateLimit-Reset: 2024-06-25T14:30:00.000Z
RateLimit-Policy: 600;w=60
  • RateLimit-Limit: Maximum requests allowed in the current window
  • RateLimit-Remaining: Requests remaining in current window
  • RateLimit-Reset: When the current window resets (ISO 8601)
  • RateLimit-Policy: Rate limit policy in format limit;w=window_seconds

When you exceed any rate limit, you'll receive a 429 status with error message.

Error Handling

The API uses standard HTTP status codes to indicate the success or failure of API calls:

  • 200 OK - Request successful

  • 400 Bad Request - Invalid request parameters

  • 401 Unauthorized - Missing or invalid API key

  • 403 Forbidden - API key valid but lacks permission for this resource

  • 404 Not Found - Resource not found

  • 429 Too Many Requests - Rate limit exceeded

  • 500 Internal Server Error - Server-side error

All error responses follow this JSON format:

{
  "error": "Description of what went wrong"
}
{
  "error": "Rate limit exceeded. Maximum 300 requests per minute."
}

Farm

Retrieve farm information and observation site information

Farm information

Returns basic farm information including observation sites that belong to the farm associated with the API key

Authorizations:
ApiKeyAuth
query Parameters
includeArchived
boolean
Default: false

Whether to include archived observation sites in the response

Responses

Response Schema: application/json
id
required
string

Unique identifier of the farm

name
required
string

Name of the farm

required
object
required
Array of objects

List of observation sites with active status

Request samples

curl -H "x-api-key: YOUR_API_KEY_HERE" \
     https://api.app.soilsense.io/api/farm

Response samples

Content type
application/json
{
  • "id": "farm_123456",
  • "name": "Green Valley Farm",
  • "location": {
    },
  • "observationSites": [
    ]
}

Observation Sites

Returns a simplified list of observation sites with their IDs and basic information

Authorizations:
ApiKeyAuth
query Parameters
includeArchived
boolean
Default: false

Whether to include archived observation sites in the response

Responses

Response Schema: application/json
Array
id
required
string

Unique identifier of the observation site

name
required
string

Name of the observation site

active
required
boolean

Whether the site is currently active (has a data logger assigned)

currentDataLoggerId
number

Current data logger device number (only present if active)

Request samples

curl -H "x-api-key: YOUR_API_KEY_HERE" \
     https://api.app.soilsense.io/api/farm/sites

Response samples

Content type
application/json
[
  • {
    }
]

Observation Site Information

Returns comprehensive information about an observation site including current and historical data source assignments, site metadata, and safe ranges

Authorizations:
ApiKeyAuth
path Parameters
siteId
required
string

ID of the observation site

query Parameters
includeHistory
boolean
Default: false

Whether to include the full observation site history (data source assignments over time)

Responses

Response Schema: application/json
id
string

Site ID

name
string

Site name

object
cropType
string

Type of crop grown at this site

locationType
string

Type of location

frostThreshold
number

Temperature threshold for frost alerts (°C)

frostAlertEnabled
boolean

Whether frost alerts are enabled

object

Safe operating ranges for various measurements

object

Currently active data logger

status
string
Enum: "active" "archived"

Current status of the observation site

Array of objects

Historical data source assignments for this observation site (only included if includeHistory=true)

Response samples

Content type
application/json
{
  • "id": "site_789",
  • "name": "North Field",
  • "coordinates": {
    },
  • "cropType": "Maize",
  • "locationType": "Field",
  • "frostThreshold": 2,
  • "frostAlertEnabled": true,
  • "safeRanges": {
    },
  • "currentDataLogger": {
    },
  • "status": "active",
  • "observationSiteHistory": [
    ]
}

Observations

Retrieve soil observations and precipitation data for observation sites

Soil Observations for a specific observation site

Returns sensor observations for a specific observation site within the specified timestamps. Can optionally include plant available water calculations.

Authorizations:
ApiKeyAuth
path Parameters
siteId
required
string

ID of the observation site

query Parameters
startTime
required
integer <int64>

Start timestamp in milliseconds since epoch

endTime
integer <int64> >= 0

Optional end timestamp in milliseconds since epoch. Leave empty in Swagger UI to use the current server time.

Responses

Response Schema: application/json
Array
timestamp
integer <int64>

Timestamp of the observation in milliseconds since epoch

rssi
number

Signal strength of the device at time of transmission (dBm)

object

Request samples

curl -H "x-api-key: YOUR_API_KEY_HERE" \
     "https://api.app.soilsense.io/api/site/SITE_ID/observations?startTime=1715155200000&endTime=1715241600000"

Response samples

Content type
application/json
[
  • {
    }
]

Precipitation data for a specific observation site

Returns precipitation measurements from rain gauge data for the observation site within the specified timestamps.

Authorizations:
ApiKeyAuth
path Parameters
siteId
required
string

ID of the observation site

query Parameters
startTime
required
integer <int64>
Example: startTime=1715155200000

Start timestamp in milliseconds since epoch

endTime
integer <int64> >= 0

Optional end timestamp in milliseconds since epoch. Leave empty in Swagger UI to use the current server time.

Responses

Response Schema: application/json
Array
timestamp
integer <int64>

Timestamp in milliseconds since epoch

mm
number

Precipitation amount in millimeters

Request samples

curl -H "x-api-key: YOUR_API_KEY_HERE" \
     "https://api.app.soilsense.io/api/site/SITE_ID/precipitation?startTime=1715155200000&endTime=1715241600000"

Response samples

Content type
application/json
[
  • {
    }
]

Latest Soil Observation for a specific observation site

Returns the most recent sensor observation for a specific observation site

Authorizations:
ApiKeyAuth
path Parameters
siteId
required
string

ID of the observation site

Responses

Response Schema: application/json
timestamp
integer <int64>

Timestamp of the observation in milliseconds since epoch

rssi
number

Signal strength of the device at time of transmission (dBm)

object

Request samples

curl -H "x-api-key: YOUR_API_KEY_HERE" \
     https://api.app.soilsense.io/api/site/SITE_ID/observations/latest

Response samples

Content type
application/json
{
  • "timestamp": 1640995200000,
  • "rssi": -75,
  • "data": {
    }
}

Complete Example

const API_KEY = 'YOUR_API_KEY_HERE';
const BASE_URL = 'https://api.app.soilsense.io';

// Get observation sites
const sitesResponse = await fetch(`${BASE_URL}/api/farm/sites`, {
  headers: { 'x-api-key': API_KEY }
});
const sites = await sitesResponse.json();

// Calculate last week timestamps (Unix timestamps in milliseconds)
const endTime = Date.now();
const startTime = endTime - (7 * 24 * 60 * 60 * 1000); // 7 days ago

// Loop through sites with rate limiting in mind
for (const site of sites) {
  // Get site details
  const siteDetailResponse = await fetch(
    `${BASE_URL}/api/farm/site/${site.id}`,
    { headers: { 'x-api-key': API_KEY } }
  );
  const siteDetails = await siteDetailResponse.json();

  // Get observations for last week using Unix timestamps
  const observationsResponse = await fetch(
    `${BASE_URL}/api/site/${site.id}/observations?startTime=${startTime}&endTime=${endTime}`,
    { headers: { 'x-api-key': API_KEY } }
  );
  const observations = await observationsResponse.json();

  console.log(`Site: ${siteDetails.name}, Observations:`, observations);
  
  // Optional: Add small delay between requests to stay well within rate limits
  await new Promise(resolve => setTimeout(resolve, 100)); // 100ms delay
}

Webhooks

Configure webhook URLs in the SoilSense interface under device settings.

SoilSense will automatically send data to your configured endpoints:

  • Telemetry dataPOST {your_webhook_url}/telemetry
  • Device attributesPOST {your_webhook_url}/attributes

Telemetry Webhook (User Implementation)

This endpoint should be implemented by you (the API user).

SoilSense will automatically send sensor telemetry data to {your_webhook_url}/telemetry when new observations are received from your devices.

When you configure a secret key for your webhook, SoilSense will include a signature in the request header:

  • SoilSense-Signature: Contains timestamp and HMAC signature in format t=<unix_ms>,v1=<hex_hmac>

Verify the signature to ensure the request came from SoilSense and wasn't tampered with.

Configure your webhook URL and optional secret key in the SoilSense interface under device settings.

header Parameters
SoilSense-Signature
string
Example: t=1640995200000,v1=a1b2c3d4e5f6789...

Signature for verification (only present if secret is configured). Format: t=<unix_ms>,v1=<hex_hmac>

  • t = signing timestamp in milliseconds since epoch
  • v1 = HMAC-SHA256 over "<t>.<rawBody>" using your shared secret
Request Body schema: application/json
required
ts
required
integer <int64>

Unix timestamp in milliseconds

required
object

Sensor measurement values (undefined values are omitted)

Responses

Request samples

Content type
application/json
{
  • "ts": 1640995200000,
  • "values": {
    }
}

Attributes Webhook (User Implementation)

This endpoint should be implemented by you (the API user).

SoilSense will automatically send observation site attributes to {your_webhook_url}/attributes when sites are created or modified.

Uses the same security protocol as the telemetry webhook. See the telemetry endpoint documentation for verification examples.

Configure your webhook URL and optional secret key in the SoilSense interface under device settings.

header Parameters
SoilSense-Signature
string
Example: t=1640995200000,v1=a1b2c3d4e5f6789...

Signature for verification (only present if secret is configured). Format: t=<unix_ms>,v1=<hex_hmac>

Request Body schema: application/json
required
siteId
required
string

Unique identifier of the observation site

siteName
required
string

Name of the observation site

required
object
cropType
string

Type of crop at this observation site

locationType
string

Type of location

frostThreshold
number

Temperature threshold for frost alerts (°C)

frostAlertEnabled
boolean

Whether frost alerts are enabled for this site

object

Sensor configuration

deviceNumber
required
string

Data logger device number assigned to this site

deviceName
string

Display name of the data logger device

farmId
required
string

Unique identifier of the farm

updatedAt
required
string <date-time>

ISO timestamp when the site was last updated

Responses

Request samples

Content type
application/json
{
  • "siteId": "site_123456",
  • "siteName": "North Field",
  • "coordinates": {
    },
  • "cropType": "Maize",
  • "locationType": "Field",
  • "frostThreshold": 2,
  • "frostAlertEnabled": true,
  • "configuration": {
    },
  • "deviceNumber": "12345",
  • "deviceName": "Data Logger 12345",
  • "farmId": "farm_123456",
  • "updatedAt": "2023-12-01T10:30:00.000Z"
}