Geofencing

The geofencing functionality allows applications to track when a given device enters or leaves a location based on the coordinates and radius or a named point of interest that have been provided.

Geofencing works off the same location information as location retrieval and verification. This means that in some cases where the area is defined as a circle, accuracy is on cell tower level, so specifying too small of an area may result in incomplete or inaccurate results and in some countries or on some networks the minimum radius may be regulated. Therefore, this functionality is best applied to situations where a course-grained location notification is desired.

Subscribing to geofencing notificationsheader link

Creating basic geofencing subscriptionsheader link

The snippet below allows you to subscribe a specific device to geofencing. It creates a geofenced circle of 2000 meters centered on latitude 47.48627616952785 and longitude 19.07915612501993 and will send a notification to https://example.com/notifications if the device enters this region.

import datetime
from network_as_code import NetworkAsCodeApi

client = NetworkAsCodeApi(
    rapidapi_host="network-as-code.nokia.rapidapi.com",
    api_key="YOUR_API_KEY",
)

subscription = client.geofencing.create_subscription(
    protocol="HTTP",
    sink="https://example.com/notifications",
    types=["org.camaraproject.geofencing-subscriptions.v0.area-entered"],
    config={
        "subscription_detail": {
            "device": {"phone_number": "+99999123456"},
            "area": {
                "area_type": "CIRCLE",
                "center": {
                    "latitude": 47.48627616952785,
                    "longitude": 19.07915612501993,
                },
                "radius": 2000,
            },
        },
    },
)

Creating geofencing subscriptions with optional parametersheader link

It's also possible to pass in optional parameters to the subscription:

from network_as_code import NetworkAsCodeApi
import datetime

client = NetworkAsCodeApi(
    rapidapi_host="network-as-code.nokia.rapidapi.com",
    api_key="YOUR_API_KEY",
)

subscription = client.geofencing.create_subscription(
    protocol="HTTP",
    sink="https://example.com/notifications",
    types=["org.camaraproject.geofencing-subscriptions.v0.area-left"],
    config={
        "subscription_detail": {
            "device": {"phone_number": "+99999123456"},
            "area": {
                "area_type": "CIRCLE",
                "center": {"latitude": 47.48627616952785, "longitude": 19.07915612501993},
                "radius": 2000,
            },
        },
        "subscription_expire_time": datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(days=1),
        "subscription_max_events": 1,
        "initial_event": True,
    },
    sink_credential={
        "credential_type": "PLAIN",
        "identifier": "client-id",
        "secret": "client-secret",
    },
)

Geofencing parametersheader link

ParameterTypeDescriptionMandatory or Optional
protocolstrIdentifier of a delivery protocol. Only HTTP is allowed for now.Mandatory
sinkstrThe address to which events shall be delivered using the selected protocol.Mandatory
typeslist[str]CAMARA event types eligible to be delivered by this subscription. Note: only one event type per subscription is enforced.Mandatory
configdictImplementation-specific configuration parameters needed by the subscription manager for acquiring events. Includes predefined attributes like subscription_expire_time, subscription_max_events, and initial_event. Specific event type attributes must be defined in subscription_detail.Mandatory
config.subscription_detaildictContains the specific event type attributes, including the target device and area.Mandatory
config.subscription_detail.devicedictIdentifies the device to monitor, e.g. via phone_number.Mandatory
config.subscription_detail.areadictDefines the geographic area to monitor, e.g. via area_type.Mandatory
config.subscription_expire_timedatetimeThe date and time when the subscription will expire.Optional
config.subscription_max_eventsintThe maximum number of events to be delivered for this subscription.Optional
config.initial_eventboolIf true, an initial event is triggered immediately upon subscription creation reflecting the current state.Optional
sink_credentialdictSpecifies how the notification is authenticated, including the authentication information.Optional

Geofencing event typesheader link

Event typeTypeDescription
area-enteredstringorg.camaraproject.geofencing-subscriptions.v0.area-entered - Used for checking if the device is connected to the network for data usage.
area-leftstringorg.camaraproject.geofencing-subscriptions.v0.area-left - Used for checking if the device is connected to the network for SMS usage.

Credential typesheader link

ParametersTypeDescription
Plainstring"PLAIN". A plain credential as a combination of an identifier and a secret.
AccessTokenstring"ACCESSTOKEN". An access token credential. An access token is a previously acquired token granting access to the target resource.

Receiving geofencing notificationsheader link

Geofencing notifications are delivered using CloudEvents to the event sink specified in the subscription. Network as Code currently only supports delivery via HTTP, which means that notifications will be sent as POST requests to the sink URL and will contain the event information as a JSON payload.

The notifications will also come with identifying information specified by the sink credentials.

There are three types of geofencing notifications that you may receive:

Notification typeTypeDescription
area-enteredstringorg.camaraproject.geofencing-subscriptions.v0.area-entered - Notifications sent if the device enters into geofenced area.
area-leftstringorg.camaraproject.geofencing-subscriptions.v0.area-left - Notifications sent if the device leaves geofenced area.
subscription-endsstringorg.camaraproject.geofencing-subscriptions.v0.subscription-ends - Notifications sent if geofencing subscription has been terminated.

Area entry notification will have a request body of the following schema:

{
  "id": "event-id-random-123",
  "source": "/whatever-api/v1/subscriptions/123",
  "time": "2025-07-01T14:15:16.789Z",
  "specversion" : "1.0",
  "type": "org.camaraproject.geofencing-subscriptions.v0.area-entered",
  "datacontenttype" : "application/json",
  "data": {
    "subscriptionId": "subscriptionId-123",
    "device": {...},
    "area": {...}
  }
}

Area left notification schema is:

{
  "id": "event-id-random-123",
  "source": "/whatever-api/v1/subscriptions/123",
  "time": "2025-07-01T14:15:16.789Z",
  "specversion" : "1.0",
  "type": "org.camaraproject.geofencing-subscriptions.v0.area-left",
  "datacontenttype" : "application/json",
  "data": {
    "subscriptionId": "subscriptionId-123",
    "device": {...},
    "area": {...}
  }
}

And subscription termination will result in:

{
  "id": "event-id-random-123",
  "source": "/whatever-api/v1/subscriptions/123",
  "time": "2025-07-01T14:15:16.789Z",
  "specversion" : "1.0",
  "type": "org.camaraproject.geofencing-subscriptions.v0.subscription-ends",
  "datacontenttype" : "application/json",
  "data": {
    "subscriptionId": "subscriptionId-123",
    "device": {...},
    "area": {...},
    "terminationReason": "..."
  }
}

The termination reason may be one of the following:

Termination reasonsTypeDescription
NETWORK_TERMINATEDstringAPI server stopped sending notification.
SUBSCRIPTION_UNPROCESSABLEstringSubscription cannot be processed due to some reason, e.g. because the specified area cannot be managed.
SUBSCRIPTION_EXPIREDstringSubscription expire time (optionally set by the requester) has been reached.
SUBSCRIPTION_DELETEDstringSubscription was deleted by the requester.
MAX_EVENTS_REACHEDstringMaximum number of events (optionally set by the requester) has been reached.
ACCESS_TOKEN_EXPIREDstringAccess Token sinkCredential (optionally set by the requester) expiration time has been reached.

Notification-keyword valuesheader link

Notification-keyword valuesTypeDescription
idstringThe event identifier.
sourcestringIdentifies the source where the event happened. It contains the Network as Code API implementation and subscription ID.
timestringTime when the event occurred. Date and time are specified in ISO 8601 format, e.g.: "2025-08-20T21:01:02.345Z".
typestringValue returned by the API with different statuses. Can be area-entered, area-left or subscription-ends. For example org.camaraproject.geofencing-subscriptions.v0.area-left.
specversionstringRepresents the specification version.
datacontenttypestringIt indicates the media type for the event payload encoding. It must be "application/json" in the context of CAMARA APIs.
dataobjectContains multiple subscription data, e.g. the subscription id and the geofencing area.

Managing geofencing subscriptionsheader link

Get all active subscriptionsheader link

All of the currently active Geofencing subscriptions can be fetched using the get-all functionality. This will return a list containing the details of each subscription that hasn't yet been terminated.

from network_as_code import NetworkAsCodeApi

client = NetworkAsCodeApi(
    rapidapi_host="network-as-code.nokia.rapidapi.com",
    api_key="YOUR_API_KEY",
)

subscriptions = client.geofencing.list_subscriptions()

Get subscription by IDheader link

Geofencing subscriptions can also be fetched by subscription ID, if you already know it. This will just return the single subscription with that ID, assuming that it has not been terminated.

from network_as_code import NetworkAsCodeApi

client = NetworkAsCodeApi(
    rapidapi_host="network-as-code.nokia.rapidapi.com",
    api_key="<YOUR_API_KEY>",
)

same_subscription = client.geofencing.get_subscription(subscription_id="<my-subscription-id>")

Delete subscriptionheader link

Subscriptions can be manually terminated by deleting them. This is done by calling the delete method or endpoint.

from network_as_code import NetworkAsCodeApi

client = NetworkAsCodeApi(
    rapidapi_host="network-as-code.nokia.rapidapi.com",
    api_key="<YOUR_API_KEY>",
)

client.geofencing.delete_subscription("<my-subscription-id>")

Last updated June 16, 2026