Submit Custom Device data
POST/api/v1/devices/{deviceId}/data-source/http-server/data
Direct HTTP ingestion of a device's telemetry payload, step 1 of 2 when the
payload includes a blob. The request body has no fixed schema. It is whatever dataPacks/blob
fields the device's DataParser channel config maps, resolved by JSON path (see
.../data-source/data-parser's configs[].dataPacks[].valueObjJsonPath).
Requires DataSource.connectorType == HTTP-Server and the device to be Activated. dataPacks
values are extracted, parsed, and published to the NATS Bus synchronously within this same request.
There is no queueing; a 201 response means the data has already been published. A blob mapping's
value is instead a nested metadata object (see Request Body) that opens a pending upload session
rather than publishing immediately. The caller must then complete the upload with the step-2 PUT
before expiresIn elapses.
Parameters
deviceId(UUID, required, path): Custom device identifier. NoorgIdin the route. This endpoint is org-less; access is gated solely by thehttp-server-data.writeclient-credential scope, not by org role.channel(integer, required, query): Selects one DataParser channel config block.
Request Body
No fixed schema. For each dataPacks/blob mapping configured on the selected channel, the server
reads the value at that mapping's valueObjJsonPath (and timePath, if configured) from this body.
A field mapped as blob must additionally be a nested object shaped like:
contentType(string, required): MIME type of the binary content to be uploaded in step 2.description(string, optional): Description of this blob.downloadFileName(string, required): Suggested filename for the downloaded content.blobMD5(string, required): MD5 checksum of the binary content, verified against the actual bytes uploaded in step 2.blobSize(integer, required): Declared size in bytes, verified against the actual bytes uploaded in step 2. Must be within the configured payload size limit.metadata(object, required): Arbitrary caller-supplied metadata, stored alongside the upload and returned unchanged in the step-2 response.
Responses
201 Created: Payload ingested and published. If no blob mapping matched,dataStreamId/uploadId/downloadUrl/expiresInare allnull. If a blob mapping matched, those four fields are populated for the step-2 upload.400 Bad Request: The payload/blob metadata is malformed, adataPacks/blobmapping's JSON path doesn't resolve against the payload, a configuredtimePath's value is present but isn't a valid Unix-milliseconds number or ISO 8601 string, or the payload exceeds the configured size limit.409 Conflict: The device exists but its current state doesn't allow ingestion: it is notActivated, its DataSourceconnectorTypeis notHTTP-Server, it has no DataParser bound yet, or the requestedchanneldoesn't exist on its DataParser. These are state conflicts on a resource that does exist, not not-found/validation problems.