Organizations & Device Groups
Structure your fleet: use organizations as sub-accounts and device groups to cluster trackers by route, terminal, or customer.
Organizations & device groups
As a fleet grows from a handful of trackers to hundreds of reefers across several terminals, two concepts keep it organized:
- Organizations — sub-accounts that isolate devices and their data (e.g. one per customer or region).
- Device groups — lightweight clusters of devices within an organization (e.g. one per route or cold-storage terminal).
Both are managed through the Platform API (https://api.surfact.com/api/v2.0/).
| Goal | Endpoint | Method |
|---|---|---|
| Retrieve an organization (account-scoped token only — see below) | /organizations/{organization_id}/ | GET |
| List an organization's devices | /organizations/{organization_id}/devices/ | GET |
| List / create device groups | /device_groups/ | GET / POST |
| Retrieve / update / delete a device group | /device_groups/{device_group_id}/ | GET / PATCH / DELETE |
| List devices in a group | /device_groups/{device_group_id}/devices/ | GET |
| Add devices to a group | /device_groups/{device_group_id}/_/assign_devices/ | POST |
| Remove devices from a group | /device_groups/{device_group_id}/_/remove_devices/ | POST |
Look inside an organization
List everything that belongs to an organization — this works with an ordinary API token:
curl -X GET 'https://api.surfact.com/api/v2.0/organizations/~nordic-cold-chain/devices/' \
-H 'X-Auth-Token: your_token_here'The same pattern works for the organization's dashboards (/organizations/{organization_id}/dashboards/).
Reading the organization object itself is a separate matter:
curl -X GET 'https://api.surfact.com/api/v2.0/organizations/~nordic-cold-chain/' \
-H 'X-Auth-Token: your_token_here'
Permission denied on the organization objectWith an ordinary API token, both
GET /organizations/andGET /organizations/{organization_id}/return403, regardless of whether you address the organization by id or by~label:{ "detail": "You do not have permission to perform this action." }Note that this body carries a
detailfield rather than thecode/messagepair the other errors use. Reading the organization object requires an organization- or account-scoped token. The sub-resources above (/devices/,/dashboards/) are unaffected and return200for every reader, so use those when you only need the organization's contents.
Group devices by route or terminal
Device groups make it easy to monitor a slice of the fleet together — say, every reefer running frozen routes:
curl -X POST 'https://api.surfact.com/api/v2.0/device_groups/' \
-H 'Content-Type: application/json' \
-H 'X-Auth-Token: your_token_here' \
-d '{
"label": "nordic-frozen-fleet",
"name": "Nordic Frozen Fleet",
"organization": "~nordic-cold-chain",
"tags": ["frozen"]
}'A new group starts empty. Membership is not set through the group's devices field — that field is read-only, and a PATCH containing it is silently ignored. Use the dedicated assignment endpoint instead:
curl -X POST 'https://api.surfact.com/api/v2.0/device_groups/~nordic-frozen-fleet/_/assign_devices/' \
-H 'Content-Type: application/json' \
-H 'X-Auth-Token: your_token_here' \
-d '[
"~reefer-trailer-21",
"~reefer-trailer-22",
{ "id": "6865acef80bcac000f4ca5db" }
]'Each entry may be a device id, a ~label, or an object with an id — you can mix all three in one call. The response is a paginated list of the devices now in the group:
{
"count": 3,
"next": null,
"previous": null,
"results": [
{
"url": "https://api.surfact.com/api/v2.0/devices/6865acf980bcac000f4ca5ec",
"id": "6865acf980bcac000f4ca5ec",
"label": "reefer-trailer-21",
"name": "Reefer Trailer 21",
"createdAt": "2026-01-15T08:30:00Z"
}
]
}By default the devices you send are appended to the group. Pass ?clear=true to replace the whole membership with exactly the devices in the request:
curl -X POST 'https://api.surfact.com/api/v2.0/device_groups/~nordic-frozen-fleet/_/assign_devices/?clear=true' \
-H 'Content-Type: application/json' \
-H 'X-Auth-Token: your_token_here' \
-d '["~reefer-trailer-21"]'Take devices back out with remove_devices, which accepts the same three identifier forms and returns an empty result set:
curl -X POST 'https://api.surfact.com/api/v2.0/device_groups/~nordic-frozen-fleet/_/remove_devices/' \
-H 'Content-Type: application/json' \
-H 'X-Auth-Token: your_token_here' \
-d '["~reefer-trailer-22"]'List the members of a group at any time:
curl -X GET 'https://api.surfact.com/api/v2.0/device_groups/~nordic-frozen-fleet/devices/' \
-H 'X-Auth-Token: your_token_here'
Device groups are also the cleanest target for fleet-wide alerts — an event can watch a whole group'stemperaturevariable instead of each device individually.
Organizations vs. device groups
| Organization | Device group | |
|---|---|---|
| Purpose | Isolation (a separate account boundary) | Convenience clustering within an account |
| Hard access boundary | Yes | No |
| Typical cold-chain use | One per customer or country | One per route, terminal, or temperature class |
Use an organization when you need a hard boundary (a customer shouldn't see another customer's reefers); use a device group when you just want to slice your own fleet for monitoring and alerts.
Updated 7 days ago