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 the real-time cache and stored with a 2-minute TTL.
- POST: Device gateways pushing uplink payloads into Yanji IoT Cloud. The API validates factor IDs, enriches missing fields, and forwards the data to the ingestion queue 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: the telemetry cache exposes a map of
agri_id -> field/valuedictionaries. - 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. - Queues the transformed batch to the ingestion pipeline.
If the queue operation fails, the API raises APIException and returns HTTP 503 with the error message.
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 |
| 503 | DATA_PIPELINE_FAILURE | Failed to enqueue data to the ingestion pipeline (POST only) |
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.
