Usa HTTPS cuando un dispositivo no pueda mantener una conexión MQTT: dispositivos con batería que se despiertan, envían y vuelven a dormir, o redes que bloquean MQTT. Los mensajes HTTP se gestionan exactamente igual que los mensajes MQTT: las mismas formas de payload, las mismas reglas de claves, los mismos límites de tasa y el mismo recuento mensual de mensajes. Esta página enumera todos los endpoints a los que puede llamar un dispositivo.
Conceptos básicos
| Elemento | Valor |
|---|---|
| Dirección base | La dirección de telemetría HTTPS en la tarjeta Detalles de conexión del dispositivo: el host de dispositivos de la plataforma en el puerto 443 |
| Inicio de sesión | Authorization: Bearer <device access token> |
| Tipo de contenido | application/json; charset=utf-8 |
| Tamaño del cuerpo | Hasta 64 KiB (el límite de payload del perfil) |
| HTTP sin cifrar | El puerto 80 funciona donde tu instalación lo ofrezca, pero los comandos entonces están limitados (ver más abajo). Usa HTTPS. |
El token nunca va en la URL, salvo en los perfiles que activan Token en la URL (ver más abajo). Los certificados de cliente no se usan en la API HTTP: los dispositivos que inician sesión con X.509 usan MQTT. Cualquier ruta que no aparezca aquí responde 404.
Endpoints
| Método | Ruta | Igual que MQTT | Cuerpo o consulta | Respuesta |
|---|---|---|---|---|
| POST | /api/v1/telemetry | v1/telemetry | un payload de telemetría | 200 |
| POST | /api/v1/attributes | v1/attributes | un objeto de atributos de cliente | 200 |
| GET | /api/v1/rpc?timeout=20000 | v1/rpc/req/{id} | long poll, hasta 60 s | un comando {"id":n,"method":…,"params":…} |
| POST | /api/v1/rpc/{id} | v1/rpc/res/{id} | la respuesta del comando | 200 |
| POST | /api/v1/rpc | v1/rpc/up/req/{id} | {"method":…,"params":…} | la respuesta de la nube |
| POST | /api/v1/provision | v1/provision/req | una solicitud de aprovisionamiento, sin cabecera bearer | la respuesta de aprovisionamiento |
| POST | /api/v1/hello | v1/hello | la autodescripción del dispositivo | usado por el firmware de dispositivos licenciados |
No disponible por HTTP: leer atributos (GET /api/v1/attributes), esperar cambios de atributos compartidos, abrir la ventana de reclamación y pedir firmware. Estas rutas responden 404. Los dispositivos que las necesiten usan MQTT.
La telemetría usa las mismas formas de payload que MQTT. Consulta Referencia de temas y payloads MQTT. Un cuerpo en POST /api/v1/telemetry que no sea JSON se guarda como una única clave raw (hasta el tamaño raw del perfil, 4 KB por defecto).
Detalles del endpoint
POST/api/v1/telemetry
Envía telemetría. Usa cualquier forma de payload: un objeto plano, un objeto con ts y values, o un array de ambos. Envía Authorization: Bearer <device access token>. La respuesta 200 llega solo después de que el mensaje esté puesto en cola de forma segura; su cuerpo está vacío.
Cuerpo de la solicitud application/json
{
"ts": 1759572000000,
"values": {
"temperature": 21.5,
"humidity": 40
}
}
Ejemplo curl
curl -X POST 'https://<your-host>/api/v1/telemetry' \
-H 'Content-Type: application/json' \
-d '{"ts":1759572000000,"values":{"temperature":21.5,"humidity":40}}'
Respuestas
200OK
Sin cuerpo de respuesta.
400Bad Request
{
"error": "invalid_payload"
}
401Unauthorized
Sin cuerpo de respuesta.
413Payload Too Large
{
"error": "payload_too_large"
}
429Too Many Requests
{
"error": "rate_limited"
}
503Service Unavailable
Sin cuerpo de respuesta.
POST/api/v1/attributes
Envía atributos de cliente. Solo cambian las claves que envíes.
Cuerpo de la solicitud application/json
{
"current_fw_title": "boiler-fw",
"current_fw_version": "26.10.2",
"lan.ip": "192.168.1.1"
}
Ejemplo curl
curl -X POST 'https://<your-host>/api/v1/attributes' \
-H 'Content-Type: application/json' \
-d '{"current_fw_title":"boiler-fw","current_fw_version":"26.10.2","lan.ip":"192.168.1.1"}'
Respuestas
200OK
Sin cuerpo de respuesta.
400Bad Request
{
"error": "invalid_payload"
}
401Unauthorized
Sin cuerpo de respuesta.
429Too Many Requests
{
"error": "rate_limited"
}
GET/api/v1/rpc?timeout=20000
Espera el siguiente comando para este dispositivo (long poll, como máximo 60 segundos). Solo puede haber una consulta abierta por dispositivo a la vez. Sobre una conexión sin TLS, un perfil que no permite ningún comando sin TLS responde 403.
Ejemplo curl
curl -X GET 'https://<your-host>/api/v1/rpc?timeout=20000'
Respuestas
200OK
{
"id": 42,
"method": "sys.ping",
"params": {
"host": "8.8.8.8",
"count": 3
}
}
403Forbidden
{
"error": "tls_required"
}
408Request Timeout
{
"error": "timeout"
}
409Conflict
{
"error": "poll_in_progress"
}
POST/api/v1/rpc/{id}
Responde al comando con este id. Usa el mismo cuerpo que en MQTT v1/rpc/res/{id}.
Cuerpo de la solicitud application/json
{
"ok": true,
"result": {
"sent": 3,
"received": 3,
"avg_ms": 18.2
}
}
Ejemplo curl
curl -X POST 'https://<your-host>/api/v1/rpc/{id}' \
-H 'Content-Type: application/json' \
-d '{"ok":true,"result":{"sent":3,"received":3,"avg_ms":18.2}}'
Respuestas
200OK
Sin cuerpo de respuesta.
413Payload Too Large
{
"error": "payload_too_large"
}
POST/api/v1/rpc
Envía una solicitud desde el dispositivo a la nube, con method y params. Tus flujos la responden; la respuesta es el cuerpo de la respuesta. Si no llega respuesta en 10 segundos, la llamada responde 408. Un cuerpo sin method responde 400.
Cuerpo de la solicitud application/json
{
"method": "app.request",
"params": {}
}
Ejemplo curl
curl -X POST 'https://<your-host>/api/v1/rpc' \
-H 'Content-Type: application/json' \
-d '{"method":"app.request","params":{}}'
Respuestas
200OK
Sin cuerpo de respuesta.
400Bad Request
Sin cuerpo de respuesta.
408Request Timeout
{
"error": "timeout"
}
POST/api/v1/provision
Registra un dispositivo con la clave y el secreto de aprovisionamiento de su perfil. No envíes cabecera bearer. La llamada responde 200 con la respuesta de aprovisionamiento; un rechazo también responde 200, con "status": "FAILURE" y el motivo en hermetry.error (por ejemplo {"status": "FAILURE", "hermetry": {"error": "rate_limited"}}). Consulta Añadir y reclamar dispositivos.
Cuerpo de la solicitud application/json
{
"deviceName": "boiler-07",
"provisionDeviceKey": "pk_8f3b2c1e9d4a7b60",
"provisionDeviceSecret": "ps_1c9e7f2a4b6d8e03"
}
Ejemplo curl
curl -X POST 'https://<your-host>/api/v1/provision' \
-H 'Content-Type: application/json' \
-d '{"deviceName":"boiler-07","provisionDeviceKey":"pk_8f3b2c1e9d4a7b60","provisionDeviceSecret":"ps_1c9e7f2a4b6d8e03"}'
Respuestas
200OK
{
"status": "SUCCESS",
"credentialsType": "ACCESS_TOKEN",
"credentialsValue": "aZ3…"
}
413Payload Too Large
{
"error": "payload_too_large"
}
503Service Unavailable
Sin cuerpo de respuesta.
Ejemplos
Envía una lectura, sellada por el servidor:
curl -X POST "https://<device host>/api/v1/telemetry" \
-H "Authorization: Bearer <ACCESS_TOKEN>" \
-H "Content-Type: application/json" \
-d '{"temperature": 21.5, "humidity": 40}'
Envía lecturas almacenadas en búfer con sus propios tiempos (milisegundos desde 1970, UTC):
curl -X POST "https://<device host>/api/v1/telemetry" \
-H "Authorization: Bearer <ACCESS_TOKEN>" \
-H "Content-Type: application/json" \
-d '[{"ts":1759572000000,"values":{"temperature":21.5}},{"ts":1759572060000,"values":{"temperature":21.7}}]'
Espera un comando y respóndelo:
curl -s "https://<device host>/api/v1/rpc?timeout=30000" -H "Authorization: Bearer <ACCESS_TOKEN>"
# → {"id": 42, "method": "sys.ping", "params": {...}}
curl -X POST "https://<device host>/api/v1/rpc/42" \
-H "Authorization: Bearer <ACCESS_TOKEN>" -H "Content-Type: application/json" \
-d '{"ok": true, "result": {"sent": 3, "received": 3}}'
Códigos de estado
| Código | Significado |
|---|---|
| 200 | Aceptado. Se envía solo después de que el mensaje esté puesto en cola de forma segura. |
| 400 | Payload no válido. |
| 401 | Token ausente o desconocido. |
| 403 | Dispositivo deshabilitado, organización suspendida, dirección fuera de las redes permitidas del perfil, o una consulta de comandos por HTTP sin cifrar que el perfil no permite (tls_required). |
| 404 | Ruta desconocida, o un token en la URL en un perfil sin Token en la URL. |
| 408 | El long poll terminó sin datos, o una solicitud del dispositivo no obtuvo respuesta en 10 segundos. |
| 409 | Ya hay otra consulta de comandos de este dispositivo abierta. |
| 413 | Cuerpo demasiado grande. |
| 429 | Límite de tasa, o demasiadas solicitudes o inicios de sesión fallidos desde tu dirección. Espera los segundos indicados en Retry-After. |
| 503 | Sobrecarga. Espera los segundos indicados en Retry-After. |
Estado de conexión para dispositivos HTTP
Los dispositivos HTTP no mantienen una conexión, así que un perfil con Conexión en vivo nunca los muestra en línea. Asigna a los dispositivos HTTP un perfil con Mensaje reciente (en línea mientras el último mensaje sea más reciente que el intervalo esperado multiplicado por el factor) o Solo última conexión. Consulta Estado de conexión y actividad.
Dispositivos que no pueden enviar cabeceras
Algunos dispositivos no pueden definir una cabecera Authorization. Para ellos, active Token in the URL en la pestaña Transport & auth del perfil. Entonces los dispositivos podrán usar:
POST /api/v1/{token}/telemetry
POST /api/v1/{token}/attributes
Advertencia
Un token en una URL puede filtrarse a través de los registros de proxy y del historial del navegador. Un perfil con este interruptor activado es solo HTTP: sus dispositivos no pueden iniciar sesión por MQTT y nunca reciben comandos. Asigne a los dispositivos que puedan enviar cabeceras un perfil sin este interruptor.
Comandos sobre HTTP sin cifrar
Una consulta larga (long poll) que no llega a Hermetry por TLS recibe solo los comandos que el perfil enumera en Commands allowed without TLS. Cualquier otro comando espera a una conexión TLS o a que expire. Si la lista está vacía, una consulta sin cifrar responde 403 tls_required.

