Geofencing
Manage geofencing subscriptions to provide notifications when devices enter or leave monitored areas
This playground version provides responses for:
- predefined phone numbers associated with the unassigned country code +990 (e.g +99012345678)
- user-defined phone numbers added using the Network APIs Playground - Admin
Introduction
The CAMARA Geofencing API provides a standardized mechanism for managing geofencing notification subscription. As API consumer you will be able to subscribe to get notification when a given device is entering of leaving a given geographical area. During the subscription request, the consumer will provide the device identifier, the area definition (as a circle) and the URL where the notification will be posted.
API Authentication
HTTPS requests to the REST API are protected with 2-Legged OAuth. To learn more about how Orange Developer handles authentication, please refer to our documentation.
In short, you will use your Orange Developer Authorization header as authorization_header for the Basic authentication with Orange Developer.
You get the Authorization header credentials when you register your application on the Orange Developer Console.
curl -X POST \
-H "Authorization: {{ authorization_header }}" \
-d "grant_type=client_credentials" \
https://api.orange.com/openidconnect/playground/v1.0/token
In response, you will get an access_token.
{
"token_type": "Bearer",
"access_token": "eyJ2ZXIiOiIxLjAiLCJ0eXAiOiJKV1Q.....ODSHIjf",
"expires_in": 3600
}
API Description
Summary of resources
This API has one resource subscriptions. The API allows to request subscriptions creation but also for a given API client to retrieve them and delete them.
Summary of methods and URL
| Use case of operation | URL method |
|---|---|
| I want to create a geofencing subscription to receive notification(s) on a specified URL, for a phone number and a geographical area | POST "https://api.orange.com/camara/playground/api/geofencing/v0.3/subscriptions" |
| I want to retrieve the list of my geofencing subscription(s) | GET "https://api.orange.com/camara/playground/api/geofencing/v0.3/subscriptions" |
| I want to terminate one (of mine) geofencing subscription | DELETE "https://api.orange.com/camara/playground/api/geofencing/v0.3/subscriptions/{subscriptionsId}" |
Summary of subscriptions body parameters
| Name | Description | Type | Mandatory |
|---|---|---|---|
| protocol | Identifier of a delivery protocol. Only HTTP is allowed for now. | String | Yes |
| sink | The address to which events shall be delivered using the selected protocol | String | Yes |
| sinkCredential | The type of the credential. if valued only ACCESSTOKEN is managed. See extension to provide if this field is valued. | string | No |
| types | Type of event subscribed: - area-entered: Event triggered when the device enters the given area. - area-left: Event triggered when the device leaves the given. Current implementation mandates to provide only one value | string | Yes |
| config | An object to define the subscription detail | See below information on config detail | Yes |
| id | Identifier of the event subscription - This attribute must not be present in the POST request as it is provided by API server. | String | Yes in response |
| startsAt | Date when the event subscription will begin/began. This attribute must not be present in the POST request as it is provided by API server. | Provided in date-time format. | No |
| expiresAt | Date when the event subscription will expire. This attribute must not be present in the POST request as it is provided by API server. | Provided in date-time format. | No |
| status | Current status of the subscription - Management of Subscription State engine is not implemented in our lab. | String | No |
Access Token extension schema:
| Name | Description | Type | Mandatory |
|---|---|---|---|
| accessToken | OAuth2 token to be used by the callback API endpoint. It MUST be indicated within HTTP Authorization header e.g. Authorization: Bearer $notificationAuthToken | string | Yes |
| accessTokenExpiresUtc | An absolute UTC instant at which the token shall be considered expired. | string (datetime) | Yes |
| accessTokenType | Must be valued to bearer. | string | Yes |
Definition of the Config structure:
The following table provides details about the device:
| Name | Description | Type | Format |
|---|---|---|---|
| subscriptionDetails | The detail of the requested event subscription | See below information on subscriptionDetails detail | Yes |
| subscriptionExpireTime | The time when the location-tracking has to be terminated (e.g. in 2 days from now on) - provided by the API consumer. | Provided in date-time format. | No |
| subscriptionMaxEvents | Identifies the maximum number of event reports to be generated (>=1) requested by the API consumer - Once this number is reached, the subscription ends. | Integer | No |
| initialEvent | Set to true by API consumer if consumer wants to get an event as soon as the subscription is created and current situation reflects event request. Example: Consumer request area entered event. If consumer sets initialEvent to true and device is already in the geofencing area, an event is triggered | Boolean | No |
Definition of the subscriptionDetails structure:
| Name | Description | Type | Mandatory |
|---|---|---|---|
| device | An object with four fields, each of them make possible to pass device identifier in different format: networkAccessIdentifier, phoneNumber, ipv4Address and ipv6Address | See below information on device | Yes |
| area | Used to define the geographical area to be monitored. | See below information on area | Yes |
Definition of the device structure:
Following table provide details about device:
| Name | Type | Format |
|---|---|---|
| networkAccessIdentifier | string | External Identifier format of the GPSI |
| phoneNumber | string | Subscriber number in E.164 format (starting with country code). Mandatory prefixed with '+' |
| Ipv4Address | string | IPv4 address may be specified in form <address/mask>. If address, we expect an IPv4 number in dotted-quad form 1.2.3.4. Only this exact IP number will match the flow control rule. If address/mask - an IP number as above with a mask width of the form 1.2.3.4/24. |
| Ipv6Address | string | IPv6 address, following IETF 5952 format, may be specified in form <address/mask>. If address, the /128 subnet is optional for single address (2001:db8:85a3:8d3:1319:8a2e:370:7344 or 2001:db8:85a3:8d3:1319:8a2e:370:7344/128). If address/mask, an IP v6 number with a mask (2001:db8:85a3:8d3::0/64 or 2001:db8:85a3:8d3::/64 ) |
Definition of the area structure:
| Name | Description | Type | Mandatory |
|---|---|---|---|
| areaType | Type of this area. Only CIRCLE value is managed | string | Yes |
| center | Structure to define circle center coordinates | See below information on center | Yes |
| radius | Accuracy expected for location verification in meters. Must between 2 000 and 200 000. | number | Yes |
Definition of the center structure:
| Name | Description | Type | Mandatory |
|---|---|---|---|
| latitude | Latitude component of location. Must between -90 and 90. | number | Yes |
| longitude | Longitude component of location. Must be between -180 and 180. | number | Yes |
Example of body request:
{
"protocol": "HTTP",
"sink": "https://notificationSendServer12.supertelco.com",
"types": [
"org.camaraproject.geofencing-subscriptions.v0.area-entered"
],
"config": {
"subscriptionDetail": {
"device": {
"phoneNumber": "+33699901032"
},
"area": {
"areaType": "CIRCLE",
"center": {
"latitude": "48.80",
"longitude": "2.259"
},
"radius": 2000
}
},
"initialEvent": true,
"subscriptionMaxEvents": 10,
"subscriptionExpireTime": "2024-03-22T05:40:58.469Z"
}
}
You can also create test phone numbers using the Network APIs Playground - Admin API
| Phone Number |
|---|
| +99012345678 |
| +990111222333 |
Request geofencing subscription creation (from MSISDN)
Request
curl -X POST "https://api.orange.com/camara/playground/api/geofencing/v0.3/subscriptions"
-H "Authorization: Bearer {your access token}"
-H "Cache-Control: no-cache"
-H 'accept: application/json'
-H 'Content-Type: application/json'
-d '{
"protocol": "HTTP",
"sink": "https://notificationSendServer12.supertelco.com",
"types": [
"org.camaraproject.geofencing-subscriptions.v0.area-entered"
],
"config": {
"subscriptionDetail": {
"device": {
"phoneNumber": "+99012345678"
},
"area": {
"areaType": "CIRCLE",
"center": {
"latitude": "48.80",
"longitude": "2.259"
},
"radius": 2000
}
},
"initialEvent": true,
"subscriptionMaxEvents": 10,
"subscriptionExpireTime": "2024-03-22T05:40:58.469Z"
}
}
Response
201 created
Content-Type: application/json
{
"protocol": "HTTP",
"sink": "https://endpoint.example.com/sink",
"sinkCredential": {
"credentialType": "PLAIN"
},
"types": [
"string"
],
"config": {
"subscriptionDetail": {
"device": {
"phoneNumber": "+99012345678"
},
"area": {
"areaType": "CIRCLE",
"center": {
"latitude": "48.80",
"longitude": "2.259"
},
"radius": 2000
}
},
"subscriptionExpireTime": "2023-01-17T13:18:23.682Z",
"subscriptionMaxEvents": 5,
"initialEvent": true
},
"id": "1119920371",
"startsAt": "2024-07-11T19:08:47.612Z",
"expiresAt": "2024-07-11T19:08:47.612Z",
"status": "ACTIVE"
}
Retrieve geofencing subscription list
All subscriptions created from the requesting client_id are provided. In the response, an array of subscriptions is provided. The complete representation of the subscription resource is provided (same structure as POST response)
Request
curl -X GET "https://api.orange.com/camara/playground/api/geofencing/v0.3/subscriptions"
-H "Authorization: Bearer {your access token}"
-H "Cache-Control: no-cache"
-H 'accept: application/json'
-H 'Content-Type: application/json'
Response
200 OK
Content-Type: application/json
[{
"protocol": "HTTP",
"sink": "https://endpoint.example.com/sink",
"sinkCredential": {
"credentialType": "PLAIN"
},
"types": [
"string"
],
"config": {
"subscriptionDetail": {
"device": {
"phoneNumber": "+99012345678"
},
"area": {
"areaType": "CIRCLE",
"center": {
"latitude": "48.80",
"longitude": "2.259"
},
"radius": 2000
}
},
"subscriptionExpireTime": "2023-01-17T13:18:23.682Z",
"subscriptionMaxEvents": 5,
"initialEvent": true
},
"id": "1119920371",
"startsAt": "2024-07-11T19:08:47.612Z",
"expiresAt": "2024-07-11T19:08:47.612Z",
"status": "ACTIVE"
]
Retrieve one geofencing subscription from its id
The subscription is retrieved only if it exists a subscription with this id for same client than the one requesting this GET operation.
In the response, a subscription is provided. The complete representation of the subscription resource is provided (same structure as POST response)
Request
curl -X GET "https://api.orange.com/camara/playground/api/geofencing/v0.3/subscriptions/{subscriptionsId}"
-H "Authorization: Bearer {your access token}"
-H "Cache-Control: no-cache"
-H 'accept: application/json'
-H 'Content-Type: application/json'
Response
The complete representation of the subscription resource is provided (same structure that POST response)
Delete one geofencing subscription
The subscription is deleted only if it exists a subscription with this id for same client than the one requesting this DELETE operation.
Request
curl -X DELETE "https://api.orange.com/camara/playground/api/geofencing/v0.3/subscriptions/{subscriptionsId}"
-H "Authorization: Bearer {your access token}"
-H "Cache-Control: no-cache"
-H 'accept: application/json'
-H 'Content-Type: application/json'
Response
204 Event subscription deleted
Most frequent errors
If invalid input are provided in POST /subscriptions, in particular for the device identifier, a 400 error is triggered.
HTTP/1.1 400 Invalid input
Content-Type: application/json
{
"code": "INVALID_ARGUMENT",
"status": 400,
"message": "Invalid input"
}
If the consumer request for a non existing subscription in GET /subscriptions/{subscriptionsId}, a 404 error is sent.
HTTP/1.1 404 Not found
Content-Type: application/json
{
"status": 404,
"code": "NOT_FOUND",
"message": "The specified resource is not found"
}
If the subscription service is down, a 503 error is sent.
HTTP/1.1 503 Service unavailable
Content-Type: application/json
{
"code": "UNAVAILABLE",
"status": 503,
"message": "Service unavailable"
}
There are some cases where your client application will no longer gain access to API resources, and get an error back.
Please check the following points:
- Here, you attempt to use an expired or revoked access_token and you get an invalid token error. You will have to request a new access_token. As an example:
HTTP/1.1 401 Unauthorized
Content-Type: application/json
{
"code": "UNAUTHENTICATED",
"status": 401,
"message": "Authorization failed: ..."
}
- Here, you removed your subscription to the API so that the capability to generate an access_token is not allowed anymore. As an example:
HTTP/1.1 403 Forbidden
Content-Type: application/json
{
"code": "PERMISSION_DENIED",
"status": 403,
"message": "Operation not allowed: ..."
}
Notifications
Notifications will be received at consumer side, on the URL provided in the subscriptions.notificationUrl field in the subscription request (see above).
The API contains also the Notification definition in the callbacks part. The CAMARA subscription model is detailed in the CAMARA API design guideline document and follows CloudEvents specification.
Following event types are managed for this API:
org.camaraproject.geofencing.v0.area-entered- Event triggered when the device enters the given areaorg.camaraproject.geofencing.v0.area-left- Event triggered when the device leaves the given area
Note: Additionally to these list, org.camaraproject.geofencing.v0.subscription-ends notification type is sent when the subscription ends. This notification does not require dedicated subscription. It is used when the subscription expire time (required by the requester) has been reached or if the API server has to stop sending notification prematurely.
Notification structure:
Following table describes the notification structure:
| Name | Description | Type | Mandatory |
|---|---|---|---|
| id | Identifier of this event, that must be unique in the source context. | string | Yes |
| source | Identifies the context in which an event happened in the specific Provider Implementation. | string | Yes |
| type | Identifies the type of the event: -area-entered: Event triggered when the device enters the given area. -area-left: Event triggered when the device leaves the given area. -subscription-ends: Event triggered when the subscription ends | string | Yes |
| specversion | Version of the specification to which this event conforms (always 1.0 in our case) | string | Yes |
| datacontenttype | media-type that describes the event payload encoding, (always "application/json" in our case) | string | No |
| time | Timestamp when the occurrence happened. | string - datetime | Yes |
| data | Data structure specific for each event type - see below | object | Yes |
data for area-entered and area-left notification
The subscription area-entered or area-left notification data structure is the following:
| Name | Description | Type | Mandatory |
|---|---|---|---|
| subscriptionId | Identifier of subscription | string | Yes |
| device | An object with four fields, each of them make possible to pass device identifier in different format: networkAccessIdentifier, phoneNumber, ipv4Address and ipv6Address | See above information on device | Yes |
| area | Used to define the geographical area to be monitored. | See above information on area | Yes |
Example of notification received:
HTTP/1.1 403 Forbidden
Content-Type: application/json
{
"id": "6a11dad7-64b3-4f12-a28f-8a24411fe8e0",
"source": "com.orange.camara.geofencing",
"type": "org.camaraproject.geofencing.v0.area-entered",
"specversion": "1.0",
"datacontenttype": "application/json",
"data": {
"device": {
"phoneNumber": "+99012345678"
},
"area": {
"areaType": "CIRCLE",
"center": {
"latitude": 48.8,
"longitude": 2.29
},
"radius": 2000
},
"subscriptionId": "5c9b3fa2-6d65-4768-ba52-a7281a525789"
},
"time": "2024-01-16T15:37:04.052088556Z"
}
data for area-entered and subscription_ends notification
The subscription ends notification data structure is the following:
| Name | Description | Type | Mandatory |
|---|---|---|---|
| subscriptionId | Identifier of subscription | string | Yes |
| device | An object with four fields, each of them make possible to pass device identifier in different format: networkAccessIdentifier, phoneNumber, ipv4Address and ipv6Address | See above information on device | Yes |
| area | Used to define the geographical area to be monitored. | See above information on area | Yes |
| terminationReason | Termination reason | string | Yes |
Example of notification received:
HTTP/1.1 403 Forbidden
Content-Type: application/json
{
"id": "9f625ec0-f8d6-4ef2-a1ee-62a0424b4cc9",
"source": "com.orange.camara.geofencing",
"type": "org.camaraproject.geofencing.v0.subscription-ends",
"specversion": "1.0",
"datacontenttype": "application/json",
"data": {
"device": {
"phoneNumber": "+99012345678"
},
"terminationReason": "SUBSCRIPTION_EXPIRED",
"area": {
"areaType": "CIRCLE",
"center": {
"latitude": 48.8,
"longitude": 2.29
},
"radius": 2000
},
"subscriptionId": "19fbaf8d-0b76-4fde-a8d1-5991613e2ab1"
},
"time": "2024-01-16T15:26:29.388137893Z"
}