Skip to main content
This is the contract every MQTT-capable device — ESP32 or otherwise — must implement to connect to PumpLink.

Connection

  • Broker: mqtt.pumplink.dev
  • Port: 41102
  • Transport: TLS required. Plain TCP is not accepted for external connections.
  • Credentials:
    • Username: the device’s numeric database ID, as a string.
    • Password: the 24-byte plaintext token shown once in the admin portal when you register a device or regenerate its credentials. It’s bcrypt-hashed server-side and never recoverable after that — your provisioning flow must capture it and burn it into firmware or device config at manufacture or setup time.
  • Client ID: unconstrained. Not checked by the backend.
Credentials are issued once and never recoverable. If you lose the plaintext token, you must regenerate credentials from the admin portal and reflash the device. Store it securely at provisioning time.
You can test your device connection using any MQTT client such as MQTT Explorer. Connect to mqtt.pumplink.dev on port 41102 with TLS enabled, using your device’s username and password. Subscribe to device/{id}/# to observe all traffic for your device.

Topics

All topics are scoped to device/{deviceID}/. The ACL denies anything outside this prefix. There are no JSON envelopes anywhere in this contract — all three topics carry bare strings.

Activation handshake

This is the core contract every device must implement:
1

Subscribe

Device subscribes to device/{id}/command.
2

Backend activates

On POST /activate, the backend publishes "on" (QoS 2, not retained).
3

Device must ack

The device must publish anything to device/{id}/ack within 10 seconds. If it doesn’t, the backend aborts, publishes "off", and returns a 504 to the caller.
4

Device runs until told to stop

The device runs until it receives "off" on the command topic. There’s no session-duration or quota message sent to the device — the backend’s own timer decides when to cut it off. Quota exhaustion, admin force-shutdown, and timer expiry all just result in an unsolicited "off".
No ack is expected or required for "off".

Client behavior expectations

  • Retained messages: none, on any topic.
  • Keepalive / clean session: no specific requirement is enforced by the backend.
No LWT (Last Will and Testament) is wired up. If a device disconnects ungracefully, the backend has no way to know unless the device proactively publishes "off" to its own status topic before going dark.If you want “power loss → session ends” behavior, you have two options:
  • Configure an LWT pointing at mqtt.pumplink.dev on your MQTT client, or
  • Have the device publish "off" on graceful shutdown.

Quota

Per-device, window-based quota is entirely server-side. The device is quota-blind and just responds to on/off commands.