Skip to main content

Subscribe to alerts

This document describes the MQTT messaging interface for the Angible Edge Backend service.

Table of Contents​


Connection Information​

MQTT Broker​

ParameterValue
HostThe AI Box's IP address on your store network
Port1883
ProtocolMQTT v3.1.1
TLSDisabled
QoS0
Client IDYour sco_id

Topic Structure​

Available Topic List (AI Box -> SCOs)​

The transaction event scan-completed triggers the AI to review the transaction, you can expect a message on exactly one of these two topics after sending out the request.

TopicDescription
angible/v1/events/{sco_id}/alertsAI alert events for an SCO
angible/v1/events/{sco_id}/no-alertNo alert events for an SCO

Message Schema​

AI Alerts​

Topic: angible/v1/events/{sco_id}/alerts Format: JSON

The most useful thing in this payload is the image — enough to show staff or the customer what the AI flagged. For your resolution popup, use issue_items[].image_path — fetch it with Get an image, passing your session token header. (additional_info.image_urls is a separate, older field kept for compatibility with a previous alert format — see the field tables below; don't treat it as an equivalent substitute for issue_items[].image_path.) The rest of the fields mostly just help you match the alert back to your own transaction records.

If you'd rather not make a separate call per image, we can instead embed it directly in this payload as base64 — ask us to enable base64 image embedding, which adds image_base64 (and scanned_image_base64, images_base64) alongside the path fields, no extra API call needed.

Schema​
{
"alert_id": "555499d2-f8d9-49f3-ada8-434901657976",
"alert_type": "Item Left",
"transaction_id": "6ae1a7e792f350bcfcdc0ca8",
"sco_transaction_id": "txn-987654",
"description": "Alert: item_left",
"severity": "high",
"timestamp": 1742355063000,
"video_url": null,
"issue_items": [
{
"item_id": "123",
"item_name": null,
"image_path": "/v1/images/sco_popup_850228_0_3699.jpg",
"timestamp": 1742355063000,
"scanned_item_id": null,
"scanned_item_name": null,
"scanned_image_path": null
}
],
"sco_id": "SCO_ID_1",
"sco_name": "Self-Checkout 1",
"additional_info": {
"camera_id": "camera_1",
"image_urls": ["/v1/images/alert_850228_0_3699.jpg"],
"video_url": null
}
}
Field Definitions​
FieldTypeDescription
alert_idstringUnique identifier for the alert
alert_typestringType of alert, as a display label (e.g., Item Left) — not a fixed enum, so don't match on exact casing
transaction_idstringInternal transaction identifier
sco_transaction_idstring | nullTransaction identifier assigned by the SCO. null if the matching transaction record could no longer be found when the alert was published (e.g. reset or expired)
descriptionstringHuman-readable explanation of the alert
severitystringAlways high today; the field exists for future differentiation
timestampintegerTimestamp in milliseconds since the Unix epoch
video_urlstring | nullFor older integrations only. Always null for new integrations
issue_itemsarrayList of items that triggered the alert
sco_idstringIdentifier of the SCO
sco_namestringDisplay name of the SCO
additional_infoobject | nullCamera/media context for the alert
Issue Item Object​
FieldTypeDescription
item_idstringAn AI-tracking ID for this flagged item. Not the same item_id you sent via item-added — treat it as an opaque token and echo it back as-is when reporting the resolution (Update Alert)
item_namestring | nullName of the item
image_pathstringThe image to show in your resolution popup for this item. Uses the AI's zoomed-in popup crop when available; falls back to the original (un-cropped) image if no crop was captured
image_base64string | nullBase64-encoded item image. Omitted when not enabled
timestampintegerTimestamp in milliseconds since the Unix epoch
scanned_item_idstring | nullReserved for a future feature. Always null for now
scanned_item_namestring | nullReserved for a future feature. Always null for now
scanned_image_pathstring | nullReserved for a future feature. Always null for now
scanned_image_base64string | nullReserved for a future feature. Always omitted for now

Note: The scanned_* fields above are reserved for a feature that isn't available yet — no need to handle them differently from null/absent today.

Additional Info Object​
FieldTypeDescription
camera_idstringIdentifier of the camera that captured the event
image_urlsarray of string | nullKept for compatibility with an older alert format; has no item ID of its own. Same order as issue_items, but always the original (un-cropped) image, never the popup crop. Use issue_items[].image_path for your resolution popup instead — don't treat this as an equivalent
video_urlstring | nullFor older integrations only. Always null for new integrations
images_base64array of string | nullList of base64-encoded images. Omitted when not enabled

Note: image_base64 and images_base64 are only present when base64 image embedding is enabled in the edge settings; otherwise they are omitted from the payload.


No Alert​

Topic: angible/v1/events/{sco_id}/no-alert Format: JSON

Schema​

{
"transaction_id": "txn-123456",
"sco_transaction_id": "sco-txn-987654",
"timestamp": 1742355063000
}

Field Definitions​

FieldTypeDescription
transaction_idstringUnique identifier for the transaction
sco_transaction_idstring | nullTransaction identifier assigned by the SCO
timestampintegerTimestamp in milliseconds since the Unix epoch

Python Example​

This section demonstrates how to connect to the MQTT broker and subscribe to alert events using the paho-mqtt library.

Prerequisites​

  • Python 3.11 or higher
  • paho-mqtt library

Subscriber Example​

import json
import paho.mqtt.client as mqtt

# Configuration
MQTT_HOST = "x.x.x.x" # Replace with the AI Box's IP address on your store network
MQTT_PORT = 1883 # Default MQTT port
SCO_ID = "SCO_ID_1" # Your SCO device ID
CLIENT_ID = SCO_ID # Use your sco_id as the client ID
TOPIC = f"angible/v1/events/{SCO_ID}/alerts" # Subscribe to alerts for your SCO


def on_connect(client, userdata, flags, rc, properties=None):
if rc == 0:
client.subscribe(TOPIC, qos=0)


def on_message(client, userdata, msg):
payload = json.loads(msg.payload.decode("utf-8"))
# Process the alert payload here


def on_disconnect(client, userdata, rc, properties=None):
pass


def main():
client = mqtt.Client(
client_id=CLIENT_ID,
protocol=mqtt.MQTTv311,
callback_api_version=mqtt.CallbackAPIVersion.VERSION2,
)

client.on_connect = on_connect
client.on_message = on_message
client.on_disconnect = on_disconnect

client.connect(MQTT_HOST, MQTT_PORT, keepalive=60)
client.loop_forever()


if __name__ == "__main__":
main()