Quickstart
Before you start
Activate the terminal. Send the activation code and the identifier the terminal was registered with. This is the only request that needs no credential.
curl -X POST https://device-narya-staging.pmadvisors.my/device/v1/activations \
-H 'Content-Type: application/json' \
-d '{"activation_code": "48392105", "device_identifier": "SN-0001"}'A 201 response contains the device token:
{
"device_id": "0192f6c4-8a1e-7b3d-9c2a-5e4f1a2b3c4d",
"credential_id": "0192f6c4-8a1f-7c11-a2b3-c4d5e6f7a8b9",
"token": "dvc_<prefix>_<secret>",
"issued_at": "2026-10-16T08:00:00Z"
}Store the token. Save token in secure storage on the terminal. Narya returns it only once. Send it on every other request as Authorization: Bearer <token>.
Send a heartbeat. Only reported_at, platform and device_state are required.
curl -X POST https://device-narya-staging.pmadvisors.my/device/v1/heartbeats \
-H 'Authorization: Bearer dvc_<prefix>_<secret>' \
-H 'Content-Type: application/json' \
-d '{"reported_at": "2026-10-16T08:00:00Z",
"platform": {"os_name": "Android", "os_version": "11", "timezone_offset": "+08:00"},
"device_state": {"uptime_seconds": 3600}}'A 200 response lists the applications and parameters the terminal should hold.
Check for changes between heartbeats. Call GET /device/v1/applications and save the ETag header from the 200 response. On the next call, send that value in If-None-Match exactly as you received it, including the quotes. A 304 with no body means nothing has changed.
curl https://device-narya-staging.pmadvisors.my/device/v1/applications \
-H 'Authorization: Bearer dvc_<prefix>_<secret>' \
-H 'If-None-Match: <etag>'Do the same with GET /device/v1/parameters.
Next, read the integration flow for every call a terminal makes and when.