Appearance
Device Data
Overview
The device data endpoint serves two audiences (fields mentioned below follow the Field Reference):
- GET: Frontend dashboards that need the latest readings for a device and any chained sub-devices. Data is sourced from Cloudflare D1 real-time database with a 2-minute cache TTL.
- POST: Device gateways pushing uplink payloads into YenGear IoT Cloud. The API validates factor IDs, enriches missing fields, and forwards the data to both SQS queue and Cloudflare D1 for downstream processing.
- Base Path:
/api/v2/projects/{project_id}/devices/{device_pk}/data/
Endpoint Summary
| Method | Purpose | Notes |
|---|---|---|
| GET | Return latest cached telemetry for the device and its child factors | See GET Device Data for parameters and cache behavior. |
| POST | Accept telemetry payloads from device clients | See POST Device Data for payload rules and enrichment. |
GET Device Data
http
GET /api/v2/projects/{project_id}/devices/{device_pk}/data/
Authorization: Bearer <token>Query Parameters
None. The endpoint automatically aggregates every factor whose agri_id starts with the device’s agri_id (covering sub-devices or modules).
Response
json
[
{
"agri_id": "d-1000-abcd-01",
"temp": 23.5,
"humi": 46.2,
"t": 1708070400
},
{
"agri_id": "d-1000-abcd-02",
"switch": 1,
"t": 1708070340
}
]Fields are flattened; each key represents a factor value stored in the real-time cache. t (if present) is a UNIX timestamp in UTC seconds. If the cache returns no data, the API responds with an empty list.
Behavior
- Cache key:
device_data_<device.agri_id>with 120-second TTL. - Data source: Cloudflare D1
factor_datatable, queried byagri_idprefix. - Filtering: Only entries whose
agri_idstarts with the device'sagri_idare returned, covering the main controller plus sub-units.
POST Device Data
http
POST /api/v2/projects/{project_id}/devices/{device_pk}/data/
Authorization: Bearer <token>
Content-Type: application/json
[
{ "agri_id": "d-1000-abcd-01", "value": 24.3, "t": 1708070400 },
{ "agri_id": "d-1000-abcd-02", "value": 68.2 }
]Payload Rules
| Field | Type | Required | Notes |
|---|---|---|---|
agri_id | string | Yes | Must start with the parent device agri_id (e.g., d-1000-abcd); otherwise the row is skipped |
value / arbitrary keys | number/string | Yes | Key/value pairs representing factor readings |
t | integer | No | UTC timestamp (seconds). If missing or invalid, server fills current UTC time |
Server-side Enrichment
For each valid row:
- Looks up factor metadata by
agri_id. - Injects
the_typefrom the factor definition. - Adds
project_idandorg_id(organization slug) to the payload. - Fills
twith current UTC timestamp if missing or invalid.
Data Pipeline
The validated data is sent to two destinations in parallel:
- AWS SQS Queue: For asynchronous processing by Lambda functions (rule engine, MongoDB storage, alerts, etc.)
- Cloudflare D1: For real-time data queries via GET endpoint. Each
agri_idkeeps only the latest value (UPSERT).
If SQS or D1 operations fail, the error is logged but does not block the response. The API returns successfully processed data.
Sample Response
json
[
{
"agri_id": "d-1000-abcd-01",
"value": 24.3,
"t": 1708070400,
"the_type": "temp",
"project_id": "greenhouse-alpha",
"org_id": "yanji-lab"
}
]Only rows that pass validation are returned. Invalid entries (missing agri_id, mismatched prefix, or unknown factor) are dropped silently to keep ingestion resilient.
Error Codes
| Status | Code | Description |
|---|---|---|
| 400 | BAD_REQUEST | Malformed JSON array or unsupported field types |
| 401 | UNAUTHORIZED | Missing/invalid token |
| 403 | FORBIDDEN | Token lacks access to the project/device |
| 404 | DEVICE_NOT_FOUND | Device PK not in project or disabled |
Operational Notes
- Prefix Enforcement: The server rejects samples whose
agri_iddoes not start with the parent device’sagri_id, preventing data leakage across devices. - Silent Drops: Invalid rows are skipped without aborting the entire batch. Always inspect the response to know which entries were accepted.
- Idempotence: The API does not deduplicate payloads. Include timestamps (
t) to help downstream services detect duplicates. - Rate Limits: Reuse the same batching strategy as other POST APIs (60 rpm burst). Large deployments should aggregate readings before posting.
- Data Consistency: GET responses may lag POST payloads by up to the cache refresh interval. For real-time monitoring, pair GET
/data/with Factor Data endpoints when historical context is needed.
