# Agrology > Agrology is a Delaware Public Benefit Corporation building a predictive agriculture > platform for specialty crops, vineyards and regenerative row-crop operations. In-field > sensor nodes capture ground-truth agronomic telemetry — soil moisture, tension, > conductivity and temperature, air temperature, humidity, vapor pressure deficit, > barometric pressure, total VOCs, CO2 and nitrous-oxide flux — and machine-learning > models turn it into microclimate predictions, synthetic metrics and threshold alerts > for frost, extreme heat, irrigation and smoke taint. This file was GENERATED by API Evangelist from Agrology's own published contract and documentation. Agrology does not serve an llms.txt of its own: https://agrology.ag/llms.txt returns HTTP 200 with the site's single-page-app HTML shell, not a document. ## API at a glance - Name: Agrology Public API v2 - Base URL: https://api.agrology.ag/v2 - Contract: OpenAPI 3.0.1 — 66 paths, 90 operations, 22 component schemas - Contract home: https://github.com/agrology/public-api-docs (Apache-2.0) - Spec: https://github.com/agrology/public-api-docs/blob/main/openapi.yml - Docs: https://github.com/agrology/public-api-docs/blob/main/README.md - Auth: bearer JWT (Authorization header) OR static API key (x-api-key header) - Format: JSON. GeoJSON (RFC 7946) on the three /geojson endpoints. - Status: the provider states the OpenAPI is "under development" and that response schemas "currently lack data typing and are subject to change". ## Getting a credential Two credentials work, and either satisfies every operation. 1. Bearer token — log in at https://grower.agrology.ag/ and click your username in the application footer. The token is a Cognito-issued JWT and EXPIRES ONE HOUR after issue. There is no refresh flow; you return to the portal for a new one. 2. API key — issued by contacting Agrology staff. Send it as `x-api-key`. Self-service key rotation is stated as a roadmap item, not a shipped feature. For unattended machine clients the API key is the only workable option. Identity provider: Amazon Cognito user pool us-east-1_qBmvSfyNK, with OAuth endpoints on https://auth.agrology.ag (authorize, token, userInfo, revoke, logout). OIDC discovery is served only at https://cognito-idp.us-east-1.amazonaws.com/us-east-1_qBmvSfyNK/.well-known/openid-configuration — no agrology.ag host serves a discovery document. ## Start here, always Call `GET /access` first. Authorization is an entity access list, not OAuth scopes: the response tells you which customers, sites and nodes your credential can reach, and your role on each. Every other path is addressed by ids drawn from it. Nothing else can be called safely without it. Identifier shapes are NOT uniform, and the docs say so: older customers and sites use slugs (`agrology`, `austin-research-station`), newer ones use UUIDs, all nodes are UUIDs, and devices are hardware identifiers (`70B3D57BA000163E`). Never validate a customerID or siteID as a UUID. ## The five datasets All five share one addressing scheme (site, optional node or device, time range) and one response envelope. Choosing between them is choosing a provenance: - `historical/ground-truth` — measured by Agrology's own in-field sensors. - `historical/weather` — historical weather service data, sourced from Tomorrow.io. - `synthetics/microclimate` — Agrology ML models applied to past ground truth to synthesize additional metrics (e.g. volumetric water content) over historical time. - `predictions/microclimate` — Agrology statistical model over forecasts plus ground truth. Up to 4 days ahead. - `predictions/weather` — Tomorrow.io forecast. Up to 4 days ahead. ## Time ranges — the part that bites The time range is a PATH SEGMENT, not a query parameter: `{startTime}-{endTime}`. The end time may be omitted (defaults to now) but THE HYPHEN IS STILL REQUIRED. Accepted start/end formats, which may be mixed in one range: - relative: `` where unit is one of s, m, h, d, w — e.g. `6d`, `20m`, `3600s`, `36h`. Compound forms like `2h5m` are NOT supported. - epoch seconds: exactly 10 digits — `1618203722` - epoch milliseconds: exactly 13 digits — `1618203722000` - human minute: exactly 12 digits `yyyyMMddhhmm`, must begin with `20`, UTC — `202108010000` - human second: exactly 14 digits `yyyyMMddhhmmss`, must begin with `20`, UTC — `20210801052530` Digit count is how the format is disambiguated, so zero-pad and never trim. ISO-8601 is NOT accepted as input, even though the alerts endpoint returns ISO-8601 timestamps. Examples: `1618203722-1618290149` (window), `1618203722-` (start to now), `4h-` (last four hours), `6h-4h` (a two-hour window ending four hours ago). ## Metrics are data, not schema Metric ids are a runtime vocabulary. Resolve them before you filter: - `GET /historical/ground-truth/metrics` - `GET /historical/ground-truth/device-types` - `GET /historical/weather/metrics` - `GET /predictions/microclimate/metrics` - `GET /predictions/weather/metrics` - `GET /synthetics/microclimate/metrics` Then filter with comma-separated lists: `?metrics=airTemp,humidity`, `?deviceType=vwc,gV1`, or both: `?deviceType=co2&metrics=co2Concentration`. With no filter you get every device and metric applicable to the site and range. In the response, each sample's `d` object is an OPEN map of metric id to value. Its keys vary by device type and dataset — do not hard-code them, and read units from the metrics endpoint. ## Response envelope ``` { "status": "ok", "request": { "requestTime": ..., "source": ..., "siteId": ..., "responseVersion": "2.1" }, "sites": { "": { "id": ..., "name": ... } }, "devices": { "": { "deviceType": ..., "position": ... } }, "nodes": { "": { "name": ..., "samples": [ { "ts": , "dev": ..., "d": {...} } ] } } } ``` Samples are grouped by node and ordered chronologically WITHIN a node. Node ordering is explicitly not guaranteed and may differ between identical requests — key on node id, never on array position. ## Geometry `GET /geojson/sites`, `GET /geojson/customer/{customerID}`, `GET /geojson/site/{siteID}` return RFC 7946 FeatureCollections. Features carry `properties.elementType` of `site` or `node`; node features carry Point geometry in longitude, latitude order, plus elevation, crops and the attached device inventory. The body also carries templated links — `historicalURL`, `predictionsURL`, `syntheticsURL` — which are the API's only link-following affordance and take you from a mapped node straight to its telemetry. Note the provider's own field spelling: `siteClassificaiton`. Match it as written. ## Files Some responses carry `s3://` locations rather than fetchable URLs. Exchange one for a short-lived pre-signed URL: `GET /fileserver/customer/{customerID}?file=/path/to/file.txt` — the `file` parameter must be urlencoded. Follow the returned URL immediately; do not cache it. ## Things an agent must know before writing - NO IDEMPOTENCY. No Idempotency-Key header exists anywhere. Retrying a timed-out collection POST (experiment, report run, library chart, dashboard, customer input, feedback) creates a DUPLICATE with a new server-assigned id, and there is no documented way to detect or collapse it. PUTs are naturally idempotent because the caller supplies the full key. - ONLY ONE DELETE IS REVERSIBLE. `DELETE /dashboards/{owner}/{id}` can be undone with `POST /dashboards/{owner}/{id}` ("Undelete a specific Dashboard"), and no retention window is published for it. Deletes of experiments, experiment groups, members, metrics, report definitions, library charts and customer inputs have NO undelete. Treat them as permanent. - NO DRY RUN. Nothing supports preview, validate or simulate. - NO PAGINATION. Collections return in full; time-series volume is bounded by the range and the filters, so the range IS your page size. - NO PUBLISHED RATE LIMITS. No X-RateLimit-*, no RateLimit-*, no Retry-After were observed and none is documented. Use conservative concurrency and exponential backoff. - ERRORS ARE UNTYPED. Not one of the 90 operations declares a 4xx or 5xx response. The observed body is the AWS API Gateway default `{"message":"..."}`. The README says a missing credential returns 401; the deployed gateway actually returns 403 with `MissingAuthenticationTokenException`, and 401 is what an INVALID credential returns. Branch on both. - HISTORY IS NOT IMMUTABLE. Agrology publishes a standing policy at https://agrology.ag/model-updates (last reviewed 2026-05-27) stating that model retraining changes values for dates in the PAST as well as the present — readings, recent history and derived aggregates all shift, with no version change and no header to detect it by. If you are building a ledger, a carbon claim or a compliance record, record the fetch time alongside every value and expect restatement. There is no way to pin a model version or query as-of a prior model. - ACCESS GRANTS ARE HIGH CONSEQUENCE. `POST /access/manage/{customerID}/{accessUser}/{accessLevel}` changes who can see a grower's agronomic data. ## Operation groups - Discovery / access: `GET /access`, `GET /access/manage/{customerID}` - Topology: `GET /sites`, `GET /nodes` - Geospatial: the three `/geojson/*` endpoints - Vocabularies: `GET /metrics` and the per-dataset `/metrics` and `/device-types` endpoints - Telemetry: `/historical/ground-truth/*`, `/historical/weather/*`, `/synthetics/microclimate/*` - Predictions: `/predictions/microclimate/*`, `/predictions/weather/*` - Alerts: `GET /alerts/customer/{customerID}` - Files: `/fileserver/*` - Reporting: `/report-definitions/*`, `/report-runs/*` - Experiments: `/experiments/*` (26 operations — experiments, groups, members, metrics, data) - Workspace: `/dashboards/*`, `/library-charts/*`, `/customer-inputs/*` - Support: `POST /feedback` ## What Agrology does not publish No SDKs or client libraries in any registry. No CLI. No Postman collection. No sandbox or test environment. No pricing page or plan tiers — the commercial motion is contact-sales via https://agrology.ag/demo. No status page. No dated changelog (the repository's commit history is the substitute). No deprecation or sunset policy. No SLA. No public MCP server and no A2A agent card. No security.txt, api-catalog or any other well-known document on any Agrology host. No AsyncAPI and no webhooks — alerts are polled from `GET /alerts/customer/{customerID}`. ## Company links - Website: https://agrology.ag - Grower's Portal (login): https://grower.agrology.ag/ - Agrology AI (chat): https://chat.agrology.ag - GitHub: https://github.com/agrology - Blog: https://agrology.ag/blog - Contact: https://agrology.ag/contact — support@agrology.ag - Terms: https://agrology.ag/terms - Privacy: https://agrology.ag/privacy - iOS app: https://apps.apple.com/us/app/agrology/id1566443704 Note: the marketing site is a client-rendered single-page application that answers HTTP 200 with the same HTML shell for every path, including ones that do not exist. Page existence above was established from the application's shipped router manifest, not from status codes. --- Generated 2026-09-13 by API Evangelist (https://apievangelist.com). Sources: https://github.com/agrology/public-api-docs (README.md, openapi.yml), live probes of api.agrology.ag, and the first-party client bundles served at agrology.ag and grower.agrology.ag.