Cloudloop (Iridium)
Cloudloop by Ground Control is the platform behind RockBLOCK Iridium modems. An OpenCollar with a RockBLOCK sends its satellite buffer over Iridium Short Burst Data; Cloudloop delivers every message to a webhook and relays commands back (architecture 25.9, decision D78).
Built from the Cloudloop knowledge base and its public Postman collection (fetched
2026-09-04); the API calls were confirmed against Smart Parks' account on 2026-09-09 (ping,
things, subscribers, hardware, groups and destinations). On 2026-09-10 the webhook path was
proven live: a destination created through the API (Data/CreateHttpDestination, format
CONTENT_TYPE_HTTP_LINGO, added to the All Things group with Data/DoAddDestination),
Cloudloop's own Data/DoTestDestination delivered to the dev server through the address
allow-list, and a real 42 byte collar message replayed through the webhook decoded into a
GNSS fix and a status message (fixtures under tests/fixtures/payloads/cloudloop/). A message
from a collar in the field and a command wait for a collar to wake.
Setup
- Under Server admin, Data sources: New data source, adapter Cloudloop (Iridium). Config:
allowed_source_ips(Cloudloop posts from35.178.100.117and52.56.155.169, confirmed live on 2026-09-10; leave the list empty to accept any address; the check uses the address the reverse proxy saw, so a caller cannot forge it),web_urlfor deep links. Credentials:token, the account's API token (requested from Ground Control support, regenerated withUser/DoGenerateToken), needed for commands and the thing list only. - Copy the webhook URL shown once after saving. It carries the source's token as
?token=...because Cloudloop sends no authentication header. - In Cloudloop Data, add an HTTP Webhook destination with that URL and format JSON (Lingo),
the recommended one, and add it to a thing group (a group can post to several destinations,
so an existing pipeline keeps its own). The destination shows grey until its first delivery
and green after; "Send test message" on it (or
Data/DoTestDestinationwith a thing) posts a text payload, which arrives as a failed source event of that thing's device, the proof that the URL, the token and the address list work. Cloudloop expects HTTP 200 within five seconds and retries with exponential backoff for about twelve hours. - The IMEI of the RockBLOCK is the device identity (type
imei). Link it to the collar, or accept it from Needs attention when the first message arrives. The Cloudloop thing id arrives as an identity attribute with the first message; the deep link and commands use it.
Inbound SBD
A LingoMO message becomes one source event on the Iridium channel:
| Lingo field | Smart Parks Protect |
|---|---|
identity.hardware.imei, sbd.imei |
identity imei |
identity.thingId, identity.subscriber.*, identity.hardware.* |
identity attributes (thing_id, subscriber_id, hardware_type, serial) |
message (base64) |
data_hex for the device driver, untouched |
sbd.sessionAt |
satellite_delivered_at, provenance only |
receivedAt |
network_received_at |
sbd.momsn, sbd.mtmsn, sbd.status, sbd.location (Iridium geolocation with cep) |
the satellite session (ADR 0023); sbd.cdrReference stays provider metadata |
| a message without payload | event type sbd_session, kept raw, nothing decoded |
The deprecated Core and form shapes (imei, momsn, transmit_time, data in hex) are
accepted too. The OpenCollar driver reads the payload as stacked stored records
([port][msg_id][len][data][timestamp], the flash storage format the satellite buffer uses),
so the record's own timestamp stays canonical and a fix that also came over LoRaWAN is one
position with two deliveries.
Outbound MT
Commands over an Iridium route call POST Data/DoSendSbdMessage with the thing id and the
frame [port][msg_id][len][data] in hex, at most 270 bytes, the framing the collar's
satellite receive path expects (wiki satellite page). The command reaches queued; Cloudloop
hands it to the collar at its next satellite session. Delivery statuses are not polled: an
MTMSN above zero in a later session says the modem received one queued message, which moves
the oldest pending command to transmitted, and the collar's answer confirms it through the
action's interpreter.
A route needs the thing id: from the first message's identity attributes, or from the management sync linked to the device.
Identity mapping
imei(15 digits): the hardware, from every message. Preferred identity.cloudloop_thing(32 characters, case sensitive): Cloudloop's device object, listed by the management sync only for a thing without hardware.
The management sync (Sync devices on the data source) joins Data/GetThings with
Sbd/GetSubscribers (the name and description shown in Cloudloop, the last seen time) and
Hardware/GetHardwares (the IMEI): a thing with a known IMEI is listed as the imei identity
its messages use, named after its subscriber, with the thing id as an attribute, so linking it
once serves the inbound path and commands before any message arrives.
Past messages
Data/GetMessageRecordsForThing (times as YYYY-MM-DD HH:MM:SS) lists a thing's messages
with their direction, size and a snippet of the first 128 bytes in hex; longer messages are
not available in full through the API, so a replay of past data is limited to messages of at
most 128 bytes. Data/GetPulseRecordsForDestination shows every delivery attempt with its
status.
Timestamps
sbd.sessionAt is when the satellite session ran, receivedAt when Cloudloop received the
message; both are provenance. The canonical time comes from the record inside the payload
(research 25.3): a fix delivered days later over satellite keeps its fix time.
What the session tells you
Every delivery carries the satellite session (ADR 0023): its outcome, the modem's session
counter (MOMSN), the size, and the network's estimate of where the modem was with its error
radius (CEP, in km). The traffic view shows them on the row, the source event dialog under
Provenance, and the device's Connectivity tab keeps the last session with the sessions, bytes,
missed sessions and redeliveries of the period, apart from the device's own health. An estimate the network stands by is also a position of
type network with its radius as accuracy (ADR 0024): it draws as a circle on the live map
("Network locations" in the Coverage tab), joins tracks, records and exports when asked, and
becomes the current position of a device or an entity only under its location source setting.
An estimate the network calls poor is kept on the session but never becomes a position. A retry of a delivery the server did not acknowledge is stored as a
duplicate, not processed twice. A fix far outside the estimate's circle is noted on the trace.
Troubleshooting
- 401 on the webhook: the URL lost its
?token=; copy it again from the data source (rotate the token if it leaked). - 403
Address ... may not post: the request came from an address outsideallowed_source_ips, or the proxy does not passX-Forwarded-For. - The identity is known but commands fail with
no Cloudloop thing id: no message arrived yet and the thing identity is not linked; run the management sync and link the thing. Cloudloop refused the token: the API token is wrong or was regenerated.- The deep link path (
{web_url}/things/{thing_id}) is a guess until seen live and can be overridden on the data source; the console lives athttps://console.cloudloop.com.