Create a geofence and activate it
const url = 'https://api.elwids.xyz/api/integration/v1/organizations/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0/geofences';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"operation_uuid":"9f8e7d6c-5b4a-4392-8170-6f5e4d3c2b1a","expected_revision":0,"name":"North paddock","geometry":{"type":"Polygon","coordinates":[[[-114.01,50.99],[-113.99,50.99],[-113.99,51.01],[-114.01,51.01],[-114.01,50.99]]]},"assignments":[{"device_uuid":"3f8a1c2e-5b6d-4e7f-8a9b-0c1d2e3f4a5b","policy":{"outside_for_seconds":60,"max_gap_seconds":45,"minimum_samples":2,"uncertainty_metres":2}}]}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://api.elwids.xyz/api/integration/v1/organizations/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0/geofences \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "operation_uuid": "9f8e7d6c-5b4a-4392-8170-6f5e4d3c2b1a", "expected_revision": 0, "name": "North paddock", "geometry": { "type": "Polygon", "coordinates": [ [ [ -114.01, 50.99 ], [ -113.99, 50.99 ], [ -113.99, 51.01 ], [ -114.01, 51.01 ], [ -114.01, 50.99 ] ] ] }, "assignments": [ { "device_uuid": "3f8a1c2e-5b6d-4e7f-8a9b-0c1d2e3f4a5b", "policy": { "outside_for_seconds": 60, "max_gap_seconds": 45, "minimum_samples": 2, "uncertainty_metres": 2 } } ] }'Requires: geofences:activate and geofences:manage
Rate limits: 240 a minute per address, 60 a minute per application
Saves a new geofence (revision 1) with one workflow per assigned device, then starts their activation and returns 202 with the activation to poll. Needs geofences:activate and geofences:manage. Idempotent on operation_uuid. 403 when an assigned device is not granted; 404 when an assigned device has no location binding; 409 when operation_uuid was used for a different request or expected_revision is not 0; 422 for invalid input, or when the runtime rejects the geofence (a message, or errors.runtime); 503 when the runtime is unavailable.
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Path Parameters
Section titled “Path Parameters”The organization UUID. A value that does not match returns 404.
Request Bodyrequired
Section titled “Request Bodyrequired”A geofence to save and activate. Every assigned device must be granted to the application and have a location binding.
object
Idempotency key and the activation’s UUID. Repeating the same request returns the same result; reusing it for a different request returns 409.
The revision the client last read; a stale value returns 409. Defaults to 0 when creating (which must stay 0) and to the current revision when updating.
Only type and coordinates; any other member is rejected.
object
Devices to assign; each device_uuid at most once. Devices left out are removed.
object
When a device counts as wandering outside the geofence.
object
Example
{ "operation_uuid": "9f8e7d6c-5b4a-4392-8170-6f5e4d3c2b1a", "expected_revision": 0, "name": "North paddock", "geometry": { "type": "Polygon", "coordinates": [ [ [ -114.01, 50.99 ], [ -113.99, 50.99 ], [ -113.99, 51.01 ], [ -114.01, 51.01 ], [ -114.01, 50.99 ] ] ] }, "assignments": [ { "device_uuid": "3f8a1c2e-5b6d-4e7f-8a9b-0c1d2e3f4a5b", "policy": { "outside_for_seconds": 60, "max_gap_seconds": 45, "minimum_samples": 2, "uncertainty_metres": 2 } } ]}Responses
Section titled “Responses”Saved; the activation is under way. Poll activation.
The saved geofence and the activation to poll.
object
A geofence, with only the assignments of devices granted to the application.
object
A GeoJSON Polygon with one ring of 4 to 257 positions.
object
One device assigned to the geofence, with its own workflow.
object
When a device counts as wandering outside the geofence.
object
pending, active, failed or removing.
object
The assignment workflow’s deployment status, for example pending, active or inactive.
The activation of one geofence revision: one item per assignment to activate or remove. Poll it until status is no longer pending.
object
The operation_uuid the client sent.
object
Pass as item to retry a failed item.
The workflow deployment that applies this item.
pending, succeeded or failed, following the workflow deployment.
Example
{ "data": { "uuid": "1e2d3c4b-5a69-4788-9a6b-5c4d3e2f1a0b", "name": "North paddock", "geometry": { "type": "Polygon", "coordinates": [ [ [ -114.01, 50.99 ], [ -113.99, 50.99 ], [ -113.99, 51.01 ], [ -114.01, 51.01 ], [ -114.01, 50.99 ] ] ] }, "revision": 1, "created_at": "2026-10-12T08:00:00.000000Z", "updated_at": "2026-10-12T08:00:00.000000Z", "assignments": [ { "uuid": "4c5d6e7f-8a9b-4c0d-9e1f-2a3b4c5d6e7f", "policy": { "outside_for_seconds": 60, "max_gap_seconds": 45, "minimum_samples": 2, "uncertainty_metres": 2 }, "desired_geofence_revision": 1, "applied_geofence_revision": null, "status": "pending", "diagnostic": null, "device": { "uuid": "3f8a1c2e-5b6d-4e7f-8a9b-0c1d2e3f4a5b", "name": "Herd tracker 17", "code": "tracker-017" }, "workflow_uuid": "5a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d", "deployment_status": "pending" } ] }, "activation": { "uuid": "9f8e7d6c-5b4a-4392-8170-6f5e4d3c2b1a", "geofence_revision": 1, "status": "pending", "created_at": "2026-10-12T08:00:00.000000Z", "updated_at": "2026-10-12T08:00:00.000000Z", "items": [ { "id": 41, "assignment_uuid": "4c5d6e7f-8a9b-4c0d-9e1f-2a3b4c5d6e7f", "device_uuid": "3f8a1c2e-5b6d-4e7f-8a9b-0c1d2e3f4a5b", "operation_uuid": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d", "target": "active", "status": "pending", "diagnostic": null } ] }}Headers
Section titled “Headers”Responses to authenticated integration requests are never cached. The header also carries private.
Example
no-store, privateNo valid credentials: no session (first-party API), or a missing, invalid, expired or revoked application token (integration API).
The body of most error responses.
object
Example generated
{ "message": "example"}The caller is not allowed: not a member of the organization, missing a tenant or platform permission, or (integration API) an ability not granted on both the application and the token.
The body of most error responses.
object
Example generated
{ "message": "example"}Not found: an unknown organization or resource, a resource in another organization or not granted to the application, or a malformed identifier (the route does not match).
The body of most error responses.
object
Example generated
{ "message": "example"}The request conflicts with the current state, for example a stale revision.
The body of most error responses.
object
Example generated
{ "message": "example"}The input failed validation (errors names the fields), or the request cannot be applied in the resource’s current state (a message only, for example an archived device or a limit reached).
422 for input that failed validation.
object
The first error, followed by a count of the others.
Messages per field, keyed by the field’s dotted path. A rejection by the device runtime appears under runtime.
object
The body of most error responses.
object
Example generated
{ "message": "example", "errors": { "runtime": [ "example" ] }}A rate limit was reached; see x-rate-limits on the operation.
The body of most error responses.
object
Example generated
{ "message": "example"}Headers
Section titled “Headers”Seconds to wait before retrying.
The device runtime is not configured, unavailable, or could not complete the request.
The body of most error responses.
object
Example generated
{ "message": "example"}